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