annotate gcc/config/gcn/gcn-tree.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
145
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1 /* Copyright (C) 2017-2020 Free Software Foundation, Inc.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3 This file is part of GCC.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
4
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
5 GCC is free software; you can redistribute it and/or modify it under
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
6 the terms of the GNU General Public License as published by the Free
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
7 Software Foundation; either version 3, or (at your option) any later
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
8 version.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
9
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
10 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
13 for more details.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
14
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
15 You should have received a copy of the GNU General Public License
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
16 along with GCC; see the file COPYING3. If not see
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
17 <http://www.gnu.org/licenses/>. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
18
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
19 /* {{{ Includes. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
20
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
21 #include "config.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
22 #include "system.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
23 #include "coretypes.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
24 #include "backend.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
25 #include "target.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
26 #include "tree.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
27 #include "gimple.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
28 #include "tree-pass.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
29 #include "gimple-iterator.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
30 #include "cfghooks.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
31 #include "cfgloop.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
32 #include "tm_p.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
33 #include "stringpool.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
34 #include "fold-const.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
35 #include "varasm.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
36 #include "omp-low.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
37 #include "omp-general.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
38 #include "internal-fn.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
39 #include "tree-vrp.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
40 #include "tree-ssanames.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
41 #include "tree-ssa-operands.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
42 #include "gimplify.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
43 #include "tree-phinodes.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
44 #include "cgraph.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
45 #include "targhooks.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
46 #include "langhooks-def.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
47
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
48 /* }}} */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
49 /* {{{ OMP GCN pass.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
50
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
51 This pass is intended to make any GCN-specfic transformations to OpenMP
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
52 target regions.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
53
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
54 At present, its only purpose is to convert some "omp" built-in functions
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
55 to use closer-to-the-metal "gcn" built-in functions. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
56
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
57 unsigned int
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
58 execute_omp_gcn (void)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
59 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
60 tree thr_num_tree = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
61 tree thr_num_id = DECL_NAME (thr_num_tree);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
62 tree team_num_tree = builtin_decl_explicit (BUILT_IN_OMP_GET_TEAM_NUM);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
63 tree team_num_id = DECL_NAME (team_num_tree);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
64 basic_block bb;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
65 gimple_stmt_iterator gsi;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
66 unsigned int todo = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
67
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
68 FOR_EACH_BB_FN (bb, cfun)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
69 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
70 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
71 gimple *call = gsi_stmt (gsi);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
72 tree decl;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
73
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
74 if (is_gimple_call (call) && (decl = gimple_call_fndecl (call)))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
75 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
76 tree decl_id = DECL_NAME (decl);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
77 tree lhs = gimple_get_lhs (call);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
78
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
79 if (decl_id == thr_num_id)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
80 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
81 if (dump_file && (dump_flags & TDF_DETAILS))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
82 fprintf (dump_file,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
83 "Replace '%s' with __builtin_gcn_dim_pos.\n",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
84 IDENTIFIER_POINTER (decl_id));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
85
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
86 /* Transform this:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
87 lhs = __builtin_omp_get_thread_num ()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
88 to this:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
89 lhs = __builtin_gcn_dim_pos (1) */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
90 tree fn = targetm.builtin_decl (GCN_BUILTIN_OMP_DIM_POS, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
91 tree fnarg = build_int_cst (unsigned_type_node, 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
92 gimple *stmt = gimple_build_call (fn, 1, fnarg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
93 gimple_call_set_lhs (stmt, lhs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
94 gsi_replace (&gsi, stmt, true);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
95
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
96 todo |= TODO_update_ssa;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
97 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
98 else if (decl_id == team_num_id)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
99 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
100 if (dump_file && (dump_flags & TDF_DETAILS))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
101 fprintf (dump_file,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
102 "Replace '%s' with __builtin_gcn_dim_pos.\n",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
103 IDENTIFIER_POINTER (decl_id));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
104
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
105 /* Transform this:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
106 lhs = __builtin_omp_get_team_num ()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
107 to this:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
108 lhs = __builtin_gcn_dim_pos (0) */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
109 tree fn = targetm.builtin_decl (GCN_BUILTIN_OMP_DIM_POS, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
110 tree fnarg = build_zero_cst (unsigned_type_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
111 gimple *stmt = gimple_build_call (fn, 1, fnarg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
112 gimple_call_set_lhs (stmt, lhs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
113 gsi_replace (&gsi, stmt, true);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
114
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
115 todo |= TODO_update_ssa;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
116 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
117 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
118 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
119
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
120 return todo;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
121 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
122
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
123 namespace
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
124 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
125
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
126 const pass_data pass_data_omp_gcn = {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
127 GIMPLE_PASS,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
128 "omp_gcn", /* name */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
129 OPTGROUP_NONE, /* optinfo_flags */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
130 TV_NONE, /* tv_id */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
131 0, /* properties_required */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
132 0, /* properties_provided */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
133 0, /* properties_destroyed */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
134 0, /* todo_flags_start */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
135 TODO_df_finish, /* todo_flags_finish */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
136 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
137
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
138 class pass_omp_gcn : public gimple_opt_pass
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
139 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
140 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
141 pass_omp_gcn (gcc::context *ctxt)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
142 : gimple_opt_pass (pass_data_omp_gcn, ctxt)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
143 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
144 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
145
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
146 /* opt_pass methods: */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
147 virtual bool gate (function *)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
148 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
149 return flag_openmp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
150 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
151
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
152 virtual unsigned int execute (function *)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
153 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
154 return execute_omp_gcn ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
155 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
156
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
157 }; /* class pass_omp_gcn. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
158
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
159 } /* anon namespace. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
160
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
161 gimple_opt_pass *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
162 make_pass_omp_gcn (gcc::context *ctxt)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
163 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
164 return new pass_omp_gcn (ctxt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
165 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
166
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
167 /* }}} */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
168 /* {{{ OpenACC reductions. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
169
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
170 /* Global lock variable, needed for 128bit worker & gang reductions. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
171
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
172 static GTY(()) tree global_lock_var;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
173
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
174 /* Lazily generate the global_lock_var decl and return its address. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
175
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
176 static tree
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
177 gcn_global_lock_addr ()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
178 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
179 tree v = global_lock_var;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
180
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
181 if (!v)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
182 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
183 tree name = get_identifier ("__reduction_lock");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
184 tree type = build_qualified_type (unsigned_type_node,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
185 TYPE_QUAL_VOLATILE);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
186 v = build_decl (BUILTINS_LOCATION, VAR_DECL, name, type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
187 global_lock_var = v;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
188 DECL_ARTIFICIAL (v) = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
189 DECL_EXTERNAL (v) = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
190 TREE_STATIC (v) = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
191 TREE_PUBLIC (v) = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
192 TREE_USED (v) = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
193 mark_addressable (v);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
194 mark_decl_referenced (v);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
195 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
196
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
197 return build_fold_addr_expr (v);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
198 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
199
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
200 /* Helper function for gcn_reduction_update.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
201
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
202 Insert code to locklessly update *PTR with *PTR OP VAR just before
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
203 GSI. We use a lockless scheme for nearly all case, which looks
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
204 like:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
205 actual = initval (OP);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
206 do {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
207 guess = actual;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
208 write = guess OP myval;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
209 actual = cmp&swap (ptr, guess, write)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
210 } while (actual bit-different-to guess);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
211 return write;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
212
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
213 This relies on a cmp&swap instruction, which is available for 32- and
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
214 64-bit types. Larger types must use a locking scheme. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
215
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
216 static tree
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
217 gcn_lockless_update (location_t loc, gimple_stmt_iterator *gsi,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
218 tree ptr, tree var, tree_code op)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
219 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
220 unsigned fn = GCN_BUILTIN_CMP_SWAP;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
221 tree_code code = NOP_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
222 tree arg_type = unsigned_type_node;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
223 tree var_type = TREE_TYPE (var);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
224
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
225 if (TREE_CODE (var_type) == COMPLEX_TYPE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
226 || TREE_CODE (var_type) == REAL_TYPE)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
227 code = VIEW_CONVERT_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
228
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
229 if (TYPE_SIZE (var_type) == TYPE_SIZE (long_long_unsigned_type_node))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
230 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
231 arg_type = long_long_unsigned_type_node;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
232 fn = GCN_BUILTIN_CMP_SWAPLL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
233 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
234
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
235 tree swap_fn = gcn_builtin_decl (fn, true);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
236
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
237 gimple_seq init_seq = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
238 tree init_var = make_ssa_name (arg_type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
239 tree init_expr = omp_reduction_init_op (loc, op, var_type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
240 init_expr = fold_build1 (code, arg_type, init_expr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
241 gimplify_assign (init_var, init_expr, &init_seq);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
242 gimple *init_end = gimple_seq_last (init_seq);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
243
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
244 gsi_insert_seq_before (gsi, init_seq, GSI_SAME_STMT);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
245
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
246 /* Split the block just after the init stmts. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
247 basic_block pre_bb = gsi_bb (*gsi);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
248 edge pre_edge = split_block (pre_bb, init_end);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
249 basic_block loop_bb = pre_edge->dest;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
250 pre_bb = pre_edge->src;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
251 /* Reset the iterator. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
252 *gsi = gsi_for_stmt (gsi_stmt (*gsi));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
253
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
254 tree expect_var = make_ssa_name (arg_type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
255 tree actual_var = make_ssa_name (arg_type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
256 tree write_var = make_ssa_name (arg_type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
257
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
258 /* Build and insert the reduction calculation. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
259 gimple_seq red_seq = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
260 tree write_expr = fold_build1 (code, var_type, expect_var);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
261 write_expr = fold_build2 (op, var_type, write_expr, var);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
262 write_expr = fold_build1 (code, arg_type, write_expr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
263 gimplify_assign (write_var, write_expr, &red_seq);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
264
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
265 gsi_insert_seq_before (gsi, red_seq, GSI_SAME_STMT);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
266
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
267 /* Build & insert the cmp&swap sequence. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
268 gimple_seq latch_seq = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
269 tree swap_expr = build_call_expr_loc (loc, swap_fn, 3,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
270 ptr, expect_var, write_var);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
271 gimplify_assign (actual_var, swap_expr, &latch_seq);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
272
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
273 gcond *cond = gimple_build_cond (EQ_EXPR, actual_var, expect_var,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
274 NULL_TREE, NULL_TREE);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
275 gimple_seq_add_stmt (&latch_seq, cond);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
276
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
277 gimple *latch_end = gimple_seq_last (latch_seq);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
278 gsi_insert_seq_before (gsi, latch_seq, GSI_SAME_STMT);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
279
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
280 /* Split the block just after the latch stmts. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
281 edge post_edge = split_block (loop_bb, latch_end);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
282 basic_block post_bb = post_edge->dest;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
283 loop_bb = post_edge->src;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
284 *gsi = gsi_for_stmt (gsi_stmt (*gsi));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
285
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
286 post_edge->flags ^= EDGE_TRUE_VALUE | EDGE_FALLTHRU;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
287 /* post_edge->probability = profile_probability::even (); */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
288 edge loop_edge = make_edge (loop_bb, loop_bb, EDGE_FALSE_VALUE);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
289 /* loop_edge->probability = profile_probability::even (); */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
290 set_immediate_dominator (CDI_DOMINATORS, loop_bb, pre_bb);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
291 set_immediate_dominator (CDI_DOMINATORS, post_bb, loop_bb);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
292
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
293 gphi *phi = create_phi_node (expect_var, loop_bb);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
294 add_phi_arg (phi, init_var, pre_edge, loc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
295 add_phi_arg (phi, actual_var, loop_edge, loc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
296
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
297 loop *loop = alloc_loop ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
298 loop->header = loop_bb;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
299 loop->latch = loop_bb;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
300 add_loop (loop, loop_bb->loop_father);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
301
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
302 return fold_build1 (code, var_type, write_var);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
303 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
304
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
305 /* Helper function for gcn_reduction_update.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
306
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
307 Insert code to lockfully update *PTR with *PTR OP VAR just before
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
308 GSI. This is necessary for types larger than 64 bits, where there
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
309 is no cmp&swap instruction to implement a lockless scheme. We use
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
310 a lock variable in global memory.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
311
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
312 while (cmp&swap (&lock_var, 0, 1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
313 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
314 T accum = *ptr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
315 accum = accum OP var;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
316 *ptr = accum;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
317 cmp&swap (&lock_var, 1, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
318 return accum;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
319
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
320 A lock in global memory is necessary to force execution engine
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
321 descheduling and avoid resource starvation that can occur if the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
322 lock is in shared memory. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
323
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
324 static tree
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
325 gcn_lockfull_update (location_t loc, gimple_stmt_iterator *gsi,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
326 tree ptr, tree var, tree_code op)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
327 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
328 tree var_type = TREE_TYPE (var);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
329 tree swap_fn = gcn_builtin_decl (GCN_BUILTIN_CMP_SWAP, true);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
330 tree uns_unlocked = build_int_cst (unsigned_type_node, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
331 tree uns_locked = build_int_cst (unsigned_type_node, 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
332
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
333 /* Split the block just before the gsi. Insert a gimple nop to make
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
334 this easier. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
335 gimple *nop = gimple_build_nop ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
336 gsi_insert_before (gsi, nop, GSI_SAME_STMT);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
337 basic_block entry_bb = gsi_bb (*gsi);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
338 edge entry_edge = split_block (entry_bb, nop);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
339 basic_block lock_bb = entry_edge->dest;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
340 /* Reset the iterator. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
341 *gsi = gsi_for_stmt (gsi_stmt (*gsi));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
342
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
343 /* Build and insert the locking sequence. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
344 gimple_seq lock_seq = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
345 tree lock_var = make_ssa_name (unsigned_type_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
346 tree lock_expr = gcn_global_lock_addr ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
347 lock_expr = build_call_expr_loc (loc, swap_fn, 3, lock_expr,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
348 uns_unlocked, uns_locked);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
349 gimplify_assign (lock_var, lock_expr, &lock_seq);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
350 gcond *cond = gimple_build_cond (EQ_EXPR, lock_var, uns_unlocked,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
351 NULL_TREE, NULL_TREE);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
352 gimple_seq_add_stmt (&lock_seq, cond);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
353 gimple *lock_end = gimple_seq_last (lock_seq);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
354 gsi_insert_seq_before (gsi, lock_seq, GSI_SAME_STMT);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
355
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
356 /* Split the block just after the lock sequence. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
357 edge locked_edge = split_block (lock_bb, lock_end);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
358 basic_block update_bb = locked_edge->dest;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
359 lock_bb = locked_edge->src;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
360 *gsi = gsi_for_stmt (gsi_stmt (*gsi));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
361
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
362 /* Create the lock loop. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
363 locked_edge->flags ^= EDGE_TRUE_VALUE | EDGE_FALLTHRU;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
364 locked_edge->probability = profile_probability::even ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
365 edge loop_edge = make_edge (lock_bb, lock_bb, EDGE_FALSE_VALUE);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
366 loop_edge->probability = profile_probability::even ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
367 set_immediate_dominator (CDI_DOMINATORS, lock_bb, entry_bb);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
368 set_immediate_dominator (CDI_DOMINATORS, update_bb, lock_bb);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
369
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
370 /* Create the loop structure. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
371 loop *lock_loop = alloc_loop ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
372 lock_loop->header = lock_bb;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
373 lock_loop->latch = lock_bb;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
374 lock_loop->nb_iterations_estimate = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
375 lock_loop->any_estimate = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
376 add_loop (lock_loop, entry_bb->loop_father);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
377
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
378 /* Build and insert the reduction calculation. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
379 gimple_seq red_seq = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
380 tree acc_in = make_ssa_name (var_type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
381 tree ref_in = build_simple_mem_ref (ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
382 TREE_THIS_VOLATILE (ref_in) = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
383 gimplify_assign (acc_in, ref_in, &red_seq);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
384
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
385 tree acc_out = make_ssa_name (var_type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
386 tree update_expr = fold_build2 (op, var_type, ref_in, var);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
387 gimplify_assign (acc_out, update_expr, &red_seq);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
388
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
389 tree ref_out = build_simple_mem_ref (ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
390 TREE_THIS_VOLATILE (ref_out) = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
391 gimplify_assign (ref_out, acc_out, &red_seq);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
392
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
393 gsi_insert_seq_before (gsi, red_seq, GSI_SAME_STMT);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
394
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
395 /* Build & insert the unlock sequence. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
396 gimple_seq unlock_seq = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
397 tree unlock_expr = gcn_global_lock_addr ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
398 unlock_expr = build_call_expr_loc (loc, swap_fn, 3, unlock_expr,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
399 uns_locked, uns_unlocked);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
400 gimplify_and_add (unlock_expr, &unlock_seq);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
401 gsi_insert_seq_before (gsi, unlock_seq, GSI_SAME_STMT);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
402
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
403 return acc_out;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
404 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
405
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
406 /* Emit a sequence to update a reduction accumulator at *PTR with the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
407 value held in VAR using operator OP. Return the updated value.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
408
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
409 TODO: optimize for atomic ops and independent complex ops. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
410
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
411 static tree
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
412 gcn_reduction_update (location_t loc, gimple_stmt_iterator *gsi,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
413 tree ptr, tree var, tree_code op)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
414 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
415 tree type = TREE_TYPE (var);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
416 tree size = TYPE_SIZE (type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
417
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
418 if (size == TYPE_SIZE (unsigned_type_node)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
419 || size == TYPE_SIZE (long_long_unsigned_type_node))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
420 return gcn_lockless_update (loc, gsi, ptr, var, op);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
421 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
422 return gcn_lockfull_update (loc, gsi, ptr, var, op);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
423 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
424
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
425 /* Return a temporary variable decl to use for an OpenACC worker reduction. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
426
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
427 static tree
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
428 gcn_goacc_get_worker_red_decl (tree type, unsigned offset)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
429 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
430 machine_function *machfun = cfun->machine;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
431 tree existing_decl;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
432
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
433 if (TREE_CODE (type) == REFERENCE_TYPE)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
434 type = TREE_TYPE (type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
435
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
436 tree var_type
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
437 = build_qualified_type (type,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
438 (TYPE_QUALS (type)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
439 | ENCODE_QUAL_ADDR_SPACE (ADDR_SPACE_LDS)));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
440
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
441 if (machfun->reduc_decls
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
442 && offset < machfun->reduc_decls->length ()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
443 && (existing_decl = (*machfun->reduc_decls)[offset]))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
444 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
445 gcc_assert (TREE_TYPE (existing_decl) == var_type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
446 return existing_decl;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
447 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
448 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
449 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
450 char name[50];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
451 sprintf (name, ".oacc_reduction_%u", offset);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
452 tree decl = create_tmp_var_raw (var_type, name);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
453
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
454 DECL_CONTEXT (decl) = NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
455 TREE_STATIC (decl) = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
456
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
457 varpool_node::finalize_decl (decl);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
458
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
459 vec_safe_grow_cleared (machfun->reduc_decls, offset + 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
460 (*machfun->reduc_decls)[offset] = decl;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
461
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
462 return decl;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
463 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
464
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
465 return NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
466 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
467
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
468 /* Expand IFN_GOACC_REDUCTION_SETUP. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
469
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
470 static void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
471 gcn_goacc_reduction_setup (gcall *call)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
472 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
473 gimple_stmt_iterator gsi = gsi_for_stmt (call);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
474 tree lhs = gimple_call_lhs (call);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
475 tree var = gimple_call_arg (call, 2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
476 int level = TREE_INT_CST_LOW (gimple_call_arg (call, 3));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
477 gimple_seq seq = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
478
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
479 push_gimplify_context (true);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
480
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
481 if (level != GOMP_DIM_GANG)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
482 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
483 /* Copy the receiver object. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
484 tree ref_to_res = gimple_call_arg (call, 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
485
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
486 if (!integer_zerop (ref_to_res))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
487 var = build_simple_mem_ref (ref_to_res);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
488 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
489
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
490 if (level == GOMP_DIM_WORKER)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
491 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
492 tree var_type = TREE_TYPE (var);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
493 /* Store incoming value to worker reduction buffer. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
494 tree offset = gimple_call_arg (call, 5);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
495 tree decl
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
496 = gcn_goacc_get_worker_red_decl (var_type, TREE_INT_CST_LOW (offset));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
497
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
498 gimplify_assign (decl, var, &seq);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
499 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
500
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
501 if (lhs)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
502 gimplify_assign (lhs, var, &seq);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
503
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
504 pop_gimplify_context (NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
505 gsi_replace_with_seq (&gsi, seq, true);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
506 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
507
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
508 /* Expand IFN_GOACC_REDUCTION_INIT. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
509
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
510 static void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
511 gcn_goacc_reduction_init (gcall *call)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
512 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
513 gimple_stmt_iterator gsi = gsi_for_stmt (call);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
514 tree lhs = gimple_call_lhs (call);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
515 tree var = gimple_call_arg (call, 2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
516 int level = TREE_INT_CST_LOW (gimple_call_arg (call, 3));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
517 enum tree_code rcode
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
518 = (enum tree_code) TREE_INT_CST_LOW (gimple_call_arg (call, 4));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
519 tree init = omp_reduction_init_op (gimple_location (call), rcode,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
520 TREE_TYPE (var));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
521 gimple_seq seq = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
522
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
523 push_gimplify_context (true);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
524
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
525 if (level == GOMP_DIM_GANG)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
526 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
527 /* If there's no receiver object, propagate the incoming VAR. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
528 tree ref_to_res = gimple_call_arg (call, 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
529 if (integer_zerop (ref_to_res))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
530 init = var;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
531 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
532
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
533 if (lhs)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
534 gimplify_assign (lhs, init, &seq);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
535
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
536 pop_gimplify_context (NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
537 gsi_replace_with_seq (&gsi, seq, true);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
538 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
539
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
540 /* Expand IFN_GOACC_REDUCTION_FINI. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
541
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
542 static void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
543 gcn_goacc_reduction_fini (gcall *call)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
544 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
545 gimple_stmt_iterator gsi = gsi_for_stmt (call);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
546 tree lhs = gimple_call_lhs (call);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
547 tree ref_to_res = gimple_call_arg (call, 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
548 tree var = gimple_call_arg (call, 2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
549 int level = TREE_INT_CST_LOW (gimple_call_arg (call, 3));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
550 enum tree_code op
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
551 = (enum tree_code) TREE_INT_CST_LOW (gimple_call_arg (call, 4));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
552 gimple_seq seq = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
553 tree r = NULL_TREE;;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
554
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
555 push_gimplify_context (true);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
556
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
557 tree accum = NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
558
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
559 if (level == GOMP_DIM_WORKER)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
560 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
561 tree var_type = TREE_TYPE (var);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
562 tree offset = gimple_call_arg (call, 5);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
563 tree decl
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
564 = gcn_goacc_get_worker_red_decl (var_type, TREE_INT_CST_LOW (offset));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
565
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
566 accum = build_fold_addr_expr (decl);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
567 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
568 else if (integer_zerop (ref_to_res))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
569 r = var;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
570 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
571 accum = ref_to_res;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
572
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
573 if (accum)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
574 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
575 /* UPDATE the accumulator. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
576 gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
577 seq = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
578 r = gcn_reduction_update (gimple_location (call), &gsi, accum, var, op);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
579 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
580
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
581 if (lhs)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
582 gimplify_assign (lhs, r, &seq);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
583 pop_gimplify_context (NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
584
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
585 gsi_replace_with_seq (&gsi, seq, true);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
586 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
587
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
588 /* Expand IFN_GOACC_REDUCTION_TEARDOWN. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
589
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
590 static void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
591 gcn_goacc_reduction_teardown (gcall *call)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
592 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
593 gimple_stmt_iterator gsi = gsi_for_stmt (call);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
594 tree lhs = gimple_call_lhs (call);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
595 tree var = gimple_call_arg (call, 2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
596 int level = TREE_INT_CST_LOW (gimple_call_arg (call, 3));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
597 gimple_seq seq = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
598
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
599 push_gimplify_context (true);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
600
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
601 if (level == GOMP_DIM_WORKER)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
602 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
603 tree var_type = TREE_TYPE (var);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
604
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
605 /* Read the worker reduction buffer. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
606 tree offset = gimple_call_arg (call, 5);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
607 tree decl
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
608 = gcn_goacc_get_worker_red_decl (var_type, TREE_INT_CST_LOW (offset));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
609 var = decl;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
610 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
611
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
612 if (level != GOMP_DIM_GANG)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
613 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
614 /* Write to the receiver object. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
615 tree ref_to_res = gimple_call_arg (call, 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
616
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
617 if (!integer_zerop (ref_to_res))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
618 gimplify_assign (build_simple_mem_ref (ref_to_res), var, &seq);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
619 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
620
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
621 if (lhs)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
622 gimplify_assign (lhs, var, &seq);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
623
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
624 pop_gimplify_context (NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
625
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
626 gsi_replace_with_seq (&gsi, seq, true);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
627 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
628
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
629 /* Implement TARGET_GOACC_REDUCTION.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
630
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
631 Expand calls to the GOACC REDUCTION internal function, into a sequence of
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
632 gimple instructions. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
633
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
634 void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
635 gcn_goacc_reduction (gcall *call)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
636 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
637 int level = TREE_INT_CST_LOW (gimple_call_arg (call, 3));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
638
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
639 if (level == GOMP_DIM_VECTOR)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
640 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
641 default_goacc_reduction (call);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
642 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
643 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
644
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
645 unsigned code = (unsigned) TREE_INT_CST_LOW (gimple_call_arg (call, 0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
646
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
647 switch (code)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
648 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
649 case IFN_GOACC_REDUCTION_SETUP:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
650 gcn_goacc_reduction_setup (call);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
651 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
652
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
653 case IFN_GOACC_REDUCTION_INIT:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
654 gcn_goacc_reduction_init (call);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
655 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
656
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
657 case IFN_GOACC_REDUCTION_FINI:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
658 gcn_goacc_reduction_fini (call);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
659 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
660
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
661 case IFN_GOACC_REDUCTION_TEARDOWN:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
662 gcn_goacc_reduction_teardown (call);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
663 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
664
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
665 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
666 gcc_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
667 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
668 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
669
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
670 /* Implement TARGET_GOACC_ADJUST_PROPAGATION_RECORD.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
671
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
672 Tweak (worker) propagation record, e.g. to put it in shared memory. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
673
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
674 tree
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
675 gcn_goacc_adjust_propagation_record (tree record_type, bool sender,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
676 const char *name)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
677 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
678 tree type = record_type;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
679
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
680 TYPE_ADDR_SPACE (type) = ADDR_SPACE_LDS;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
681
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
682 if (!sender)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
683 type = build_pointer_type (type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
684
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
685 tree decl = create_tmp_var_raw (type, name);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
686
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
687 if (sender)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
688 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
689 DECL_CONTEXT (decl) = NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
690 TREE_STATIC (decl) = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
691 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
692
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
693 if (sender)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
694 varpool_node::finalize_decl (decl);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
695
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
696 return decl;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
697 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
698
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
699 void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
700 gcn_goacc_adjust_gangprivate_decl (tree var)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
701 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
702 tree type = TREE_TYPE (var);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
703 tree lds_type = build_qualified_type (type,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
704 TYPE_QUALS_NO_ADDR_SPACE (type)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
705 | ENCODE_QUAL_ADDR_SPACE (ADDR_SPACE_LDS));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
706 machine_function *machfun = cfun->machine;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
707
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
708 TREE_TYPE (var) = lds_type;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
709 TREE_STATIC (var) = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
710
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
711 /* We're making VAR static. We have to mangle the name to avoid collisions
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
712 between different local variables that share the same names. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
713 lhd_set_decl_assembler_name (var);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
714
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
715 varpool_node::finalize_decl (var);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
716
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
717 if (machfun)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
718 machfun->use_flat_addressing = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
719 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
720
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
721 /* }}} */