xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/hsa-common.h (revision 4c3eb207d36f67d31994830c0a694161fc1ca39b)
1 /* HSAIL and BRIG related macros and definitions.
2    Copyright (C) 2013-2020 Free Software Foundation, Inc.
3 
4 This file is part of GCC.
5 
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
10 
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along 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"
30 #include "bitmap.h"
31 
32 
33 /* Return true if the compiler should produce HSAIL.  */
34 
35 static inline bool
hsa_gen_requested_p(void)36 hsa_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 
48 class hsa_op_immed;
49 class hsa_op_cst_list;
50 class hsa_insn_basic;
51 class hsa_op_address;
52 class hsa_op_reg;
53 class hsa_bb;
54 
55 /* Class representing an input argument, output argument (result) or a
56    variable, that will eventually end up being a symbol directive.  */
57 
58 class hsa_symbol
59 {
60 public:
61   /* Constructor.  */
62   hsa_symbol (BrigType16_t type, BrigSegment8_t segment,
63 	      BrigLinkage8_t linkage, bool global_scope_p = false,
64 	      BrigAllocation allocation = BRIG_ALLOCATION_AUTOMATIC,
65 	      BrigAlignment8_t align = BRIG_ALIGNMENT_8);
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
76      RESULT_DECL for the output parameters.  Also can be CONST_DECL for Fortran
77      constants which need to be put into readonly segment.  */
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 
116   /* Flag used for global variables if a variable is already emitted or not.  */
117   bool m_emitted_to_brig;
118 
119   /* Alignment of the symbol.  */
120   BrigAlignment8_t m_align;
121 
122 private:
123   /* Default constructor.  */
124   hsa_symbol ();
125 };
126 
127 /* Abstract class for HSA instruction operands.  */
128 
129 class hsa_op_base
130 {
131 public:
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 
143 protected:
144   hsa_op_base (BrigKind16_t k);
145 private:
146   /* Make the default constructor inaccessible.  */
hsa_op_base()147   hsa_op_base () {}
148 };
149 
150 /* Common abstract ancestor for operands which have a type.  */
151 
152 class hsa_op_with_type : public hsa_op_base
153 {
154 public:
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);
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);
164 
165 protected:
166   hsa_op_with_type (BrigKind16_t k, BrigType16_t t);
167 private:
168   /* Make the default constructor inaccessible.  */
hsa_op_with_type()169   hsa_op_with_type () : hsa_op_base (BRIG_KIND_NONE) {}
170 };
171 
172 /* An immediate HSA operand.  */
173 
174 class hsa_op_immed : public hsa_op_with_type
175 {
176 public:
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 
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 
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 
194 private:
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.  */
delete(void *)199   void operator delete (void *) {}
200 };
201 
202 /* Report whether or not P is an immediate operand.  */
203 
204 template <>
205 template <>
206 inline bool
test(hsa_op_base * p)207 is_a_helper <hsa_op_immed *>::test (hsa_op_base *p)
208 {
209   return p->m_kind == BRIG_KIND_OPERAND_CONSTANT_BYTES;
210 }
211 
212 /* Likewise, but for a more specified base. */
213 
214 template <>
215 template <>
216 inline bool
test(hsa_op_with_type * p)217 is_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 
223 /* HSA register operand.  */
224 
225 class hsa_op_reg : public hsa_op_with_type
226 {
227   friend class hsa_insn_basic;
228   friend class hsa_insn_phi;
229 public:
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 
258 private:
259   /* Make the default constructor inaccessible.  */
hsa_op_reg()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.  */
delete(void *)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.  */
267   auto_vec <hsa_insn_basic *> m_uses;
268 };
269 
270 /* Report whether or not P is a register operand.  */
271 
272 template <>
273 template <>
274 inline bool
test(hsa_op_base * p)275 is_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 
282 template <>
283 template <>
284 inline bool
test(hsa_op_with_type * p)285 is_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 
292 class hsa_op_address : public hsa_op_base
293 {
294 public:
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 
322 private:
323   /* Make the default constructor inaccessible.  */
hsa_op_address()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.  */
delete(void *)327   void operator delete (void *) {}
328 };
329 
330 /* Report whether or not P is an address operand.  */
331 
332 template <>
333 template <>
334 inline bool
test(hsa_op_base * p)335 is_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 
343 class hsa_op_code_ref : public hsa_op_base
344 {
345 public:
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 
354 template <>
355 template <>
356 inline bool
test(hsa_op_base * p)357 is_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 
364 class hsa_op_code_list: public hsa_op_base
365 {
366 public:
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;
373 private:
374   /* Make the default constructor inaccessible.  */
hsa_op_code_list()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.  */
delete(void *)378   void operator delete (void *) {}
379 };
380 
381 /* Report whether or not P is a code list operand.  */
382 
383 template <>
384 template <>
385 inline bool
test(hsa_op_base * p)386 is_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 
393 class hsa_op_operand_list: public hsa_op_base
394 {
395 public:
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;
403 private:
404   /* Make the default constructor inaccessible.  */
hsa_op_operand_list()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.  */
delete(void *)408   void operator delete (void *) {}
409 };
410 
411 /* Report whether or not P is a code list operand.  */
412 
413 template <>
414 template <>
415 inline bool
test(hsa_op_base * p)416 is_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 
434 class hsa_insn_basic
435 {
436 public:
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 
475 private:
476   /* Make the default constructor inaccessible.  */
hsa_insn_basic()477   hsa_insn_basic () {}
478   /* All objects are deallocated by destroying their pool, so make delete
479      inaccessible too.  */
delete(void *)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 
491 class hsa_insn_phi : public hsa_insn_basic
492 {
493 public:
494   hsa_insn_phi (unsigned nops, hsa_op_reg *dst);
495 
496   /* Destination.  */
497   hsa_op_reg *m_dest;
498 
499 private:
500   /* Make the default constructor inaccessible.  */
hsa_insn_phi()501   hsa_insn_phi () : hsa_insn_basic (1, HSA_OPCODE_PHI) {}
502 };
503 
504 /* Report whether or not P is a PHI node.  */
505 
506 template <>
507 template <>
508 inline bool
test(hsa_insn_basic * p)509 is_a_helper <hsa_insn_phi *>::test (hsa_insn_basic *p)
510 {
511   return p->m_opcode == HSA_OPCODE_PHI;
512 }
513 
514 /* HSA instruction for  */
515 class hsa_insn_br : public hsa_insn_basic
516 {
517 public:
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);
521 
522   /* Number of work-items affected in the same way by the instruction.  */
523   BrigWidth8_t m_width;
524 
525 private:
526   /* Make the default constructor inaccessible.  */
hsa_insn_br()527   hsa_insn_br () : hsa_insn_basic (0, BRIG_OPCODE_BR) {}
528 };
529 
530 /* Return true if P is a branching/synchronization instruction.  */
531 
532 template <>
533 template <>
534 inline bool
test(hsa_insn_basic * p)535 is_a_helper <hsa_insn_br *>::test (hsa_insn_basic *p)
536 {
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 
545 class hsa_insn_cbr : public hsa_insn_br
546 {
547 public:
548   hsa_insn_cbr (hsa_op_reg *ctrl);
549 
550 private:
551   /* Make the default constructor inaccessible.  */
hsa_insn_cbr()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 
558 template <>
559 template <>
560 inline bool
test(hsa_insn_basic * p)561 is_a_helper <hsa_insn_cbr *>::test (hsa_insn_basic *p)
562 {
563   return p->m_opcode == BRIG_OPCODE_CBR;
564 }
565 
566 /* HSA instruction for switch branches.  */
567 
568 class hsa_insn_sbr : public hsa_insn_basic
569 {
570 public:
571   hsa_insn_sbr (hsa_op_reg *index, unsigned jump_count);
572 
573   /* Default destructor.  */
574   ~hsa_insn_sbr ();
575 
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 
584   /* Code list for label references.  */
585   hsa_op_code_list *m_label_code_list;
586 
587 private:
588   /* Make the default constructor inaccessible.  */
hsa_insn_sbr()589   hsa_insn_sbr () : hsa_insn_basic (1, BRIG_OPCODE_SBR) {}
590 };
591 
592 /* Report whether P is a switch branching instruction.  */
593 
594 template <>
595 template <>
596 inline bool
test(hsa_insn_basic * p)597 is_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 
604 class hsa_insn_cmp : public hsa_insn_basic
605 {
606 public:
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 
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.  */
618 private:
619   /* Make the default constructor inaccessible.  */
hsa_insn_cmp()620   hsa_insn_cmp () : hsa_insn_basic (1, BRIG_OPCODE_CMP) {}
621 };
622 
623 /* Report whether or not P is a comparison instruction.  */
624 
625 template <>
626 template <>
627 inline bool
test(hsa_insn_basic * p)628 is_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 
635 class hsa_insn_mem : public hsa_insn_basic
636 {
637 public:
638   hsa_insn_mem (int opc, BrigType16_t t, hsa_op_base *arg0, hsa_op_base *arg1);
639 
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.  */
654 protected:
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 
659 private:
660   /* Make the default constructor inaccessible.  */
hsa_insn_mem()661   hsa_insn_mem () : hsa_insn_basic (1, BRIG_OPCODE_LD) {}
662 };
663 
664 /* Report whether or not P is a memory instruction.  */
665 
666 template <>
667 template <>
668 inline bool
test(hsa_insn_basic * p)669 is_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 
677 class hsa_insn_atomic : public hsa_insn_mem
678 {
679 public:
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);
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 
694 private:
695   /* Make the default constructor inaccessible.  */
hsa_insn_atomic()696   hsa_insn_atomic () : hsa_insn_mem (1, BRIG_KIND_NONE, BRIG_TYPE_NONE) {}
697 };
698 
699 /* Report whether or not P is an atomic instruction.  */
700 
701 template <>
702 template <>
703 inline bool
test(hsa_insn_basic * p)704 is_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 
712 class hsa_insn_signal : public hsa_insn_basic
713 {
714 public:
715   hsa_insn_signal (int nops, int opc, enum BrigAtomicOperation sop,
716 		   BrigType16_t t, BrigMemoryOrder memorder,
717 		   hsa_op_base *arg0 = NULL, hsa_op_base *arg1 = NULL,
718 		   hsa_op_base *arg2 = NULL, hsa_op_base *arg3 = NULL);
719 
720   /* Things like acquire/release/aligned.  */
721   enum BrigMemoryOrder m_memory_order;
722 
723   /* The operation itself.  */
724   enum BrigAtomicOperation m_signalop;
725 };
726 
727 /* Report whether or not P is a signal instruction.  */
728 
729 template <>
730 template <>
731 inline bool
test(hsa_insn_basic * p)732 is_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 
740 class hsa_insn_seg : public hsa_insn_basic
741 {
742 public:
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 
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;
750 private:
751   /* Make the default constructor inaccessible.  */
hsa_insn_seg()752   hsa_insn_seg () : hsa_insn_basic (1, BRIG_OPCODE_STOF) {}
753 };
754 
755 /* Report whether or not P is a segment conversion instruction.  */
756 
757 template <>
758 template <>
759 inline bool
test(hsa_insn_basic * p)760 is_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 
768 class hsa_internal_fn
769 {
770 public:
hsa_internal_fn(enum internal_fn fn,unsigned type_bit_size)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 
hsa_internal_fn(const hsa_internal_fn * f)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 
800 class hsa_insn_call : public hsa_insn_basic
801 {
802 public:
803   hsa_insn_call (tree callee);
804   hsa_insn_call (hsa_internal_fn *fn);
805 
806   /* Default destructor.  */
807   ~hsa_insn_call ();
808 
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;
832 private:
833   /* Make the default constructor inaccessible.  */
hsa_insn_call()834   hsa_insn_call () : hsa_insn_basic (0, BRIG_OPCODE_CALL) {}
835 };
836 
837 /* Report whether or not P is a call instruction.  */
838 
839 template <>
840 template <>
841 inline bool
test(hsa_insn_basic * p)842 is_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 
853 class hsa_insn_arg_block : public hsa_insn_basic
854 {
855 public:
856   hsa_insn_arg_block (BrigKind brig_kind, hsa_insn_call * call);
857 
858   /* Kind of argument block.  */
859   BrigKind m_kind;
860 
861   /* Call instruction.  */
862   hsa_insn_call *m_call_insn;
863 };
864 
865 /* Report whether or not P is a call block instruction.  */
866 
867 template <>
868 template <>
869 inline bool
test(hsa_insn_basic * p)870 is_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 
877 class hsa_insn_comment: public hsa_insn_basic
878 {
879 public:
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 
886   char *m_comment;
887 };
888 
889 /* Report whether or not P is a call block instruction.  */
890 
891 template <>
892 template <>
893 inline bool
test(hsa_insn_basic * p)894 is_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 
901 class hsa_insn_queue: public hsa_insn_basic
902 {
903 public:
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);
908 
909   /* Destructor.  */
910   ~hsa_insn_queue ();
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;
916 };
917 
918 /* Report whether or not P is a queue instruction.  */
919 
920 template <>
921 template <>
922 inline bool
test(hsa_insn_basic * p)923 is_a_helper <hsa_insn_queue *>::test (hsa_insn_basic *p)
924 {
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);
931 }
932 
933 /* HSA source type instruction.  */
934 
935 class hsa_insn_srctype: public hsa_insn_basic
936 {
937 public:
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 
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 
951 template <>
952 template <>
953 inline bool
test(hsa_insn_basic * p)954 is_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 
963 class hsa_insn_packed : public hsa_insn_srctype
964 {
965 public:
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 
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 
979 template <>
980 template <>
981 inline bool
test(hsa_insn_basic * p)982 is_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 
990 class hsa_insn_cvt: public hsa_insn_basic
991 {
992 public:
993   hsa_insn_cvt (hsa_op_with_type *dest, hsa_op_with_type *src);
994 };
995 
996 /* Report whether or not P is a convert instruction.  */
997 
998 template <>
999 template <>
1000 inline bool
test(hsa_insn_basic * p)1001 is_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 
1008 class hsa_insn_alloca: public hsa_insn_basic
1009 {
1010 public:
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;
1016 };
1017 
1018 /* Report whether or not P is an alloca instruction.  */
1019 
1020 template <>
1021 template <>
1022 inline bool
test(hsa_insn_basic * p)1023 is_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 
1030 class hsa_bb
1031 {
1032 public:
1033   hsa_bb (basic_block cfg_bb);
1034   hsa_bb (basic_block cfg_bb, int idx);
1035 
1036   /* Append an instruction INSN into the basic block.  */
1037   void append_insn (hsa_insn_basic *insn);
1038 
1039   /* Add a PHI instruction.  */
1040   void append_phi (hsa_insn_phi *phi);
1041 
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 
1056   auto_bitmap m_liveout, m_livein;
1057 private:
1058   /* Make the default constructor inaccessible.  */
1059   hsa_bb ();
1060   /* All objects are deallocated by destroying their pool, so make delete
1061      inaccessible too.  */
delete(void *)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 
1068 static inline hsa_bb *
hsa_bb_for_bb(basic_block bb)1069 hsa_bb_for_bb (basic_block bb)
1070 {
1071   return (class hsa_bb *) bb->aux;
1072 }
1073 
1074 /* Class for hashing local hsa_symbols.  */
1075 
1076 struct 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 
1084 inline hashval_t
hash(const value_type item)1085 hsa_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 
1092 inline bool
equal(const value_type a,const compare_type b)1093 hsa_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 
1101 class hsa_function_representation
1102 {
1103 public:
1104   hsa_function_representation (tree fdecl, bool kernel_p,
1105 			       unsigned ssa_names_count,
1106 			       bool modified_cfg = false);
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 
1122   /* Update CFG dominators if m_modified_cfg flag is set.  */
1123   void update_dominance ();
1124 
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.  */
1153   vec <class hsa_symbol *> m_spill_symbols;
1154 
1155   /* Vector of pointers to global variables and transformed string constants
1156      that are used by the function.  */
1157   vec <class hsa_symbol *> m_global_symbols;
1158 
1159   /* Private function artificial variables.  */
1160   vec <class hsa_symbol *> m_private_variables;
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.  */
1204   vec <hsa_op_reg *> m_ssa_map;
1205 
1206   /* Flag whether a function needs update of dominators before RA.  */
1207   bool m_modified_cfg;
1208 };
1209 
1210 enum hsa_function_kind
1211 {
1212   HSA_INVALID,
1213   HSA_KERNEL,
1214   HSA_FUNCTION
1215 };
1216 
1217 class hsa_function_summary
1218 {
1219 public:
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.
1227      In case of the function is a HSA function, the bound function points
1228      to the host function.  */
1229   cgraph_node *m_bound_function;
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 
1238 inline
hsa_function_summary()1239 hsa_function_summary::hsa_function_summary (): m_kind (HSA_INVALID),
1240   m_bound_function (NULL), m_gpu_implementation_p (false)
1241 {
1242 }
1243 
1244 /* Function summary for HSA functions.  */
1245 class hsa_summary_t: public function_summary <hsa_function_summary *>
1246 {
1247 public:
hsa_summary_t(symbol_table * table)1248   hsa_summary_t (symbol_table *table):
1249     function_summary<hsa_function_summary *> (table)
1250   {
1251     disable_insertion_hook ();
1252   }
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);
1261 
1262 private:
1263   void process_gpu_implementation_attributes (tree gdecl);
1264 };
1265 
1266 /* OMP simple builtin describes behavior that should be done for
1267    the routine.  */
1268 class omp_simple_builtin
1269 {
1270 public:
1271   omp_simple_builtin (const char *name, const char *warning_message,
1272 	       bool sorry, hsa_op_immed *return_value = NULL):
m_name(name)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 
1298 struct 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 
1306 inline hashval_t
hash(const value_type item)1307 hsa_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 
1314 inline bool
equal(const value_type a,const compare_type b)1315 hsa_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 
1320 /* in hsa-common.c */
1321 extern class hsa_function_representation *hsa_cfun;
1322 extern hash_map <tree, vec <const char *> *> *hsa_decl_kernel_dependencies;
1323 extern hsa_summary_t *hsa_summaries;
1324 extern hsa_symbol *hsa_num_threads;
1325 extern unsigned hsa_kernel_calls_counter;
1326 extern hash_set <tree> *hsa_failed_functions;
1327 extern hash_table <hsa_noop_symbol_hasher> *hsa_global_variable_symbols;
1328 
1329 bool hsa_callable_function_p (tree fndecl);
1330 void hsa_init_compilation_unit_data (void);
1331 void hsa_deinit_compilation_unit_data (void);
1332 bool hsa_machine_large_p (void);
1333 bool hsa_full_profile_p (void);
1334 bool hsa_opcode_floating_bit_insn_p (BrigOpcode16_t);
1335 unsigned hsa_type_bit_size (BrigType16_t t);
1336 BrigType16_t hsa_bittype_for_bitsize (unsigned bitsize);
1337 BrigType16_t hsa_uint_for_bitsize (unsigned bitsize);
1338 BrigType16_t hsa_float_for_bitsize (unsigned bitsize);
1339 BrigType16_t hsa_bittype_for_type (BrigType16_t t);
1340 BrigType16_t hsa_unsigned_type_for_type (BrigType16_t t);
1341 bool hsa_type_packed_p (BrigType16_t type);
1342 bool hsa_type_float_p (BrigType16_t type);
1343 bool hsa_type_integer_p (BrigType16_t type);
1344 bool hsa_btype_p (BrigType16_t type);
1345 BrigAlignment8_t hsa_alignment_encoding (unsigned n);
1346 BrigAlignment8_t hsa_natural_alignment (BrigType16_t type);
1347 BrigAlignment8_t hsa_object_alignment (tree t);
1348 unsigned hsa_byte_alignment (BrigAlignment8_t alignment);
1349 void hsa_destroy_operand (hsa_op_base *op);
1350 void hsa_destroy_insn (hsa_insn_basic *insn);
1351 void hsa_add_kern_decl_mapping (tree decl, char *name, unsigned, bool);
1352 unsigned hsa_get_number_decl_kernel_mappings (void);
1353 tree hsa_get_decl_kernel_mapping_decl (unsigned i);
1354 char *hsa_get_decl_kernel_mapping_name (unsigned i);
1355 unsigned hsa_get_decl_kernel_mapping_omp_size (unsigned i);
1356 bool hsa_get_decl_kernel_mapping_gridified (unsigned i);
1357 void hsa_free_decl_kernel_mapping (void);
1358 tree *hsa_get_ctor_statements (void);
1359 tree *hsa_get_dtor_statements (void);
1360 tree *hsa_get_kernel_dispatch_type (void);
1361 void hsa_add_kernel_dependency (tree caller, const char *called_function);
1362 void hsa_sanitize_name (char *p);
1363 char *hsa_brig_function_name (const char *p);
1364 const char *hsa_get_declaration_name (tree decl);
1365 void hsa_register_kernel (cgraph_node *host);
1366 void hsa_register_kernel (cgraph_node *gpu, cgraph_node *host);
1367 bool hsa_seen_error (void);
1368 void hsa_fail_cfun (void);
1369 
1370 /* In hsa-gen.c.  */
1371 void hsa_build_append_simple_mov (hsa_op_reg *, hsa_op_base *, hsa_bb *);
1372 hsa_symbol *hsa_get_spill_symbol (BrigType16_t);
1373 hsa_symbol *hsa_get_string_cst_symbol (BrigType16_t);
1374 hsa_op_reg *hsa_spill_in (hsa_insn_basic *, hsa_op_reg *, hsa_op_reg **);
1375 hsa_op_reg *hsa_spill_out (hsa_insn_basic *, hsa_op_reg *, hsa_op_reg **);
1376 hsa_bb *hsa_init_new_bb (basic_block);
1377 hsa_function_representation *hsa_generate_function_declaration (tree decl);
1378 hsa_function_representation *hsa_generate_internal_fn_decl (hsa_internal_fn *);
1379 tree hsa_get_host_function (tree decl);
1380 
1381 /* In hsa-regalloc.c.  */
1382 void hsa_regalloc (void);
1383 
1384 /* In hsa-brig.c.  */
1385 extern hash_table <hsa_internal_fn_hasher> *hsa_emitted_internal_decls;
1386 void hsa_brig_emit_function (void);
1387 void hsa_output_brig (void);
1388 unsigned hsa_get_imm_brig_type_len (BrigType16_t type);
1389 void hsa_brig_emit_omp_symbols (void);
1390 
1391 /*  In hsa-dump.c.  */
1392 const char *hsa_seg_name (BrigSegment8_t);
1393 void dump_hsa_insn (FILE *f, hsa_insn_basic *insn);
1394 void dump_hsa_bb (FILE *, hsa_bb *);
1395 void dump_hsa_cfun (FILE *);
1396 DEBUG_FUNCTION void debug_hsa_operand (hsa_op_base *opc);
1397 DEBUG_FUNCTION void debug_hsa_insn (hsa_insn_basic *insn);
1398 
1399 union 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 
1409 static inline bool
hsa_gpu_implementation_p(tree decl)1410 hsa_gpu_implementation_p (tree decl)
1411 {
1412   if (hsa_summaries == NULL)
1413     return false;
1414 
1415   hsa_function_summary *s = hsa_summaries->get (cgraph_node::get_create (decl));
1416   return s != NULL && s->m_gpu_implementation_p;
1417 }
1418 
1419 #endif /* HSA_H */
1420