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