Daily bump.
[official-gcc.git] / gcc / brig / brigfrontend / brig-variable-handler.cc
blob3edb786a1dd106b7c6d9d8c0d83339db1d79c1e4
1 /* brig-variable-handler.cc -- brig variable directive handling
2 Copyright (C) 2016-2018 Free Software Foundation, Inc.
3 Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
4 for General Processor Tech.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 #include "brig-code-entry-handler.h"
24 #include "stringpool.h"
25 #include "errors.h"
26 #include "brig-machine.h"
27 #include "brig-util.h"
28 #include "print-tree.h"
29 #include "diagnostic-core.h"
31 tree
32 brig_directive_variable_handler::build_variable
33 (const BrigDirectiveVariable *brigVar, tree_code var_decltype)
35 std::string var_name = m_parent.get_mangled_name (brigVar);
37 bool is_definition = brigVar->modifier & BRIG_VARIABLE_DEFINITION;
39 tree name_identifier = get_identifier (var_name.c_str ());
41 tree var_decl;
42 tree t;
43 if (brigVar->type & BRIG_TYPE_ARRAY)
45 tree element_type
46 = gccbrig_tree_type_for_hsa_type (brigVar->type & ~BRIG_TYPE_ARRAY);
47 uint64_t element_count = gccbrig_to_uint64_t (brigVar->dim);
48 if (is_definition && element_count == 0)
49 fatal_error (UNKNOWN_LOCATION, "Array definition with zero elements.");
50 if (var_decltype == PARM_DECL)
51 t = build_pointer_type (element_type);
52 else
53 t = build_array_type_nelts (element_type, element_count);
55 else
57 t = gccbrig_tree_type_for_hsa_type (brigVar->type);
60 size_t alignment = get_brig_var_alignment (brigVar);
62 if (brigVar->segment == BRIG_SEGMENT_READONLY
63 || brigVar->segment == BRIG_SEGMENT_KERNARG
64 || (brigVar->modifier & BRIG_VARIABLE_CONST))
65 TYPE_READONLY (t) = 1;
67 TYPE_ADDR_SPACE (t) = gccbrig_get_target_addr_space_id (brigVar->segment);
69 var_decl = build_decl (UNKNOWN_LOCATION, var_decltype, name_identifier, t);
71 SET_DECL_ALIGN (var_decl, alignment * BITS_PER_UNIT);
73 /* Force the HSA alignments. */
74 DECL_USER_ALIGN (var_decl) = 1;
76 TREE_USED (var_decl) = 1;
78 TREE_PUBLIC (var_decl) = 1;
79 if (is_definition)
80 DECL_EXTERNAL (var_decl) = 0;
81 else
82 DECL_EXTERNAL (var_decl) = 1; /* The definition is elsewhere. */
84 if (brigVar->init != 0)
86 gcc_assert (brigVar->segment == BRIG_SEGMENT_READONLY
87 || brigVar->segment == BRIG_SEGMENT_GLOBAL);
89 const BrigBase *cst_operand_data
90 = m_parent.get_brig_operand_entry (brigVar->init);
92 tree initializer = NULL_TREE;
93 if (cst_operand_data->kind == BRIG_KIND_OPERAND_CONSTANT_BYTES)
94 initializer = get_tree_cst_for_hsa_operand
95 ((const BrigOperandConstantBytes *) cst_operand_data, t);
96 else
97 error ("variable initializers of type %x not implemented",
98 cst_operand_data->kind);
99 gcc_assert (initializer != NULL_TREE);
100 DECL_INITIAL (var_decl) = initializer;
103 if (var_decltype == PARM_DECL)
105 DECL_ARG_TYPE (var_decl) = TREE_TYPE (var_decl);
106 DECL_EXTERNAL (var_decl) = 0;
107 TREE_PUBLIC (var_decl) = 0;
110 TREE_ADDRESSABLE (var_decl) = 1;
112 TREE_USED (var_decl) = 1;
113 DECL_NONLOCAL (var_decl) = 1;
114 DECL_ARTIFICIAL (var_decl) = 0;
116 return var_decl;
119 size_t
120 brig_directive_variable_handler::operator () (const BrigBase *base)
122 const BrigDirectiveVariable *brigVar = (const BrigDirectiveVariable *) base;
124 bool is_definition = brigVar->modifier & BRIG_VARIABLE_DEFINITION;
126 size_t var_size;
127 tree var_type;
128 if (brigVar->type & BRIG_TYPE_ARRAY)
130 tree element_type
131 = gccbrig_tree_type_for_hsa_type (brigVar->type & ~BRIG_TYPE_ARRAY);
132 uint64_t element_count = gccbrig_to_uint64_t (brigVar->dim);
133 if (is_definition && element_count == 0)
134 fatal_error (UNKNOWN_LOCATION, "Array definition with zero elements.");
135 var_type = build_array_type_nelts (element_type, element_count);
136 size_t element_size = tree_to_uhwi (TYPE_SIZE (element_type));
137 var_size = element_size * element_count / 8;
139 else
141 var_type = gccbrig_tree_type_for_hsa_type (brigVar->type);
142 var_size = tree_to_uhwi (TYPE_SIZE (var_type)) / 8;
145 size_t alignment = get_brig_var_alignment (brigVar);
147 bool function_scope = m_parent.m_cf != NULL;
149 if (function_scope)
150 m_parent.m_cf->m_function_scope_vars.insert (base);
152 std::string var_name = m_parent.get_mangled_name (brigVar);
153 if (brigVar->segment == BRIG_SEGMENT_GROUP)
155 /* Non-kernel scope group variables have been added at the
156 'analyze' stage. */
157 m_parent.add_group_variable (var_name, var_size, alignment,
158 function_scope);
159 return base->byteCount;
162 /* During analyze, handle only (module scope) group variables. */
163 if (m_parent.m_analyzing)
164 return base->byteCount;
166 if (brigVar->segment == BRIG_SEGMENT_KERNARG)
168 /* Do not create a real variable, but only a table of
169 offsets to the kernarg segment buffer passed as the
170 single argument by the kernel launcher for later
171 reference. Ignore kernel declarations. */
172 if (m_parent.m_cf != NULL && m_parent.m_cf->m_func_decl != NULL_TREE)
173 m_parent.m_cf->append_kernel_arg (brigVar, var_size, alignment);
174 return base->byteCount;
176 else if (brigVar->segment == BRIG_SEGMENT_PRIVATE
177 || brigVar->segment == BRIG_SEGMENT_SPILL)
179 /* Private variables are handled like group variables,
180 except that their offsets are multiplied by the work-item
181 flat id, when accessed. */
182 if (!m_parent.has_private_variable (var_name))
183 m_parent.append_private_variable (var_name, var_size, alignment);
184 return base->byteCount;
186 else if (brigVar->segment == BRIG_SEGMENT_GLOBAL
187 || brigVar->segment == BRIG_SEGMENT_READONLY)
189 tree def = is_definition ? NULL_TREE :
190 m_parent.global_variable (var_name);
192 if (!is_definition && def != NULL_TREE)
194 /* We have a definition already for this declaration.
195 Use the definition instead of the declaration. */
197 else if (gccbrig_might_be_host_defined_var_p (brigVar))
199 tree var_decl = build_variable (brigVar);
200 m_parent.add_host_def_var_ptr (var_name, var_decl);
202 else
204 tree var_decl = build_variable (brigVar);
205 /* Make all global variables program scope for now
206 so we can get their address from the Runtime API. */
207 DECL_CONTEXT (var_decl) = NULL_TREE;
208 TREE_STATIC (var_decl) = 1;
209 m_parent.add_global_variable (var_name, var_decl);
212 else if (brigVar->segment == BRIG_SEGMENT_ARG)
215 if (m_parent.m_cf->m_generating_arg_block)
217 tree var_decl = build_variable (brigVar);
218 tree bind_expr = m_parent.m_cf->m_current_bind_expr;
220 DECL_CONTEXT (var_decl) = m_parent.m_cf->m_func_decl;
221 DECL_CHAIN (var_decl) = BIND_EXPR_VARS (bind_expr);
222 BIND_EXPR_VARS (bind_expr) = var_decl;
223 TREE_PUBLIC (var_decl) = 0;
225 m_parent.m_cf->add_arg_variable (brigVar, var_decl);
227 else
229 /* Must be an incoming function argument which has
230 been parsed in brig-function-handler.cc. No
231 need to generate anything here. */
234 else
235 gcc_unreachable ();
237 return base->byteCount;
240 /* Returns the alignment for the given BRIG variable. In case the variable
241 explicitly defines alignment and its larger than the natural alignment,
242 returns it instead of the natural one. */
244 size_t
245 brig_directive_variable_handler::get_brig_var_alignment
246 (const BrigDirectiveVariable *brigVar)
249 size_t defined_alignment
250 = brigVar->align == BRIG_ALIGNMENT_NONE ? 0 : 1 << (brigVar->align - 1);
251 size_t natural_alignment;
252 if (brigVar->type & BRIG_TYPE_ARRAY)
254 tree element_type
255 = gccbrig_tree_type_for_hsa_type (brigVar->type & ~BRIG_TYPE_ARRAY);
256 size_t element_size = tree_to_uhwi (TYPE_SIZE (element_type));
257 natural_alignment = element_size / BITS_PER_UNIT;
259 else
261 tree t = gccbrig_tree_type_for_hsa_type (brigVar->type);
262 natural_alignment = tree_to_uhwi (TYPE_SIZE (t)) / BITS_PER_UNIT;
265 return natural_alignment > defined_alignment
266 ? natural_alignment : defined_alignment;