]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/hsa-common.h
c++: Handle multiple aggregate overloads [PR95319].
[thirdparty/gcc.git] / gcc / hsa-common.h
CommitLineData
b2b40051 1/* HSAIL and BRIG related macros and definitions.
8d9254fc 2 Copyright (C) 2013-2020 Free Software Foundation, Inc.
b2b40051
MJ
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 3, or (at your option)
9any later version.
10
11GCC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
19
20#ifndef HSA_H
21#define HSA_H
22
23#include "hsa-brig-format.h"
24#include "is-a.h"
25#include "predict.h"
26#include "tree.h"
27#include "vec.h"
28#include "hash-table.h"
29#include "basic-block.h"
0e3de1d4 30#include "bitmap.h"
b2b40051
MJ
31
32
33/* Return true if the compiler should produce HSAIL. */
34
35static inline bool
36hsa_gen_requested_p (void)
37{
38#ifndef ENABLE_HSA
39 return false;
40#endif
41 return !flag_disable_hsa;
42}
43
44/* Standard warning message if we failed to generate HSAIL for a function. */
45
46#define HSA_SORRY_MSG "could not emit HSAIL for the function"
47
48class hsa_op_immed;
49class hsa_op_cst_list;
50class hsa_insn_basic;
51class hsa_op_address;
52class hsa_op_reg;
53class hsa_bb;
b2b40051
MJ
54
55/* Class representing an input argument, output argument (result) or a
56 variable, that will eventually end up being a symbol directive. */
57
6c1dae73 58class hsa_symbol
b2b40051 59{
6c1dae73 60public:
b2b40051
MJ
61 /* Constructor. */
62 hsa_symbol (BrigType16_t type, BrigSegment8_t segment,
63 BrigLinkage8_t linkage, bool global_scope_p = false,
320c1a36
ML
64 BrigAllocation allocation = BRIG_ALLOCATION_AUTOMATIC,
65 BrigAlignment8_t align = BRIG_ALIGNMENT_8);
b2b40051
MJ
66
67 /* Return total size of the symbol. */
68 unsigned HOST_WIDE_INT total_byte_size ();
69
70 /* Fill in those values into the symbol according to DECL, which are
71 determined independently from whether it is parameter, result,
72 or a variable, local or global. */
73 void fillup_for_decl (tree decl);
74
75 /* Pointer to the original tree, which is PARM_DECL for input parameters and
56b1c60e
MJ
76 RESULT_DECL for the output parameters. Also can be CONST_DECL for Fortran
77 constants which need to be put into readonly segment. */
b2b40051
MJ
78 tree m_decl;
79
80 /* Name of the symbol, that will be written into output and dumps. Can be
81 NULL, see name_number below. */
82 const char *m_name;
83
84 /* If name is NULL, artificial name will be formed from the segment name and
85 this number. */
86 int m_name_number;
87
88 /* Once written, this is the offset of the associated symbol directive. Zero
89 means the symbol has not been written yet. */
90 unsigned m_directive_offset;
91
92 /* HSA type of the parameter. */
93 BrigType16_t m_type;
94
95 /* The HSA segment this will eventually end up in. */
96 BrigSegment8_t m_segment;
97
98 /* The HSA kind of linkage. */
99 BrigLinkage8_t m_linkage;
100
101 /* Array dimension, if non-zero. */
102 unsigned HOST_WIDE_INT m_dim;
103
104 /* Constant value, used for string constants. */
105 hsa_op_immed *m_cst_value;
106
107 /* Is in global scope. */
108 bool m_global_scope_p;
109
110 /* True if an error has been seen for the symbol. */
111 bool m_seen_error;
112
113 /* Symbol allocation. */
114 BrigAllocation m_allocation;
115
c1db25ac
ML
116 /* Flag used for global variables if a variable is already emitted or not. */
117 bool m_emitted_to_brig;
118
320c1a36
ML
119 /* Alignment of the symbol. */
120 BrigAlignment8_t m_align;
121
b2b40051
MJ
122private:
123 /* Default constructor. */
124 hsa_symbol ();
125};
126
127/* Abstract class for HSA instruction operands. */
128
129class hsa_op_base
130{
131public:
132 /* Next operand scheduled to be written when writing BRIG operand
133 section. */
134 hsa_op_base *m_next;
135
136 /* Offset to which the associated operand structure will be written. Zero if
137 yet not scheduled for writing. */
138 unsigned m_brig_op_offset;
139
140 /* The type of a particular operand. */
141 BrigKind16_t m_kind;
142
143protected:
144 hsa_op_base (BrigKind16_t k);
145private:
146 /* Make the default constructor inaccessible. */
147 hsa_op_base () {}
148};
149
150/* Common abstract ancestor for operands which have a type. */
151
152class hsa_op_with_type : public hsa_op_base
153{
154public:
155 /* The type. */
156 BrigType16_t m_type;
157
158 /* Convert an operand to a destination type DTYPE and attach insns
159 to HBB if needed. */
160 hsa_op_with_type *get_in_type (BrigType16_t dtype, hsa_bb *hbb);
191411e4
MJ
161 /* If this operand has integer type smaller than 32 bits, extend it to 32
162 bits, adding instructions to HBB if needed. */
163 hsa_op_with_type *extend_int_to_32bit (hsa_bb *hbb);
b2b40051
MJ
164
165protected:
166 hsa_op_with_type (BrigKind16_t k, BrigType16_t t);
167private:
168 /* Make the default constructor inaccessible. */
169 hsa_op_with_type () : hsa_op_base (BRIG_KIND_NONE) {}
170};
171
172/* An immediate HSA operand. */
173
174class hsa_op_immed : public hsa_op_with_type
175{
176public:
177 hsa_op_immed (tree tree_val, bool min32int = true);
178 hsa_op_immed (HOST_WIDE_INT int_value, BrigType16_t type);
179 void *operator new (size_t);
180 ~hsa_op_immed ();
181 void set_type (BrigKind16_t t);
182
6f652a50
ML
183 /* Function returns pointer to a buffer that contains binary representation
184 of the immeadiate value. The buffer has length of BRIG_SIZE and
185 a caller is responsible for deallocation of the buffer. */
186 char *emit_to_buffer (unsigned *brig_size);
187
b2b40051
MJ
188 /* Value as represented by middle end. */
189 tree m_tree_value;
190
191 /* Integer value representation. */
192 HOST_WIDE_INT m_int_value;
193
b2b40051
MJ
194private:
195 /* Make the default constructor inaccessible. */
196 hsa_op_immed ();
197 /* All objects are deallocated by destroying their pool, so make delete
198 inaccessible too. */
199 void operator delete (void *) {}
b2b40051
MJ
200};
201
53b28abf 202/* Report whether or not P is an immediate operand. */
b2b40051
MJ
203
204template <>
205template <>
206inline bool
207is_a_helper <hsa_op_immed *>::test (hsa_op_base *p)
208{
209 return p->m_kind == BRIG_KIND_OPERAND_CONSTANT_BYTES;
210}
211
b15e4689
MJ
212/* Likewise, but for a more specified base. */
213
214template <>
215template <>
216inline bool
217is_a_helper <hsa_op_immed *>::test (hsa_op_with_type *p)
218{
219 return p->m_kind == BRIG_KIND_OPERAND_CONSTANT_BYTES;
220}
221
222
b2b40051
MJ
223/* HSA register operand. */
224
225class hsa_op_reg : public hsa_op_with_type
226{
227 friend class hsa_insn_basic;
228 friend class hsa_insn_phi;
229public:
230 hsa_op_reg (BrigType16_t t);
231 void *operator new (size_t);
232
233 /* Verify register operand. */
234 void verify_ssa ();
235
236 /* If NON-NULL, gimple SSA that we come from. NULL if none. */
237 tree m_gimple_ssa;
238
239 /* Defining instruction while still in the SSA. */
240 hsa_insn_basic *m_def_insn;
241
242 /* If the register allocator decides to spill the register, this is the
243 appropriate spill symbol. */
244 hsa_symbol *m_spill_sym;
245
246 /* Number of this register structure in the order in which they were
247 allocated. */
248 int m_order;
249 int m_lr_begin, m_lr_end;
250
251 /* Zero if the register is not yet allocated. After, allocation, this must
252 be 'c', 's', 'd' or 'q'. */
253 char m_reg_class;
254 /* If allocated, the number of the HW register (within its HSA register
255 class). */
256 char m_hard_num;
257
258private:
259 /* Make the default constructor inaccessible. */
260 hsa_op_reg () : hsa_op_with_type (BRIG_KIND_NONE, BRIG_TYPE_NONE) {}
261 /* All objects are deallocated by destroying their pool, so make delete
262 inaccessible too. */
263 void operator delete (void *) {}
264 /* Set definition where the register is defined. */
265 void set_definition (hsa_insn_basic *insn);
266 /* Uses of the value while still in SSA. */
56b1c60e 267 auto_vec <hsa_insn_basic *> m_uses;
b2b40051
MJ
268};
269
b2b40051
MJ
270/* Report whether or not P is a register operand. */
271
272template <>
273template <>
274inline bool
275is_a_helper <hsa_op_reg *>::test (hsa_op_base *p)
276{
277 return p->m_kind == BRIG_KIND_OPERAND_REGISTER;
278}
279
280/* Report whether or not P is a register operand. */
281
282template <>
283template <>
284inline bool
285is_a_helper <hsa_op_reg *>::test (hsa_op_with_type *p)
286{
287 return p->m_kind == BRIG_KIND_OPERAND_REGISTER;
288}
289
290/* An address HSA operand. */
291
292class hsa_op_address : public hsa_op_base
293{
294public:
295 /* set up a new address operand consisting of base symbol SYM, register R and
296 immediate OFFSET. If the machine model is not large and offset is 64 bit,
297 the upper, 32 bits have to be zero. */
298 hsa_op_address (hsa_symbol *sym, hsa_op_reg *reg,
299 HOST_WIDE_INT offset = 0);
300
301 void *operator new (size_t);
302
303 /* Set up a new address operand consisting of base symbol SYM and
304 immediate OFFSET. If the machine model is not large and offset is 64 bit,
305 the upper, 32 bits have to be zero. */
306 hsa_op_address (hsa_symbol *sym, HOST_WIDE_INT offset = 0);
307
308 /* Set up a new address operand consisting of register R and
309 immediate OFFSET. If the machine model is not large and offset is 64 bit,
310 the upper, 32 bits have to be zero. */
311 hsa_op_address (hsa_op_reg *reg, HOST_WIDE_INT offset = 0);
312
313 /* Symbol base of the address. Can be NULL if there is none. */
314 hsa_symbol *m_symbol;
315
316 /* Register offset. Can be NULL if there is none. */
317 hsa_op_reg *m_reg;
318
319 /* Immediate byte offset. */
320 HOST_WIDE_INT m_imm_offset;
321
322private:
323 /* Make the default constructor inaccessible. */
324 hsa_op_address () : hsa_op_base (BRIG_KIND_NONE) {}
325 /* All objects are deallocated by destroying their pool, so make delete
326 inaccessible too. */
327 void operator delete (void *) {}
328};
329
330/* Report whether or not P is an address operand. */
331
332template <>
333template <>
334inline bool
335is_a_helper <hsa_op_address *>::test (hsa_op_base *p)
336{
337 return p->m_kind == BRIG_KIND_OPERAND_ADDRESS;
338}
339
340/* A reference to code HSA operand. It can be either reference
341 to a start of a BB or a start of a function. */
342
343class hsa_op_code_ref : public hsa_op_base
344{
345public:
346 hsa_op_code_ref ();
347
348 /* Offset in the code section that this refers to. */
349 unsigned m_directive_offset;
350};
351
352/* Report whether or not P is a code reference operand. */
353
354template <>
355template <>
356inline bool
357is_a_helper <hsa_op_code_ref *>::test (hsa_op_base *p)
358{
359 return p->m_kind == BRIG_KIND_OPERAND_CODE_REF;
360}
361
362/* Code list HSA operand. */
363
364class hsa_op_code_list: public hsa_op_base
365{
366public:
367 hsa_op_code_list (unsigned elements);
368 void *operator new (size_t);
369
370 /* Offset to variable-sized array in hsa_data section, where
371 are offsets to entries in the hsa_code section. */
372 auto_vec<unsigned> m_offsets;
373private:
374 /* Make the default constructor inaccessible. */
375 hsa_op_code_list () : hsa_op_base (BRIG_KIND_NONE) {}
376 /* All objects are deallocated by destroying their pool, so make delete
377 inaccessible too. */
378 void operator delete (void *) {}
379};
380
381/* Report whether or not P is a code list operand. */
382
383template <>
384template <>
385inline bool
386is_a_helper <hsa_op_code_list *>::test (hsa_op_base *p)
387{
388 return p->m_kind == BRIG_KIND_OPERAND_CODE_LIST;
389}
390
391/* Operand list HSA operand. */
392
393class hsa_op_operand_list: public hsa_op_base
394{
395public:
396 hsa_op_operand_list (unsigned elements);
397 ~hsa_op_operand_list ();
398 void *operator new (size_t);
399
400 /* Offset to variable-sized array in hsa_data section, where
401 are offsets to entries in the hsa_code section. */
402 auto_vec<unsigned> m_offsets;
403private:
404 /* Make the default constructor inaccessible. */
405 hsa_op_operand_list () : hsa_op_base (BRIG_KIND_NONE) {}
406 /* All objects are deallocated by destroying their pool, so make delete
407 inaccessible too. */
408 void operator delete (void *) {}
409};
410
411/* Report whether or not P is a code list operand. */
412
413template <>
414template <>
415inline bool
416is_a_helper <hsa_op_operand_list *>::test (hsa_op_base *p)
417{
418 return p->m_kind == BRIG_KIND_OPERAND_OPERAND_LIST;
419}
420
421/* Opcodes of instructions that are not part of HSA but that we use to
422 represent it nevertheless. */
423
424#define HSA_OPCODE_PHI (-1)
425#define HSA_OPCODE_ARG_BLOCK (-2)
426
427/* The number of operand pointers we can directly in an instruction. */
428#define HSA_BRIG_INT_STORAGE_OPERANDS 5
429
430/* Class representing an HSA instruction. Unlike typical ancestors for
431 specialized classes, this one is also directly used for all instructions
432 that are then represented as BrigInstBasic. */
433
434class hsa_insn_basic
435{
436public:
437 hsa_insn_basic (unsigned nops, int opc);
438 hsa_insn_basic (unsigned nops, int opc, BrigType16_t t,
439 hsa_op_base *arg0 = NULL,
440 hsa_op_base *arg1 = NULL,
441 hsa_op_base *arg2 = NULL,
442 hsa_op_base *arg3 = NULL);
443
444 void *operator new (size_t);
445 void set_op (int index, hsa_op_base *op);
446 hsa_op_base *get_op (int index);
447 hsa_op_base **get_op_addr (int index);
448 unsigned int operand_count ();
449 void verify ();
450 unsigned input_count ();
451 unsigned num_used_ops ();
452 void set_output_in_type (hsa_op_reg *dest, unsigned op_index, hsa_bb *hbb);
453 bool op_output_p (unsigned opnum);
454
455 /* The previous and next instruction in the basic block. */
456 hsa_insn_basic *m_prev, *m_next;
457
458 /* Basic block this instruction belongs to. */
459 basic_block m_bb;
460
461 /* Operand code distinguishing different types of instructions. Eventually
462 these should only be BRIG_INST_* values from the BrigOpcode16_t range but
463 initially we use negative values for PHI nodes and such. */
464 int m_opcode;
465
466 /* Linearized number assigned to the instruction by HSA RA. */
467 int m_number;
468
469 /* Type of the destination of the operations. */
470 BrigType16_t m_type;
471
472 /* BRIG offset of the instruction in code section. */
473 unsigned int m_brig_offset;
474
475private:
476 /* Make the default constructor inaccessible. */
477 hsa_insn_basic () {}
478 /* All objects are deallocated by destroying their pool, so make delete
479 inaccessible too. */
480 void operator delete (void *) {}
481 /* The individual operands. All instructions but PHI nodes have five or
482 fewer instructions and so will fit the internal storage. */
483 /* TODO: Vast majority of instructions have three or fewer operands, so we
484 may actually try reducing it. */
485 auto_vec<hsa_op_base *, HSA_BRIG_INT_STORAGE_OPERANDS> m_operands;
486};
487
488/* Class representing a PHI node of the SSA form of HSA virtual
489 registers. */
490
491class hsa_insn_phi : public hsa_insn_basic
492{
493public:
494 hsa_insn_phi (unsigned nops, hsa_op_reg *dst);
495
b2b40051
MJ
496 /* Destination. */
497 hsa_op_reg *m_dest;
498
499private:
500 /* Make the default constructor inaccessible. */
501 hsa_insn_phi () : hsa_insn_basic (1, HSA_OPCODE_PHI) {}
b2b40051
MJ
502};
503
504/* Report whether or not P is a PHI node. */
505
506template <>
507template <>
508inline bool
509is_a_helper <hsa_insn_phi *>::test (hsa_insn_basic *p)
510{
511 return p->m_opcode == HSA_OPCODE_PHI;
512}
513
56b1c60e 514/* HSA instruction for */
b2b40051
MJ
515class hsa_insn_br : public hsa_insn_basic
516{
517public:
56b1c60e
MJ
518 hsa_insn_br (unsigned nops, int opc, BrigType16_t t, BrigWidth8_t width,
519 hsa_op_base *arg0 = NULL, hsa_op_base *arg1 = NULL,
520 hsa_op_base *arg2 = NULL, hsa_op_base *arg3 = NULL);
b2b40051 521
56b1c60e 522 /* Number of work-items affected in the same way by the instruction. */
b2b40051 523 BrigWidth8_t m_width;
56b1c60e 524
b2b40051
MJ
525private:
526 /* Make the default constructor inaccessible. */
56b1c60e 527 hsa_insn_br () : hsa_insn_basic (0, BRIG_OPCODE_BR) {}
b2b40051
MJ
528};
529
56b1c60e 530/* Return true if P is a branching/synchronization instruction. */
b2b40051
MJ
531
532template <>
533template <>
534inline bool
535is_a_helper <hsa_insn_br *>::test (hsa_insn_basic *p)
536{
56b1c60e
MJ
537 return p->m_opcode == BRIG_OPCODE_BARRIER
538 || p->m_opcode == BRIG_OPCODE_BR;
539}
540
541/* HSA instruction for conditional branches. Structurally the same as
542 hsa_insn_br but we represent it specially because of inherent control
543 flow it represents. */
544
545class hsa_insn_cbr : public hsa_insn_br
546{
547public:
548 hsa_insn_cbr (hsa_op_reg *ctrl);
549
550private:
551 /* Make the default constructor inaccessible. */
552 hsa_insn_cbr () : hsa_insn_br (0, BRIG_OPCODE_CBR, BRIG_TYPE_B1,
553 BRIG_WIDTH_1) {}
554};
555
556/* Report whether P is a contitional branching instruction. */
557
558template <>
559template <>
560inline bool
561is_a_helper <hsa_insn_cbr *>::test (hsa_insn_basic *p)
562{
563 return p->m_opcode == BRIG_OPCODE_CBR;
b2b40051
MJ
564}
565
566/* HSA instruction for switch branches. */
567
568class hsa_insn_sbr : public hsa_insn_basic
569{
570public:
571 hsa_insn_sbr (hsa_op_reg *index, unsigned jump_count);
572
573 /* Default destructor. */
574 ~hsa_insn_sbr ();
575
b2b40051
MJ
576 void replace_all_labels (basic_block old_bb, basic_block new_bb);
577
578 /* Width as described in HSA documentation. */
579 BrigWidth8_t m_width;
580
581 /* Jump table. */
582 vec <basic_block> m_jump_table;
583
b2b40051
MJ
584 /* Code list for label references. */
585 hsa_op_code_list *m_label_code_list;
586
587private:
588 /* Make the default constructor inaccessible. */
589 hsa_insn_sbr () : hsa_insn_basic (1, BRIG_OPCODE_SBR) {}
b2b40051
MJ
590};
591
592/* Report whether P is a switch branching instruction. */
593
594template <>
595template <>
596inline bool
597is_a_helper <hsa_insn_sbr *>::test (hsa_insn_basic *p)
598{
599 return p->m_opcode == BRIG_OPCODE_SBR;
600}
601
602/* HSA instruction for comparisons. */
603
604class hsa_insn_cmp : public hsa_insn_basic
605{
606public:
607 hsa_insn_cmp (BrigCompareOperation8_t cmp, BrigType16_t t,
608 hsa_op_base *arg0 = NULL, hsa_op_base *arg1 = NULL,
609 hsa_op_base *arg2 = NULL);
610
b2b40051
MJ
611 /* Source type should be derived from operand types. */
612
613 /* The comparison operation. */
614 BrigCompareOperation8_t m_compare;
615
616 /* TODO: Modifiers and packing control are missing but so are everywhere
617 else. */
618private:
619 /* Make the default constructor inaccessible. */
620 hsa_insn_cmp () : hsa_insn_basic (1, BRIG_OPCODE_CMP) {}
b2b40051
MJ
621};
622
623/* Report whether or not P is a comparison instruction. */
624
625template <>
626template <>
627inline bool
628is_a_helper <hsa_insn_cmp *>::test (hsa_insn_basic *p)
629{
630 return p->m_opcode == BRIG_OPCODE_CMP;
631}
632
633/* HSA instruction for memory operations. */
634
635class hsa_insn_mem : public hsa_insn_basic
636{
637public:
638 hsa_insn_mem (int opc, BrigType16_t t, hsa_op_base *arg0, hsa_op_base *arg1);
639
b2b40051
MJ
640 /* Set alignment to VALUE. */
641
642 void set_align (BrigAlignment8_t value);
643
644 /* The segment is of the memory access is either the segment of the symbol in
645 the address operand or flat address is there is no symbol there. */
646
647 /* Required alignment of the memory operation. */
648 BrigAlignment8_t m_align;
649
650 /* HSA equiv class, basically an alias set number. */
651 uint8_t m_equiv_class;
652
653 /* TODO: Add width modifier, perhaps also other things. */
654protected:
655 hsa_insn_mem (unsigned nops, int opc, BrigType16_t t,
656 hsa_op_base *arg0 = NULL, hsa_op_base *arg1 = NULL,
657 hsa_op_base *arg2 = NULL, hsa_op_base *arg3 = NULL);
658
659private:
660 /* Make the default constructor inaccessible. */
661 hsa_insn_mem () : hsa_insn_basic (1, BRIG_OPCODE_LD) {}
b2b40051
MJ
662};
663
664/* Report whether or not P is a memory instruction. */
665
666template <>
667template <>
668inline bool
669is_a_helper <hsa_insn_mem *>::test (hsa_insn_basic *p)
670{
671 return (p->m_opcode == BRIG_OPCODE_LD
672 || p->m_opcode == BRIG_OPCODE_ST);
673}
674
675/* HSA instruction for atomic operations. */
676
677class hsa_insn_atomic : public hsa_insn_mem
678{
679public:
680 hsa_insn_atomic (int nops, int opc, enum BrigAtomicOperation aop,
681 BrigType16_t t, BrigMemoryOrder memorder,
682 hsa_op_base *arg0 = NULL, hsa_op_base *arg1 = NULL,
683 hsa_op_base *arg2 = NULL, hsa_op_base *arg3 = NULL);
b2b40051
MJ
684
685 /* The operation itself. */
686 enum BrigAtomicOperation m_atomicop;
687
688 /* Things like acquire/release/aligned. */
689 enum BrigMemoryOrder m_memoryorder;
690
691 /* Scope of the atomic operation. */
692 enum BrigMemoryScope m_memoryscope;
693
694private:
695 /* Make the default constructor inaccessible. */
696 hsa_insn_atomic () : hsa_insn_mem (1, BRIG_KIND_NONE, BRIG_TYPE_NONE) {}
b2b40051
MJ
697};
698
699/* Report whether or not P is an atomic instruction. */
700
701template <>
702template <>
703inline bool
704is_a_helper <hsa_insn_atomic *>::test (hsa_insn_basic *p)
705{
706 return (p->m_opcode == BRIG_OPCODE_ATOMIC
707 || p->m_opcode == BRIG_OPCODE_ATOMICNORET);
708}
709
710/* HSA instruction for signal operations. */
711
56b1c60e 712class hsa_insn_signal : public hsa_insn_basic
b2b40051
MJ
713{
714public:
715 hsa_insn_signal (int nops, int opc, enum BrigAtomicOperation sop,
56b1c60e
MJ
716 BrigType16_t t, BrigMemoryOrder memorder,
717 hsa_op_base *arg0 = NULL, hsa_op_base *arg1 = NULL,
b2b40051
MJ
718 hsa_op_base *arg2 = NULL, hsa_op_base *arg3 = NULL);
719
56b1c60e
MJ
720 /* Things like acquire/release/aligned. */
721 enum BrigMemoryOrder m_memory_order;
b2b40051 722
56b1c60e
MJ
723 /* The operation itself. */
724 enum BrigAtomicOperation m_signalop;
b2b40051
MJ
725};
726
727/* Report whether or not P is a signal instruction. */
728
729template <>
730template <>
731inline bool
732is_a_helper <hsa_insn_signal *>::test (hsa_insn_basic *p)
733{
734 return (p->m_opcode == BRIG_OPCODE_SIGNAL
735 || p->m_opcode == BRIG_OPCODE_SIGNALNORET);
736}
737
738/* HSA instruction to convert between flat addressing and segments. */
739
740class hsa_insn_seg : public hsa_insn_basic
741{
742public:
743 hsa_insn_seg (int opc, BrigType16_t destt, BrigType16_t srct,
744 BrigSegment8_t seg, hsa_op_base *arg0, hsa_op_base *arg1);
745
b2b40051
MJ
746 /* Source type. Depends on the source addressing/segment. */
747 BrigType16_t m_src_type;
748 /* The segment we are converting from or to. */
749 BrigSegment8_t m_segment;
750private:
751 /* Make the default constructor inaccessible. */
752 hsa_insn_seg () : hsa_insn_basic (1, BRIG_OPCODE_STOF) {}
b2b40051
MJ
753};
754
755/* Report whether or not P is a segment conversion instruction. */
756
757template <>
758template <>
759inline bool
760is_a_helper <hsa_insn_seg *>::test (hsa_insn_basic *p)
761{
762 return (p->m_opcode == BRIG_OPCODE_STOF
763 || p->m_opcode == BRIG_OPCODE_FTOS);
764}
765
766/* Class for internal functions for purpose of HSA emission. */
767
768class hsa_internal_fn
769{
770public:
771 hsa_internal_fn (enum internal_fn fn, unsigned type_bit_size):
772 m_fn (fn), m_type_bit_size (type_bit_size), m_offset (0) {}
773
774 hsa_internal_fn (const hsa_internal_fn *f):
775 m_fn (f->m_fn), m_type_bit_size (f->m_type_bit_size),
776 m_offset (f->m_offset) {}
777
778 /* Return arity of the internal function. */
779 unsigned get_arity ();
780
781 /* Return BRIG type of N-th argument, if -1 is passed, return value type
782 is received. */
783 BrigType16_t get_argument_type (int n);
784
785 /* Return function name. The memory must be released by a caller. */
786 char *name ();
787
788 /* Internal function. */
789 enum internal_fn m_fn;
790
791 /* Bit width of return type. */
792 unsigned m_type_bit_size;
793
794 /* BRIG offset of declaration of the function. */
795 BrigCodeOffset32_t m_offset;
796};
797
798/* HSA instruction for function call. */
799
800class hsa_insn_call : public hsa_insn_basic
801{
802public:
803 hsa_insn_call (tree callee);
804 hsa_insn_call (hsa_internal_fn *fn);
805
806 /* Default destructor. */
807 ~hsa_insn_call ();
808
b2b40051
MJ
809 /* Called function. */
810 tree m_called_function;
811
812 /* Called internal function. */
813 hsa_internal_fn *m_called_internal_fn;
814
815 /* Input formal arguments. */
816 auto_vec <hsa_symbol *> m_input_args;
817
818 /* Input arguments store instructions. */
819 auto_vec <hsa_insn_mem *> m_input_arg_insns;
820
821 /* Output argument, can be NULL for void functions. */
822 hsa_symbol *m_output_arg;
823
824 /* Called function code reference. */
825 hsa_op_code_ref m_func;
826
827 /* Code list for arguments of the function. */
828 hsa_op_code_list *m_args_code_list;
829
830 /* Code list for result of the function. */
831 hsa_op_code_list *m_result_code_list;
832private:
833 /* Make the default constructor inaccessible. */
834 hsa_insn_call () : hsa_insn_basic (0, BRIG_OPCODE_CALL) {}
b2b40051
MJ
835};
836
837/* Report whether or not P is a call instruction. */
838
839template <>
840template <>
841inline bool
842is_a_helper <hsa_insn_call *>::test (hsa_insn_basic *p)
843{
844 return (p->m_opcode == BRIG_OPCODE_CALL);
845}
846
847/* HSA call instruction block encapsulates definition of arguments,
848 result type, corresponding loads and a possible store.
849 Moreover, it contains a single call instruction.
850 Emission of the instruction will produce multiple
851 HSAIL instructions. */
852
853class hsa_insn_arg_block : public hsa_insn_basic
854{
855public:
856 hsa_insn_arg_block (BrigKind brig_kind, hsa_insn_call * call);
857
b2b40051
MJ
858 /* Kind of argument block. */
859 BrigKind m_kind;
860
861 /* Call instruction. */
862 hsa_insn_call *m_call_insn;
b2b40051
MJ
863};
864
865/* Report whether or not P is a call block instruction. */
866
867template <>
868template <>
869inline bool
870is_a_helper <hsa_insn_arg_block *>::test (hsa_insn_basic *p)
871{
872 return (p->m_opcode == HSA_OPCODE_ARG_BLOCK);
873}
874
875/* HSA comment instruction. */
876
877class hsa_insn_comment: public hsa_insn_basic
878{
879public:
880 /* Constructor of class representing the comment in HSAIL. */
881 hsa_insn_comment (const char *s);
882
883 /* Default destructor. */
884 ~hsa_insn_comment ();
885
b2b40051
MJ
886 char *m_comment;
887};
888
889/* Report whether or not P is a call block instruction. */
890
891template <>
892template <>
893inline bool
894is_a_helper <hsa_insn_comment *>::test (hsa_insn_basic *p)
895{
896 return (p->m_opcode == BRIG_KIND_DIRECTIVE_COMMENT);
897}
898
899/* HSA queue instruction. */
900
901class hsa_insn_queue: public hsa_insn_basic
902{
903public:
56b1c60e
MJ
904 hsa_insn_queue (int nops, int opcode, BrigSegment segment,
905 BrigMemoryOrder memory_order,
906 hsa_op_base *arg0 = NULL, hsa_op_base *arg1 = NULL,
907 hsa_op_base *arg2 = NULL, hsa_op_base *arg3 = NULL);
b2b40051
MJ
908
909 /* Destructor. */
910 ~hsa_insn_queue ();
56b1c60e
MJ
911
912 /* Segment used to refer to the queue. Must be global or flat. */
913 BrigSegment m_segment;
914 /* Memory order used to specify synchronization. */
915 BrigMemoryOrder m_memory_order;
b2b40051
MJ
916};
917
918/* Report whether or not P is a queue instruction. */
919
920template <>
921template <>
922inline bool
923is_a_helper <hsa_insn_queue *>::test (hsa_insn_basic *p)
924{
56b1c60e
MJ
925 return (p->m_opcode == BRIG_OPCODE_ADDQUEUEWRITEINDEX
926 || p->m_opcode == BRIG_OPCODE_CASQUEUEWRITEINDEX
927 || p->m_opcode == BRIG_OPCODE_LDQUEUEREADINDEX
928 || p->m_opcode == BRIG_OPCODE_LDQUEUEWRITEINDEX
929 || p->m_opcode == BRIG_OPCODE_STQUEUEREADINDEX
930 || p->m_opcode == BRIG_OPCODE_STQUEUEWRITEINDEX);
b2b40051
MJ
931}
932
933/* HSA source type instruction. */
934
935class hsa_insn_srctype: public hsa_insn_basic
936{
937public:
938 hsa_insn_srctype (int nops, BrigOpcode opcode, BrigType16_t destt,
939 BrigType16_t srct, hsa_op_base *arg0, hsa_op_base *arg1,
940 hsa_op_base *arg2);
941
b2b40051
MJ
942 /* Source type. */
943 BrigType16_t m_source_type;
944
945 /* Destructor. */
946 ~hsa_insn_srctype ();
947};
948
949/* Report whether or not P is a source type instruction. */
950
951template <>
952template <>
953inline bool
954is_a_helper <hsa_insn_srctype *>::test (hsa_insn_basic *p)
955{
956 return (p->m_opcode == BRIG_OPCODE_POPCOUNT
957 || p->m_opcode == BRIG_OPCODE_FIRSTBIT
958 || p->m_opcode == BRIG_OPCODE_LASTBIT);
959}
960
961/* HSA packed instruction. */
962
963class hsa_insn_packed : public hsa_insn_srctype
964{
965public:
966 hsa_insn_packed (int nops, BrigOpcode opcode, BrigType16_t destt,
967 BrigType16_t srct, hsa_op_base *arg0, hsa_op_base *arg1,
968 hsa_op_base *arg2);
969
b2b40051
MJ
970 /* Operand list for an operand of the instruction. */
971 hsa_op_operand_list *m_operand_list;
972
973 /* Destructor. */
974 ~hsa_insn_packed ();
975};
976
977/* Report whether or not P is a combine instruction. */
978
979template <>
980template <>
981inline bool
982is_a_helper <hsa_insn_packed *>::test (hsa_insn_basic *p)
983{
984 return (p->m_opcode == BRIG_OPCODE_COMBINE
985 || p->m_opcode == BRIG_OPCODE_EXPAND);
986}
987
988/* HSA convert instruction. */
989
990class hsa_insn_cvt: public hsa_insn_basic
991{
992public:
993 hsa_insn_cvt (hsa_op_with_type *dest, hsa_op_with_type *src);
b2b40051
MJ
994};
995
996/* Report whether or not P is a convert instruction. */
997
998template <>
999template <>
1000inline bool
1001is_a_helper <hsa_insn_cvt *>::test (hsa_insn_basic *p)
1002{
1003 return (p->m_opcode == BRIG_OPCODE_CVT);
1004}
1005
1006/* HSA alloca instruction. */
1007
1008class hsa_insn_alloca: public hsa_insn_basic
1009{
1010public:
1011 hsa_insn_alloca (hsa_op_with_type *dest, hsa_op_with_type *size,
1012 unsigned alignment = 0);
1013
1014 /* Required alignment of the allocation. */
1015 BrigAlignment8_t m_align;
b2b40051
MJ
1016};
1017
1018/* Report whether or not P is an alloca instruction. */
1019
1020template <>
1021template <>
1022inline bool
1023is_a_helper <hsa_insn_alloca *>::test (hsa_insn_basic *p)
1024{
1025 return (p->m_opcode == BRIG_OPCODE_ALLOCA);
1026}
1027
1028/* Basic block of HSA instructions. */
1029
1030class hsa_bb
1031{
1032public:
1033 hsa_bb (basic_block cfg_bb);
1034 hsa_bb (basic_block cfg_bb, int idx);
b2b40051
MJ
1035
1036 /* Append an instruction INSN into the basic block. */
1037 void append_insn (hsa_insn_basic *insn);
1038
56b1c60e
MJ
1039 /* Add a PHI instruction. */
1040 void append_phi (hsa_insn_phi *phi);
1041
b2b40051
MJ
1042 /* The real CFG BB that this HBB belongs to. */
1043 basic_block m_bb;
1044
1045 /* The operand that refers to the label to this BB. */
1046 hsa_op_code_ref m_label_ref;
1047
1048 /* The first and last instruction. */
1049 hsa_insn_basic *m_first_insn, *m_last_insn;
1050 /* The first and last phi node. */
1051 hsa_insn_phi *m_first_phi, *m_last_phi;
1052
1053 /* Just a number to construct names from. */
1054 int m_index;
1055
0e3de1d4 1056 auto_bitmap m_liveout, m_livein;
b2b40051
MJ
1057private:
1058 /* Make the default constructor inaccessible. */
1059 hsa_bb ();
1060 /* All objects are deallocated by destroying their pool, so make delete
1061 inaccessible too. */
1062 void operator delete (void *) {}
1063};
1064
1065/* Return the corresponding HSA basic block structure for the given control
1066 flow basic_block BB. */
1067
1068static inline hsa_bb *
1069hsa_bb_for_bb (basic_block bb)
1070{
99b1c316 1071 return (class hsa_bb *) bb->aux;
b2b40051
MJ
1072}
1073
1074/* Class for hashing local hsa_symbols. */
1075
1076struct hsa_noop_symbol_hasher : nofree_ptr_hash <hsa_symbol>
1077{
1078 static inline hashval_t hash (const value_type);
1079 static inline bool equal (const value_type, const compare_type);
1080};
1081
1082/* Hash hsa_symbol. */
1083
1084inline hashval_t
1085hsa_noop_symbol_hasher::hash (const value_type item)
1086{
1087 return DECL_UID (item->m_decl);
1088}
1089
1090/* Return true if the DECL_UIDs of decls both symbols refer to are equal. */
1091
1092inline bool
1093hsa_noop_symbol_hasher::equal (const value_type a, const compare_type b)
1094{
1095 return (DECL_UID (a->m_decl) == DECL_UID (b->m_decl));
1096}
1097
1098/* Structure that encapsulates intermediate representation of a HSA
1099 function. */
1100
1101class hsa_function_representation
1102{
1103public:
1104 hsa_function_representation (tree fdecl, bool kernel_p,
65e21467
ML
1105 unsigned ssa_names_count,
1106 bool modified_cfg = false);
b2b40051
MJ
1107 hsa_function_representation (hsa_internal_fn *fn);
1108 ~hsa_function_representation ();
1109
1110 /* Builds a shadow register that is utilized to a kernel dispatch. */
1111 hsa_op_reg *get_shadow_reg ();
1112
1113 /* Return true if we are in a function that has kernel dispatch
1114 shadow register. */
1115 bool has_shadow_reg_p ();
1116
1117 /* The entry/exit blocks don't contain incoming code,
1118 but the HSA generator might use them to put code into,
1119 so we need hsa_bb instances of them. */
1120 void init_extra_bbs ();
1121
65e21467
ML
1122 /* Update CFG dominators if m_modified_cfg flag is set. */
1123 void update_dominance ();
1124
b2b40051
MJ
1125 /* Return linkage of the representation. */
1126 BrigLinkage8_t get_linkage ();
1127
1128 /* Create a private symbol of requested TYPE. */
1129 hsa_symbol *create_hsa_temporary (BrigType16_t type);
1130
1131 /* Lookup or create a HSA pseudo register for a given gimple SSA name. */
1132 hsa_op_reg *reg_for_gimple_ssa (tree ssa);
1133
1134 /* Name of the function. */
1135 char *m_name;
1136
1137 /* Number of allocated register structures. */
1138 int m_reg_count;
1139
1140 /* Input arguments. */
1141 vec <hsa_symbol *> m_input_args;
1142
1143 /* Output argument or NULL if there is none. */
1144 hsa_symbol *m_output_arg;
1145
1146 /* Hash table of local variable symbols. */
1147 hash_table <hsa_noop_symbol_hasher> *m_local_symbols;
1148
1149 /* Hash map for string constants. */
1150 hash_map <tree, hsa_symbol *> m_string_constants_map;
1151
1152 /* Vector of pointers to spill symbols. */
99b1c316 1153 vec <class hsa_symbol *> m_spill_symbols;
b2b40051
MJ
1154
1155 /* Vector of pointers to global variables and transformed string constants
1156 that are used by the function. */
99b1c316 1157 vec <class hsa_symbol *> m_global_symbols;
b2b40051
MJ
1158
1159 /* Private function artificial variables. */
99b1c316 1160 vec <class hsa_symbol *> m_private_variables;
b2b40051
MJ
1161
1162 /* Vector of called function declarations. */
1163 vec <tree> m_called_functions;
1164
1165 /* Vector of used internal functions. */
1166 vec <hsa_internal_fn *> m_called_internal_fns;
1167
1168 /* Number of HBB BBs. */
1169 int m_hbb_count;
1170
1171 /* Whether or not we could check and enforce SSA properties. */
1172 bool m_in_ssa;
1173
1174 /* True if the function is kernel function. */
1175 bool m_kern_p;
1176
1177 /* True if the function representation is a declaration. */
1178 bool m_declaration_p;
1179
1180 /* Function declaration tree. */
1181 tree m_decl;
1182
1183 /* Internal function info is used for declarations of internal functions. */
1184 hsa_internal_fn *m_internal_fn;
1185
1186 /* Runtime shadow register. */
1187 hsa_op_reg *m_shadow_reg;
1188
1189 /* Number of kernel dispatched which take place in the function. */
1190 unsigned m_kernel_dispatch_count;
1191
1192 /* If the function representation contains a kernel dispatch,
1193 OMP data size is necessary memory that is used for copying before
1194 a kernel dispatch. */
1195 unsigned m_maximum_omp_data_size;
1196
1197 /* Return true if there's an HSA-specific warning already seen. */
1198 bool m_seen_error;
1199
1200 /* Counter for temporary symbols created in the function representation. */
1201 unsigned m_temp_symbol_count;
1202
1203 /* SSA names mapping. */
56b1c60e 1204 vec <hsa_op_reg *> m_ssa_map;
65e21467
ML
1205
1206 /* Flag whether a function needs update of dominators before RA. */
1207 bool m_modified_cfg;
b2b40051
MJ
1208};
1209
1210enum hsa_function_kind
1211{
0148358a 1212 HSA_INVALID,
b2b40051
MJ
1213 HSA_KERNEL,
1214 HSA_FUNCTION
1215};
1216
6c1dae73 1217class hsa_function_summary
b2b40051 1218{
6c1dae73 1219public:
b2b40051
MJ
1220 /* Default constructor. */
1221 hsa_function_summary ();
1222
1223 /* Kind of GPU/host function. */
1224 hsa_function_kind m_kind;
1225
1226 /* Pointer to a cgraph node which is a HSA implementation of the function.
56b1c60e 1227 In case of the function is a HSA function, the bound function points
b2b40051 1228 to the host function. */
56b1c60e 1229 cgraph_node *m_bound_function;
b2b40051
MJ
1230
1231 /* Identifies if the function is an HSA function or a host function. */
1232 bool m_gpu_implementation_p;
1233
1234 /* True if the function is a gridified kernel. */
1235 bool m_gridified_kernel_p;
1236};
1237
1238inline
0148358a 1239hsa_function_summary::hsa_function_summary (): m_kind (HSA_INVALID),
56b1c60e 1240 m_bound_function (NULL), m_gpu_implementation_p (false)
b2b40051
MJ
1241{
1242}
1243
1244/* Function summary for HSA functions. */
1245class hsa_summary_t: public function_summary <hsa_function_summary *>
1246{
1247public:
1248 hsa_summary_t (symbol_table *table):
0148358a
ML
1249 function_summary<hsa_function_summary *> (table)
1250 {
1251 disable_insertion_hook ();
1252 }
b2b40051
MJ
1253
1254 /* Couple GPU and HOST as gpu-specific and host-specific implementation of
1255 the same function. KIND determines whether GPU is a host-invokable kernel
1256 or gpu-callable function and GRIDIFIED_KERNEL_P is set if the function was
1257 gridified in OMP. */
1258
1259 void link_functions (cgraph_node *gpu, cgraph_node *host,
1260 hsa_function_kind kind, bool gridified_kernel_p);
56b1c60e
MJ
1261
1262private:
1263 void process_gpu_implementation_attributes (tree gdecl);
b2b40051
MJ
1264};
1265
1266/* OMP simple builtin describes behavior that should be done for
1267 the routine. */
1268class omp_simple_builtin
1269{
1270public:
1271 omp_simple_builtin (const char *name, const char *warning_message,
1272 bool sorry, hsa_op_immed *return_value = NULL):
1273 m_name (name), m_warning_message (warning_message), m_sorry (sorry),
1274 m_return_value (return_value)
1275 {}
1276
1277 /* Generate HSAIL instructions for the builtin or produce warning message. */
1278 void generate (gimple *stmt, hsa_bb *hbb);
1279
1280 /* Name of function. */
1281 const char *m_name;
1282
1283 /* Warning message. */
1284 const char *m_warning_message;
1285
1286 /* Flag if we should sorry after the warning message is printed. */
1287 bool m_sorry;
1288
1289 /* Return value of the function. */
1290 hsa_op_immed *m_return_value;
1291
1292 /* Emission function. */
1293 void (*m_emit_func) (gimple *stmt, hsa_bb *);
1294};
1295
1296/* Class for hashing hsa_internal_fn. */
1297
1298struct hsa_internal_fn_hasher: free_ptr_hash <hsa_internal_fn>
1299{
1300 static inline hashval_t hash (const value_type);
1301 static inline bool equal (const value_type, const compare_type);
1302};
1303
1304/* Hash hsa_symbol. */
1305
1306inline hashval_t
1307hsa_internal_fn_hasher::hash (const value_type item)
1308{
1309 return item->m_fn;
1310}
1311
1312/* Return true if the DECL_UIDs of decls both symbols refer to are equal. */
1313
1314inline bool
1315hsa_internal_fn_hasher::equal (const value_type a, const compare_type b)
1316{
1317 return a->m_fn == b->m_fn && a->m_type_bit_size == b->m_type_bit_size;
1318}
1319
13293add 1320/* in hsa-common.c */
99b1c316 1321extern class hsa_function_representation *hsa_cfun;
b2b40051
MJ
1322extern hash_map <tree, vec <const char *> *> *hsa_decl_kernel_dependencies;
1323extern hsa_summary_t *hsa_summaries;
1324extern hsa_symbol *hsa_num_threads;
1325extern unsigned hsa_kernel_calls_counter;
1326extern hash_set <tree> *hsa_failed_functions;
1327extern hash_table <hsa_noop_symbol_hasher> *hsa_global_variable_symbols;
1328
1329bool hsa_callable_function_p (tree fndecl);
1330void hsa_init_compilation_unit_data (void);
1331void hsa_deinit_compilation_unit_data (void);
1332bool hsa_machine_large_p (void);
1333bool hsa_full_profile_p (void);
1334bool hsa_opcode_floating_bit_insn_p (BrigOpcode16_t);
1335unsigned hsa_type_bit_size (BrigType16_t t);
1336BrigType16_t hsa_bittype_for_bitsize (unsigned bitsize);
1337BrigType16_t hsa_uint_for_bitsize (unsigned bitsize);
1338BrigType16_t hsa_float_for_bitsize (unsigned bitsize);
1339BrigType16_t hsa_bittype_for_type (BrigType16_t t);
b15e4689 1340BrigType16_t hsa_unsigned_type_for_type (BrigType16_t t);
27d39ae1 1341bool hsa_type_packed_p (BrigType16_t type);
b2b40051
MJ
1342bool hsa_type_float_p (BrigType16_t type);
1343bool hsa_type_integer_p (BrigType16_t type);
1344bool hsa_btype_p (BrigType16_t type);
1345BrigAlignment8_t hsa_alignment_encoding (unsigned n);
1346BrigAlignment8_t hsa_natural_alignment (BrigType16_t type);
320c1a36
ML
1347BrigAlignment8_t hsa_object_alignment (tree t);
1348unsigned hsa_byte_alignment (BrigAlignment8_t alignment);
b2b40051
MJ
1349void hsa_destroy_operand (hsa_op_base *op);
1350void hsa_destroy_insn (hsa_insn_basic *insn);
1351void hsa_add_kern_decl_mapping (tree decl, char *name, unsigned, bool);
1352unsigned hsa_get_number_decl_kernel_mappings (void);
1353tree hsa_get_decl_kernel_mapping_decl (unsigned i);
1354char *hsa_get_decl_kernel_mapping_name (unsigned i);
1355unsigned hsa_get_decl_kernel_mapping_omp_size (unsigned i);
1356bool hsa_get_decl_kernel_mapping_gridified (unsigned i);
1357void hsa_free_decl_kernel_mapping (void);
4bf1cec7
MJ
1358tree *hsa_get_ctor_statements (void);
1359tree *hsa_get_dtor_statements (void);
1360tree *hsa_get_kernel_dispatch_type (void);
b2b40051
MJ
1361void hsa_add_kernel_dependency (tree caller, const char *called_function);
1362void hsa_sanitize_name (char *p);
1363char *hsa_brig_function_name (const char *p);
1364const char *hsa_get_declaration_name (tree decl);
1365void hsa_register_kernel (cgraph_node *host);
1366void hsa_register_kernel (cgraph_node *gpu, cgraph_node *host);
1367bool hsa_seen_error (void);
1368void hsa_fail_cfun (void);
1369
1370/* In hsa-gen.c. */
1371void hsa_build_append_simple_mov (hsa_op_reg *, hsa_op_base *, hsa_bb *);
1372hsa_symbol *hsa_get_spill_symbol (BrigType16_t);
1373hsa_symbol *hsa_get_string_cst_symbol (BrigType16_t);
1374hsa_op_reg *hsa_spill_in (hsa_insn_basic *, hsa_op_reg *, hsa_op_reg **);
1375hsa_op_reg *hsa_spill_out (hsa_insn_basic *, hsa_op_reg *, hsa_op_reg **);
1376hsa_bb *hsa_init_new_bb (basic_block);
1377hsa_function_representation *hsa_generate_function_declaration (tree decl);
1378hsa_function_representation *hsa_generate_internal_fn_decl (hsa_internal_fn *);
1379tree hsa_get_host_function (tree decl);
1380
1381/* In hsa-regalloc.c. */
1382void hsa_regalloc (void);
1383
1384/* In hsa-brig.c. */
1385extern hash_table <hsa_internal_fn_hasher> *hsa_emitted_internal_decls;
1386void hsa_brig_emit_function (void);
1387void hsa_output_brig (void);
1388unsigned hsa_get_imm_brig_type_len (BrigType16_t type);
1389void hsa_brig_emit_omp_symbols (void);
1390
1391/* In hsa-dump.c. */
1392const char *hsa_seg_name (BrigSegment8_t);
1393void dump_hsa_insn (FILE *f, hsa_insn_basic *insn);
1394void dump_hsa_bb (FILE *, hsa_bb *);
1395void dump_hsa_cfun (FILE *);
1396DEBUG_FUNCTION void debug_hsa_operand (hsa_op_base *opc);
1397DEBUG_FUNCTION void debug_hsa_insn (hsa_insn_basic *insn);
1398
1399union hsa_bytes
1400{
1401 uint8_t b8;
1402 uint16_t b16;
1403 uint32_t b32;
1404 uint64_t b64;
1405};
1406
1407/* Return true if a function DECL is an HSA implementation. */
1408
1409static inline bool
1410hsa_gpu_implementation_p (tree decl)
1411{
1412 if (hsa_summaries == NULL)
1413 return false;
1414
0148358a
ML
1415 hsa_function_summary *s = hsa_summaries->get (cgraph_node::get_create (decl));
1416 return s != NULL && s->m_gpu_implementation_p;
b2b40051
MJ
1417}
1418
1419#endif /* HSA_H */