annotate gcc/brig/brigfrontend/brig-to-generic.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 /* brig2tree.cc -- brig to gcc generic/gimple tree conversion
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 <cassert>
kono
parents:
diff changeset
23 #include <iostream>
kono
parents:
diff changeset
24 #include <iomanip>
kono
parents:
diff changeset
25 #include <sstream>
kono
parents:
diff changeset
26
kono
parents:
diff changeset
27 #include "config.h"
kono
parents:
diff changeset
28 #include "system.h"
kono
parents:
diff changeset
29 #include "coretypes.h"
kono
parents:
diff changeset
30 #include "target.h"
kono
parents:
diff changeset
31 #include "function.h"
kono
parents:
diff changeset
32 #include "brig-to-generic.h"
kono
parents:
diff changeset
33 #include "stringpool.h"
kono
parents:
diff changeset
34 #include "tree-iterator.h"
kono
parents:
diff changeset
35 #include "toplev.h"
kono
parents:
diff changeset
36 #include "gimplify.h"
kono
parents:
diff changeset
37 #include "gimple-expr.h"
kono
parents:
diff changeset
38 #include "print-tree.h"
kono
parents:
diff changeset
39 #include "hsa-brig-format.h"
kono
parents:
diff changeset
40 #include "stor-layout.h"
kono
parents:
diff changeset
41 #include "diagnostic-core.h"
kono
parents:
diff changeset
42 #include "brig-code-entry-handler.h"
kono
parents:
diff changeset
43 #include "brig-machine.h"
kono
parents:
diff changeset
44 #include "brig-util.h"
kono
parents:
diff changeset
45 #include "phsa.h"
kono
parents:
diff changeset
46 #include "tree-pretty-print.h"
kono
parents:
diff changeset
47 #include "dumpfile.h"
kono
parents:
diff changeset
48 #include "profile-count.h"
kono
parents:
diff changeset
49 #include "tree-cfg.h"
kono
parents:
diff changeset
50 #include "errors.h"
kono
parents:
diff changeset
51 #include "fold-const.h"
kono
parents:
diff changeset
52 #include "cgraph.h"
kono
parents:
diff changeset
53 #include "dumpfile.h"
kono
parents:
diff changeset
54 #include "tree-pretty-print.h"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
55 #include "attribs.h"
111
kono
parents:
diff changeset
56
kono
parents:
diff changeset
57 extern int gccbrig_verbose;
kono
parents:
diff changeset
58
kono
parents:
diff changeset
59 tree brig_to_generic::s_fp16_type;
kono
parents:
diff changeset
60 tree brig_to_generic::s_fp32_type;
kono
parents:
diff changeset
61 tree brig_to_generic::s_fp64_type;
kono
parents:
diff changeset
62
kono
parents:
diff changeset
63 brig_to_generic::brig_to_generic ()
kono
parents:
diff changeset
64 : m_cf (NULL), m_analyzing (true), m_total_group_segment_usage (0),
kono
parents:
diff changeset
65 m_brig (NULL), m_next_private_offset (0)
kono
parents:
diff changeset
66 {
kono
parents:
diff changeset
67 m_globals = NULL_TREE;
kono
parents:
diff changeset
68
kono
parents:
diff changeset
69 /* Initialize the basic REAL types.
kono
parents:
diff changeset
70 This doesn't work straight away because most of the targets
kono
parents:
diff changeset
71 do not support fp16 natively. Let's by default convert
kono
parents:
diff changeset
72 to fp32 and back before and after each instruction (handle it as
kono
parents:
diff changeset
73 a storage format only), and later add an optimization pass
kono
parents:
diff changeset
74 that removes the extra converts (in case of multiple fp16 ops
kono
parents:
diff changeset
75 in a row). */
kono
parents:
diff changeset
76 s_fp16_type = make_node (REAL_TYPE);
kono
parents:
diff changeset
77 TYPE_PRECISION (s_fp16_type) = 16;
kono
parents:
diff changeset
78 TYPE_SIZE (s_fp16_type) = bitsize_int (16);
kono
parents:
diff changeset
79 TYPE_SIZE_UNIT (s_fp16_type) = size_int (2);
kono
parents:
diff changeset
80 SET_TYPE_ALIGN (s_fp16_type, 16);
kono
parents:
diff changeset
81 layout_type (s_fp16_type);
kono
parents:
diff changeset
82
kono
parents:
diff changeset
83 s_fp32_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_F32);
kono
parents:
diff changeset
84 s_fp64_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_F64);
kono
parents:
diff changeset
85
kono
parents:
diff changeset
86 /* TODO: (machine)query the preferred rounding mode that is set by
kono
parents:
diff changeset
87 the machine by default. This can be redefined by each BRIG module
kono
parents:
diff changeset
88 header. */
kono
parents:
diff changeset
89 m_default_float_rounding_mode = BRIG_ROUND_FLOAT_ZERO;
kono
parents:
diff changeset
90
kono
parents:
diff changeset
91 m_dump_file = dump_begin (TDI_original, &m_dump_flags);
kono
parents:
diff changeset
92 }
kono
parents:
diff changeset
93
kono
parents:
diff changeset
94 class unimplemented_entry_handler : public brig_code_entry_handler
kono
parents:
diff changeset
95 {
kono
parents:
diff changeset
96 public:
kono
parents:
diff changeset
97 unimplemented_entry_handler (brig_to_generic &parent)
kono
parents:
diff changeset
98 : brig_code_entry_handler (parent)
kono
parents:
diff changeset
99 {
kono
parents:
diff changeset
100 }
kono
parents:
diff changeset
101
kono
parents:
diff changeset
102 size_t
kono
parents:
diff changeset
103 operator () (const BrigBase *base)
kono
parents:
diff changeset
104 {
kono
parents:
diff changeset
105 gcc_unreachable ();
kono
parents:
diff changeset
106 return base->byteCount;
kono
parents:
diff changeset
107 }
kono
parents:
diff changeset
108 };
kono
parents:
diff changeset
109
kono
parents:
diff changeset
110 /* Handler for entries that can be (and are) safely skipped for the purposes
kono
parents:
diff changeset
111 of GENERIC generation. */
kono
parents:
diff changeset
112
kono
parents:
diff changeset
113 class skipped_entry_handler : public brig_code_entry_handler
kono
parents:
diff changeset
114 {
kono
parents:
diff changeset
115 public:
kono
parents:
diff changeset
116 skipped_entry_handler (brig_to_generic &parent)
kono
parents:
diff changeset
117 : brig_code_entry_handler (parent)
kono
parents:
diff changeset
118 {
kono
parents:
diff changeset
119 }
kono
parents:
diff changeset
120
kono
parents:
diff changeset
121 size_t
kono
parents:
diff changeset
122 operator () (const BrigBase *base)
kono
parents:
diff changeset
123 {
kono
parents:
diff changeset
124 return base->byteCount;
kono
parents:
diff changeset
125 }
kono
parents:
diff changeset
126 };
kono
parents:
diff changeset
127
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
128 class brig_reg_use_analyzer : public brig_code_entry_handler
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
129 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
130 public:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
131 brig_reg_use_analyzer (brig_to_generic &parent)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
132 : brig_code_entry_handler (parent)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
133 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
134 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
135
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
136 size_t
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
137 operator () (const BrigBase *base)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
138 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
139 const BrigInstBase *brig_inst = (const BrigInstBase *) base;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
140 analyze_operands (*brig_inst);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
141 return base->byteCount;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
142 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
143
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
144 };
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
145
111
kono
parents:
diff changeset
146 /* Helper struct for pairing a BrigKind and a BrigCodeEntryHandler that
kono
parents:
diff changeset
147 should handle its data. */
kono
parents:
diff changeset
148
kono
parents:
diff changeset
149 struct code_entry_handler_info
kono
parents:
diff changeset
150 {
kono
parents:
diff changeset
151 BrigKind kind;
kono
parents:
diff changeset
152 brig_code_entry_handler *handler;
kono
parents:
diff changeset
153 };
kono
parents:
diff changeset
154
kono
parents:
diff changeset
155
kono
parents:
diff changeset
156 /* Finds the BRIG file sections in the currently processed file. */
kono
parents:
diff changeset
157
kono
parents:
diff changeset
158 void
kono
parents:
diff changeset
159 brig_to_generic::find_brig_sections ()
kono
parents:
diff changeset
160 {
kono
parents:
diff changeset
161 m_data = m_code = m_operand = NULL;
kono
parents:
diff changeset
162 const BrigModuleHeader *mheader = (const BrigModuleHeader *) m_brig;
kono
parents:
diff changeset
163
kono
parents:
diff changeset
164 /* Find the positions of the different sections. */
kono
parents:
diff changeset
165 for (uint32_t sec = 0; sec < mheader->sectionCount; ++sec)
kono
parents:
diff changeset
166 {
kono
parents:
diff changeset
167 uint64_t offset
kono
parents:
diff changeset
168 = ((const uint64_t *) (m_brig + mheader->sectionIndex))[sec];
kono
parents:
diff changeset
169
kono
parents:
diff changeset
170 const BrigSectionHeader *section_header
kono
parents:
diff changeset
171 = (const BrigSectionHeader *) (m_brig + offset);
kono
parents:
diff changeset
172
kono
parents:
diff changeset
173 std::string name ((const char *) (&section_header->name),
kono
parents:
diff changeset
174 section_header->nameLength);
kono
parents:
diff changeset
175
kono
parents:
diff changeset
176 if (sec == BRIG_SECTION_INDEX_DATA && name == "hsa_data")
kono
parents:
diff changeset
177 {
kono
parents:
diff changeset
178 m_data = (const char *) section_header;
kono
parents:
diff changeset
179 m_data_size = section_header->byteCount;
kono
parents:
diff changeset
180 }
kono
parents:
diff changeset
181 else if (sec == BRIG_SECTION_INDEX_CODE && name == "hsa_code")
kono
parents:
diff changeset
182 {
kono
parents:
diff changeset
183 m_code = (const char *) section_header;
kono
parents:
diff changeset
184 m_code_size = section_header->byteCount;
kono
parents:
diff changeset
185 }
kono
parents:
diff changeset
186 else if (sec == BRIG_SECTION_INDEX_OPERAND && name == "hsa_operand")
kono
parents:
diff changeset
187 {
kono
parents:
diff changeset
188 m_operand = (const char *) section_header;
kono
parents:
diff changeset
189 m_operand_size = section_header->byteCount;
kono
parents:
diff changeset
190 }
kono
parents:
diff changeset
191 else
kono
parents:
diff changeset
192 {
kono
parents:
diff changeset
193 gcc_unreachable ();
kono
parents:
diff changeset
194 }
kono
parents:
diff changeset
195 }
kono
parents:
diff changeset
196
kono
parents:
diff changeset
197 if (m_code == NULL)
kono
parents:
diff changeset
198 gcc_unreachable ();
kono
parents:
diff changeset
199 if (m_data == NULL)
kono
parents:
diff changeset
200 gcc_unreachable ();
kono
parents:
diff changeset
201 if (m_operand == NULL)
kono
parents:
diff changeset
202 gcc_unreachable ();
kono
parents:
diff changeset
203
kono
parents:
diff changeset
204 }
kono
parents:
diff changeset
205
kono
parents:
diff changeset
206 /* Does a first pass over the given BRIG to collect data needed for the
kono
parents:
diff changeset
207 actual parsing. Currently this includes only collecting the
kono
parents:
diff changeset
208 group segment variable usage to support the experimental HSA PRM feature
kono
parents:
diff changeset
209 where group variables can be declared also in module and function scope
kono
parents:
diff changeset
210 (in addition to kernel scope).
kono
parents:
diff changeset
211 */
kono
parents:
diff changeset
212
kono
parents:
diff changeset
213 void
kono
parents:
diff changeset
214 brig_to_generic::analyze (const char *brig_blob)
kono
parents:
diff changeset
215 {
kono
parents:
diff changeset
216 const BrigModuleHeader *mheader = (const BrigModuleHeader *) brig_blob;
kono
parents:
diff changeset
217
kono
parents:
diff changeset
218 if (strncmp (mheader->identification, "HSA BRIG", 8) != 0)
kono
parents:
diff changeset
219 fatal_error (UNKNOWN_LOCATION, PHSA_ERROR_PREFIX_INCOMPATIBLE_MODULE
kono
parents:
diff changeset
220 "Unrecognized file format.");
kono
parents:
diff changeset
221 if (mheader->brigMajor != 1 || mheader->brigMinor != 0)
kono
parents:
diff changeset
222 fatal_error (UNKNOWN_LOCATION, PHSA_ERROR_PREFIX_INCOMPATIBLE_MODULE
kono
parents:
diff changeset
223 "BRIG version not supported. BRIG 1.0 required.");
kono
parents:
diff changeset
224
kono
parents:
diff changeset
225 m_brig = brig_blob;
kono
parents:
diff changeset
226
kono
parents:
diff changeset
227 find_brig_sections ();
kono
parents:
diff changeset
228
kono
parents:
diff changeset
229 brig_directive_variable_handler var_handler (*this);
kono
parents:
diff changeset
230 brig_directive_fbarrier_handler fbar_handler (*this);
kono
parents:
diff changeset
231 brig_directive_function_handler func_handler (*this);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
232 brig_reg_use_analyzer reg_use_analyzer (*this);
111
kono
parents:
diff changeset
233
kono
parents:
diff changeset
234 /* Need this for grabbing the module names for mangling the
kono
parents:
diff changeset
235 group variable names. */
kono
parents:
diff changeset
236 brig_directive_module_handler module_handler (*this);
kono
parents:
diff changeset
237 skipped_entry_handler skipped_handler (*this);
kono
parents:
diff changeset
238
kono
parents:
diff changeset
239 const BrigSectionHeader *csection_header = (const BrigSectionHeader *) m_code;
kono
parents:
diff changeset
240
kono
parents:
diff changeset
241 code_entry_handler_info handlers[]
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
242 = {{BRIG_KIND_INST_BASIC, &reg_use_analyzer},
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
243 {BRIG_KIND_INST_MOD, &reg_use_analyzer},
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
244 {BRIG_KIND_INST_CMP, &reg_use_analyzer},
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
245 {BRIG_KIND_INST_MEM, &reg_use_analyzer},
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
246 {BRIG_KIND_INST_CVT, &reg_use_analyzer},
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
247 {BRIG_KIND_INST_SEG_CVT, &reg_use_analyzer},
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
248 {BRIG_KIND_INST_SEG, &reg_use_analyzer},
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
249 {BRIG_KIND_INST_ADDR, &reg_use_analyzer},
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
250 {BRIG_KIND_INST_SOURCE_TYPE, &reg_use_analyzer},
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
251 {BRIG_KIND_INST_ATOMIC, &reg_use_analyzer},
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
252 {BRIG_KIND_INST_SIGNAL, &reg_use_analyzer},
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
253 {BRIG_KIND_INST_BR, &reg_use_analyzer},
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
254 {BRIG_KIND_INST_LANE, &reg_use_analyzer},
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
255 {BRIG_KIND_INST_QUEUE, &reg_use_analyzer},
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
256 {BRIG_KIND_DIRECTIVE_VARIABLE, &var_handler},
111
kono
parents:
diff changeset
257 {BRIG_KIND_DIRECTIVE_FBARRIER, &fbar_handler},
kono
parents:
diff changeset
258 {BRIG_KIND_DIRECTIVE_KERNEL, &func_handler},
kono
parents:
diff changeset
259 {BRIG_KIND_DIRECTIVE_MODULE, &module_handler},
kono
parents:
diff changeset
260 {BRIG_KIND_DIRECTIVE_FUNCTION, &func_handler}};
kono
parents:
diff changeset
261
kono
parents:
diff changeset
262 m_analyzing = true;
kono
parents:
diff changeset
263 for (size_t b = csection_header->headerByteCount; b < m_code_size;)
kono
parents:
diff changeset
264 {
kono
parents:
diff changeset
265 const BrigBase *entry = (const BrigBase *) (m_code + b);
kono
parents:
diff changeset
266
kono
parents:
diff changeset
267 brig_code_entry_handler *handler = &skipped_handler;
kono
parents:
diff changeset
268
kono
parents:
diff changeset
269 if (m_cf != NULL && b >= m_cf->m_brig_def->nextModuleEntry)
kono
parents:
diff changeset
270 {
kono
parents:
diff changeset
271 /* The function definition ended. We can just discard the place
kono
parents:
diff changeset
272 holder function. */
kono
parents:
diff changeset
273 m_total_group_segment_usage += m_cf->m_local_group_variables.size ();
kono
parents:
diff changeset
274 delete m_cf;
kono
parents:
diff changeset
275 m_cf = NULL;
kono
parents:
diff changeset
276 }
kono
parents:
diff changeset
277
kono
parents:
diff changeset
278 /* Find a handler. */
kono
parents:
diff changeset
279 for (size_t i = 0;
kono
parents:
diff changeset
280 i < sizeof (handlers) / sizeof (code_entry_handler_info); ++i)
kono
parents:
diff changeset
281 {
kono
parents:
diff changeset
282 if (handlers[i].kind == entry->kind)
kono
parents:
diff changeset
283 handler = handlers[i].handler;
kono
parents:
diff changeset
284 }
kono
parents:
diff changeset
285
kono
parents:
diff changeset
286 int bytes_processed = (*handler) (entry);
kono
parents:
diff changeset
287 if (bytes_processed == 0)
kono
parents:
diff changeset
288 fatal_error (UNKNOWN_LOCATION, PHSA_ERROR_PREFIX_CORRUPTED_MODULE
kono
parents:
diff changeset
289 "Element with 0 bytes.");
kono
parents:
diff changeset
290 b += bytes_processed;
kono
parents:
diff changeset
291 }
kono
parents:
diff changeset
292
kono
parents:
diff changeset
293 if (m_cf != NULL)
kono
parents:
diff changeset
294 {
kono
parents:
diff changeset
295 m_total_group_segment_usage += m_cf->m_local_group_variables.size ();
kono
parents:
diff changeset
296 delete m_cf;
kono
parents:
diff changeset
297 m_cf = NULL;
kono
parents:
diff changeset
298 }
kono
parents:
diff changeset
299
kono
parents:
diff changeset
300 m_total_group_segment_usage += m_module_group_variables.size ();
kono
parents:
diff changeset
301 m_analyzing = false;
kono
parents:
diff changeset
302 }
kono
parents:
diff changeset
303
kono
parents:
diff changeset
304 /* Parses the given BRIG blob. */
kono
parents:
diff changeset
305
kono
parents:
diff changeset
306 void
kono
parents:
diff changeset
307 brig_to_generic::parse (const char *brig_blob)
kono
parents:
diff changeset
308 {
kono
parents:
diff changeset
309 m_brig = brig_blob;
kono
parents:
diff changeset
310 find_brig_sections ();
kono
parents:
diff changeset
311
kono
parents:
diff changeset
312 brig_basic_inst_handler inst_handler (*this);
kono
parents:
diff changeset
313 brig_branch_inst_handler branch_inst_handler (*this);
kono
parents:
diff changeset
314 brig_cvt_inst_handler cvt_inst_handler (*this);
kono
parents:
diff changeset
315 brig_seg_inst_handler seg_inst_handler (*this);
kono
parents:
diff changeset
316 brig_copy_move_inst_handler copy_move_inst_handler (*this);
kono
parents:
diff changeset
317 brig_signal_inst_handler signal_inst_handler (*this);
kono
parents:
diff changeset
318 brig_atomic_inst_handler atomic_inst_handler (*this);
kono
parents:
diff changeset
319 brig_cmp_inst_handler cmp_inst_handler (*this);
kono
parents:
diff changeset
320 brig_mem_inst_handler mem_inst_handler (*this);
kono
parents:
diff changeset
321 brig_inst_mod_handler inst_mod_handler (*this);
kono
parents:
diff changeset
322 brig_directive_label_handler label_handler (*this);
kono
parents:
diff changeset
323 brig_directive_variable_handler var_handler (*this);
kono
parents:
diff changeset
324 brig_directive_fbarrier_handler fbar_handler (*this);
kono
parents:
diff changeset
325 brig_directive_comment_handler comment_handler (*this);
kono
parents:
diff changeset
326 brig_directive_function_handler func_handler (*this);
kono
parents:
diff changeset
327 brig_directive_control_handler control_handler (*this);
kono
parents:
diff changeset
328 brig_directive_arg_block_handler arg_block_handler (*this);
kono
parents:
diff changeset
329 brig_directive_module_handler module_handler (*this);
kono
parents:
diff changeset
330 brig_lane_inst_handler lane_inst_handler (*this);
kono
parents:
diff changeset
331 brig_queue_inst_handler queue_inst_handler (*this);
kono
parents:
diff changeset
332 skipped_entry_handler skipped_handler (*this);
kono
parents:
diff changeset
333 unimplemented_entry_handler unimplemented_handler (*this);
kono
parents:
diff changeset
334
kono
parents:
diff changeset
335 struct code_entry_handler_info
kono
parents:
diff changeset
336 {
kono
parents:
diff changeset
337 BrigKind kind;
kono
parents:
diff changeset
338 brig_code_entry_handler *handler;
kono
parents:
diff changeset
339 };
kono
parents:
diff changeset
340
kono
parents:
diff changeset
341 /* TODO: Convert to a hash table / map. For now, put the more common
kono
parents:
diff changeset
342 entries to the top to keep the scan fast on average. */
kono
parents:
diff changeset
343 code_entry_handler_info handlers[]
kono
parents:
diff changeset
344 = {{BRIG_KIND_INST_BASIC, &inst_handler},
kono
parents:
diff changeset
345 {BRIG_KIND_INST_CMP, &cmp_inst_handler},
kono
parents:
diff changeset
346 {BRIG_KIND_INST_MEM, &mem_inst_handler},
kono
parents:
diff changeset
347 {BRIG_KIND_INST_MOD, &inst_mod_handler},
kono
parents:
diff changeset
348 {BRIG_KIND_INST_CVT, &cvt_inst_handler},
kono
parents:
diff changeset
349 {BRIG_KIND_INST_SEG_CVT, &seg_inst_handler},
kono
parents:
diff changeset
350 {BRIG_KIND_INST_SEG, &seg_inst_handler},
kono
parents:
diff changeset
351 {BRIG_KIND_INST_ADDR, &copy_move_inst_handler},
kono
parents:
diff changeset
352 {BRIG_KIND_INST_SOURCE_TYPE, &copy_move_inst_handler},
kono
parents:
diff changeset
353 {BRIG_KIND_INST_ATOMIC, &atomic_inst_handler},
kono
parents:
diff changeset
354 {BRIG_KIND_INST_SIGNAL, &signal_inst_handler},
kono
parents:
diff changeset
355 {BRIG_KIND_INST_BR, &branch_inst_handler},
kono
parents:
diff changeset
356 {BRIG_KIND_INST_LANE, &lane_inst_handler},
kono
parents:
diff changeset
357 {BRIG_KIND_INST_QUEUE, &queue_inst_handler},
kono
parents:
diff changeset
358 /* Assuming fences are not needed. FIXME: call builtins
kono
parents:
diff changeset
359 when porting to a platform where they are. */
kono
parents:
diff changeset
360 {BRIG_KIND_INST_MEM_FENCE, &skipped_handler},
kono
parents:
diff changeset
361 {BRIG_KIND_DIRECTIVE_LABEL, &label_handler},
kono
parents:
diff changeset
362 {BRIG_KIND_DIRECTIVE_VARIABLE, &var_handler},
kono
parents:
diff changeset
363 {BRIG_KIND_DIRECTIVE_ARG_BLOCK_START, &arg_block_handler},
kono
parents:
diff changeset
364 {BRIG_KIND_DIRECTIVE_ARG_BLOCK_END, &arg_block_handler},
kono
parents:
diff changeset
365 {BRIG_KIND_DIRECTIVE_FBARRIER, &fbar_handler},
kono
parents:
diff changeset
366 {BRIG_KIND_DIRECTIVE_COMMENT, &comment_handler},
kono
parents:
diff changeset
367 {BRIG_KIND_DIRECTIVE_KERNEL, &func_handler},
kono
parents:
diff changeset
368 {BRIG_KIND_DIRECTIVE_SIGNATURE, &func_handler},
kono
parents:
diff changeset
369 {BRIG_KIND_DIRECTIVE_FUNCTION, &func_handler},
kono
parents:
diff changeset
370 {BRIG_KIND_DIRECTIVE_INDIRECT_FUNCTION, &func_handler},
kono
parents:
diff changeset
371 {BRIG_KIND_DIRECTIVE_MODULE, &module_handler},
kono
parents:
diff changeset
372 /* Skipping debug locations for now as not needed for conformance. */
kono
parents:
diff changeset
373 {BRIG_KIND_DIRECTIVE_LOC, &skipped_handler},
kono
parents:
diff changeset
374 /* There are no supported pragmas at this moment. */
kono
parents:
diff changeset
375 {BRIG_KIND_DIRECTIVE_PRAGMA, &skipped_handler},
kono
parents:
diff changeset
376 {BRIG_KIND_DIRECTIVE_CONTROL, &control_handler},
kono
parents:
diff changeset
377 {BRIG_KIND_DIRECTIVE_EXTENSION, &skipped_handler},
kono
parents:
diff changeset
378 /* BRIG_KIND_NONE entries are valid anywhere. They can be used
kono
parents:
diff changeset
379 for patching BRIGs before finalization. */
kono
parents:
diff changeset
380 {BRIG_KIND_NONE, &skipped_handler}};
kono
parents:
diff changeset
381
kono
parents:
diff changeset
382 const BrigSectionHeader *csection_header = (const BrigSectionHeader *) m_code;
kono
parents:
diff changeset
383
kono
parents:
diff changeset
384 for (size_t b = csection_header->headerByteCount; b < m_code_size;)
kono
parents:
diff changeset
385 {
kono
parents:
diff changeset
386 const BrigBase *entry = (const BrigBase *) (m_code + b);
kono
parents:
diff changeset
387
kono
parents:
diff changeset
388 brig_code_entry_handler *handler = &unimplemented_handler;
kono
parents:
diff changeset
389
kono
parents:
diff changeset
390 if (m_cf != NULL && b >= m_cf->m_brig_def->nextModuleEntry)
kono
parents:
diff changeset
391 finish_function (); /* The function definition ended. */
kono
parents:
diff changeset
392
kono
parents:
diff changeset
393 /* Find a handler. */
kono
parents:
diff changeset
394 for (size_t i = 0;
kono
parents:
diff changeset
395 i < sizeof (handlers) / sizeof (code_entry_handler_info); ++i)
kono
parents:
diff changeset
396 {
kono
parents:
diff changeset
397 if (handlers[i].kind == entry->kind)
kono
parents:
diff changeset
398 handler = handlers[i].handler;
kono
parents:
diff changeset
399 }
kono
parents:
diff changeset
400 b += (*handler) (entry);
kono
parents:
diff changeset
401 }
kono
parents:
diff changeset
402
kono
parents:
diff changeset
403 finish_function ();
kono
parents:
diff changeset
404 }
kono
parents:
diff changeset
405
kono
parents:
diff changeset
406 const BrigData *
kono
parents:
diff changeset
407 brig_to_generic::get_brig_data_entry (size_t entry_offset) const
kono
parents:
diff changeset
408 {
kono
parents:
diff changeset
409 return (const BrigData *) (m_data + entry_offset);
kono
parents:
diff changeset
410 }
kono
parents:
diff changeset
411
kono
parents:
diff changeset
412 const BrigBase *
kono
parents:
diff changeset
413 brig_to_generic::get_brig_operand_entry (size_t entry_offset) const
kono
parents:
diff changeset
414 {
kono
parents:
diff changeset
415 return (const BrigBase *) (m_operand + entry_offset);
kono
parents:
diff changeset
416 }
kono
parents:
diff changeset
417
kono
parents:
diff changeset
418 const BrigBase *
kono
parents:
diff changeset
419 brig_to_generic::get_brig_code_entry (size_t entry_offset) const
kono
parents:
diff changeset
420 {
kono
parents:
diff changeset
421 return (const BrigBase *) (m_code + entry_offset);
kono
parents:
diff changeset
422 }
kono
parents:
diff changeset
423
kono
parents:
diff changeset
424 void
kono
parents:
diff changeset
425 brig_to_generic::append_global (tree g)
kono
parents:
diff changeset
426 {
kono
parents:
diff changeset
427 if (m_globals == NULL_TREE)
kono
parents:
diff changeset
428 {
kono
parents:
diff changeset
429 m_globals = g;
kono
parents:
diff changeset
430 return;
kono
parents:
diff changeset
431 }
kono
parents:
diff changeset
432 else
kono
parents:
diff changeset
433 {
kono
parents:
diff changeset
434 tree last = tree_last (m_globals);
kono
parents:
diff changeset
435 TREE_CHAIN (last) = g;
kono
parents:
diff changeset
436 }
kono
parents:
diff changeset
437 }
kono
parents:
diff changeset
438
kono
parents:
diff changeset
439 tree
kono
parents:
diff changeset
440 brig_to_generic::global_variable (const std::string &name) const
kono
parents:
diff changeset
441 {
kono
parents:
diff changeset
442 label_index::const_iterator i = m_global_variables.find (name);
kono
parents:
diff changeset
443 if (i == m_global_variables.end ())
kono
parents:
diff changeset
444 return NULL_TREE;
kono
parents:
diff changeset
445 else
kono
parents:
diff changeset
446 return (*i).second;
kono
parents:
diff changeset
447 }
kono
parents:
diff changeset
448
kono
parents:
diff changeset
449 /* Returns a function declaration with the given name. Assumes it has been
kono
parents:
diff changeset
450 created previously via a DirectiveFunction or similar. */
kono
parents:
diff changeset
451
kono
parents:
diff changeset
452 tree
kono
parents:
diff changeset
453 brig_to_generic::function_decl (const std::string &name)
kono
parents:
diff changeset
454 {
kono
parents:
diff changeset
455 label_index::const_iterator i = m_function_index.find (name);
kono
parents:
diff changeset
456 if (i == m_function_index.end ())
kono
parents:
diff changeset
457 return NULL_TREE;
kono
parents:
diff changeset
458 return (*i).second;
kono
parents:
diff changeset
459 }
kono
parents:
diff changeset
460
kono
parents:
diff changeset
461 void
kono
parents:
diff changeset
462 brig_to_generic::add_function_decl (const std::string &name, tree func_decl)
kono
parents:
diff changeset
463 {
kono
parents:
diff changeset
464 m_function_index[name] = func_decl;
kono
parents:
diff changeset
465 }
kono
parents:
diff changeset
466
kono
parents:
diff changeset
467 /* Adds a GENERIC global variable VAR_DECL with the given NAME to the
kono
parents:
diff changeset
468 current module. If we have generated a host def var ptr (a place holder
kono
parents:
diff changeset
469 for variables that are defined by the HSA host code) for this global
kono
parents:
diff changeset
470 variable definition (because there was a declaration earlier which looked
kono
parents:
diff changeset
471 like it might have been a host defined variable), we now have
kono
parents:
diff changeset
472 to assign its address and make it private to allow the references to
kono
parents:
diff changeset
473 point to the defined variable instead. */
kono
parents:
diff changeset
474
kono
parents:
diff changeset
475 void
kono
parents:
diff changeset
476 brig_to_generic::add_global_variable (const std::string &name, tree var_decl)
kono
parents:
diff changeset
477 {
kono
parents:
diff changeset
478 append_global (var_decl);
kono
parents:
diff changeset
479 m_global_variables[name] = var_decl;
kono
parents:
diff changeset
480
kono
parents:
diff changeset
481 std::string host_def_var_name
kono
parents:
diff changeset
482 = std::string (PHSA_HOST_DEF_PTR_PREFIX) + name;
kono
parents:
diff changeset
483 tree host_def_var = global_variable (host_def_var_name);
kono
parents:
diff changeset
484 if (host_def_var == NULL_TREE)
kono
parents:
diff changeset
485 return;
kono
parents:
diff changeset
486
kono
parents:
diff changeset
487 tree ptype = build_pointer_type (TREE_TYPE (var_decl));
kono
parents:
diff changeset
488 tree var_addr = build1 (ADDR_EXPR, ptype, var_decl);
kono
parents:
diff changeset
489
kono
parents:
diff changeset
490 DECL_INITIAL (host_def_var) = var_addr;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
491 TREE_PUBLIC (host_def_var) = 1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
492
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
493 set_externally_visible (host_def_var);
111
kono
parents:
diff changeset
494 }
kono
parents:
diff changeset
495
kono
parents:
diff changeset
496 /* Adds an indirection pointer for a potential host-defined program scope
kono
parents:
diff changeset
497 variable declaration. */
kono
parents:
diff changeset
498
kono
parents:
diff changeset
499 void
kono
parents:
diff changeset
500 brig_to_generic::add_host_def_var_ptr (const std::string &name, tree var_decl)
kono
parents:
diff changeset
501 {
kono
parents:
diff changeset
502 std::string var_name = std::string (PHSA_HOST_DEF_PTR_PREFIX) + name;
kono
parents:
diff changeset
503
kono
parents:
diff changeset
504 tree name_identifier = get_identifier (var_name.c_str ());
kono
parents:
diff changeset
505
kono
parents:
diff changeset
506 tree ptr_var = build_decl (UNKNOWN_LOCATION, VAR_DECL, name_identifier,
kono
parents:
diff changeset
507 build_pointer_type (TREE_TYPE (var_decl)));
kono
parents:
diff changeset
508 DECL_EXTERNAL (ptr_var) = 0;
kono
parents:
diff changeset
509 DECL_ARTIFICIAL (ptr_var) = 0;
kono
parents:
diff changeset
510
kono
parents:
diff changeset
511 TREE_PUBLIC (ptr_var) = 1;
kono
parents:
diff changeset
512 TREE_USED (ptr_var) = 1;
kono
parents:
diff changeset
513 TREE_ADDRESSABLE (ptr_var) = 1;
kono
parents:
diff changeset
514 TREE_STATIC (ptr_var) = 1;
kono
parents:
diff changeset
515
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
516 set_externally_visible (ptr_var);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
517
111
kono
parents:
diff changeset
518 append_global (ptr_var);
kono
parents:
diff changeset
519 m_global_variables[var_name] = ptr_var;
kono
parents:
diff changeset
520 }
kono
parents:
diff changeset
521
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
522 void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
523 brig_to_generic::add_decl_call (tree call)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
524 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
525 m_decl_call.push_back (call);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
526 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
527
111
kono
parents:
diff changeset
528 /* Produce a "mangled name" for the given brig function or kernel.
kono
parents:
diff changeset
529 The mangling is used to make unique global symbol name in case of
kono
parents:
diff changeset
530 module scope functions. Program scope functions are not mangled
kono
parents:
diff changeset
531 (except for dropping the leading &), which makes the functions
kono
parents:
diff changeset
532 directly visible for linking using the original function name. */
kono
parents:
diff changeset
533
kono
parents:
diff changeset
534 std::string
kono
parents:
diff changeset
535 brig_to_generic::get_mangled_name
kono
parents:
diff changeset
536 (const BrigDirectiveExecutable *func) const
kono
parents:
diff changeset
537 {
kono
parents:
diff changeset
538 /* Strip the leading &. */
kono
parents:
diff changeset
539 std::string func_name = get_string (func->name).substr (1);
kono
parents:
diff changeset
540 if (func->linkage == BRIG_LINKAGE_MODULE)
kono
parents:
diff changeset
541 {
kono
parents:
diff changeset
542 /* Mangle the module scope function names with the module name and
kono
parents:
diff changeset
543 make them public so they can be queried by the HSA runtime from
kono
parents:
diff changeset
544 the produced binary. Assume it's the currently processed function
kono
parents:
diff changeset
545 we are always referring to. */
kono
parents:
diff changeset
546 func_name = "gccbrig." + m_module_name + "." + func_name;
kono
parents:
diff changeset
547 }
kono
parents:
diff changeset
548 return func_name;
kono
parents:
diff changeset
549 }
kono
parents:
diff changeset
550
kono
parents:
diff changeset
551 std::string
kono
parents:
diff changeset
552 brig_to_generic::get_string (size_t entry_offset) const
kono
parents:
diff changeset
553 {
kono
parents:
diff changeset
554 const BrigData *data_item = get_brig_data_entry (entry_offset);
kono
parents:
diff changeset
555 return std::string ((const char *) &data_item->bytes, data_item->byteCount);
kono
parents:
diff changeset
556 }
kono
parents:
diff changeset
557
kono
parents:
diff changeset
558 /* Adapted from c-semantics.c. */
kono
parents:
diff changeset
559
kono
parents:
diff changeset
560 tree
kono
parents:
diff changeset
561 build_stmt (enum tree_code code, ...)
kono
parents:
diff changeset
562 {
kono
parents:
diff changeset
563 tree ret;
kono
parents:
diff changeset
564 int length, i;
kono
parents:
diff changeset
565 va_list p;
kono
parents:
diff changeset
566 bool side_effects;
kono
parents:
diff changeset
567
kono
parents:
diff changeset
568 /* This function cannot be used to construct variably-sized nodes. */
kono
parents:
diff changeset
569 gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);
kono
parents:
diff changeset
570
kono
parents:
diff changeset
571 va_start (p, code);
kono
parents:
diff changeset
572
kono
parents:
diff changeset
573 ret = make_node (code);
kono
parents:
diff changeset
574 TREE_TYPE (ret) = void_type_node;
kono
parents:
diff changeset
575 length = TREE_CODE_LENGTH (code);
kono
parents:
diff changeset
576
kono
parents:
diff changeset
577 /* TREE_SIDE_EFFECTS will already be set for statements with
kono
parents:
diff changeset
578 implicit side effects. Here we make sure it is set for other
kono
parents:
diff changeset
579 expressions by checking whether the parameters have side
kono
parents:
diff changeset
580 effects. */
kono
parents:
diff changeset
581
kono
parents:
diff changeset
582 side_effects = false;
kono
parents:
diff changeset
583 for (i = 0; i < length; i++)
kono
parents:
diff changeset
584 {
kono
parents:
diff changeset
585 tree t = va_arg (p, tree);
kono
parents:
diff changeset
586 if (t && !TYPE_P (t))
kono
parents:
diff changeset
587 side_effects |= TREE_SIDE_EFFECTS (t);
kono
parents:
diff changeset
588 TREE_OPERAND (ret, i) = t;
kono
parents:
diff changeset
589 }
kono
parents:
diff changeset
590
kono
parents:
diff changeset
591 TREE_SIDE_EFFECTS (ret) |= side_effects;
kono
parents:
diff changeset
592
kono
parents:
diff changeset
593 va_end (p);
kono
parents:
diff changeset
594 return ret;
kono
parents:
diff changeset
595 }
kono
parents:
diff changeset
596
kono
parents:
diff changeset
597 /* BRIG regs are untyped, but GENERIC is not. We need to add implicit casts
kono
parents:
diff changeset
598 in case treating the operand with an instruction with a type different
kono
parents:
diff changeset
599 than the created reg var type in order to select correct instruction type
kono
parents:
diff changeset
600 later on. This function creates the necessary reinterpret type cast from
kono
parents:
diff changeset
601 a source variable to the destination type. In case no cast is needed to
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
602 the same type, SOURCE is returned directly.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
603
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
604 In case of mismatched type sizes, casting:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
605 - to narrower type the upper bits are clipped and
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
606 - to wider type the source value is zero extended. */
111
kono
parents:
diff changeset
607
kono
parents:
diff changeset
608 tree
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
609 build_resize_convert_view (tree destination_type, tree source)
111
kono
parents:
diff changeset
610 {
kono
parents:
diff changeset
611
kono
parents:
diff changeset
612 gcc_assert (source && destination_type && TREE_TYPE (source) != NULL_TREE
kono
parents:
diff changeset
613 && destination_type != NULL_TREE);
kono
parents:
diff changeset
614
kono
parents:
diff changeset
615 tree source_type = TREE_TYPE (source);
kono
parents:
diff changeset
616 if (TREE_CODE (source) == CALL_EXPR)
kono
parents:
diff changeset
617 {
kono
parents:
diff changeset
618 tree func_decl = TREE_OPERAND (TREE_OPERAND (source, 1), 0);
kono
parents:
diff changeset
619 source_type = TREE_TYPE (TREE_TYPE (func_decl));
kono
parents:
diff changeset
620 }
kono
parents:
diff changeset
621
kono
parents:
diff changeset
622 if (destination_type == source_type)
kono
parents:
diff changeset
623 return source;
kono
parents:
diff changeset
624
kono
parents:
diff changeset
625 size_t src_size = int_size_in_bytes (source_type);
kono
parents:
diff changeset
626 size_t dst_size = int_size_in_bytes (destination_type);
kono
parents:
diff changeset
627 if (src_size == dst_size)
kono
parents:
diff changeset
628 return build1 (VIEW_CONVERT_EXPR, destination_type, source);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
629 else /* src_size != dst_size */
111
kono
parents:
diff changeset
630 {
kono
parents:
diff changeset
631 /* The src_size can be smaller at least with f16 scalars which are
kono
parents:
diff changeset
632 stored to 32b register variables. First convert to an equivalent
kono
parents:
diff changeset
633 size unsigned type, then extend to an unsigned type of the
kono
parents:
diff changeset
634 target width, after which VIEW_CONVERT_EXPR can be used to
kono
parents:
diff changeset
635 force to the target type. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
636 tree resized = convert (get_scalar_unsigned_int_type (destination_type),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
637 build_reinterpret_to_uint (source));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
638 gcc_assert ((size_t)int_size_in_bytes (TREE_TYPE (resized)) == dst_size);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
639 return build_resize_convert_view (destination_type, resized);
111
kono
parents:
diff changeset
640 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
641 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
642
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
643 /* Reinterprets SOURCE as a scalar unsigned int with the size
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
644 corresponding to the orignal. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
645
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
646 tree build_reinterpret_to_uint (tree source)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
647 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
648 tree src_type = TREE_TYPE (source);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
649 if (INTEGRAL_TYPE_P (src_type) && TYPE_UNSIGNED (src_type))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
650 return source;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
651 tree dest_type = get_scalar_unsigned_int_type (src_type);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
652 return build1 (VIEW_CONVERT_EXPR, dest_type, source);
111
kono
parents:
diff changeset
653 }
kono
parents:
diff changeset
654
kono
parents:
diff changeset
655 /* Returns the finished brig_function for the given generic FUNC_DECL,
kono
parents:
diff changeset
656 or NULL, if not found. */
kono
parents:
diff changeset
657
kono
parents:
diff changeset
658 brig_function *
kono
parents:
diff changeset
659 brig_to_generic::get_finished_function (tree func_decl)
kono
parents:
diff changeset
660 {
kono
parents:
diff changeset
661 std::string func_name
kono
parents:
diff changeset
662 = identifier_to_locale (IDENTIFIER_POINTER (DECL_NAME (func_decl)));
kono
parents:
diff changeset
663 std::map<std::string, brig_function *>::iterator i
kono
parents:
diff changeset
664 = m_finished_functions.find (func_name);
kono
parents:
diff changeset
665 if (i != m_finished_functions.end ())
kono
parents:
diff changeset
666 return (*i).second;
kono
parents:
diff changeset
667 else
kono
parents:
diff changeset
668 return NULL;
kono
parents:
diff changeset
669 }
kono
parents:
diff changeset
670
kono
parents:
diff changeset
671 /* Adds a group variable to a correct book keeping structure depending
kono
parents:
diff changeset
672 on its segment. */
kono
parents:
diff changeset
673
kono
parents:
diff changeset
674 void
kono
parents:
diff changeset
675 brig_to_generic::add_group_variable (const std::string &name, size_t size,
kono
parents:
diff changeset
676 size_t alignment, bool function_scope)
kono
parents:
diff changeset
677 {
kono
parents:
diff changeset
678 /* Module and function scope group region variables are an experimental
kono
parents:
diff changeset
679 feature. We implement module scope group variables with a separate
kono
parents:
diff changeset
680 book keeping inside brig_to_generic which is populated in the 'analyze()'
kono
parents:
diff changeset
681 prepass. This is to ensure we know the group segment offsets when
kono
parents:
diff changeset
682 processing the functions that might refer to them. */
kono
parents:
diff changeset
683 if (!function_scope)
kono
parents:
diff changeset
684 {
kono
parents:
diff changeset
685 if (!m_module_group_variables.has_variable (name))
kono
parents:
diff changeset
686 m_module_group_variables.add (name, size, alignment);
kono
parents:
diff changeset
687 return;
kono
parents:
diff changeset
688 }
kono
parents:
diff changeset
689
kono
parents:
diff changeset
690 if (!m_cf->m_local_group_variables.has_variable (name))
kono
parents:
diff changeset
691 m_cf->m_local_group_variables.add (name, size, alignment);
kono
parents:
diff changeset
692 }
kono
parents:
diff changeset
693
kono
parents:
diff changeset
694 /* Finalizes the currently handled function. Should be called before
kono
parents:
diff changeset
695 setting a new function. */
kono
parents:
diff changeset
696
kono
parents:
diff changeset
697 void
kono
parents:
diff changeset
698 brig_to_generic::finish_function ()
kono
parents:
diff changeset
699 {
kono
parents:
diff changeset
700 if (m_cf == NULL || m_cf->m_func_decl == NULL_TREE)
kono
parents:
diff changeset
701 {
kono
parents:
diff changeset
702 /* It can be a finished func declaration fingerprint, in that case we
kono
parents:
diff changeset
703 don't have m_func_decl. */
kono
parents:
diff changeset
704 m_cf = NULL;
kono
parents:
diff changeset
705 return;
kono
parents:
diff changeset
706 }
kono
parents:
diff changeset
707
kono
parents:
diff changeset
708 if (!m_cf->m_is_kernel)
kono
parents:
diff changeset
709 {
kono
parents:
diff changeset
710 tree bind_expr = m_cf->m_current_bind_expr;
kono
parents:
diff changeset
711 tree stmts = BIND_EXPR_BODY (bind_expr);
kono
parents:
diff changeset
712 m_cf->finish ();
kono
parents:
diff changeset
713 m_cf->emit_metadata (stmts);
kono
parents:
diff changeset
714 dump_function (m_dump_file, m_cf);
kono
parents:
diff changeset
715 }
kono
parents:
diff changeset
716 else
kono
parents:
diff changeset
717 /* Emit the kernel only at the very end so we can analyze the total
kono
parents:
diff changeset
718 group and private memory usage. */
kono
parents:
diff changeset
719 m_kernels.push_back (m_cf);
kono
parents:
diff changeset
720
kono
parents:
diff changeset
721 pop_cfun ();
kono
parents:
diff changeset
722
kono
parents:
diff changeset
723 m_finished_functions[m_cf->m_name] = m_cf;
kono
parents:
diff changeset
724 m_cf = NULL;
kono
parents:
diff changeset
725 }
kono
parents:
diff changeset
726
kono
parents:
diff changeset
727 /* Initializes a new currently handled function. */
kono
parents:
diff changeset
728
kono
parents:
diff changeset
729 void
kono
parents:
diff changeset
730 brig_to_generic::start_function (tree f)
kono
parents:
diff changeset
731 {
kono
parents:
diff changeset
732 if (DECL_STRUCT_FUNCTION (f) == NULL)
kono
parents:
diff changeset
733 push_struct_function (f);
kono
parents:
diff changeset
734 else
kono
parents:
diff changeset
735 push_cfun (DECL_STRUCT_FUNCTION (f));
kono
parents:
diff changeset
736
kono
parents:
diff changeset
737 m_cf->m_func_decl = f;
kono
parents:
diff changeset
738 }
kono
parents:
diff changeset
739
kono
parents:
diff changeset
740 /* Appends a new variable to the current kernel's private segment. */
kono
parents:
diff changeset
741
kono
parents:
diff changeset
742 void
kono
parents:
diff changeset
743 brig_to_generic::append_private_variable (const std::string &name,
kono
parents:
diff changeset
744 size_t size, size_t alignment)
kono
parents:
diff changeset
745 {
kono
parents:
diff changeset
746 /* We need to take care of two cases of alignment with private
kono
parents:
diff changeset
747 variables because of the layout where the same variable for
kono
parents:
diff changeset
748 each work-item is laid out in successive addresses.
kono
parents:
diff changeset
749
kono
parents:
diff changeset
750 1) Ensure the first work-item's variable is in an aligned
kono
parents:
diff changeset
751 offset: */
kono
parents:
diff changeset
752 size_t align_padding = m_next_private_offset % alignment == 0 ?
kono
parents:
diff changeset
753 0 : (alignment - m_next_private_offset % alignment);
kono
parents:
diff changeset
754
kono
parents:
diff changeset
755 /* 2) Each successive per-work-item copy should be aligned.
kono
parents:
diff changeset
756 If the variable has wider alignment than size then we need
kono
parents:
diff changeset
757 to add extra padding to ensure it. The padding must be
kono
parents:
diff changeset
758 included in the size to allow per-work-item offset computation
kono
parents:
diff changeset
759 to find their own aligned copy. */
kono
parents:
diff changeset
760
kono
parents:
diff changeset
761 size_t per_var_padding = size % alignment == 0 ?
kono
parents:
diff changeset
762 0 : (alignment - size % alignment);
kono
parents:
diff changeset
763 m_private_data_sizes[name] = size + per_var_padding;
kono
parents:
diff changeset
764
kono
parents:
diff changeset
765 m_next_private_offset += align_padding;
kono
parents:
diff changeset
766 m_private_offsets[name] = m_next_private_offset;
kono
parents:
diff changeset
767 m_next_private_offset += size + per_var_padding;
kono
parents:
diff changeset
768 }
kono
parents:
diff changeset
769
kono
parents:
diff changeset
770 size_t
kono
parents:
diff changeset
771 brig_to_generic::private_variable_segment_offset
kono
parents:
diff changeset
772 (const std::string &name) const
kono
parents:
diff changeset
773 {
kono
parents:
diff changeset
774 var_offset_table::const_iterator i = m_private_offsets.find (name);
kono
parents:
diff changeset
775 gcc_assert (i != m_private_offsets.end ());
kono
parents:
diff changeset
776 return (*i).second;
kono
parents:
diff changeset
777 }
kono
parents:
diff changeset
778
kono
parents:
diff changeset
779 bool
kono
parents:
diff changeset
780 brig_to_generic::has_private_variable (const std::string &name) const
kono
parents:
diff changeset
781 {
kono
parents:
diff changeset
782 std::map<std::string, size_t>::const_iterator i
kono
parents:
diff changeset
783 = m_private_data_sizes.find (name);
kono
parents:
diff changeset
784 return i != m_private_data_sizes.end ();
kono
parents:
diff changeset
785 }
kono
parents:
diff changeset
786
kono
parents:
diff changeset
787 size_t
kono
parents:
diff changeset
788 brig_to_generic::private_variable_size (const std::string &name) const
kono
parents:
diff changeset
789 {
kono
parents:
diff changeset
790 std::map<std::string, size_t>::const_iterator i
kono
parents:
diff changeset
791 = m_private_data_sizes.find (name);
kono
parents:
diff changeset
792 gcc_assert (i != m_private_data_sizes.end ());
kono
parents:
diff changeset
793 return (*i).second;
kono
parents:
diff changeset
794 }
kono
parents:
diff changeset
795
kono
parents:
diff changeset
796
kono
parents:
diff changeset
797 /* The size of private segment required by a single work-item executing
kono
parents:
diff changeset
798 the currently processed kernel. */
kono
parents:
diff changeset
799
kono
parents:
diff changeset
800 size_t
kono
parents:
diff changeset
801 brig_to_generic::private_segment_size () const
kono
parents:
diff changeset
802 {
kono
parents:
diff changeset
803 return m_next_private_offset;
kono
parents:
diff changeset
804 }
kono
parents:
diff changeset
805
kono
parents:
diff changeset
806 /* Cached builtins indexed by name. */
kono
parents:
diff changeset
807
kono
parents:
diff changeset
808 typedef std::map<std::string, tree> builtin_index;
kono
parents:
diff changeset
809 builtin_index builtin_cache_;
kono
parents:
diff changeset
810
kono
parents:
diff changeset
811 /* Build a call to a builtin function. PDECL is the builtin function to
kono
parents:
diff changeset
812 call. NARGS is the number of input arguments, RETTYPE the built-in
kono
parents:
diff changeset
813 functions return value type, and ... is the list of arguments passed to
kono
parents:
diff changeset
814 the call with type first, then the value. */
kono
parents:
diff changeset
815
kono
parents:
diff changeset
816 tree
kono
parents:
diff changeset
817 call_builtin (tree pdecl, int nargs, tree rettype, ...)
kono
parents:
diff changeset
818 {
kono
parents:
diff changeset
819 if (rettype == error_mark_node)
kono
parents:
diff changeset
820 return error_mark_node;
kono
parents:
diff changeset
821
kono
parents:
diff changeset
822 tree *types = new tree[nargs];
kono
parents:
diff changeset
823 tree *args = new tree[nargs];
kono
parents:
diff changeset
824
kono
parents:
diff changeset
825 va_list ap;
kono
parents:
diff changeset
826 va_start (ap, rettype);
kono
parents:
diff changeset
827 for (int i = 0; i < nargs; ++i)
kono
parents:
diff changeset
828 {
kono
parents:
diff changeset
829 types[i] = va_arg (ap, tree);
kono
parents:
diff changeset
830 tree arg = va_arg (ap, tree);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
831 args[i] = build_resize_convert_view (types[i], arg);
111
kono
parents:
diff changeset
832 if (types[i] == error_mark_node || args[i] == error_mark_node)
kono
parents:
diff changeset
833 {
kono
parents:
diff changeset
834 delete[] types;
kono
parents:
diff changeset
835 delete[] args;
kono
parents:
diff changeset
836 va_end (ap);
kono
parents:
diff changeset
837 return error_mark_node;
kono
parents:
diff changeset
838 }
kono
parents:
diff changeset
839 }
kono
parents:
diff changeset
840 va_end (ap);
kono
parents:
diff changeset
841
kono
parents:
diff changeset
842 tree fnptr = build_fold_addr_expr (pdecl);
kono
parents:
diff changeset
843
kono
parents:
diff changeset
844 tree ret = build_call_array (rettype, fnptr, nargs, args);
kono
parents:
diff changeset
845
kono
parents:
diff changeset
846 delete[] types;
kono
parents:
diff changeset
847 delete[] args;
kono
parents:
diff changeset
848
kono
parents:
diff changeset
849 return ret;
kono
parents:
diff changeset
850 }
kono
parents:
diff changeset
851
kono
parents:
diff changeset
852 /* Generate all global declarations. Should be called after the last
kono
parents:
diff changeset
853 BRIG has been fed in. */
kono
parents:
diff changeset
854
kono
parents:
diff changeset
855 void
kono
parents:
diff changeset
856 brig_to_generic::write_globals ()
kono
parents:
diff changeset
857 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
858
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
859 /* Replace calls to declarations with calls to definitions. Otherwise
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
860 inlining will fail to find the definition to inline from. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
861
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
862 for (size_t i = 0; i < m_decl_call.size(); ++i)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
863 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
864 tree decl_call = m_decl_call.at(i);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
865 tree func_decl = get_callee_fndecl (decl_call);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
866 brig_function *brig_function = get_finished_function (func_decl);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
867
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
868 if (brig_function && brig_function->m_func_decl
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
869 && DECL_EXTERNAL (brig_function->m_func_decl) == 0
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
870 && brig_function->m_func_decl != func_decl)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
871 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
872
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
873 decl_call = CALL_EXPR_FN (decl_call);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
874 STRIP_NOPS (decl_call);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
875 if (TREE_CODE (decl_call) == ADDR_EXPR
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
876 && TREE_CODE (TREE_OPERAND (decl_call, 0)) == FUNCTION_DECL)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
877 TREE_OPERAND (decl_call, 0) = brig_function->m_func_decl;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
878 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
879 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
880
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
881 for (std::map<std::string, brig_function *>::iterator i
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
882 = m_finished_functions.begin(), e = m_finished_functions.end();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
883 i != e; ++i)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
884 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
885 brig_function *brig_f = (*i).second;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
886 if (brig_f->m_is_kernel)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
887 continue;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
888
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
889 /* Finalize only at this point to allow the cgraph analysis to
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
890 see definitions to calls to later functions. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
891 gimplify_function_tree (brig_f->m_func_decl);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
892 cgraph_node::finalize_function (brig_f->m_func_decl, true);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
893 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
894
111
kono
parents:
diff changeset
895 /* Now that the whole BRIG module has been processed, build a launcher
kono
parents:
diff changeset
896 and a metadata section for each built kernel. */
kono
parents:
diff changeset
897 for (size_t i = 0; i < m_kernels.size (); ++i)
kono
parents:
diff changeset
898 {
kono
parents:
diff changeset
899 brig_function *f = m_kernels[i];
kono
parents:
diff changeset
900
kono
parents:
diff changeset
901 /* Finish kernels now that we know the call graphs and their barrier
kono
parents:
diff changeset
902 usage. */
kono
parents:
diff changeset
903 f->finish_kernel ();
kono
parents:
diff changeset
904
kono
parents:
diff changeset
905 dump_function (m_dump_file, f);
kono
parents:
diff changeset
906 gimplify_function_tree (f->m_func_decl);
kono
parents:
diff changeset
907 cgraph_node::finalize_function (f->m_func_decl, true);
kono
parents:
diff changeset
908
kono
parents:
diff changeset
909 f->m_descriptor.is_kernel = 1;
kono
parents:
diff changeset
910 /* TODO: analyze the kernel's actual private and group segment usage
kono
parents:
diff changeset
911 using call graph. Now the mem size is overly
kono
parents:
diff changeset
912 pessimistic in case of multiple kernels in the same module.
kono
parents:
diff changeset
913 */
kono
parents:
diff changeset
914 f->m_descriptor.group_segment_size = m_total_group_segment_usage;
kono
parents:
diff changeset
915 f->m_descriptor.private_segment_size = private_segment_size ();
kono
parents:
diff changeset
916
kono
parents:
diff changeset
917 /* The kernarg size is rounded up to a multiple of 16 according to
kono
parents:
diff changeset
918 the PRM specs. */
kono
parents:
diff changeset
919 f->m_descriptor.kernarg_segment_size = f->m_next_kernarg_offset;
kono
parents:
diff changeset
920 if (f->m_descriptor.kernarg_segment_size % 16 > 0)
kono
parents:
diff changeset
921 f->m_descriptor.kernarg_segment_size
kono
parents:
diff changeset
922 += 16 - f->m_next_kernarg_offset % 16;
kono
parents:
diff changeset
923 f->m_descriptor.kernarg_max_align = f->m_kernarg_max_align;
kono
parents:
diff changeset
924
kono
parents:
diff changeset
925 tree launcher = f->emit_launcher_and_metadata ();
kono
parents:
diff changeset
926
kono
parents:
diff changeset
927 append_global (launcher);
kono
parents:
diff changeset
928
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
929 if (m_dump_file)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
930 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
931 std::string kern_name = f->m_name.substr (1);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
932 fprintf (m_dump_file, "\n;; Function %s", kern_name.c_str());
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
933 fprintf (m_dump_file, "\n;; enabled by -%s\n\n",
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
934 dump_flag_name (TDI_original));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
935 print_generic_decl (m_dump_file, launcher, TDF_NONE);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
936 print_generic_expr (m_dump_file, DECL_SAVED_TREE (launcher),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
937 TDF_NONE);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
938 fprintf (m_dump_file, "\n");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
939 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
940
111
kono
parents:
diff changeset
941 gimplify_function_tree (launcher);
kono
parents:
diff changeset
942 cgraph_node::finalize_function (launcher, true);
kono
parents:
diff changeset
943 pop_cfun ();
kono
parents:
diff changeset
944 }
kono
parents:
diff changeset
945
kono
parents:
diff changeset
946 int no_globals = list_length (m_globals);
kono
parents:
diff changeset
947 tree *vec = new tree[no_globals];
kono
parents:
diff changeset
948
kono
parents:
diff changeset
949 int i = 0;
kono
parents:
diff changeset
950 tree global = m_globals;
kono
parents:
diff changeset
951 while (global)
kono
parents:
diff changeset
952 {
kono
parents:
diff changeset
953 vec[i] = global;
kono
parents:
diff changeset
954 ++i;
kono
parents:
diff changeset
955 global = TREE_CHAIN (global);
kono
parents:
diff changeset
956 }
kono
parents:
diff changeset
957
kono
parents:
diff changeset
958 wrapup_global_declarations (vec, no_globals);
kono
parents:
diff changeset
959
kono
parents:
diff changeset
960 delete[] vec;
kono
parents:
diff changeset
961
kono
parents:
diff changeset
962 }
kono
parents:
diff changeset
963
kono
parents:
diff changeset
964 /* Returns an type with unsigned int elements corresponding to the
kono
parents:
diff changeset
965 size and element count of ORIGINAL_TYPE. */
kono
parents:
diff changeset
966
kono
parents:
diff changeset
967 tree
kono
parents:
diff changeset
968 get_unsigned_int_type (tree original_type)
kono
parents:
diff changeset
969 {
kono
parents:
diff changeset
970 if (VECTOR_TYPE_P (original_type))
kono
parents:
diff changeset
971 {
kono
parents:
diff changeset
972 size_t esize
kono
parents:
diff changeset
973 = int_size_in_bytes (TREE_TYPE (original_type)) * BITS_PER_UNIT;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
974 poly_uint64 ecount = TYPE_VECTOR_SUBPARTS (original_type);
111
kono
parents:
diff changeset
975 return build_vector_type (build_nonstandard_integer_type (esize, true),
kono
parents:
diff changeset
976 ecount);
kono
parents:
diff changeset
977 }
kono
parents:
diff changeset
978 else
kono
parents:
diff changeset
979 return build_nonstandard_integer_type (int_size_in_bytes (original_type)
kono
parents:
diff changeset
980 * BITS_PER_UNIT,
kono
parents:
diff changeset
981 true);
kono
parents:
diff changeset
982 }
kono
parents:
diff changeset
983
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
984 /* Returns a type with unsigned int corresponding to the size
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
985 ORIGINAL_TYPE. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
986
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
987 tree
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
988 get_scalar_unsigned_int_type (tree original_type)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
989 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
990 return build_nonstandard_integer_type (int_size_in_bytes (original_type)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
991 * BITS_PER_UNIT, true);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
992 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
993
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
994 /* Set the declaration externally visible so it won't get removed by
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
995 whole program optimizations. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
996
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
997 void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
998 set_externally_visible (tree decl)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
999 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1000 if (!lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1001 DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("externally_visible"),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1002 NULL, DECL_ATTRIBUTES (decl));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1003 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1004
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1005 void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1006 set_inline (tree decl)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1007 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1008 if (!lookup_attribute ("inline", DECL_ATTRIBUTES (decl)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1009 DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("inline"),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1010 NULL, DECL_ATTRIBUTES (decl));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1011 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1012
111
kono
parents:
diff changeset
1013 void
kono
parents:
diff changeset
1014 dump_function (FILE *dump_file, brig_function *f)
kono
parents:
diff changeset
1015 {
kono
parents:
diff changeset
1016 /* Dump the BRIG-specific tree IR. */
kono
parents:
diff changeset
1017 if (dump_file)
kono
parents:
diff changeset
1018 {
kono
parents:
diff changeset
1019 fprintf (dump_file, "\n;; Function %s", f->m_name.c_str ());
kono
parents:
diff changeset
1020 fprintf (dump_file, "\n;; enabled by -%s\n\n",
kono
parents:
diff changeset
1021 dump_flag_name (TDI_original));
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1022 print_generic_decl (dump_file, f->m_func_decl, TDF_NONE);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1023 print_generic_expr (dump_file, f->m_current_bind_expr, TDF_NONE);
111
kono
parents:
diff changeset
1024 fprintf (dump_file, "\n");
kono
parents:
diff changeset
1025 }
kono
parents:
diff changeset
1026 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1027
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1028 /* Records use of the BRIG_REG as a TYPE in the current function. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1029
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1030 void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1031 brig_to_generic::add_reg_used_as_type (const BrigOperandRegister &brig_reg,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1032 tree type)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1033 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1034 gcc_assert (m_cf);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1035 reg_use_info &info
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1036 = m_fn_regs_use_index[m_cf->m_name][gccbrig_hsa_reg_id (brig_reg)];
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1037
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1038 if (info.m_type_refs_lookup.count (type))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1039 info.m_type_refs[info.m_type_refs_lookup[type]].second++;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1040 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1041 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1042 info.m_type_refs.push_back (std::make_pair (type, 1));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1043 info.m_type_refs_lookup[type] = info.m_type_refs.size () - 1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1044 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1045 }