annotate gcc/brig/brigfrontend/brig-function.cc @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* brig-function.cc -- declaration of brig_function class.
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 Copyright (C) 2016-2020 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
3 Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
kono
parents:
diff changeset
4 for General Processor Tech.
kono
parents:
diff changeset
5
kono
parents:
diff changeset
6 This file is part of GCC.
kono
parents:
diff changeset
7
kono
parents:
diff changeset
8 GCC is free software; you can redistribute it and/or modify it under
kono
parents:
diff changeset
9 the terms of the GNU General Public License as published by the Free
kono
parents:
diff changeset
10 Software Foundation; either version 3, or (at your option) any later
kono
parents:
diff changeset
11 version.
kono
parents:
diff changeset
12
kono
parents:
diff changeset
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
kono
parents:
diff changeset
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
kono
parents:
diff changeset
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
kono
parents:
diff changeset
16 for more details.
kono
parents:
diff changeset
17
kono
parents:
diff changeset
18 You should have received a copy of the GNU General Public License
kono
parents:
diff changeset
19 along with GCC; see the file COPYING3. If not see
kono
parents:
diff changeset
20 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
21
kono
parents:
diff changeset
22 #include <sstream>
kono
parents:
diff changeset
23 #include <iomanip>
kono
parents:
diff changeset
24
kono
parents:
diff changeset
25 #include "brig-function.h"
kono
parents:
diff changeset
26 #include "stringpool.h"
kono
parents:
diff changeset
27 #include "tree-iterator.h"
kono
parents:
diff changeset
28 #include "toplev.h"
kono
parents:
diff changeset
29 #include "gimplify.h"
kono
parents:
diff changeset
30 #include "gimple-expr.h"
kono
parents:
diff changeset
31 #include "print-tree.h"
kono
parents:
diff changeset
32 #include "hsa-brig-format.h"
kono
parents:
diff changeset
33 #include "stor-layout.h"
kono
parents:
diff changeset
34 #include "diagnostic-core.h"
kono
parents:
diff changeset
35 #include "brig-code-entry-handler.h"
kono
parents:
diff changeset
36 #include "brig-machine.h"
kono
parents:
diff changeset
37 #include "brig-util.h"
kono
parents:
diff changeset
38 #include "phsa.h"
kono
parents:
diff changeset
39 #include "tree-pretty-print.h"
kono
parents:
diff changeset
40 #include "dumpfile.h"
kono
parents:
diff changeset
41 #include "profile-count.h"
kono
parents:
diff changeset
42 #include "tree-cfg.h"
kono
parents:
diff changeset
43 #include "errors.h"
kono
parents:
diff changeset
44 #include "function.h"
kono
parents:
diff changeset
45 #include "brig-to-generic.h"
kono
parents:
diff changeset
46 #include "brig-builtins.h"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
47 #include "options.h"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
48 #include "fold-const.h"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
49 #include "target.h"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
50 #include "builtins.h"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
51
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
52 brig_function::builtin_map brig_function::s_custom_builtins;
111
kono
parents:
diff changeset
53
kono
parents:
diff changeset
54 brig_function::brig_function (const BrigDirectiveExecutable *exec,
kono
parents:
diff changeset
55 brig_to_generic *parent)
kono
parents:
diff changeset
56 : m_brig_def (exec), m_is_kernel (false), m_is_finished (false), m_name (""),
kono
parents:
diff changeset
57 m_current_bind_expr (NULL_TREE), m_func_decl (NULL_TREE),
kono
parents:
diff changeset
58 m_context_arg (NULL_TREE), m_group_base_arg (NULL_TREE),
kono
parents:
diff changeset
59 m_private_base_arg (NULL_TREE), m_ret_value (NULL_TREE),
kono
parents:
diff changeset
60 m_next_kernarg_offset (0), m_kernarg_max_align (0),
kono
parents:
diff changeset
61 m_ret_value_brig_var (NULL), m_has_barriers (false), m_has_allocas (false),
kono
parents:
diff changeset
62 m_has_function_calls_with_barriers (false), m_calls_analyzed (false),
kono
parents:
diff changeset
63 m_is_wg_function (false), m_has_unexpanded_dp_builtins (false),
kono
parents:
diff changeset
64 m_generating_arg_block (false), m_parent (parent)
kono
parents:
diff changeset
65 {
kono
parents:
diff changeset
66 memset (m_regs, 0,
kono
parents:
diff changeset
67 BRIG_2_TREE_HSAIL_TOTAL_REG_COUNT * sizeof (BrigOperandRegister *));
kono
parents:
diff changeset
68 memset (&m_descriptor, 0, sizeof (phsa_descriptor));
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
69
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
70 if (s_custom_builtins.size () > 0) return;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
71
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
72 /* Populate the builtin index. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
73 #undef DEF_HSAIL_ATOMIC_BUILTIN
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
74 #undef DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
75 #undef DEF_HSAIL_INTR_BUILTIN
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
76 #undef DEF_HSAIL_SAT_BUILTIN
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
77 #undef DEF_HSAIL_BUILTIN
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
78 #define DEF_HSAIL_BUILTIN(ENUM, HSAIL_OPCODE, HSAIL_TYPE, NAME, TYPE, ATTRS) \
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
79 s_custom_builtins[std::make_pair (HSAIL_OPCODE, HSAIL_TYPE)] \
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
80 = builtin_decl_explicit (ENUM);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
81
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
82 #include "brig-builtins.def"
111
kono
parents:
diff changeset
83 }
kono
parents:
diff changeset
84
kono
parents:
diff changeset
85 brig_function::~brig_function ()
kono
parents:
diff changeset
86 {
kono
parents:
diff changeset
87 for (size_t i = 0; i < BRIG_2_TREE_HSAIL_TOTAL_REG_COUNT; ++i)
kono
parents:
diff changeset
88 {
kono
parents:
diff changeset
89 if (m_regs[i] != NULL)
kono
parents:
diff changeset
90 {
kono
parents:
diff changeset
91 delete m_regs[i];
kono
parents:
diff changeset
92 m_regs[i] = NULL;
kono
parents:
diff changeset
93 }
kono
parents:
diff changeset
94 }
kono
parents:
diff changeset
95 }
kono
parents:
diff changeset
96
kono
parents:
diff changeset
97 /* Returns a GENERIC label with the given name in the given function.
kono
parents:
diff changeset
98 Creates it, if not yet found. */
kono
parents:
diff changeset
99
kono
parents:
diff changeset
100 tree
kono
parents:
diff changeset
101 brig_function::label (const std::string &name)
kono
parents:
diff changeset
102 {
kono
parents:
diff changeset
103 label_index::const_iterator i = m_label_index.find (name);
kono
parents:
diff changeset
104 if (i == m_label_index.end ())
kono
parents:
diff changeset
105 {
kono
parents:
diff changeset
106 tree name_identifier
kono
parents:
diff changeset
107 = get_identifier_with_length (name.c_str (), name.size ());
kono
parents:
diff changeset
108
kono
parents:
diff changeset
109 tree label_decl = build_decl (UNKNOWN_LOCATION, LABEL_DECL,
kono
parents:
diff changeset
110 name_identifier, void_type_node);
kono
parents:
diff changeset
111
kono
parents:
diff changeset
112 DECL_CONTEXT (label_decl) = m_func_decl;
kono
parents:
diff changeset
113 DECL_ARTIFICIAL (label_decl) = 0;
kono
parents:
diff changeset
114
kono
parents:
diff changeset
115 m_label_index[name] = label_decl;
kono
parents:
diff changeset
116 return label_decl;
kono
parents:
diff changeset
117 }
kono
parents:
diff changeset
118 else
kono
parents:
diff changeset
119 return (*i).second;
kono
parents:
diff changeset
120 }
kono
parents:
diff changeset
121
kono
parents:
diff changeset
122 /* Record an argument variable for later use. This includes both local
kono
parents:
diff changeset
123 variables inside arg blocks and incoming function arguments. */
kono
parents:
diff changeset
124
kono
parents:
diff changeset
125 void
kono
parents:
diff changeset
126 brig_function::add_arg_variable (const BrigDirectiveVariable *brigVar,
kono
parents:
diff changeset
127 tree treeDecl)
kono
parents:
diff changeset
128 {
kono
parents:
diff changeset
129 m_arg_variables[brigVar] = treeDecl;
kono
parents:
diff changeset
130 }
kono
parents:
diff changeset
131
kono
parents:
diff changeset
132 tree
kono
parents:
diff changeset
133 brig_function::arg_variable (const BrigDirectiveVariable *var) const
kono
parents:
diff changeset
134 {
kono
parents:
diff changeset
135 variable_index::const_iterator i = m_arg_variables.find (var);
kono
parents:
diff changeset
136 if (i == m_arg_variables.end ())
kono
parents:
diff changeset
137 return NULL_TREE;
kono
parents:
diff changeset
138 else
kono
parents:
diff changeset
139 return (*i).second;
kono
parents:
diff changeset
140 }
kono
parents:
diff changeset
141
kono
parents:
diff changeset
142 /* Appends a new kernel argument descriptor for the current kernel's
kono
parents:
diff changeset
143 arg space. */
kono
parents:
diff changeset
144
kono
parents:
diff changeset
145 void
kono
parents:
diff changeset
146 brig_function::append_kernel_arg (const BrigDirectiveVariable *var, size_t size,
kono
parents:
diff changeset
147 size_t alignment)
kono
parents:
diff changeset
148 {
kono
parents:
diff changeset
149 gcc_assert (m_func_decl != NULL_TREE);
kono
parents:
diff changeset
150 gcc_assert (m_is_kernel);
kono
parents:
diff changeset
151
kono
parents:
diff changeset
152 size_t align_padding = m_next_kernarg_offset % alignment == 0 ?
kono
parents:
diff changeset
153 0 : (alignment - m_next_kernarg_offset % alignment);
kono
parents:
diff changeset
154 m_next_kernarg_offset += align_padding;
kono
parents:
diff changeset
155 m_kernarg_offsets[var] = m_next_kernarg_offset;
kono
parents:
diff changeset
156 m_next_kernarg_offset += size;
kono
parents:
diff changeset
157
kono
parents:
diff changeset
158 m_kernarg_max_align
kono
parents:
diff changeset
159 = m_kernarg_max_align < alignment ? alignment : m_kernarg_max_align;
kono
parents:
diff changeset
160 }
kono
parents:
diff changeset
161
kono
parents:
diff changeset
162 size_t
kono
parents:
diff changeset
163 brig_function::kernel_arg_offset (const BrigDirectiveVariable *var) const
kono
parents:
diff changeset
164 {
kono
parents:
diff changeset
165 var_offset_table::const_iterator i = m_kernarg_offsets.find (var);
kono
parents:
diff changeset
166 gcc_assert (i != m_kernarg_offsets.end ());
kono
parents:
diff changeset
167 return (*i).second;
kono
parents:
diff changeset
168 }
kono
parents:
diff changeset
169
kono
parents:
diff changeset
170 /* Add work-item ID variables to the beginning of the kernel function
kono
parents:
diff changeset
171 which can be used for address computation as kernel dispatch packet
kono
parents:
diff changeset
172 instructions can be expanded to GENERIC nodes referring to them. */
kono
parents:
diff changeset
173
kono
parents:
diff changeset
174 void
kono
parents:
diff changeset
175 brig_function::add_id_variables ()
kono
parents:
diff changeset
176 {
kono
parents:
diff changeset
177 tree bind_expr = m_current_bind_expr;
kono
parents:
diff changeset
178 tree stmts = BIND_EXPR_BODY (bind_expr);
kono
parents:
diff changeset
179
kono
parents:
diff changeset
180 /* Initialize the WG limits and local ids. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
181 m_kernel_entry = tsi_start (stmts);
111
kono
parents:
diff changeset
182
kono
parents:
diff changeset
183 for (int i = 0; i < 3; ++i)
kono
parents:
diff changeset
184 {
kono
parents:
diff changeset
185 char dim_char = (char) ((int) 'x' + i);
kono
parents:
diff changeset
186
kono
parents:
diff changeset
187 /* The local sizes are limited to 16b values, but let's still use 32b
kono
parents:
diff changeset
188 to avoid unnecessary casts (the ID functions are 32b). */
kono
parents:
diff changeset
189 m_local_id_vars[i]
kono
parents:
diff changeset
190 = add_local_variable (std::string ("__local_") + dim_char,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
191 long_long_integer_type_node);
111
kono
parents:
diff changeset
192
kono
parents:
diff changeset
193 tree workitemid_call
kono
parents:
diff changeset
194 = call_builtin (builtin_decl_explicit (BUILT_IN_HSAIL_WORKITEMID), 2,
kono
parents:
diff changeset
195 uint32_type_node, uint32_type_node,
kono
parents:
diff changeset
196 build_int_cst (uint32_type_node, i), ptr_type_node,
kono
parents:
diff changeset
197 m_context_arg);
kono
parents:
diff changeset
198
kono
parents:
diff changeset
199 tree id_init = build2 (MODIFY_EXPR, TREE_TYPE (m_local_id_vars[i]),
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
200 m_local_id_vars[i],
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
201 convert (TREE_TYPE (m_local_id_vars[i]),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
202 workitemid_call));
111
kono
parents:
diff changeset
203
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
204 append_statement (id_init);
111
kono
parents:
diff changeset
205
kono
parents:
diff changeset
206 m_cur_wg_size_vars[i]
kono
parents:
diff changeset
207 = add_local_variable (std::string ("__cur_wg_size_") + dim_char,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
208 long_long_integer_type_node);
111
kono
parents:
diff changeset
209
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
210 tree cwgz_call;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
211 if (flag_assume_phsa)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
212 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
213 tree_stl_vec operands
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
214 = tree_stl_vec (1, build_int_cst (uint32_type_node, i));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
215 cwgz_call
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
216 = expand_or_call_builtin (BRIG_OPCODE_CURRENTWORKGROUPSIZE,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
217 BRIG_TYPE_U32, uint32_type_node,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
218 operands);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
219 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
220 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
221 cwgz_call = call_builtin
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
222 (builtin_decl_explicit (BUILT_IN_HSAIL_CURRENTWORKGROUPSIZE),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
223 2, uint32_type_node, uint32_type_node,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
224 build_int_cst (uint32_type_node, i), ptr_type_node, m_context_arg);
111
kono
parents:
diff changeset
225
kono
parents:
diff changeset
226 tree limit_init = build2 (MODIFY_EXPR, TREE_TYPE (m_cur_wg_size_vars[i]),
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
227 m_cur_wg_size_vars[i],
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
228 convert (TREE_TYPE (m_cur_wg_size_vars[i]),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
229 cwgz_call));
111
kono
parents:
diff changeset
230
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
231 append_statement (limit_init);
111
kono
parents:
diff changeset
232
kono
parents:
diff changeset
233 m_wg_id_vars[i]
kono
parents:
diff changeset
234 = add_local_variable (std::string ("__workgroupid_") + dim_char,
kono
parents:
diff changeset
235 uint32_type_node);
kono
parents:
diff changeset
236
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
237 tree wgid_call;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
238 if (flag_assume_phsa)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
239 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
240 tree_stl_vec operands
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
241 = tree_stl_vec (1, build_int_cst (uint32_type_node, i));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
242 wgid_call
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
243 = expand_or_call_builtin (BRIG_OPCODE_WORKGROUPID, BRIG_TYPE_U32,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
244 uint32_type_node, operands);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
245 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
246 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
247 wgid_call
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
248 = call_builtin (builtin_decl_explicit (BUILT_IN_HSAIL_WORKGROUPID),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
249 2, uint32_type_node, uint32_type_node,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
250 build_int_cst (uint32_type_node, i), ptr_type_node,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
251 m_context_arg);
111
kono
parents:
diff changeset
252
kono
parents:
diff changeset
253 tree wgid_init = build2 (MODIFY_EXPR, TREE_TYPE (m_wg_id_vars[i]),
kono
parents:
diff changeset
254 m_wg_id_vars[i], wgid_call);
kono
parents:
diff changeset
255
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
256 append_statement (wgid_init);
111
kono
parents:
diff changeset
257
kono
parents:
diff changeset
258 m_wg_size_vars[i]
kono
parents:
diff changeset
259 = add_local_variable (std::string ("__workgroupsize_") + dim_char,
kono
parents:
diff changeset
260 uint32_type_node);
kono
parents:
diff changeset
261
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
262 tree wgsize_call;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
263 if (flag_assume_phsa)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
264 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
265 tree_stl_vec operands
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
266 = tree_stl_vec (1, build_int_cst (uint32_type_node, i));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
267 wgsize_call
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
268 = expand_or_call_builtin (BRIG_OPCODE_WORKGROUPSIZE, BRIG_TYPE_U32,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
269 uint32_type_node, operands);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
270 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
271 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
272 wgsize_call
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
273 = call_builtin (builtin_decl_explicit (BUILT_IN_HSAIL_WORKGROUPSIZE),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
274 2, uint32_type_node, uint32_type_node,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
275 build_int_cst (uint32_type_node, i), ptr_type_node,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
276 m_context_arg);
111
kono
parents:
diff changeset
277
kono
parents:
diff changeset
278 tree wgsize_init = build2 (MODIFY_EXPR, TREE_TYPE (m_wg_size_vars[i]),
kono
parents:
diff changeset
279 m_wg_size_vars[i], wgsize_call);
kono
parents:
diff changeset
280
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
281 append_statement (wgsize_init);
111
kono
parents:
diff changeset
282
kono
parents:
diff changeset
283 m_grid_size_vars[i]
kono
parents:
diff changeset
284 = add_local_variable (std::string ("__gridsize_") + dim_char,
kono
parents:
diff changeset
285 uint32_type_node);
kono
parents:
diff changeset
286
kono
parents:
diff changeset
287 tree gridsize_call
kono
parents:
diff changeset
288 = call_builtin (builtin_decl_explicit (BUILT_IN_HSAIL_GRIDSIZE), 2,
kono
parents:
diff changeset
289 uint32_type_node, uint32_type_node,
kono
parents:
diff changeset
290 build_int_cst (uint32_type_node, i), ptr_type_node,
kono
parents:
diff changeset
291 m_context_arg);
kono
parents:
diff changeset
292
kono
parents:
diff changeset
293 tree gridsize_init = build2 (MODIFY_EXPR, TREE_TYPE (m_grid_size_vars[i]),
kono
parents:
diff changeset
294 m_grid_size_vars[i], gridsize_call);
kono
parents:
diff changeset
295
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
296 append_statement (gridsize_init);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
297
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
298 m_abs_id_base_vars[i]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
299 = add_local_variable (std::string ("__abs_id_base_") + dim_char,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
300 long_long_integer_type_node);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
301
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
302 m_abs_id_vars[i]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
303 = add_local_variable (std::string ("__abs_id_") + dim_char,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
304 long_long_integer_type_node);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
305
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
306 tree abs_id_base
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
307 = build2 (MULT_EXPR, long_long_integer_type_node,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
308 convert (long_long_integer_type_node, m_wg_id_vars[i]),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
309 convert (long_long_integer_type_node, m_wg_size_vars[i]));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
310 tree abs_id
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
311 = build2 (PLUS_EXPR, long_long_integer_type_node, abs_id_base,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
312 convert (long_long_integer_type_node, m_local_id_vars[i]));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
313
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
314 tree abs_id_base_init
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
315 = build2 (MODIFY_EXPR, TREE_TYPE (m_abs_id_base_vars[i]),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
316 m_abs_id_base_vars[i], abs_id_base);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
317 append_statement (abs_id_base_init);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
318
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
319 tree abs_id_init = build2 (MODIFY_EXPR,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
320 TREE_TYPE (m_abs_id_vars[i]),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
321 m_abs_id_vars[i], abs_id);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
322 append_statement (abs_id_init);
111
kono
parents:
diff changeset
323 }
kono
parents:
diff changeset
324 }
kono
parents:
diff changeset
325
kono
parents:
diff changeset
326 /* Creates a new local variable with the given NAME and given GENERIC
kono
parents:
diff changeset
327 TYPE. */
kono
parents:
diff changeset
328
kono
parents:
diff changeset
329 tree
kono
parents:
diff changeset
330 brig_function::add_local_variable (std::string name, tree type)
kono
parents:
diff changeset
331 {
kono
parents:
diff changeset
332 tree name_identifier
kono
parents:
diff changeset
333 = get_identifier_with_length (name.c_str (), name.size ());
kono
parents:
diff changeset
334 tree variable
kono
parents:
diff changeset
335 = build_decl (UNKNOWN_LOCATION, VAR_DECL, name_identifier, type);
kono
parents:
diff changeset
336
kono
parents:
diff changeset
337 DECL_NONLOCAL (variable) = 0;
kono
parents:
diff changeset
338 TREE_ADDRESSABLE (variable) = 0;
kono
parents:
diff changeset
339 TREE_STATIC (variable) = 0;
kono
parents:
diff changeset
340 TREE_USED (variable) = 1;
kono
parents:
diff changeset
341 DECL_ARTIFICIAL (variable) = 0;
kono
parents:
diff changeset
342
kono
parents:
diff changeset
343 tree bind_expr = DECL_SAVED_TREE (m_func_decl);
kono
parents:
diff changeset
344
kono
parents:
diff changeset
345 DECL_CONTEXT (variable) = m_func_decl;
kono
parents:
diff changeset
346
kono
parents:
diff changeset
347 DECL_CHAIN (variable) = BIND_EXPR_VARS (bind_expr);
kono
parents:
diff changeset
348 BIND_EXPR_VARS (bind_expr) = variable;
kono
parents:
diff changeset
349 return variable;
kono
parents:
diff changeset
350 }
kono
parents:
diff changeset
351
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
352 /* Return tree type for an HSA register.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
353
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
354 The tree type can be anything (scalar, vector, int, float, etc.)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
355 but its size is guaranteed to match the HSA register size.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
356
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
357 HSA registers are untyped but we select a type based on their use
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
358 to reduce (sometimes unoptimizable) VIEW_CONVERT_EXPR nodes (seems
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
359 to occur when use or def reaches over current BB). */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
360
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
361 tree
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
362 brig_function::get_tree_type_for_hsa_reg (const BrigOperandRegister *reg) const
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
363 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
364 size_t reg_size = gccbrig_reg_size (reg);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
365
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
366 /* The default type. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
367 tree type = build_nonstandard_integer_type (reg_size, true);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
368
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
369 if (m_parent->m_fn_regs_use_index.count (m_name) == 0)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
370 return type;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
371
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
372 const regs_use_index &index = m_parent->m_fn_regs_use_index[m_name];
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
373 size_t reg_id = gccbrig_hsa_reg_id (*reg);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
374 if (index.count (reg_id) == 0)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
375 return type;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
376
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
377 const reg_use_info &info = index.find (reg_id)->second;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
378 std::vector<std::pair<tree, size_t> >::const_iterator it
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
379 = info.m_type_refs.begin ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
380 std::vector<std::pair<tree, size_t> >::const_iterator it_end
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
381 = info.m_type_refs.end ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
382 size_t max_refs_as_type_count = 0;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
383 for (; it != it_end; it++)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
384 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
385 size_t type_bit_size = int_size_in_bytes (it->first) * BITS_PER_UNIT;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
386 if (type_bit_size != reg_size) continue;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
387 if (it->second > max_refs_as_type_count)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
388 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
389 type = it->first;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
390 max_refs_as_type_count = it->second;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
391 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
392 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
393
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
394 return type;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
395 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
396
111
kono
parents:
diff changeset
397 /* Returns a DECL_VAR for the given HSAIL operand register.
kono
parents:
diff changeset
398 If it has not been created yet for the function being generated,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
399 creates it as a type determined by analysis phase. */
111
kono
parents:
diff changeset
400
kono
parents:
diff changeset
401 tree
kono
parents:
diff changeset
402 brig_function::get_m_var_declfor_reg (const BrigOperandRegister *reg)
kono
parents:
diff changeset
403 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
404 size_t offset = gccbrig_hsa_reg_id (*reg);
111
kono
parents:
diff changeset
405
kono
parents:
diff changeset
406 reg_decl_index_entry *regEntry = m_regs[offset];
kono
parents:
diff changeset
407 if (regEntry == NULL)
kono
parents:
diff changeset
408 {
kono
parents:
diff changeset
409 size_t reg_size = gccbrig_reg_size (reg);
kono
parents:
diff changeset
410 tree type;
kono
parents:
diff changeset
411 if (reg_size > 1)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
412 type = get_tree_type_for_hsa_reg (reg);
111
kono
parents:
diff changeset
413 else
kono
parents:
diff changeset
414 type = boolean_type_node;
kono
parents:
diff changeset
415
kono
parents:
diff changeset
416 /* Drop the const qualifier so we do not end up with a read only
kono
parents:
diff changeset
417 register variable which cannot be written to later. */
kono
parents:
diff changeset
418 tree nonconst_type = build_type_variant (type, false, false);
kono
parents:
diff changeset
419
kono
parents:
diff changeset
420 regEntry = new reg_decl_index_entry;
kono
parents:
diff changeset
421
kono
parents:
diff changeset
422 regEntry->m_var_decl
kono
parents:
diff changeset
423 = add_local_variable (gccbrig_reg_name (reg), nonconst_type);
kono
parents:
diff changeset
424 m_regs[offset] = regEntry;
kono
parents:
diff changeset
425 }
kono
parents:
diff changeset
426 return regEntry->m_var_decl;
kono
parents:
diff changeset
427 }
kono
parents:
diff changeset
428
kono
parents:
diff changeset
429 /* Builds a work-item do..while loop for a single DIM. HEADER_ENTRY is
kono
parents:
diff changeset
430 a statement after which the iteration variables should be initialized and
kono
parents:
diff changeset
431 the loop body starts. BRANCH_AFTER is the statement after which the loop
kono
parents:
diff changeset
432 predicate check and the back edge goto will be appended. */
kono
parents:
diff changeset
433
kono
parents:
diff changeset
434 void
kono
parents:
diff changeset
435 brig_function::add_wi_loop (int dim, tree_stmt_iterator *header_entry,
kono
parents:
diff changeset
436 tree_stmt_iterator *branch_after)
kono
parents:
diff changeset
437 {
kono
parents:
diff changeset
438 tree ivar = m_local_id_vars[dim];
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
439 tree abs_id_base_var = m_abs_id_base_vars[dim];
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
440 tree abs_id_var = m_abs_id_vars[dim];
111
kono
parents:
diff changeset
441 tree ivar_max = m_cur_wg_size_vars[dim];
kono
parents:
diff changeset
442 tree_stmt_iterator entry = *header_entry;
kono
parents:
diff changeset
443
kono
parents:
diff changeset
444 /* TODO: this is not a parallel loop as we share the "register variables"
kono
parents:
diff changeset
445 across work-items. Should create a copy of them per WI instance. That
kono
parents:
diff changeset
446 is, declare temporaries for new definitions inside the loop body, not at
kono
parents:
diff changeset
447 function scope. */
kono
parents:
diff changeset
448
kono
parents:
diff changeset
449 tree ivar_init = build2 (MODIFY_EXPR, TREE_TYPE (ivar), ivar,
kono
parents:
diff changeset
450 build_zero_cst (TREE_TYPE (ivar)));
kono
parents:
diff changeset
451 tsi_link_after (&entry, ivar_init, TSI_NEW_STMT);
kono
parents:
diff changeset
452
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
453 tree abs_id_var_init = build2 (MODIFY_EXPR, TREE_TYPE (abs_id_var),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
454 abs_id_var,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
455 convert (TREE_TYPE (abs_id_var),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
456 abs_id_base_var));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
457 tsi_link_after (&entry, abs_id_var_init, TSI_NEW_STMT);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
458
111
kono
parents:
diff changeset
459 tree loop_body_label
kono
parents:
diff changeset
460 = label (std::string ("__wi_loop_") + (char) ((int) 'x' + dim));
kono
parents:
diff changeset
461 tree loop_body_label_stmt = build_stmt (LABEL_EXPR, loop_body_label);
kono
parents:
diff changeset
462
kono
parents:
diff changeset
463 tsi_link_after (&entry, loop_body_label_stmt, TSI_NEW_STMT);
kono
parents:
diff changeset
464
kono
parents:
diff changeset
465 if (m_has_unexpanded_dp_builtins)
kono
parents:
diff changeset
466 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
467 if (!flag_assume_phsa)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
468 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
469 tree id_set_builtin
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
470 = builtin_decl_explicit (BUILT_IN_HSAIL_SETWORKITEMID);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
471 /* Set the local ID to the current wi-loop iteration variable value
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
472 to ensure the builtins see the correct values. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
473 tree id_set_call
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
474 = call_builtin (id_set_builtin, 3,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
475 void_type_node, uint32_type_node,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
476 build_int_cst (uint32_type_node, dim),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
477 uint32_type_node, convert (uint32_type_node, ivar),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
478 ptr_type_node, m_context_arg);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
479 tsi_link_after (&entry, id_set_call, TSI_NEW_STMT);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
480 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
481 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
482 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
483 tree ptr_type = build_pointer_type (uint32_type_node);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
484 tree ctx = build2 (MEM_REF, uint32_type_node, m_context_arg,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
485 build_int_cst (ptr_type, dim * 4));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
486 tree assign = build2 (MODIFY_EXPR, uint32_type_node, ctx,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
487 convert (uint32_type_node, ivar));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
488
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
489 tsi_link_after (&entry, assign, TSI_NEW_STMT);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
490 }
111
kono
parents:
diff changeset
491 }
kono
parents:
diff changeset
492
kono
parents:
diff changeset
493 /* Increment the WI iteration variable. */
kono
parents:
diff changeset
494 tree incr = build2 (PREINCREMENT_EXPR, TREE_TYPE (ivar), ivar,
kono
parents:
diff changeset
495 build_one_cst (TREE_TYPE (ivar)));
kono
parents:
diff changeset
496
kono
parents:
diff changeset
497 tsi_link_after (branch_after, incr, TSI_NEW_STMT);
kono
parents:
diff changeset
498
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
499 /* ...and the abs id variable. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
500 tree abs_id_incr = build2 (PREINCREMENT_EXPR, TREE_TYPE (abs_id_var),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
501 abs_id_var,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
502 build_one_cst (TREE_TYPE (abs_id_var)));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
503
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
504 tsi_link_after (branch_after, abs_id_incr, TSI_NEW_STMT);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
505
111
kono
parents:
diff changeset
506 /* Append the predicate check with the back edge goto. */
kono
parents:
diff changeset
507 tree condition = build2 (LT_EXPR, TREE_TYPE (ivar), ivar, ivar_max);
kono
parents:
diff changeset
508 tree target_goto = build1 (GOTO_EXPR, void_type_node, loop_body_label);
kono
parents:
diff changeset
509 tree if_stmt
kono
parents:
diff changeset
510 = build3 (COND_EXPR, void_type_node, condition, target_goto, NULL_TREE);
kono
parents:
diff changeset
511 tsi_link_after (branch_after, if_stmt, TSI_NEW_STMT);
kono
parents:
diff changeset
512 }
kono
parents:
diff changeset
513
kono
parents:
diff changeset
514 /* Recursively analyzes the function and its callees for barrier usage. */
kono
parents:
diff changeset
515
kono
parents:
diff changeset
516 void
kono
parents:
diff changeset
517 brig_function::analyze_calls ()
kono
parents:
diff changeset
518 {
kono
parents:
diff changeset
519 if (m_calls_analyzed)
kono
parents:
diff changeset
520 return;
kono
parents:
diff changeset
521
kono
parents:
diff changeset
522 /* Set this early to not get stuck in case of recursive call graphs.
kono
parents:
diff changeset
523 This is safe because if the function calls itself, either the function
kono
parents:
diff changeset
524 has barrier calls which implies a call to a function with barrier calls,
kono
parents:
diff changeset
525 or it doesn't in which case the result depends on the later called
kono
parents:
diff changeset
526 functions. */
kono
parents:
diff changeset
527 m_calls_analyzed = true;
kono
parents:
diff changeset
528
kono
parents:
diff changeset
529 for (size_t i = 0; i < m_called_functions.size (); ++i)
kono
parents:
diff changeset
530 {
kono
parents:
diff changeset
531 tree f = m_called_functions[i];
kono
parents:
diff changeset
532 brig_function *called_f = m_parent->get_finished_function (f);
kono
parents:
diff changeset
533 if (called_f == NULL)
kono
parents:
diff changeset
534 {
kono
parents:
diff changeset
535 /* Unfinished function (only declaration within the set of BRIGs)
kono
parents:
diff changeset
536 found. Cannot finish the CG analysis. Have to assume it does have
kono
parents:
diff changeset
537 a barrier for safety. */
kono
parents:
diff changeset
538 m_has_function_calls_with_barriers = true;
kono
parents:
diff changeset
539 m_has_unexpanded_dp_builtins = true;
kono
parents:
diff changeset
540 break;
kono
parents:
diff changeset
541 }
kono
parents:
diff changeset
542 called_f->analyze_calls ();
kono
parents:
diff changeset
543 /* We can assume m_has_barriers has been correctly set during the
kono
parents:
diff changeset
544 construction of the function decl. No need to reanalyze it. */
kono
parents:
diff changeset
545 m_has_function_calls_with_barriers |= called_f->m_has_barriers;
kono
parents:
diff changeset
546
kono
parents:
diff changeset
547 /* If the function or any of its called functions has dispatch
kono
parents:
diff changeset
548 packet builtin calls that require the local id, we need to
kono
parents:
diff changeset
549 set the local id to the context in the work item loop before
kono
parents:
diff changeset
550 the functions are called. If we analyze the opposite, these
kono
parents:
diff changeset
551 function calls can be omitted. */
kono
parents:
diff changeset
552 m_has_unexpanded_dp_builtins |= called_f->m_has_unexpanded_dp_builtins;
kono
parents:
diff changeset
553 }
kono
parents:
diff changeset
554 }
kono
parents:
diff changeset
555
kono
parents:
diff changeset
556 /* Tries to convert the current kernel to a work-group function that executes
kono
parents:
diff changeset
557 all work-items using loops. Returns true in case the conversion was
kono
parents:
diff changeset
558 successful. */
kono
parents:
diff changeset
559
kono
parents:
diff changeset
560 bool
kono
parents:
diff changeset
561 brig_function::convert_to_wg_function ()
kono
parents:
diff changeset
562 {
kono
parents:
diff changeset
563 if (!m_calls_analyzed)
kono
parents:
diff changeset
564 analyze_calls ();
kono
parents:
diff changeset
565
kono
parents:
diff changeset
566 if (m_has_barriers || m_has_function_calls_with_barriers)
kono
parents:
diff changeset
567 return false;
kono
parents:
diff changeset
568
kono
parents:
diff changeset
569 /* The most trivial case: No barriers at all in the kernel.
kono
parents:
diff changeset
570 We can create one big work-item loop around the whole kernel. */
kono
parents:
diff changeset
571 tree bind_expr = m_current_bind_expr;
kono
parents:
diff changeset
572 tree stmts = BIND_EXPR_BODY (bind_expr);
kono
parents:
diff changeset
573
kono
parents:
diff changeset
574 for (int i = 0; i < 3; ++i)
kono
parents:
diff changeset
575 {
kono
parents:
diff changeset
576 /* The previous loop has added a new label to the end of the function,
kono
parents:
diff changeset
577 the next level loop should wrap around it also. */
kono
parents:
diff changeset
578 tree_stmt_iterator function_exit = tsi_last (stmts);
kono
parents:
diff changeset
579 add_wi_loop (i, &m_kernel_entry, &function_exit);
kono
parents:
diff changeset
580 }
kono
parents:
diff changeset
581
kono
parents:
diff changeset
582 m_is_wg_function = true;
kono
parents:
diff changeset
583 return false;
kono
parents:
diff changeset
584 }
kono
parents:
diff changeset
585
kono
parents:
diff changeset
586 /* Emits a kernel description to a special ELF section so it can be
kono
parents:
diff changeset
587 utilized by an HSA runtime implementation. The assembly block
kono
parents:
diff changeset
588 must be emitted to a statement list of an function, which is given
kono
parents:
diff changeset
589 as an argument. Returns the assembly block used to emit the section. */
kono
parents:
diff changeset
590
kono
parents:
diff changeset
591 tree
kono
parents:
diff changeset
592 brig_function::emit_metadata (tree stmt_list)
kono
parents:
diff changeset
593 {
kono
parents:
diff changeset
594 /* Emit an ELF section via an assembly directive that generates a special
kono
parents:
diff changeset
595 ELF section for each kernel that contains raw bytes of a descriptor
kono
parents:
diff changeset
596 object. This is pretty disgusting, but life is never perfect ;) */
kono
parents:
diff changeset
597
kono
parents:
diff changeset
598 /* Use the original kernel name without the '_' prefix in the section name. */
kono
parents:
diff changeset
599 std::string kern_name = m_is_kernel ? m_name.substr (1) : m_name;
kono
parents:
diff changeset
600
kono
parents:
diff changeset
601 std::ostringstream strstr;
kono
parents:
diff changeset
602 strstr << std::endl
kono
parents:
diff changeset
603 << ".pushsection " << PHSA_DESC_SECTION_PREFIX << kern_name
kono
parents:
diff changeset
604 << std::endl
kono
parents:
diff changeset
605 << "\t.p2align 1, 1, 1" << std::endl
kono
parents:
diff changeset
606 << "\t.byte ";
kono
parents:
diff changeset
607
kono
parents:
diff changeset
608 for (size_t i = 0; i < sizeof (phsa_descriptor); ++i)
kono
parents:
diff changeset
609 {
kono
parents:
diff changeset
610 strstr << "0x" << std::setw (2) << std::setfill ('0') << std::hex
kono
parents:
diff changeset
611 << (unsigned) *((unsigned char *) &m_descriptor + i);
kono
parents:
diff changeset
612 if (i + 1 < sizeof (phsa_descriptor))
kono
parents:
diff changeset
613 strstr << ", ";
kono
parents:
diff changeset
614 }
kono
parents:
diff changeset
615
kono
parents:
diff changeset
616 strstr << std::endl << ".popsection" << std::endl << std::endl;
kono
parents:
diff changeset
617
kono
parents:
diff changeset
618 tree metadata_asm
kono
parents:
diff changeset
619 = build_stmt (ASM_EXPR,
kono
parents:
diff changeset
620 build_string (strstr.str ().size (), strstr.str ().c_str ()),
kono
parents:
diff changeset
621 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE);
kono
parents:
diff changeset
622
kono
parents:
diff changeset
623 append_to_statement_list_force (metadata_asm, &stmt_list);
kono
parents:
diff changeset
624 return metadata_asm;
kono
parents:
diff changeset
625 }
kono
parents:
diff changeset
626
kono
parents:
diff changeset
627 /* Emits the kernel launcher function. Also emits the metadata section
kono
parents:
diff changeset
628 creation statements in it.
kono
parents:
diff changeset
629
kono
parents:
diff changeset
630 The launcher function calls the device-side runtime
kono
parents:
diff changeset
631 that runs the kernel for all work-items. In C:
kono
parents:
diff changeset
632
kono
parents:
diff changeset
633 void KernelName (void* context, void* group_base_addr)
kono
parents:
diff changeset
634 {
kono
parents:
diff changeset
635 __hsail_launch_kernel (_KernelName, context, group_base_addr);
kono
parents:
diff changeset
636 }
kono
parents:
diff changeset
637
kono
parents:
diff changeset
638 or, in case of a successful conversion to a work-group function:
kono
parents:
diff changeset
639
kono
parents:
diff changeset
640 void KernelName (void* context, void* group_base_addr)
kono
parents:
diff changeset
641 {
kono
parents:
diff changeset
642 __hsail_launch_wg_function (_KernelName, context, group_base_addr);
kono
parents:
diff changeset
643 }
kono
parents:
diff changeset
644
kono
parents:
diff changeset
645 The user/host sees this function as the kernel to call from the
kono
parents:
diff changeset
646 outside. The actual kernel generated from HSAIL was named _KernelName.
kono
parents:
diff changeset
647 */
kono
parents:
diff changeset
648
kono
parents:
diff changeset
649 tree
kono
parents:
diff changeset
650 brig_function::emit_launcher_and_metadata ()
kono
parents:
diff changeset
651 {
kono
parents:
diff changeset
652 /* The original kernel name without the '_' prefix. */
kono
parents:
diff changeset
653 std::string kern_name = m_name.substr (1);
kono
parents:
diff changeset
654
kono
parents:
diff changeset
655 tree name_identifier
kono
parents:
diff changeset
656 = get_identifier_with_length (kern_name.c_str (), kern_name.size ());
kono
parents:
diff changeset
657
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
658 tree restrict_void_ptr
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
659 = build_qualified_type (build_pointer_type (void_type_node),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
660 TYPE_QUAL_RESTRICT);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
661 tree restrict_char_ptr
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
662 = build_qualified_type (build_pointer_type (char_type_node),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
663 TYPE_QUAL_RESTRICT);
111
kono
parents:
diff changeset
664 tree launcher
kono
parents:
diff changeset
665 = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, name_identifier,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
666 build_function_type_list (void_type_node, restrict_void_ptr,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
667 restrict_char_ptr, NULL_TREE));
111
kono
parents:
diff changeset
668
kono
parents:
diff changeset
669 TREE_USED (launcher) = 1;
kono
parents:
diff changeset
670 DECL_ARTIFICIAL (launcher) = 1;
kono
parents:
diff changeset
671
kono
parents:
diff changeset
672 tree context_arg = build_decl (UNKNOWN_LOCATION, PARM_DECL,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
673 get_identifier ("__context"),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
674 restrict_void_ptr);
111
kono
parents:
diff changeset
675
kono
parents:
diff changeset
676 DECL_ARGUMENTS (launcher) = context_arg;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
677 DECL_ARG_TYPE (context_arg) = restrict_void_ptr;
111
kono
parents:
diff changeset
678 DECL_CONTEXT (context_arg) = launcher;
kono
parents:
diff changeset
679 TREE_USED (context_arg) = 1;
kono
parents:
diff changeset
680 DECL_ARTIFICIAL (context_arg) = 1;
kono
parents:
diff changeset
681
kono
parents:
diff changeset
682 tree group_base_addr_arg
kono
parents:
diff changeset
683 = build_decl (UNKNOWN_LOCATION, PARM_DECL,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
684 get_identifier ("__group_base_addr"), restrict_char_ptr);
111
kono
parents:
diff changeset
685
kono
parents:
diff changeset
686 chainon (DECL_ARGUMENTS (launcher), group_base_addr_arg);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
687 DECL_ARG_TYPE (group_base_addr_arg) = restrict_char_ptr;
111
kono
parents:
diff changeset
688 DECL_CONTEXT (group_base_addr_arg) = launcher;
kono
parents:
diff changeset
689 TREE_USED (group_base_addr_arg) = 1;
kono
parents:
diff changeset
690 DECL_ARTIFICIAL (group_base_addr_arg) = 1;
kono
parents:
diff changeset
691
kono
parents:
diff changeset
692 tree resdecl
kono
parents:
diff changeset
693 = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, void_type_node);
kono
parents:
diff changeset
694
kono
parents:
diff changeset
695 DECL_RESULT (launcher) = resdecl;
kono
parents:
diff changeset
696 DECL_CONTEXT (resdecl) = launcher;
kono
parents:
diff changeset
697
kono
parents:
diff changeset
698 DECL_INITIAL (launcher) = make_node (BLOCK);
kono
parents:
diff changeset
699 TREE_USED (DECL_INITIAL (launcher)) = 1;
kono
parents:
diff changeset
700
kono
parents:
diff changeset
701 tree stmt_list = alloc_stmt_list ();
kono
parents:
diff changeset
702
kono
parents:
diff changeset
703 tree bind_expr = build3 (BIND_EXPR, void_type_node, NULL, stmt_list, NULL);
kono
parents:
diff changeset
704
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
705 TREE_STATIC (launcher) = 1;
111
kono
parents:
diff changeset
706 TREE_PUBLIC (launcher) = 1;
kono
parents:
diff changeset
707
kono
parents:
diff changeset
708 DECL_SAVED_TREE (launcher) = bind_expr;
kono
parents:
diff changeset
709
kono
parents:
diff changeset
710 if (DECL_STRUCT_FUNCTION (launcher) == NULL)
kono
parents:
diff changeset
711 push_struct_function (launcher);
kono
parents:
diff changeset
712 else
kono
parents:
diff changeset
713 push_cfun (DECL_STRUCT_FUNCTION (launcher));
kono
parents:
diff changeset
714
kono
parents:
diff changeset
715 tree kernel_func_ptr = build1 (ADDR_EXPR, ptr_type_node, m_func_decl);
kono
parents:
diff changeset
716
kono
parents:
diff changeset
717 tree phsail_launch_kernel_call;
kono
parents:
diff changeset
718
kono
parents:
diff changeset
719 /* Compute the local group segment frame start pointer. */
kono
parents:
diff changeset
720 tree group_local_offset_temp
kono
parents:
diff changeset
721 = create_tmp_var (uint32_type_node, "group_local_offset");
kono
parents:
diff changeset
722 tree group_local_offset_arg
kono
parents:
diff changeset
723 = build2 (MODIFY_EXPR, uint32_type_node,
kono
parents:
diff changeset
724 group_local_offset_temp,
kono
parents:
diff changeset
725 build_int_cst (uint32_type_node,
kono
parents:
diff changeset
726 m_parent->m_module_group_variables.size()));
kono
parents:
diff changeset
727
kono
parents:
diff changeset
728 /* Emit a launcher depending whether we converted the kernel function to
kono
parents:
diff changeset
729 a work group function or not. */
kono
parents:
diff changeset
730 if (m_is_wg_function)
kono
parents:
diff changeset
731 phsail_launch_kernel_call
kono
parents:
diff changeset
732 = call_builtin (builtin_decl_explicit (BUILT_IN_HSAIL_LAUNCH_WG_FUNC),
kono
parents:
diff changeset
733 4, void_type_node,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
734 ptr_type_node, kernel_func_ptr, restrict_void_ptr,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
735 context_arg, restrict_char_ptr, group_base_addr_arg,
111
kono
parents:
diff changeset
736 uint32_type_node, group_local_offset_arg);
kono
parents:
diff changeset
737 else
kono
parents:
diff changeset
738 phsail_launch_kernel_call
kono
parents:
diff changeset
739 = call_builtin (builtin_decl_explicit (BUILT_IN_HSAIL_LAUNCH_KERNEL),
kono
parents:
diff changeset
740 4, void_type_node,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
741 ptr_type_node, kernel_func_ptr, restrict_void_ptr,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
742 context_arg, restrict_char_ptr, group_base_addr_arg,
111
kono
parents:
diff changeset
743 uint32_type_node, group_local_offset_arg);
kono
parents:
diff changeset
744
kono
parents:
diff changeset
745 append_to_statement_list_force (phsail_launch_kernel_call, &stmt_list);
kono
parents:
diff changeset
746
kono
parents:
diff changeset
747 emit_metadata (stmt_list);
kono
parents:
diff changeset
748
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
749 set_externally_visible (launcher);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
750
111
kono
parents:
diff changeset
751 return launcher;
kono
parents:
diff changeset
752 }
kono
parents:
diff changeset
753
kono
parents:
diff changeset
754 tree
kono
parents:
diff changeset
755 brig_function::append_statement (tree stmt)
kono
parents:
diff changeset
756 {
kono
parents:
diff changeset
757 gcc_assert (m_func_decl != NULL);
kono
parents:
diff changeset
758
kono
parents:
diff changeset
759 tree bind_expr = m_current_bind_expr;
kono
parents:
diff changeset
760 tree stmts = BIND_EXPR_BODY (bind_expr);
kono
parents:
diff changeset
761
kono
parents:
diff changeset
762 append_to_statement_list_force (stmt, &stmts);
kono
parents:
diff changeset
763 return stmt;
kono
parents:
diff changeset
764 }
kono
parents:
diff changeset
765
kono
parents:
diff changeset
766 /* Creates a new "alloca frame" for the current function by
kono
parents:
diff changeset
767 injecting an alloca frame push in the beginning of the function
kono
parents:
diff changeset
768 and an alloca frame pop before all function exit points. */
kono
parents:
diff changeset
769
kono
parents:
diff changeset
770 void
kono
parents:
diff changeset
771 brig_function::create_alloca_frame ()
kono
parents:
diff changeset
772 {
kono
parents:
diff changeset
773 tree_stmt_iterator entry;
kono
parents:
diff changeset
774
kono
parents:
diff changeset
775 /* Adds the alloca push only after the ids have been initialized
kono
parents:
diff changeset
776 in case of a kernel function. */
kono
parents:
diff changeset
777 if (m_is_kernel)
kono
parents:
diff changeset
778 entry = m_kernel_entry;
kono
parents:
diff changeset
779 else
kono
parents:
diff changeset
780 {
kono
parents:
diff changeset
781 tree bind_expr = m_current_bind_expr;
kono
parents:
diff changeset
782 tree stmts = BIND_EXPR_BODY (bind_expr);
kono
parents:
diff changeset
783 entry = tsi_start (stmts);
kono
parents:
diff changeset
784 }
kono
parents:
diff changeset
785
kono
parents:
diff changeset
786 tree push_frame_builtin = builtin_decl_explicit (BUILT_IN_HSAIL_PUSH_FRAME);
kono
parents:
diff changeset
787 tree push_frame_call
kono
parents:
diff changeset
788 = call_builtin (push_frame_builtin, 1, void_type_node, ptr_type_node,
kono
parents:
diff changeset
789 m_context_arg);
kono
parents:
diff changeset
790
kono
parents:
diff changeset
791 tsi_link_before (&entry, push_frame_call, TSI_NEW_STMT);
kono
parents:
diff changeset
792
kono
parents:
diff changeset
793 tree pop_frame_builtin = builtin_decl_explicit (BUILT_IN_HSAIL_POP_FRAME);
kono
parents:
diff changeset
794
kono
parents:
diff changeset
795 do
kono
parents:
diff changeset
796 {
kono
parents:
diff changeset
797 tree stmt = tsi_stmt (entry);
kono
parents:
diff changeset
798 if (TREE_CODE (stmt) == RETURN_EXPR)
kono
parents:
diff changeset
799 {
kono
parents:
diff changeset
800 tree pop_frame_call
kono
parents:
diff changeset
801 = call_builtin (pop_frame_builtin, 1, void_type_node,
kono
parents:
diff changeset
802 ptr_type_node, m_context_arg);
kono
parents:
diff changeset
803
kono
parents:
diff changeset
804 tsi_link_before (&entry, pop_frame_call, TSI_SAME_STMT);
kono
parents:
diff changeset
805 }
kono
parents:
diff changeset
806 tsi_next (&entry);
kono
parents:
diff changeset
807 }
kono
parents:
diff changeset
808 while (!tsi_end_p (entry));
kono
parents:
diff changeset
809 }
kono
parents:
diff changeset
810
kono
parents:
diff changeset
811 /* Finishes the currently built function. After calling this, no new
kono
parents:
diff changeset
812 statements should be appeneded to the function. */
kono
parents:
diff changeset
813 void
kono
parents:
diff changeset
814 brig_function::finish ()
kono
parents:
diff changeset
815 {
kono
parents:
diff changeset
816 append_return_stmt ();
kono
parents:
diff changeset
817
kono
parents:
diff changeset
818 /* Currently assume single alloca frame per WG. */
kono
parents:
diff changeset
819 if (m_has_allocas)
kono
parents:
diff changeset
820 create_alloca_frame ();
kono
parents:
diff changeset
821 }
kono
parents:
diff changeset
822
kono
parents:
diff changeset
823 void
kono
parents:
diff changeset
824 brig_function::finish_kernel ()
kono
parents:
diff changeset
825 {
kono
parents:
diff changeset
826 /* Kernel functions should have a single exit point.
kono
parents:
diff changeset
827 Let's create one. The return instructions should have
kono
parents:
diff changeset
828 been converted to branches to this label. */
kono
parents:
diff changeset
829 append_statement (build_stmt (LABEL_EXPR, m_exit_label));
kono
parents:
diff changeset
830 /* Attempt to convert the kernel to a work-group function that
kono
parents:
diff changeset
831 executes all work-items of the WG using a loop. */
kono
parents:
diff changeset
832 convert_to_wg_function ();
kono
parents:
diff changeset
833
kono
parents:
diff changeset
834 append_return_stmt ();
kono
parents:
diff changeset
835
kono
parents:
diff changeset
836 /* Currently assume single alloca frame per WG. */
kono
parents:
diff changeset
837 if (m_has_allocas)
kono
parents:
diff changeset
838 create_alloca_frame ();
kono
parents:
diff changeset
839 }
kono
parents:
diff changeset
840
kono
parents:
diff changeset
841 void
kono
parents:
diff changeset
842 brig_function::append_return_stmt ()
kono
parents:
diff changeset
843 {
kono
parents:
diff changeset
844 gcc_assert (m_current_bind_expr != NULL_TREE);
kono
parents:
diff changeset
845 tree stmts = BIND_EXPR_BODY (m_current_bind_expr);
kono
parents:
diff changeset
846
kono
parents:
diff changeset
847 if (STATEMENT_LIST_TAIL (stmts) == NULL)
kono
parents:
diff changeset
848 return; /* Empty function. */
kono
parents:
diff changeset
849
kono
parents:
diff changeset
850 tree last_stmt = tsi_stmt (tsi_last (stmts));
kono
parents:
diff changeset
851
kono
parents:
diff changeset
852 if (TREE_CODE (last_stmt) == RETURN_EXPR)
kono
parents:
diff changeset
853 return;
kono
parents:
diff changeset
854
kono
parents:
diff changeset
855 if (m_ret_value != NULL_TREE)
kono
parents:
diff changeset
856 {
kono
parents:
diff changeset
857 tree result_assign
kono
parents:
diff changeset
858 = build2 (MODIFY_EXPR, TREE_TYPE (m_ret_value), m_ret_value,
kono
parents:
diff changeset
859 m_ret_temp);
kono
parents:
diff changeset
860
kono
parents:
diff changeset
861 tree return_expr
kono
parents:
diff changeset
862 = build1 (RETURN_EXPR, TREE_TYPE (result_assign), result_assign);
kono
parents:
diff changeset
863 append_to_statement_list_force (return_expr, &stmts);
kono
parents:
diff changeset
864 }
kono
parents:
diff changeset
865 else
kono
parents:
diff changeset
866 {
kono
parents:
diff changeset
867 tree return_stmt = build_stmt (RETURN_EXPR, NULL);
kono
parents:
diff changeset
868 append_to_statement_list_force (return_stmt, &stmts);
kono
parents:
diff changeset
869 }
kono
parents:
diff changeset
870 }
kono
parents:
diff changeset
871
kono
parents:
diff changeset
872 bool
kono
parents:
diff changeset
873 brig_function::has_function_scope_var (const BrigBase* var) const
kono
parents:
diff changeset
874 {
kono
parents:
diff changeset
875 return m_function_scope_vars.find (var) != m_function_scope_vars.end ();
kono
parents:
diff changeset
876 }
kono
parents:
diff changeset
877
kono
parents:
diff changeset
878 size_t
kono
parents:
diff changeset
879 brig_function::group_variable_segment_offset (const std::string &name) const
kono
parents:
diff changeset
880 {
kono
parents:
diff changeset
881 if (m_local_group_variables.has_variable (name))
kono
parents:
diff changeset
882 return m_local_group_variables.segment_offset (name);
kono
parents:
diff changeset
883
kono
parents:
diff changeset
884 gcc_assert (m_parent->m_module_group_variables.has_variable (name));
kono
parents:
diff changeset
885 return m_parent->m_module_group_variables.segment_offset (name);
kono
parents:
diff changeset
886 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
887
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
888 /* Try to expand the given builtin call to reuse a previously generated
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
889 variable, if possible. If not, just call the given builtin.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
890 BRIG_OPCODE and BRIG_TYPE identify the builtin's BRIG opcode/type,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
891 ARITH_TYPE its GENERIC type, and OPERANDS contains the builtin's
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
892 input operands. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
893
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
894 tree
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
895 brig_function::expand_or_call_builtin (BrigOpcode16_t brig_opcode,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
896 BrigType16_t brig_type,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
897 tree arith_type,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
898 tree_stl_vec &operands)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
899 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
900 if (needs_workitem_context_data (brig_opcode))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
901 m_has_unexpanded_dp_builtins = true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
902
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
903 if (can_expand_builtin (brig_opcode))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
904 return expand_builtin (brig_opcode, operands);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
905
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
906 tree built_in
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
907 = get_builtin_for_hsa_opcode (arith_type, brig_opcode, brig_type);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
908
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
909 if (!VECTOR_TYPE_P (TREE_TYPE (TREE_TYPE (built_in)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
910 && arith_type != NULL_TREE && VECTOR_TYPE_P (arith_type)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
911 && brig_opcode != BRIG_OPCODE_LERP
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
912 && brig_opcode != BRIG_OPCODE_PACKCVT
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
913 && brig_opcode != BRIG_OPCODE_SAD
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
914 && brig_opcode != BRIG_OPCODE_SADHI)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
915 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
916 /* Call the scalar built-in for all elements in the vector. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
917 tree_stl_vec operand0_elements;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
918 if (operands.size () > 0)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
919 unpack (operands[0], operand0_elements);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
920
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
921 tree_stl_vec operand1_elements;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
922 if (operands.size () > 1)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
923 unpack (operands[1], operand1_elements);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
924
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
925 tree_stl_vec result_elements;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
926
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
927 size_t element_count = gccbrig_type_vector_subparts (arith_type);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
928 for (size_t i = 0; i < element_count; ++i)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
929 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
930 tree_stl_vec call_operands;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
931 if (operand0_elements.size () > 0)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
932 call_operands.push_back (operand0_elements.at (i));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
933
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
934 if (operand1_elements.size () > 0)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
935 call_operands.push_back (operand1_elements.at (i));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
936
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
937 result_elements.push_back
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
938 (expand_or_call_builtin (brig_opcode, brig_type,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
939 TREE_TYPE (arith_type),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
940 call_operands));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
941 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
942 return pack (result_elements);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
943 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
944
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
945 tree_stl_vec call_operands;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
946 tree_stl_vec operand_types;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
947
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
948 tree arg_type_chain = TYPE_ARG_TYPES (TREE_TYPE (built_in));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
949
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
950 for (size_t i = 0; i < operands.size (); ++i)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
951 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
952 tree operand_type = TREE_VALUE (arg_type_chain);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
953 call_operands.push_back (convert (operand_type, operands[i]));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
954 operand_types.push_back (operand_type);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
955 arg_type_chain = TREE_CHAIN (arg_type_chain);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
956 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
957
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
958 if (needs_workitem_context_data (brig_opcode))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
959 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
960 call_operands.push_back (m_context_arg);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
961 operand_types.push_back (ptr_type_node);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
962 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
963
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
964 size_t operand_count = call_operands.size ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
965
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
966 call_operands.resize (4, NULL_TREE);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
967 operand_types.resize (4, NULL_TREE);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
968 for (size_t i = 0; i < operand_count; ++i)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
969 call_operands.at (i) = build_resize_convert_view (operand_types.at (i),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
970 call_operands.at (i));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
971
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
972 tree fnptr = build_fold_addr_expr (built_in);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
973 return build_call_array (TREE_TYPE (TREE_TYPE (built_in)), fnptr,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
974 operand_count, &call_operands[0]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
975 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
976
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
977 /* Instead of calling a built-in function, use a more efficient mechanism
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
978 such as reuse a previously returned value known to be still valid, or
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
979 access the work-item context struct directly. This is beneficial especially
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
980 for the work-item identification related builtins as not having them as
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
981 unanalyzable black box calls can lead to more easily vectorizable parallel
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
982 loops for multi work-item work-groups. BRIG_OPCODE identifies the builtin
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
983 and OPERANDS store the operands. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
984
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
985 tree
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
986 brig_function::expand_builtin (BrigOpcode16_t brig_opcode,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
987 tree_stl_vec &operands)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
988 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
989 tree_stl_vec uint32_0 = tree_stl_vec (1, build_int_cst (uint32_type_node, 0));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
990
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
991 tree_stl_vec uint32_1 = tree_stl_vec (1, build_int_cst (uint32_type_node, 1));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
992
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
993 tree_stl_vec uint32_2 = tree_stl_vec (1, build_int_cst (uint32_type_node, 2));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
994
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
995 if (brig_opcode == BRIG_OPCODE_WORKITEMFLATABSID)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
996 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
997 tree id0 = expand_builtin (BRIG_OPCODE_WORKITEMABSID, uint32_0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
998 id0 = convert (uint64_type_node, id0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
999
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1000 tree id1 = expand_builtin (BRIG_OPCODE_WORKITEMABSID, uint32_1);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1001 id1 = convert (uint64_type_node, id1);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1002
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1003 tree id2 = expand_builtin (BRIG_OPCODE_WORKITEMABSID, uint32_2);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1004 id2 = convert (uint64_type_node, id2);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1005
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1006 tree max0 = convert (uint64_type_node, m_grid_size_vars[0]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1007 tree max1 = convert (uint64_type_node, m_grid_size_vars[1]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1008
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1009 tree id2_x_max0_x_max1 = build2 (MULT_EXPR, uint64_type_node, id2, max0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1010 id2_x_max0_x_max1
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1011 = build2 (MULT_EXPR, uint64_type_node, id2_x_max0_x_max1, max1);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1012
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1013 tree id1_x_max0 = build2 (MULT_EXPR, uint64_type_node, id1, max0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1014
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1015 tree sum = build2 (PLUS_EXPR, uint64_type_node, id0, id1_x_max0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1016 sum = build2 (PLUS_EXPR, uint64_type_node, sum, id2_x_max0_x_max1);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1017
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1018 return add_temp_var ("workitemflatabsid", sum);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1019 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1020 else if (brig_opcode == BRIG_OPCODE_WORKITEMABSID)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1021 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1022 HOST_WIDE_INT dim = int_constant_value (operands[0]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1023 return m_abs_id_vars[dim];
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1024 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1025 else if (brig_opcode == BRIG_OPCODE_WORKITEMFLATID)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1026 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1027
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1028 tree wg_size_x = expand_builtin (BRIG_OPCODE_WORKGROUPSIZE, uint32_0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1029 tree wg_size_y = expand_builtin (BRIG_OPCODE_WORKGROUPSIZE, uint32_1);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1030 tree z_x_wgsx_wgsy
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1031 = build2 (MULT_EXPR, uint32_type_node,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1032 convert (uint32_type_node,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1033 expand_builtin (BRIG_OPCODE_WORKITEMID, uint32_2)),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1034 wg_size_x);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1035 z_x_wgsx_wgsy = build2 (MULT_EXPR, uint32_type_node, z_x_wgsx_wgsy,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1036 wg_size_y);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1037
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1038 tree y_x_wgsx
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1039 = build2 (MULT_EXPR, uint32_type_node,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1040 convert (uint32_type_node,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1041 expand_builtin (BRIG_OPCODE_WORKITEMID, uint32_1)),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1042 wg_size_x);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1043
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1044 tree sum = build2 (PLUS_EXPR, uint32_type_node, y_x_wgsx, z_x_wgsx_wgsy);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1045 sum = build2 (PLUS_EXPR, uint32_type_node,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1046 convert (uint32_type_node,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1047 expand_builtin (BRIG_OPCODE_WORKITEMID, uint32_0)),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1048 sum);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1049 return add_temp_var ("workitemflatid", sum);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1050 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1051 else if (brig_opcode == BRIG_OPCODE_WORKGROUPSIZE)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1052 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1053 HOST_WIDE_INT dim = int_constant_value (operands[0]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1054 if (flag_assume_phsa)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1055 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1056 tree ptr_type = build_pointer_type (uint32_type_node);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1057 tree ctx = build2 (MEM_REF, uint32_type_node, m_context_arg,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1058 build_int_cst (ptr_type,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1059 PHSA_CONTEXT_WG_SIZES
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1060 + dim * 4));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1061 std::string name ("wgsize_x");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1062 name [name.length() - 1] += dim;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1063 return add_temp_var (name.c_str(), ctx);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1064 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1065 else if (m_is_kernel)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1066 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1067 /* For kernels without phsa we generate certain temps before
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1068 the WI loop, which means we don't need to rely on LICM to get
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1069 them moved out. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1070 return m_wg_size_vars[dim];
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1071 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1072 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1073 gcc_unreachable ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1074 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1075 else if (brig_opcode == BRIG_OPCODE_WORKITEMID)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1076 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1077 HOST_WIDE_INT dim = int_constant_value (operands[0]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1078 if (m_is_kernel)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1079 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1080 return m_local_id_vars [dim];
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1081 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1082 else if (flag_assume_phsa)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1083 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1084 tree ptr_type = build_pointer_type (uint32_type_node);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1085 tree ctx = build2 (MEM_REF, uint32_type_node, m_context_arg,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1086 build_int_cst (ptr_type,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1087 PHSA_CONTEXT_OFFS_WI_IDS
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1088 + dim * 4));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1089 std::string name ("wiid_x");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1090 name [name.length() - 1] += dim;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1091 return add_temp_var (name.c_str(), ctx);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1092 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1093 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1094 gcc_unreachable ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1095 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1096 else if (brig_opcode == BRIG_OPCODE_WORKGROUPID)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1097 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1098 HOST_WIDE_INT dim = int_constant_value (operands[0]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1099 if (flag_assume_phsa)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1100 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1101 tree ptr_type = build_pointer_type (uint32_type_node);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1102 tree ctx = build2 (MEM_REF, uint32_type_node, m_context_arg,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1103 build_int_cst (ptr_type,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1104 PHSA_CONTEXT_OFFS_WG_IDS
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1105 + dim * 4));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1106 std::string name ("wgid_x");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1107 name [name.length() - 1] += dim;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1108 return add_temp_var (name.c_str(), ctx);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1109 } else if (m_is_kernel)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1110 return m_wg_id_vars [dim];
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1111 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1112 gcc_unreachable ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1113 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1114 else if (brig_opcode == BRIG_OPCODE_CURRENTWORKGROUPSIZE)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1115 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1116 HOST_WIDE_INT dim = int_constant_value (operands[0]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1117 if (flag_assume_phsa)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1118 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1119 tree ptr_type = build_pointer_type (uint32_type_node);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1120 tree ctx = build2 (MEM_REF, uint32_type_node, m_context_arg,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1121 build_int_cst (ptr_type,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1122 PHSA_CONTEXT_CURRENT_WG_SIZES
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1123 + dim * 4));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1124 std::string name ("curwgsize_x");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1125 name [name.length() - 1] += dim;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1126 return add_temp_var (name.c_str(), ctx);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1127 } else if (m_is_kernel)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1128 return m_cur_wg_size_vars[dim];
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1129 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1130 gcc_unreachable ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1131 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1132 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1133 gcc_unreachable ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1134
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1135 return NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1136 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1137
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1138 /* Returns true in case the given opcode that would normally be generated
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1139 as a builtin call can be expanded to tree nodes. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1140
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1141 bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1142 brig_function::can_expand_builtin (BrigOpcode16_t brig_opcode) const
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1143 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1144 switch (brig_opcode)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1145 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1146 case BRIG_OPCODE_CURRENTWORKGROUPSIZE:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1147 case BRIG_OPCODE_WORKITEMFLATID:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1148 case BRIG_OPCODE_WORKITEMID:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1149 case BRIG_OPCODE_WORKGROUPID:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1150 case BRIG_OPCODE_WORKGROUPSIZE:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1151 return m_is_kernel || flag_assume_phsa;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1152 case BRIG_OPCODE_WORKITEMFLATABSID:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1153 case BRIG_OPCODE_WORKITEMABSID:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1154 return m_is_kernel;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1155 default:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1156 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1157 };
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1158 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1159
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1160 /* In case the HSA instruction must be implemented using a builtin,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1161 this function is called to get the correct builtin function.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1162 TYPE is the instruction tree type, BRIG_OPCODE the opcode of the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1163 brig instruction and BRIG_TYPE the brig instruction's type. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1164
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1165 tree
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1166 brig_function::get_builtin_for_hsa_opcode
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1167 (tree type, BrigOpcode16_t brig_opcode, BrigType16_t brig_type) const
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1168 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1169 tree builtin = NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1170 tree builtin_type = type;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1171
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1172 /* For vector types, first find the scalar version of the builtin. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1173 if (type != NULL_TREE && VECTOR_TYPE_P (type))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1174 builtin_type = TREE_TYPE (type);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1175 BrigType16_t brig_inner_type = brig_type & BRIG_TYPE_BASE_MASK;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1176
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1177 /* Some BRIG opcodes can use the same builtins for unsigned and
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1178 signed types. Force these cases to unsigned types. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1179
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1180 if (brig_opcode == BRIG_OPCODE_BORROW
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1181 || brig_opcode == BRIG_OPCODE_CARRY
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1182 || brig_opcode == BRIG_OPCODE_LASTBIT
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1183 || brig_opcode == BRIG_OPCODE_BITINSERT)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1184 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1185 if (brig_type == BRIG_TYPE_S32)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1186 brig_type = BRIG_TYPE_U32;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1187 else if (brig_type == BRIG_TYPE_S64)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1188 brig_type = BRIG_TYPE_U64;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1189 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1190
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1191 switch (brig_opcode)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1192 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1193 case BRIG_OPCODE_FLOOR:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1194 builtin = mathfn_built_in (builtin_type, BUILT_IN_FLOOR);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1195 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1196 case BRIG_OPCODE_CEIL:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1197 builtin = mathfn_built_in (builtin_type, BUILT_IN_CEIL);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1198 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1199 case BRIG_OPCODE_SQRT:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1200 case BRIG_OPCODE_NSQRT:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1201 builtin = mathfn_built_in (builtin_type, BUILT_IN_SQRT);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1202 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1203 case BRIG_OPCODE_RINT:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1204 builtin = mathfn_built_in (builtin_type, BUILT_IN_RINT);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1205 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1206 case BRIG_OPCODE_TRUNC:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1207 builtin = mathfn_built_in (builtin_type, BUILT_IN_TRUNC);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1208 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1209 case BRIG_OPCODE_COPYSIGN:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1210 builtin = mathfn_built_in (builtin_type, BUILT_IN_COPYSIGN);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1211 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1212 case BRIG_OPCODE_NSIN:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1213 builtin = mathfn_built_in (builtin_type, BUILT_IN_SIN);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1214 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1215 case BRIG_OPCODE_NLOG2:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1216 builtin = mathfn_built_in (builtin_type, BUILT_IN_LOG2);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1217 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1218 case BRIG_OPCODE_NEXP2:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1219 builtin = mathfn_built_in (builtin_type, BUILT_IN_EXP2);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1220 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1221 case BRIG_OPCODE_FMA:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1222 case BRIG_OPCODE_NFMA:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1223 builtin = mathfn_built_in (builtin_type, BUILT_IN_FMA);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1224 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1225 case BRIG_OPCODE_NCOS:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1226 builtin = mathfn_built_in (builtin_type, BUILT_IN_COS);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1227 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1228 case BRIG_OPCODE_POPCOUNT:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1229 /* Popcount should be typed by its argument type (the return value
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1230 is always u32). Let's use a b64 version for also for b32 for now. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1231 return builtin_decl_explicit (BUILT_IN_POPCOUNTL);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1232 case BRIG_OPCODE_BORROW:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1233 /* Borrow uses the same builtin for unsigned and signed types. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1234 if (brig_type == BRIG_TYPE_S32 || brig_type == BRIG_TYPE_U32)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1235 return builtin_decl_explicit (BUILT_IN_HSAIL_BORROW_U32);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1236 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1237 return builtin_decl_explicit (BUILT_IN_HSAIL_BORROW_U64);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1238 case BRIG_OPCODE_CARRY:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1239 /* Carry also uses the same builtin for unsigned and signed types. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1240 if (brig_type == BRIG_TYPE_S32 || brig_type == BRIG_TYPE_U32)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1241 return builtin_decl_explicit (BUILT_IN_HSAIL_CARRY_U32);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1242 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1243 return builtin_decl_explicit (BUILT_IN_HSAIL_CARRY_U64);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1244 default:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1245
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1246 /* Use our builtin index for finding a proper builtin for the BRIG
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1247 opcode and BRIG type. This takes care most of the builtin cases,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1248 the special cases are handled in the separate 'case' statements
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1249 above. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1250 builtin_map::const_iterator i
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1251 = s_custom_builtins.find (std::make_pair (brig_opcode, brig_type));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1252 if (i != s_custom_builtins.end ())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1253 return (*i).second;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1254
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1255 if (brig_inner_type != brig_type)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1256 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1257 /* Try to find a scalar built-in we could use. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1258 i = s_custom_builtins.find
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1259 (std::make_pair (brig_opcode, brig_inner_type));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1260 if (i != s_custom_builtins.end ())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1261 return (*i).second;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1262 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1263
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1264 /* In case this is an fp16 operation that is promoted to fp32,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1265 try to find a fp32 scalar built-in. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1266 if (brig_inner_type == BRIG_TYPE_F16)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1267 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1268 i = s_custom_builtins.find
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1269 (std::make_pair (brig_opcode, BRIG_TYPE_F32));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1270 if (i != s_custom_builtins.end ())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1271 return (*i).second;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1272 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1273 gcc_unreachable ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1274 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1275
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1276 if (VECTOR_TYPE_P (type) && builtin != NULL_TREE)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1277 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1278 /* Try to find a vectorized version of the built-in.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1279 TODO: properly assert that builtin is a mathfn builtin? */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1280 tree vec_builtin
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1281 = targetm.vectorize.builtin_vectorized_function
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1282 (builtin_mathfn_code (builtin), type, type);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1283 if (vec_builtin != NULL_TREE)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1284 return vec_builtin;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1285 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1286 return builtin;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1287 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1288 if (builtin == NULL_TREE)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1289 gcc_unreachable ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1290 return builtin;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1291 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1292
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1293 /* Unpacks the elements of the vector in VALUE to scalars (bit field
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1294 references) in ELEMENTS. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1295
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1296 void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1297 brig_function::unpack (tree value, tree_stl_vec &elements)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1298 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1299 size_t vec_size = int_size_in_bytes (TREE_TYPE (value));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1300 size_t element_size
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1301 = int_size_in_bytes (TREE_TYPE (TREE_TYPE (value))) * BITS_PER_UNIT;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1302 size_t element_count
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1303 = vec_size * BITS_PER_UNIT / element_size;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1304
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1305 tree input_element_type = TREE_TYPE (TREE_TYPE (value));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1306
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1307 value = add_temp_var ("unpack_input", value);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1308
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1309 for (size_t i = 0; i < element_count; ++i)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1310 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1311 tree element
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1312 = build3 (BIT_FIELD_REF, input_element_type, value,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1313 TYPE_SIZE (input_element_type),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1314 bitsize_int(i * element_size));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1315
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1316 element = add_temp_var ("scalar", element);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1317 elements.push_back (element);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1318 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1319 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1320
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1321 /* Pack the elements of the scalars in ELEMENTS to the returned vector. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1322
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1323 tree
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1324 brig_function::pack (tree_stl_vec &elements)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1325 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1326 size_t element_count = elements.size ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1327
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1328 gcc_assert (element_count > 1);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1329
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1330 tree output_element_type = TREE_TYPE (elements.at (0));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1331
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1332 vec<constructor_elt, va_gc> *constructor_vals = NULL;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1333 for (size_t i = 0; i < element_count; ++i)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1334 CONSTRUCTOR_APPEND_ELT (constructor_vals, NULL_TREE, elements.at (i));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1335
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1336 tree vec_type = build_vector_type (output_element_type, element_count);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1337
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1338 /* build_constructor creates a vector type which is not a vector_cst
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1339 that requires compile time constant elements. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1340 tree vec = build_constructor (vec_type, constructor_vals);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1341
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1342 /* Add a temp variable for readability. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1343 tree tmp_var = create_tmp_var (vec_type, "vec_out");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1344 tree vec_tmp_assign = build2 (MODIFY_EXPR, TREE_TYPE (tmp_var), tmp_var, vec);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1345 append_statement (vec_tmp_assign);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1346 return tmp_var;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1347 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1348
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1349 /* Returns true in case the given opcode needs to know about work-item context
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1350 data. In such case the context data is passed as a pointer to a work-item
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1351 context object, as the last argument in the builtin call. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1352
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1353 bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1354 brig_function::needs_workitem_context_data
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1355 (BrigOpcode16_t brig_opcode)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1356 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1357 switch (brig_opcode)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1358 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1359 case BRIG_OPCODE_WORKITEMABSID:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1360 case BRIG_OPCODE_WORKITEMFLATABSID:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1361 case BRIG_OPCODE_WORKITEMFLATID:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1362 case BRIG_OPCODE_CURRENTWORKITEMFLATID:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1363 case BRIG_OPCODE_WORKITEMID:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1364 case BRIG_OPCODE_WORKGROUPID:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1365 case BRIG_OPCODE_WORKGROUPSIZE:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1366 case BRIG_OPCODE_CURRENTWORKGROUPSIZE:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1367 case BRIG_OPCODE_GRIDGROUPS:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1368 case BRIG_OPCODE_GRIDSIZE:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1369 case BRIG_OPCODE_DIM:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1370 case BRIG_OPCODE_PACKETID:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1371 case BRIG_OPCODE_PACKETCOMPLETIONSIG:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1372 case BRIG_OPCODE_BARRIER:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1373 case BRIG_OPCODE_WAVEBARRIER:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1374 case BRIG_OPCODE_ARRIVEFBAR:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1375 case BRIG_OPCODE_INITFBAR:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1376 case BRIG_OPCODE_JOINFBAR:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1377 case BRIG_OPCODE_LEAVEFBAR:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1378 case BRIG_OPCODE_RELEASEFBAR:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1379 case BRIG_OPCODE_WAITFBAR:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1380 case BRIG_OPCODE_CUID:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1381 case BRIG_OPCODE_MAXCUID:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1382 case BRIG_OPCODE_DEBUGTRAP:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1383 case BRIG_OPCODE_GROUPBASEPTR:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1384 case BRIG_OPCODE_KERNARGBASEPTR:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1385 case BRIG_OPCODE_ALLOCA:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1386 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1387 default:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1388 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1389 };
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1390 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1391
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1392 /* Appends and returns a new temp variable and an accompanying assignment
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1393 statement that stores the value of the given EXPR and has the given NAME. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1394
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1395 tree
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1396 brig_function::add_temp_var (std::string name, tree expr)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1397 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1398 tree temp_var = create_tmp_var (TREE_TYPE (expr), name.c_str ());
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1399 tree assign = build2 (MODIFY_EXPR, TREE_TYPE (temp_var), temp_var, expr);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1400 append_statement (assign);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1401 return temp_var;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1402 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1403
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1404 /* Returns the integer constant value of the given node.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1405 If it's a cast, looks into the source of the cast. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1406
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1407 HOST_WIDE_INT
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1408 brig_function::int_constant_value (tree node)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1409 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1410 tree n = node;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1411 if (TREE_CODE (n) == VIEW_CONVERT_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1412 n = TREE_OPERAND (n, 0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1413 return int_cst_value (n);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1414 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1415
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1416 /* Returns the tree code that should be used to implement the given
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1417 HSA instruction opcode (BRIG_OPCODE) for the given type of instruction
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1418 (BRIG_TYPE). In case the opcode cannot be mapped to a TREE node directly,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1419 returns TREE_LIST (if it can be emulated with a simple chain of tree
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1420 nodes) or CALL_EXPR if the opcode should be implemented using a builtin
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1421 call. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1422
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1423 tree_code
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1424 brig_function::get_tree_code_for_hsa_opcode
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1425 (BrigOpcode16_t brig_opcode, BrigType16_t brig_type)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1426 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1427 BrigType16_t brig_inner_type = brig_type & BRIG_TYPE_BASE_MASK;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1428 switch (brig_opcode)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1429 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1430 case BRIG_OPCODE_NOP:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1431 return NOP_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1432 case BRIG_OPCODE_ADD:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1433 return PLUS_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1434 case BRIG_OPCODE_CMOV:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1435 if (brig_inner_type == brig_type)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1436 return COND_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1437 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1438 return VEC_COND_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1439 case BRIG_OPCODE_SUB:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1440 return MINUS_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1441 case BRIG_OPCODE_MUL:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1442 case BRIG_OPCODE_MUL24:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1443 return MULT_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1444 case BRIG_OPCODE_MULHI:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1445 case BRIG_OPCODE_MUL24HI:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1446 return MULT_HIGHPART_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1447 case BRIG_OPCODE_DIV:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1448 if (gccbrig_is_float_type (brig_inner_type))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1449 return RDIV_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1450 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1451 return TRUNC_DIV_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1452 case BRIG_OPCODE_NEG:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1453 return NEGATE_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1454 case BRIG_OPCODE_MIN:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1455 if (gccbrig_is_float_type (brig_inner_type))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1456 return CALL_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1457 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1458 return MIN_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1459 case BRIG_OPCODE_MAX:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1460 if (gccbrig_is_float_type (brig_inner_type))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1461 return CALL_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1462 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1463 return MAX_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1464 case BRIG_OPCODE_ABS:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1465 return ABS_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1466 case BRIG_OPCODE_SHL:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1467 return LSHIFT_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1468 case BRIG_OPCODE_SHR:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1469 return RSHIFT_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1470 case BRIG_OPCODE_OR:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1471 return BIT_IOR_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1472 case BRIG_OPCODE_XOR:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1473 return BIT_XOR_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1474 case BRIG_OPCODE_AND:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1475 return BIT_AND_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1476 case BRIG_OPCODE_NOT:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1477 return BIT_NOT_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1478 case BRIG_OPCODE_RET:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1479 return RETURN_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1480 case BRIG_OPCODE_MOV:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1481 case BRIG_OPCODE_LDF:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1482 return MODIFY_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1483 case BRIG_OPCODE_LD:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1484 case BRIG_OPCODE_ST:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1485 return MEM_REF;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1486 case BRIG_OPCODE_BR:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1487 return GOTO_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1488 case BRIG_OPCODE_REM:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1489 if (brig_type == BRIG_TYPE_U64 || brig_type == BRIG_TYPE_U32)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1490 return TRUNC_MOD_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1491 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1492 return CALL_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1493 case BRIG_OPCODE_NRCP:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1494 case BRIG_OPCODE_NRSQRT:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1495 /* Implement as 1/f (x). gcc should pattern detect that and
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1496 use a native instruction, if available, for it. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1497 return TREE_LIST;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1498 case BRIG_OPCODE_FMA:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1499 case BRIG_OPCODE_FLOOR:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1500 case BRIG_OPCODE_CEIL:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1501 case BRIG_OPCODE_SQRT:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1502 case BRIG_OPCODE_NSQRT:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1503 case BRIG_OPCODE_RINT:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1504 case BRIG_OPCODE_TRUNC:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1505 case BRIG_OPCODE_POPCOUNT:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1506 case BRIG_OPCODE_COPYSIGN:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1507 case BRIG_OPCODE_NCOS:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1508 case BRIG_OPCODE_NSIN:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1509 case BRIG_OPCODE_NLOG2:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1510 case BRIG_OPCODE_NEXP2:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1511 case BRIG_OPCODE_NFMA:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1512 /* Class has type B1 regardless of the float type, thus
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1513 the below builtin map search cannot find it. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1514 case BRIG_OPCODE_CLASS:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1515 case BRIG_OPCODE_WORKITEMABSID:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1516 return CALL_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1517 default:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1518
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1519 /* Some BRIG opcodes can use the same builtins for unsigned and
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1520 signed types. Force these cases to unsigned types.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1521 */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1522
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1523 if (brig_opcode == BRIG_OPCODE_BORROW
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1524 || brig_opcode == BRIG_OPCODE_CARRY
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1525 || brig_opcode == BRIG_OPCODE_LASTBIT
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1526 || brig_opcode == BRIG_OPCODE_BITINSERT)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1527 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1528 if (brig_type == BRIG_TYPE_S32)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1529 brig_type = BRIG_TYPE_U32;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1530 else if (brig_type == BRIG_TYPE_S64)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1531 brig_type = BRIG_TYPE_U64;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1532 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1533
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1534
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1535 builtin_map::const_iterator i
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1536 = s_custom_builtins.find (std::make_pair (brig_opcode, brig_type));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1537 if (i != s_custom_builtins.end ())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1538 return CALL_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1539 else if (s_custom_builtins.find
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1540 (std::make_pair (brig_opcode, brig_inner_type))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1541 != s_custom_builtins.end ())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1542 return CALL_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1543 if (brig_inner_type == BRIG_TYPE_F16
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1544 && s_custom_builtins.find
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1545 (std::make_pair (brig_opcode, BRIG_TYPE_F32))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1546 != s_custom_builtins.end ())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1547 return CALL_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1548 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1549 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1550 return TREE_LIST; /* Emulate using a chain of nodes. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1551 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1552
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1553 /* Inform of an update to the REG_VAR. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1554
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1555 void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1556 brig_function::add_reg_var_update (tree reg_var, tree var)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1557 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1558 if (var == m_abs_id_vars[0] || var == m_abs_id_vars[1]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1559 || var == m_abs_id_vars[2] || var == m_local_id_vars[0]
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1560 || var == m_local_id_vars[1] || var == m_local_id_vars[2])
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1561 m_id_val_defs [reg_var] = var;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1562 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1563 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1564 /* Possible overwrite of an ID value. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1565
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1566 id_val_map::iterator i = m_id_val_defs.find (reg_var);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1567 if (i != m_id_val_defs.end())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1568 m_id_val_defs.erase (i);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1569 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1570 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1571
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1572 /* If the REG_VAR is known to contain an ID value at this point in
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1573 the basic block, return true. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1574
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1575 bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1576 brig_function::is_id_val (tree reg_var)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1577 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1578 id_val_map::iterator i = m_id_val_defs.find (reg_var);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1579 return i != m_id_val_defs.end();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1580 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1581
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1582 /* Return an ID value for the given REG_VAR if its known to contain
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1583 one at this point in the BB, NULL_TREE otherwise. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1584
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1585 tree
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1586 brig_function::id_val (tree reg_var)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1587 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1588 id_val_map::iterator i = m_id_val_defs.find (reg_var);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1589 if (i != m_id_val_defs.end())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1590 return (*i).second;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1591 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1592 return NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1593 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1594
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1595 /* Informs of starting a new basic block. Called when generating
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1596 a label, a call, a jump, or a return. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1597
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1598 void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1599 brig_function::start_new_bb ()
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1600 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1601 m_id_val_defs.clear ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1602 }