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