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