Backport from GCC mainline.
[platform/upstream/linaro-gcc.git] / gcc / hsa.h
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
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.  */
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.  */
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.  */
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
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
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.  */
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.  */
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
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
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.  */
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.  */
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
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
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.  */
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.  */
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
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.  */
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.  */
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
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.  */
474   hsa_insn_basic () {}
475   /* All objects are deallocated by destroying their pool, so make delete
476      inaccessible too.  */
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.  */
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.  */
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
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.  */
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.  */
533   void operator delete (void *) {}
534 };
535
536 /* Report whether P is a branching instruction.  */
537
538 template <>
539 template <>
540 inline bool
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.  */
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.  */
575   void operator delete (void *) {}
576 };
577
578 /* Report whether P is a switch branching instruction.  */
579
580 template <>
581 template <>
582 inline bool
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.  */
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.  */
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
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.  */
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.  */
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
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.  */
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.  */
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
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.  */
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
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.  */
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.  */
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
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:
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
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.  */
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.  */
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
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.  */
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
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
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
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
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
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
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
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.  */
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 *
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
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
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
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:
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):
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
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
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
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 */