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