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