Mercurial > hg > CbC > CbC_gcc
comparison gcc/brig/brigfrontend/brig-function-handler.cc @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
111:04ced10e8804 | 131:84e7813d76e9 |
---|---|
1 /* brig-code-entry-handler.cc -- brig function directive handling | 1 /* brig-code-entry-handler.cc -- brig function directive handling |
2 Copyright (C) 2016-2017 Free Software Foundation, Inc. | 2 Copyright (C) 2016-2018 Free Software Foundation, Inc. |
3 Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com> | 3 Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com> |
4 for General Processor Tech. | 4 for General Processor Tech. |
5 | 5 |
6 This file is part of GCC. | 6 This file is part of GCC. |
7 | 7 |
78 /* During the analyze step, the above information is all we need per | 78 /* During the analyze step, the above information is all we need per |
79 function. */ | 79 function. */ |
80 if (m_parent.m_analyzing) | 80 if (m_parent.m_analyzing) |
81 return bytes_consumed; | 81 return bytes_consumed; |
82 | 82 |
83 /* There can be multiple forward declarations of the same function. | |
84 Skip all but the first one. */ | |
85 if (!is_definition && m_parent.function_decl (func_name) != NULL_TREE) | |
86 return bytes_consumed; | |
83 tree fndecl; | 87 tree fndecl; |
84 tree ret_value = NULL_TREE; | 88 tree ret_value = NULL_TREE; |
85 | 89 |
86 tree stmt_list = alloc_stmt_list (); | 90 tree stmt_list = alloc_stmt_list (); |
87 | 91 |
88 /* Add a function scope BIND_EXPR using which we can push local variables that | 92 /* Add a function scope BIND_EXPR using which we can push local variables that |
89 represent HSAIL registers. */ | 93 represent HSAIL registers. */ |
90 tree bind_expr = build3 (BIND_EXPR, void_type_node, NULL, stmt_list, NULL); | 94 tree bind_expr = build3 (BIND_EXPR, void_type_node, NULL, stmt_list, NULL); |
95 | |
96 tree restrict_char_ptr | |
97 = build_qualified_type (build_pointer_type (char_type_node), | |
98 TYPE_QUAL_RESTRICT); | |
99 tree restrict_void_ptr | |
100 = build_qualified_type (build_pointer_type (void_type_node), | |
101 TYPE_QUAL_RESTRICT); | |
102 | |
103 tree restrict_const_char_ptr | |
104 = build_qualified_type (build_pointer_type | |
105 (build_qualified_type (char_type_node, | |
106 TYPE_QUAL_CONST)), | |
107 TYPE_QUAL_RESTRICT); | |
108 | |
109 tree restrict_const_void_ptr | |
110 = build_qualified_type (build_pointer_type | |
111 (build_qualified_type (void_type_node, | |
112 TYPE_QUAL_CONST)), | |
113 TYPE_QUAL_RESTRICT); | |
91 | 114 |
92 if (is_kernel) | 115 if (is_kernel) |
93 { | 116 { |
94 tree name_identifier | 117 tree name_identifier |
95 = get_identifier_with_length (func_name.c_str (), func_name.size ()); | 118 = get_identifier_with_length (func_name.c_str (), func_name.size ()); |
101 2) a void* parameter that points to a phsail-finalizer context object | 124 2) a void* parameter that points to a phsail-finalizer context object |
102 which passes the hsa kernel packet etc. | 125 which passes the hsa kernel packet etc. |
103 3) a void* parameter that contains the first flat address of the group | 126 3) a void* parameter that contains the first flat address of the group |
104 region allocated to the current work-group. */ | 127 region allocated to the current work-group. */ |
105 | 128 |
106 tree char_ptr_type_node = build_pointer_type (char_type_node); | |
107 fndecl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, name_identifier, | 129 fndecl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, name_identifier, |
108 build_function_type_list (void_type_node, | 130 build_function_type_list (void_type_node, |
109 char_ptr_type_node, | 131 restrict_const_char_ptr, |
110 ptr_type_node, | 132 restrict_void_ptr, |
111 ptr_type_node, NULL_TREE)); | 133 restrict_char_ptr, NULL_TREE)); |
112 | 134 |
113 SET_DECL_ASSEMBLER_NAME (fndecl, name_identifier); | 135 SET_DECL_ASSEMBLER_NAME (fndecl, name_identifier); |
114 | 136 |
115 tree resdecl | 137 tree resdecl |
116 = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, void_type_node); | 138 = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, void_type_node); |
119 tree argtype = TREE_VALUE (typelist); | 141 tree argtype = TREE_VALUE (typelist); |
120 TYPE_ADDR_SPACE (argtype) | 142 TYPE_ADDR_SPACE (argtype) |
121 = gccbrig_get_target_addr_space_id (BRIG_SEGMENT_KERNARG); | 143 = gccbrig_get_target_addr_space_id (BRIG_SEGMENT_KERNARG); |
122 | 144 |
123 tree arg_arg = build_decl (UNKNOWN_LOCATION, PARM_DECL, | 145 tree arg_arg = build_decl (UNKNOWN_LOCATION, PARM_DECL, |
124 get_identifier ("__args"), char_ptr_type_node); | 146 get_identifier ("__args"), |
147 restrict_const_char_ptr); | |
125 DECL_ARGUMENTS (fndecl) = arg_arg; | 148 DECL_ARGUMENTS (fndecl) = arg_arg; |
126 DECL_ARG_TYPE (arg_arg) = char_ptr_type_node; | 149 DECL_ARG_TYPE (arg_arg) = restrict_const_char_ptr; |
127 DECL_CONTEXT (arg_arg) = fndecl; | 150 DECL_CONTEXT (arg_arg) = fndecl; |
128 DECL_ARTIFICIAL (arg_arg) = 1; | 151 DECL_ARTIFICIAL (arg_arg) = 1; |
129 TREE_READONLY (arg_arg) = 1; | 152 TREE_READONLY (arg_arg) = 1; |
130 TREE_USED (arg_arg) = 1; | 153 TREE_USED (arg_arg) = 1; |
131 | 154 |
132 DECL_RESULT (fndecl) = resdecl; | 155 DECL_RESULT (fndecl) = resdecl; |
133 DECL_CONTEXT (resdecl) = fndecl; | 156 DECL_CONTEXT (resdecl) = fndecl; |
134 DECL_EXTERNAL (fndecl) = 0; | 157 DECL_EXTERNAL (fndecl) = 0; |
158 | |
159 /* Aggressive inlining to the kernel function is usually a good | |
160 idea with offlined functionality to enchance SIMD execution on | |
161 GPUs and vector units. */ | |
162 | |
163 DECL_ATTRIBUTES (fndecl) | |
164 = tree_cons (get_identifier ("flatten"), NULL, | |
165 DECL_ATTRIBUTES (fndecl)); | |
135 } | 166 } |
136 else | 167 else |
137 { | 168 { |
138 /* Build a regular function fingerprint to enable targets to optimize | 169 /* Build a regular function fingerprint to enable targets to optimize |
139 the calling convention as they see fit. */ | 170 the calling convention as they see fit. */ |
175 m_parent.m_cf->add_arg_variable (brigVar, arg_var); | 206 m_parent.m_cf->add_arg_variable (brigVar, arg_var); |
176 | 207 |
177 if (arg_decls == NULL_TREE) | 208 if (arg_decls == NULL_TREE) |
178 arg_decls = arg_var; | 209 arg_decls = arg_var; |
179 else | 210 else |
180 chainon (arg_decls, arg_var); | 211 arg_decls = chainon (arg_decls, arg_var); |
181 | 212 |
182 m_parent.m_cf->add_arg_variable (brigVar, arg_var); | 213 m_parent.m_cf->add_arg_variable (brigVar, arg_var); |
183 | 214 |
184 ret_value = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, | 215 ret_value = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, |
185 void_type_node); | 216 void_type_node); |
216 tree arg_var = varhandler.build_variable (brigVar, PARM_DECL); | 247 tree arg_var = varhandler.build_variable (brigVar, PARM_DECL); |
217 arg_offset += brigVar->base.byteCount; | 248 arg_offset += brigVar->base.byteCount; |
218 vec_safe_push (args, TREE_TYPE (arg_var)); | 249 vec_safe_push (args, TREE_TYPE (arg_var)); |
219 | 250 |
220 m_parent.m_cf->add_arg_variable (brigVar, arg_var); | 251 m_parent.m_cf->add_arg_variable (brigVar, arg_var); |
221 | 252 arg_decls = chainon (arg_decls, arg_var); |
222 if (arg_decls == NULL_TREE) | |
223 arg_decls = arg_var; | |
224 else | |
225 chainon (arg_decls, arg_var); | |
226 } | 253 } |
227 } | 254 } |
228 | 255 vec_safe_push (args, restrict_void_ptr); |
229 vec_safe_push (args, ptr_type_node); | 256 vec_safe_push (args, restrict_char_ptr); |
230 vec_safe_push (args, ptr_type_node); | 257 vec_safe_push (args, uint32_type_node); |
258 vec_safe_push (args, restrict_char_ptr); | |
231 | 259 |
232 fndecl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, name_identifier, | 260 fndecl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, name_identifier, |
233 build_function_type_vec (ret_type, args)); | 261 build_function_type_vec (ret_type, args)); |
234 | 262 |
235 DECL_RESULT (fndecl) = ret_value; | 263 DECL_RESULT (fndecl) = ret_value; |
238 DECL_ARGUMENTS (fndecl) = arg_decls; | 266 DECL_ARGUMENTS (fndecl) = arg_decls; |
239 } | 267 } |
240 | 268 |
241 /* All functions need the hidden __context argument passed on | 269 /* All functions need the hidden __context argument passed on |
242 because they might call WI-specific functions which need | 270 because they might call WI-specific functions which need |
243 the context info. */ | 271 the context info. Only kernels can write it, if they need |
272 to update the local ids in the work-item loop. */ | |
273 | |
274 tree context_arg_type | |
275 = true ? restrict_void_ptr : restrict_const_void_ptr; | |
244 tree context_arg = build_decl (UNKNOWN_LOCATION, PARM_DECL, | 276 tree context_arg = build_decl (UNKNOWN_LOCATION, PARM_DECL, |
245 get_identifier ("__context"), ptr_type_node); | 277 get_identifier ("__context"), |
246 if (DECL_ARGUMENTS (fndecl) == NULL_TREE) | 278 context_arg_type); |
247 DECL_ARGUMENTS (fndecl) = context_arg; | 279 DECL_ARGUMENTS (fndecl) = chainon (DECL_ARGUMENTS (fndecl), context_arg); |
248 else | |
249 chainon (DECL_ARGUMENTS (fndecl), context_arg); | |
250 DECL_CONTEXT (context_arg) = fndecl; | 280 DECL_CONTEXT (context_arg) = fndecl; |
251 DECL_ARG_TYPE (context_arg) = ptr_type_node; | 281 DECL_ARG_TYPE (context_arg) = context_arg_type; |
252 DECL_ARTIFICIAL (context_arg) = 1; | 282 DECL_ARTIFICIAL (context_arg) = 1; |
253 TREE_READONLY (context_arg) = 1; | 283 TREE_READONLY (context_arg) = 1; |
254 TREE_USED (context_arg) = 1; | 284 TREE_USED (context_arg) = 1; |
285 m_parent.m_cf->m_context_arg = context_arg; | |
255 | 286 |
256 /* They can also access group memory, so we need to pass the | 287 /* They can also access group memory, so we need to pass the |
257 group pointer along too. */ | 288 group pointer along too. */ |
258 tree group_base_arg | 289 tree group_base_arg |
259 = build_decl (UNKNOWN_LOCATION, PARM_DECL, | 290 = build_decl (UNKNOWN_LOCATION, PARM_DECL, |
260 get_identifier ("__group_base_addr"), ptr_type_node); | 291 get_identifier ("__group_base_addr"), |
261 chainon (DECL_ARGUMENTS (fndecl), group_base_arg); | 292 restrict_char_ptr); |
262 DECL_ARG_TYPE (group_base_arg) = ptr_type_node; | 293 DECL_ARGUMENTS (fndecl) = chainon (DECL_ARGUMENTS (fndecl), group_base_arg); |
294 DECL_ARG_TYPE (group_base_arg) = restrict_char_ptr; | |
263 DECL_CONTEXT (group_base_arg) = fndecl; | 295 DECL_CONTEXT (group_base_arg) = fndecl; |
264 DECL_ARTIFICIAL (group_base_arg) = 1; | 296 DECL_ARTIFICIAL (group_base_arg) = 1; |
265 TREE_READONLY (group_base_arg) = 1; | 297 TREE_READONLY (group_base_arg) = 1; |
266 TREE_USED (group_base_arg) = 1; | 298 TREE_USED (group_base_arg) = 1; |
267 m_parent.m_cf->m_group_base_arg = group_base_arg; | 299 m_parent.m_cf->m_group_base_arg = group_base_arg; |
272 That must be substracted from any function local group variable offsets to | 304 That must be substracted from any function local group variable offsets to |
273 get the address related to the bottom of the group memory chunk. */ | 305 get the address related to the bottom of the group memory chunk. */ |
274 tree group_local_offset_arg | 306 tree group_local_offset_arg |
275 = build_decl (UNKNOWN_LOCATION, PARM_DECL, | 307 = build_decl (UNKNOWN_LOCATION, PARM_DECL, |
276 get_identifier ("__group_local_offset"), uint32_type_node); | 308 get_identifier ("__group_local_offset"), uint32_type_node); |
277 chainon (DECL_ARGUMENTS (fndecl), group_local_offset_arg); | 309 DECL_ARGUMENTS (fndecl) = chainon (DECL_ARGUMENTS (fndecl), group_local_offset_arg); |
278 DECL_ARG_TYPE (group_local_offset_arg) = uint32_type_node; | 310 DECL_ARG_TYPE (group_local_offset_arg) = uint32_type_node; |
279 DECL_CONTEXT (group_local_offset_arg) = fndecl; | 311 DECL_CONTEXT (group_local_offset_arg) = fndecl; |
280 DECL_ARTIFICIAL (group_local_offset_arg) = 1; | 312 DECL_ARTIFICIAL (group_local_offset_arg) = 1; |
281 TREE_READONLY (group_local_offset_arg) = 1; | 313 TREE_READONLY (group_local_offset_arg) = 1; |
282 TREE_USED (group_local_offset_arg) = 1; | 314 TREE_USED (group_local_offset_arg) = 1; |
283 m_parent.m_cf->m_group_local_offset_arg = group_local_offset_arg; | 315 m_parent.m_cf->m_group_local_offset_arg = group_local_offset_arg; |
284 | 316 |
285 /* Same for private. */ | 317 /* Same for private. */ |
286 tree private_base_arg | 318 tree private_base_arg |
287 = build_decl (UNKNOWN_LOCATION, PARM_DECL, | 319 = build_decl (UNKNOWN_LOCATION, PARM_DECL, |
288 get_identifier ("__private_base_addr"), ptr_type_node); | 320 get_identifier ("__private_base_addr"), restrict_char_ptr); |
289 chainon (DECL_ARGUMENTS (fndecl), private_base_arg); | 321 DECL_ARGUMENTS (fndecl) = chainon (DECL_ARGUMENTS (fndecl), private_base_arg); |
290 DECL_ARG_TYPE (private_base_arg) = ptr_type_node; | 322 DECL_ARG_TYPE (private_base_arg) = restrict_char_ptr; |
291 DECL_CONTEXT (private_base_arg) = fndecl; | 323 DECL_CONTEXT (private_base_arg) = fndecl; |
292 DECL_ARTIFICIAL (private_base_arg) = 1; | 324 DECL_ARTIFICIAL (private_base_arg) = 1; |
293 TREE_READONLY (private_base_arg) = 1; | 325 TREE_READONLY (private_base_arg) = 1; |
294 TREE_USED (private_base_arg) = 1; | 326 TREE_USED (private_base_arg) = 1; |
327 m_parent.m_cf->m_private_base_arg = private_base_arg; | |
295 | 328 |
296 DECL_SAVED_TREE (fndecl) = bind_expr; | 329 DECL_SAVED_TREE (fndecl) = bind_expr; |
297 | 330 |
298 /* Try to preserve the functions across IPA. */ | |
299 DECL_PRESERVE_P (fndecl) = 1; | |
300 TREE_SIDE_EFFECTS (fndecl) = 1; | |
301 | |
302 TREE_ADDRESSABLE (fndecl) = 1; | |
303 | |
304 if (base->kind == BRIG_KIND_DIRECTIVE_FUNCTION) | 331 if (base->kind == BRIG_KIND_DIRECTIVE_FUNCTION) |
305 { | 332 { |
306 TREE_STATIC (fndecl) = 1; | 333 TREE_STATIC (fndecl) = 0; |
307 TREE_PUBLIC (fndecl) = 1; | 334 TREE_PUBLIC (fndecl) = 1; |
335 DECL_EXTERNAL (fndecl) = 0; | |
336 DECL_DECLARED_INLINE_P (fndecl) = 1; | |
337 set_inline (fndecl); | |
338 set_externally_visible (fndecl); | |
308 } | 339 } |
309 else if (base->kind == BRIG_KIND_DIRECTIVE_KERNEL) | 340 else if (base->kind == BRIG_KIND_DIRECTIVE_KERNEL) |
310 { | 341 { |
311 TREE_STATIC (fndecl) = 1; | 342 TREE_STATIC (fndecl) = 0; |
312 TREE_PUBLIC (fndecl) = 1; | 343 TREE_PUBLIC (fndecl) = 1; |
344 DECL_EXTERNAL (fndecl) = 0; | |
345 set_externally_visible (fndecl); | |
313 } | 346 } |
314 else if (base->kind == BRIG_KIND_DIRECTIVE_SIGNATURE) | 347 else if (base->kind == BRIG_KIND_DIRECTIVE_SIGNATURE) |
315 { | 348 { |
316 TREE_STATIC (fndecl) = 0; | 349 TREE_STATIC (fndecl) = 0; |
317 TREE_PUBLIC (fndecl) = 1; | 350 TREE_PUBLIC (fndecl) = 1; |
318 DECL_EXTERNAL (fndecl) = 1; | 351 DECL_EXTERNAL (fndecl) = 1; |
352 set_inline (fndecl); | |
319 } | 353 } |
320 else if (base->kind == BRIG_KIND_DIRECTIVE_INDIRECT_FUNCTION) | 354 else if (base->kind == BRIG_KIND_DIRECTIVE_INDIRECT_FUNCTION) |
321 { | 355 { |
322 TREE_STATIC (fndecl) = 0; | 356 TREE_STATIC (fndecl) = 0; |
323 TREE_PUBLIC (fndecl) = 1; | 357 TREE_PUBLIC (fndecl) = 1; |
347 } | 381 } |
348 | 382 |
349 m_parent.add_function_decl (func_name, fndecl); | 383 m_parent.add_function_decl (func_name, fndecl); |
350 m_parent.append_global (fndecl); | 384 m_parent.append_global (fndecl); |
351 | 385 |
386 | |
352 if (!is_definition) | 387 if (!is_definition) |
353 return bytes_consumed; | 388 { |
389 DECL_EXTERNAL (fndecl) = 1; | |
390 return bytes_consumed; | |
391 } | |
354 | 392 |
355 m_parent.start_function (fndecl); | 393 m_parent.start_function (fndecl); |
356 | |
357 m_parent.m_cf->m_func_decl = fndecl; | 394 m_parent.m_cf->m_func_decl = fndecl; |
358 m_parent.m_cf->m_current_bind_expr = bind_expr; | 395 m_parent.m_cf->m_current_bind_expr = bind_expr; |
359 m_parent.m_cf->m_context_arg = context_arg; | |
360 m_parent.m_cf->m_private_base_arg = private_base_arg; | |
361 | 396 |
362 if (ret_value != NULL_TREE && TREE_TYPE (ret_value) != void_type_node) | 397 if (ret_value != NULL_TREE && TREE_TYPE (ret_value) != void_type_node) |
363 { | 398 { |
364 /* We cannot assign to <<retval>> directly in gcc trunk. We need to | 399 /* We cannot assign to <<retval>> directly in gcc trunk. We need to |
365 create a local temporary variable which can be stored to and when | 400 create a local temporary variable which can be stored to and when |