annotate 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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* brig-code-entry-handler.cc -- brig function directive handling
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2 Copyright (C) 2016-2018 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-code-entry-handler.h"
kono
parents:
diff changeset
26
kono
parents:
diff changeset
27 #include "brig-machine.h"
kono
parents:
diff changeset
28 #include "stringpool.h"
kono
parents:
diff changeset
29 #include "tree-iterator.h"
kono
parents:
diff changeset
30 #include "gimple-expr.h"
kono
parents:
diff changeset
31 #include "function.h"
kono
parents:
diff changeset
32 #include "phsa.h"
kono
parents:
diff changeset
33
kono
parents:
diff changeset
34 #include "tree-pretty-print.h"
kono
parents:
diff changeset
35 #include "print-tree.h"
kono
parents:
diff changeset
36
kono
parents:
diff changeset
37 extern int gccbrig_verbose;
kono
parents:
diff changeset
38
kono
parents:
diff changeset
39 size_t
kono
parents:
diff changeset
40 brig_directive_function_handler::operator () (const BrigBase *base)
kono
parents:
diff changeset
41 {
kono
parents:
diff changeset
42 if (!m_parent.m_analyzing)
kono
parents:
diff changeset
43 m_parent.finish_function ();
kono
parents:
diff changeset
44
kono
parents:
diff changeset
45 size_t bytes_consumed = base->byteCount;
kono
parents:
diff changeset
46
kono
parents:
diff changeset
47 const BrigDirectiveExecutable *exec = (const BrigDirectiveExecutable *) base;
kono
parents:
diff changeset
48
kono
parents:
diff changeset
49 if (gccbrig_verbose)
kono
parents:
diff changeset
50 {
kono
parents:
diff changeset
51 printf ("brig: function name %s\n",
kono
parents:
diff changeset
52 m_parent.get_string (exec->name).c_str());
kono
parents:
diff changeset
53 printf ("brig: inargs %d outargs %d name offset %d\n", exec->inArgCount,
kono
parents:
diff changeset
54 exec->outArgCount, exec->name);
kono
parents:
diff changeset
55 }
kono
parents:
diff changeset
56
kono
parents:
diff changeset
57 const bool is_definition
kono
parents:
diff changeset
58 = exec->modifier & BRIG_EXECUTABLE_DEFINITION;
kono
parents:
diff changeset
59
kono
parents:
diff changeset
60 const bool is_kernel = base->kind == BRIG_KIND_DIRECTIVE_KERNEL;
kono
parents:
diff changeset
61
kono
parents:
diff changeset
62 /* There doesn't seem to be actual use cases for kernel declarations
kono
parents:
diff changeset
63 as they cannot be called by the program. Ignore them until there's
kono
parents:
diff changeset
64 a reason not to. */
kono
parents:
diff changeset
65 if (is_kernel && !is_definition)
kono
parents:
diff changeset
66 return bytes_consumed;
kono
parents:
diff changeset
67
kono
parents:
diff changeset
68 std::string func_name = m_parent.get_mangled_name (exec);
kono
parents:
diff changeset
69 if (is_kernel)
kono
parents:
diff changeset
70 /* The generated kernel function is not the one that should be
kono
parents:
diff changeset
71 called by the host. */
kono
parents:
diff changeset
72 func_name = std::string ("_") + func_name;
kono
parents:
diff changeset
73
kono
parents:
diff changeset
74 m_parent.m_cf = new brig_function (exec, &m_parent);
kono
parents:
diff changeset
75 m_parent.m_cf->m_name = func_name;
kono
parents:
diff changeset
76 m_parent.m_cf->m_is_kernel = is_kernel;
kono
parents:
diff changeset
77
kono
parents:
diff changeset
78 /* During the analyze step, the above information is all we need per
kono
parents:
diff changeset
79 function. */
kono
parents:
diff changeset
80 if (m_parent.m_analyzing)
kono
parents:
diff changeset
81 return bytes_consumed;
kono
parents:
diff changeset
82
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
83 /* There can be multiple forward declarations of the same function.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
84 Skip all but the first one. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
85 if (!is_definition && m_parent.function_decl (func_name) != NULL_TREE)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
86 return bytes_consumed;
111
kono
parents:
diff changeset
87 tree fndecl;
kono
parents:
diff changeset
88 tree ret_value = NULL_TREE;
kono
parents:
diff changeset
89
kono
parents:
diff changeset
90 tree stmt_list = alloc_stmt_list ();
kono
parents:
diff changeset
91
kono
parents:
diff changeset
92 /* Add a function scope BIND_EXPR using which we can push local variables that
kono
parents:
diff changeset
93 represent HSAIL registers. */
kono
parents:
diff changeset
94 tree bind_expr = build3 (BIND_EXPR, void_type_node, NULL, stmt_list, NULL);
kono
parents:
diff changeset
95
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
96 tree restrict_char_ptr
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
97 = build_qualified_type (build_pointer_type (char_type_node),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
98 TYPE_QUAL_RESTRICT);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
99 tree restrict_void_ptr
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
100 = build_qualified_type (build_pointer_type (void_type_node),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
101 TYPE_QUAL_RESTRICT);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
102
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
103 tree restrict_const_char_ptr
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
104 = build_qualified_type (build_pointer_type
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
105 (build_qualified_type (char_type_node,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
106 TYPE_QUAL_CONST)),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
107 TYPE_QUAL_RESTRICT);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
108
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
109 tree restrict_const_void_ptr
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
110 = build_qualified_type (build_pointer_type
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
111 (build_qualified_type (void_type_node,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
112 TYPE_QUAL_CONST)),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
113 TYPE_QUAL_RESTRICT);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
114
111
kono
parents:
diff changeset
115 if (is_kernel)
kono
parents:
diff changeset
116 {
kono
parents:
diff changeset
117 tree name_identifier
kono
parents:
diff changeset
118 = get_identifier_with_length (func_name.c_str (), func_name.size ());
kono
parents:
diff changeset
119
kono
parents:
diff changeset
120 /* The generated kernel functions take the following arguments:
kono
parents:
diff changeset
121
kono
parents:
diff changeset
122 1) a char* which is a starting address of the argument segment where
kono
parents:
diff changeset
123 the call's arguments are stored by the launcher.
kono
parents:
diff changeset
124 2) a void* parameter that points to a phsail-finalizer context object
kono
parents:
diff changeset
125 which passes the hsa kernel packet etc.
kono
parents:
diff changeset
126 3) a void* parameter that contains the first flat address of the group
kono
parents:
diff changeset
127 region allocated to the current work-group. */
kono
parents:
diff changeset
128
kono
parents:
diff changeset
129 fndecl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, name_identifier,
kono
parents:
diff changeset
130 build_function_type_list (void_type_node,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
131 restrict_const_char_ptr,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
132 restrict_void_ptr,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
133 restrict_char_ptr, NULL_TREE));
111
kono
parents:
diff changeset
134
kono
parents:
diff changeset
135 SET_DECL_ASSEMBLER_NAME (fndecl, name_identifier);
kono
parents:
diff changeset
136
kono
parents:
diff changeset
137 tree resdecl
kono
parents:
diff changeset
138 = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, void_type_node);
kono
parents:
diff changeset
139
kono
parents:
diff changeset
140 tree typelist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
kono
parents:
diff changeset
141 tree argtype = TREE_VALUE (typelist);
kono
parents:
diff changeset
142 TYPE_ADDR_SPACE (argtype)
kono
parents:
diff changeset
143 = gccbrig_get_target_addr_space_id (BRIG_SEGMENT_KERNARG);
kono
parents:
diff changeset
144
kono
parents:
diff changeset
145 tree arg_arg = build_decl (UNKNOWN_LOCATION, PARM_DECL,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
146 get_identifier ("__args"),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
147 restrict_const_char_ptr);
111
kono
parents:
diff changeset
148 DECL_ARGUMENTS (fndecl) = arg_arg;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
149 DECL_ARG_TYPE (arg_arg) = restrict_const_char_ptr;
111
kono
parents:
diff changeset
150 DECL_CONTEXT (arg_arg) = fndecl;
kono
parents:
diff changeset
151 DECL_ARTIFICIAL (arg_arg) = 1;
kono
parents:
diff changeset
152 TREE_READONLY (arg_arg) = 1;
kono
parents:
diff changeset
153 TREE_USED (arg_arg) = 1;
kono
parents:
diff changeset
154
kono
parents:
diff changeset
155 DECL_RESULT (fndecl) = resdecl;
kono
parents:
diff changeset
156 DECL_CONTEXT (resdecl) = fndecl;
kono
parents:
diff changeset
157 DECL_EXTERNAL (fndecl) = 0;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
158
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
159 /* Aggressive inlining to the kernel function is usually a good
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
160 idea with offlined functionality to enchance SIMD execution on
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
161 GPUs and vector units. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
162
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
163 DECL_ATTRIBUTES (fndecl)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
164 = tree_cons (get_identifier ("flatten"), NULL,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
165 DECL_ATTRIBUTES (fndecl));
111
kono
parents:
diff changeset
166 }
kono
parents:
diff changeset
167 else
kono
parents:
diff changeset
168 {
kono
parents:
diff changeset
169 /* Build a regular function fingerprint to enable targets to optimize
kono
parents:
diff changeset
170 the calling convention as they see fit. */
kono
parents:
diff changeset
171 tree name_identifier
kono
parents:
diff changeset
172 = get_identifier_with_length (func_name.c_str (), func_name.size ());
kono
parents:
diff changeset
173
kono
parents:
diff changeset
174 m_parent.m_cf->m_arg_variables.clear ();
kono
parents:
diff changeset
175
kono
parents:
diff changeset
176 brig_directive_variable_handler arg_handler (m_parent);
kono
parents:
diff changeset
177
kono
parents:
diff changeset
178 vec<tree, va_gc> *args;
kono
parents:
diff changeset
179 vec_alloc (args, 4);
kono
parents:
diff changeset
180
kono
parents:
diff changeset
181 tree arg_decls = NULL_TREE;
kono
parents:
diff changeset
182
kono
parents:
diff changeset
183 tree ret_type = void_type_node;
kono
parents:
diff changeset
184 if (exec->outArgCount == 1)
kono
parents:
diff changeset
185 {
kono
parents:
diff changeset
186 /* The return value variable should be the first entry after the
kono
parents:
diff changeset
187 function directive. */
kono
parents:
diff changeset
188 const BrigBase *retval
kono
parents:
diff changeset
189 = (const BrigBase *) ((const char *) base + base->byteCount);
kono
parents:
diff changeset
190 gcc_assert (retval->kind == BRIG_KIND_DIRECTIVE_VARIABLE);
kono
parents:
diff changeset
191
kono
parents:
diff changeset
192 const BrigDirectiveVariable *brigVar
kono
parents:
diff changeset
193 = (const BrigDirectiveVariable *) retval;
kono
parents:
diff changeset
194
kono
parents:
diff changeset
195 brig_directive_variable_handler varhandler (m_parent);
kono
parents:
diff changeset
196
kono
parents:
diff changeset
197 if (brigVar->type & BRIG_TYPE_ARRAY)
kono
parents:
diff changeset
198 {
kono
parents:
diff changeset
199 /* Push array output arguments to the beginning of the
kono
parents:
diff changeset
200 function argument list instead of regular function
kono
parents:
diff changeset
201 return values. */
kono
parents:
diff changeset
202
kono
parents:
diff changeset
203 tree arg_var = varhandler.build_variable (brigVar, PARM_DECL);
kono
parents:
diff changeset
204 vec_safe_push (args, TREE_TYPE (arg_var));
kono
parents:
diff changeset
205
kono
parents:
diff changeset
206 m_parent.m_cf->add_arg_variable (brigVar, arg_var);
kono
parents:
diff changeset
207
kono
parents:
diff changeset
208 if (arg_decls == NULL_TREE)
kono
parents:
diff changeset
209 arg_decls = arg_var;
kono
parents:
diff changeset
210 else
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
211 arg_decls = chainon (arg_decls, arg_var);
111
kono
parents:
diff changeset
212
kono
parents:
diff changeset
213 m_parent.m_cf->add_arg_variable (brigVar, arg_var);
kono
parents:
diff changeset
214
kono
parents:
diff changeset
215 ret_value = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE,
kono
parents:
diff changeset
216 void_type_node);
kono
parents:
diff changeset
217 }
kono
parents:
diff changeset
218 else
kono
parents:
diff changeset
219 {
kono
parents:
diff changeset
220 ret_value = varhandler.build_variable (brigVar, RESULT_DECL);
kono
parents:
diff changeset
221 m_parent.m_cf->m_ret_value = ret_value;
kono
parents:
diff changeset
222 ret_type = TREE_TYPE (ret_value);
kono
parents:
diff changeset
223 m_parent.m_cf->m_ret_value_brig_var = brigVar;
kono
parents:
diff changeset
224 }
kono
parents:
diff changeset
225 bytes_consumed += retval->byteCount;
kono
parents:
diff changeset
226 }
kono
parents:
diff changeset
227 else
kono
parents:
diff changeset
228 ret_value = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE,
kono
parents:
diff changeset
229 void_type_node);
kono
parents:
diff changeset
230
kono
parents:
diff changeset
231 TREE_ADDRESSABLE (ret_value) = 1;
kono
parents:
diff changeset
232
kono
parents:
diff changeset
233 if (exec->inArgCount > 0)
kono
parents:
diff changeset
234 {
kono
parents:
diff changeset
235 uint32_t arg_offset = exec->firstInArg;
kono
parents:
diff changeset
236 for (size_t arg = 0; arg < exec->inArgCount; ++arg)
kono
parents:
diff changeset
237 {
kono
parents:
diff changeset
238
kono
parents:
diff changeset
239 const BrigDirectiveVariable *brigVar
kono
parents:
diff changeset
240 = (const BrigDirectiveVariable *) m_parent.get_brig_code_entry
kono
parents:
diff changeset
241 (arg_offset);
kono
parents:
diff changeset
242
kono
parents:
diff changeset
243 gcc_assert (brigVar->base.kind == BRIG_KIND_DIRECTIVE_VARIABLE);
kono
parents:
diff changeset
244
kono
parents:
diff changeset
245 /* Delegate to the brig_directive_variable_handler. */
kono
parents:
diff changeset
246 brig_directive_variable_handler varhandler (m_parent);
kono
parents:
diff changeset
247 tree arg_var = varhandler.build_variable (brigVar, PARM_DECL);
kono
parents:
diff changeset
248 arg_offset += brigVar->base.byteCount;
kono
parents:
diff changeset
249 vec_safe_push (args, TREE_TYPE (arg_var));
kono
parents:
diff changeset
250
kono
parents:
diff changeset
251 m_parent.m_cf->add_arg_variable (brigVar, arg_var);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
252 arg_decls = chainon (arg_decls, arg_var);
111
kono
parents:
diff changeset
253 }
kono
parents:
diff changeset
254 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
255 vec_safe_push (args, restrict_void_ptr);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
256 vec_safe_push (args, restrict_char_ptr);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
257 vec_safe_push (args, uint32_type_node);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
258 vec_safe_push (args, restrict_char_ptr);
111
kono
parents:
diff changeset
259
kono
parents:
diff changeset
260 fndecl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, name_identifier,
kono
parents:
diff changeset
261 build_function_type_vec (ret_type, args));
kono
parents:
diff changeset
262
kono
parents:
diff changeset
263 DECL_RESULT (fndecl) = ret_value;
kono
parents:
diff changeset
264 DECL_CONTEXT (ret_value) = fndecl;
kono
parents:
diff changeset
265 DECL_EXTERNAL (fndecl) = 0;
kono
parents:
diff changeset
266 DECL_ARGUMENTS (fndecl) = arg_decls;
kono
parents:
diff changeset
267 }
kono
parents:
diff changeset
268
kono
parents:
diff changeset
269 /* All functions need the hidden __context argument passed on
kono
parents:
diff changeset
270 because they might call WI-specific functions which need
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
271 the context info. Only kernels can write it, if they need
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
272 to update the local ids in the work-item loop. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
273
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
274 tree context_arg_type
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
275 = true ? restrict_void_ptr : restrict_const_void_ptr;
111
kono
parents:
diff changeset
276 tree context_arg = build_decl (UNKNOWN_LOCATION, PARM_DECL,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
277 get_identifier ("__context"),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
278 context_arg_type);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
279 DECL_ARGUMENTS (fndecl) = chainon (DECL_ARGUMENTS (fndecl), context_arg);
111
kono
parents:
diff changeset
280 DECL_CONTEXT (context_arg) = fndecl;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
281 DECL_ARG_TYPE (context_arg) = context_arg_type;
111
kono
parents:
diff changeset
282 DECL_ARTIFICIAL (context_arg) = 1;
kono
parents:
diff changeset
283 TREE_READONLY (context_arg) = 1;
kono
parents:
diff changeset
284 TREE_USED (context_arg) = 1;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
285 m_parent.m_cf->m_context_arg = context_arg;
111
kono
parents:
diff changeset
286
kono
parents:
diff changeset
287 /* They can also access group memory, so we need to pass the
kono
parents:
diff changeset
288 group pointer along too. */
kono
parents:
diff changeset
289 tree group_base_arg
kono
parents:
diff changeset
290 = build_decl (UNKNOWN_LOCATION, PARM_DECL,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
291 get_identifier ("__group_base_addr"),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
292 restrict_char_ptr);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
293 DECL_ARGUMENTS (fndecl) = chainon (DECL_ARGUMENTS (fndecl), group_base_arg);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
294 DECL_ARG_TYPE (group_base_arg) = restrict_char_ptr;
111
kono
parents:
diff changeset
295 DECL_CONTEXT (group_base_arg) = fndecl;
kono
parents:
diff changeset
296 DECL_ARTIFICIAL (group_base_arg) = 1;
kono
parents:
diff changeset
297 TREE_READONLY (group_base_arg) = 1;
kono
parents:
diff changeset
298 TREE_USED (group_base_arg) = 1;
kono
parents:
diff changeset
299 m_parent.m_cf->m_group_base_arg = group_base_arg;
kono
parents:
diff changeset
300
kono
parents:
diff changeset
301 /* To implement call stack and (non-kernel) function scope group variables,
kono
parents:
diff changeset
302 we need to pass an offset which describes how far are we from
kono
parents:
diff changeset
303 group_base_ptr.
kono
parents:
diff changeset
304 That must be substracted from any function local group variable offsets to
kono
parents:
diff changeset
305 get the address related to the bottom of the group memory chunk. */
kono
parents:
diff changeset
306 tree group_local_offset_arg
kono
parents:
diff changeset
307 = build_decl (UNKNOWN_LOCATION, PARM_DECL,
kono
parents:
diff changeset
308 get_identifier ("__group_local_offset"), uint32_type_node);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
309 DECL_ARGUMENTS (fndecl) = chainon (DECL_ARGUMENTS (fndecl), group_local_offset_arg);
111
kono
parents:
diff changeset
310 DECL_ARG_TYPE (group_local_offset_arg) = uint32_type_node;
kono
parents:
diff changeset
311 DECL_CONTEXT (group_local_offset_arg) = fndecl;
kono
parents:
diff changeset
312 DECL_ARTIFICIAL (group_local_offset_arg) = 1;
kono
parents:
diff changeset
313 TREE_READONLY (group_local_offset_arg) = 1;
kono
parents:
diff changeset
314 TREE_USED (group_local_offset_arg) = 1;
kono
parents:
diff changeset
315 m_parent.m_cf->m_group_local_offset_arg = group_local_offset_arg;
kono
parents:
diff changeset
316
kono
parents:
diff changeset
317 /* Same for private. */
kono
parents:
diff changeset
318 tree private_base_arg
kono
parents:
diff changeset
319 = build_decl (UNKNOWN_LOCATION, PARM_DECL,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
320 get_identifier ("__private_base_addr"), restrict_char_ptr);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
321 DECL_ARGUMENTS (fndecl) = chainon (DECL_ARGUMENTS (fndecl), private_base_arg);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
322 DECL_ARG_TYPE (private_base_arg) = restrict_char_ptr;
111
kono
parents:
diff changeset
323 DECL_CONTEXT (private_base_arg) = fndecl;
kono
parents:
diff changeset
324 DECL_ARTIFICIAL (private_base_arg) = 1;
kono
parents:
diff changeset
325 TREE_READONLY (private_base_arg) = 1;
kono
parents:
diff changeset
326 TREE_USED (private_base_arg) = 1;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
327 m_parent.m_cf->m_private_base_arg = private_base_arg;
111
kono
parents:
diff changeset
328
kono
parents:
diff changeset
329 DECL_SAVED_TREE (fndecl) = bind_expr;
kono
parents:
diff changeset
330
kono
parents:
diff changeset
331 if (base->kind == BRIG_KIND_DIRECTIVE_FUNCTION)
kono
parents:
diff changeset
332 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
333 TREE_STATIC (fndecl) = 0;
111
kono
parents:
diff changeset
334 TREE_PUBLIC (fndecl) = 1;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
335 DECL_EXTERNAL (fndecl) = 0;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
336 DECL_DECLARED_INLINE_P (fndecl) = 1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
337 set_inline (fndecl);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
338 set_externally_visible (fndecl);
111
kono
parents:
diff changeset
339 }
kono
parents:
diff changeset
340 else if (base->kind == BRIG_KIND_DIRECTIVE_KERNEL)
kono
parents:
diff changeset
341 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
342 TREE_STATIC (fndecl) = 0;
111
kono
parents:
diff changeset
343 TREE_PUBLIC (fndecl) = 1;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
344 DECL_EXTERNAL (fndecl) = 0;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
345 set_externally_visible (fndecl);
111
kono
parents:
diff changeset
346 }
kono
parents:
diff changeset
347 else if (base->kind == BRIG_KIND_DIRECTIVE_SIGNATURE)
kono
parents:
diff changeset
348 {
kono
parents:
diff changeset
349 TREE_STATIC (fndecl) = 0;
kono
parents:
diff changeset
350 TREE_PUBLIC (fndecl) = 1;
kono
parents:
diff changeset
351 DECL_EXTERNAL (fndecl) = 1;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
352 set_inline (fndecl);
111
kono
parents:
diff changeset
353 }
kono
parents:
diff changeset
354 else if (base->kind == BRIG_KIND_DIRECTIVE_INDIRECT_FUNCTION)
kono
parents:
diff changeset
355 {
kono
parents:
diff changeset
356 TREE_STATIC (fndecl) = 0;
kono
parents:
diff changeset
357 TREE_PUBLIC (fndecl) = 1;
kono
parents:
diff changeset
358 }
kono
parents:
diff changeset
359 else
kono
parents:
diff changeset
360 gcc_unreachable ();
kono
parents:
diff changeset
361
kono
parents:
diff changeset
362 TREE_USED (fndecl) = 1;
kono
parents:
diff changeset
363 DECL_ARTIFICIAL (fndecl) = 0;
kono
parents:
diff changeset
364
kono
parents:
diff changeset
365 tree initial_block = make_node (BLOCK);
kono
parents:
diff changeset
366 DECL_INITIAL (fndecl) = initial_block;
kono
parents:
diff changeset
367 TREE_USED (DECL_INITIAL (fndecl)) = 1;
kono
parents:
diff changeset
368
kono
parents:
diff changeset
369 if (ret_value != NULL_TREE && TREE_TYPE (ret_value) != void_type_node)
kono
parents:
diff changeset
370 {
kono
parents:
diff changeset
371 DECL_CONTEXT (ret_value) = fndecl;
kono
parents:
diff changeset
372 DECL_CHAIN (ret_value) = BIND_EXPR_VARS (bind_expr);
kono
parents:
diff changeset
373 BIND_EXPR_VARS (bind_expr) = ret_value;
kono
parents:
diff changeset
374 }
kono
parents:
diff changeset
375
kono
parents:
diff changeset
376 tree arg;
kono
parents:
diff changeset
377 for (arg = DECL_ARGUMENTS (fndecl); arg != NULL_TREE; arg = TREE_CHAIN (arg))
kono
parents:
diff changeset
378 {
kono
parents:
diff changeset
379 DECL_CONTEXT (arg) = fndecl;
kono
parents:
diff changeset
380 DECL_ARG_TYPE (arg) = TREE_TYPE (arg);
kono
parents:
diff changeset
381 }
kono
parents:
diff changeset
382
kono
parents:
diff changeset
383 m_parent.add_function_decl (func_name, fndecl);
kono
parents:
diff changeset
384 m_parent.append_global (fndecl);
kono
parents:
diff changeset
385
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
386
111
kono
parents:
diff changeset
387 if (!is_definition)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
388 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
389 DECL_EXTERNAL (fndecl) = 1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
390 return bytes_consumed;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
391 }
111
kono
parents:
diff changeset
392
kono
parents:
diff changeset
393 m_parent.start_function (fndecl);
kono
parents:
diff changeset
394 m_parent.m_cf->m_func_decl = fndecl;
kono
parents:
diff changeset
395 m_parent.m_cf->m_current_bind_expr = bind_expr;
kono
parents:
diff changeset
396
kono
parents:
diff changeset
397 if (ret_value != NULL_TREE && TREE_TYPE (ret_value) != void_type_node)
kono
parents:
diff changeset
398 {
kono
parents:
diff changeset
399 /* We cannot assign to <<retval>> directly in gcc trunk. We need to
kono
parents:
diff changeset
400 create a local temporary variable which can be stored to and when
kono
parents:
diff changeset
401 returning from the function, we'll copy it to the actual <<retval>>
kono
parents:
diff changeset
402 in return statement's argument. */
kono
parents:
diff changeset
403 tree temp_var = m_parent.m_cf->m_ret_temp
kono
parents:
diff changeset
404 = m_parent.m_cf->add_local_variable ("_retvalue_temp",
kono
parents:
diff changeset
405 TREE_TYPE (ret_value));
kono
parents:
diff changeset
406 TREE_ADDRESSABLE (temp_var) = 1;
kono
parents:
diff changeset
407 }
kono
parents:
diff changeset
408
kono
parents:
diff changeset
409 if (is_kernel)
kono
parents:
diff changeset
410 {
kono
parents:
diff changeset
411 m_parent.m_cf->add_id_variables ();
kono
parents:
diff changeset
412
kono
parents:
diff changeset
413 /* Create a single entry point in the function. */
kono
parents:
diff changeset
414 m_parent.m_cf->m_entry_label_stmt
kono
parents:
diff changeset
415 = build_stmt (LABEL_EXPR, m_parent.m_cf->label ("__kernel_entry"));
kono
parents:
diff changeset
416 m_parent.m_cf->append_statement (m_parent.m_cf->m_entry_label_stmt);
kono
parents:
diff changeset
417
kono
parents:
diff changeset
418 tree bind_expr = m_parent.m_cf->m_current_bind_expr;
kono
parents:
diff changeset
419 tree stmts = BIND_EXPR_BODY (bind_expr);
kono
parents:
diff changeset
420
kono
parents:
diff changeset
421 m_parent.m_cf->m_kernel_entry = tsi_last (stmts);
kono
parents:
diff changeset
422
kono
parents:
diff changeset
423 /* Let's not append the exit label yet, but only after the
kono
parents:
diff changeset
424 function has been built. We need to build it so it can
kono
parents:
diff changeset
425 be referred to because returns are converted to gotos to this
kono
parents:
diff changeset
426 label. */
kono
parents:
diff changeset
427 m_parent.m_cf->m_exit_label = m_parent.m_cf->label ("__kernel_exit");
kono
parents:
diff changeset
428 }
kono
parents:
diff changeset
429
kono
parents:
diff changeset
430 return bytes_consumed;
kono
parents:
diff changeset
431 }