PR driver/69265 and 69453: improved suggestions for various misspelled options
[official-gcc.git] / gcc / hsa.h
blobf0436f3cf69190ecdf5680b869cdbcc5d626f3ee
1 /* HSAIL and BRIG related macros and definitions.
2 Copyright (C) 2013-2016 Free Software Foundation, Inc.
4 This file is part of GCC.
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.
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.
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/>. */
20 #ifndef HSA_H
21 #define HSA_H
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"
32 /* Return true if the compiler should produce HSAIL. */
34 static inline bool
35 hsa_gen_requested_p (void)
37 #ifndef ENABLE_HSA
38 return false;
39 #endif
40 return !flag_disable_hsa;
43 /* Standard warning message if we failed to generate HSAIL for a function. */
45 #define HSA_SORRY_MSG "could not emit HSAIL for the function"
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;
55 /* Class representing an input argument, output argument (result) or a
56 variable, that will eventually end up being a symbol directive. */
58 struct hsa_symbol
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);
65 /* Return total size of the symbol. */
66 unsigned HOST_WIDE_INT total_byte_size ();
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);
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;
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;
81 /* If name is NULL, artificial name will be formed from the segment name and
82 this number. */
83 int m_name_number;
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;
89 /* HSA type of the parameter. */
90 BrigType16_t m_type;
92 /* The HSA segment this will eventually end up in. */
93 BrigSegment8_t m_segment;
95 /* The HSA kind of linkage. */
96 BrigLinkage8_t m_linkage;
98 /* Array dimension, if non-zero. */
99 unsigned HOST_WIDE_INT m_dim;
101 /* Constant value, used for string constants. */
102 hsa_op_immed *m_cst_value;
104 /* Is in global scope. */
105 bool m_global_scope_p;
107 /* True if an error has been seen for the symbol. */
108 bool m_seen_error;
110 /* Symbol allocation. */
111 BrigAllocation m_allocation;
113 private:
114 /* Default constructor. */
115 hsa_symbol ();
118 /* Abstract class for HSA instruction operands. */
120 class hsa_op_base
122 public:
123 /* Next operand scheduled to be written when writing BRIG operand
124 section. */
125 hsa_op_base *m_next;
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;
131 /* The type of a particular operand. */
132 BrigKind16_t m_kind;
134 protected:
135 hsa_op_base (BrigKind16_t k);
136 private:
137 /* Make the default constructor inaccessible. */
138 hsa_op_base () {}
141 /* Common abstract ancestor for operands which have a type. */
143 class hsa_op_with_type : public hsa_op_base
145 public:
146 /* The type. */
147 BrigType16_t m_type;
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);
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) {}
160 /* An immediate HSA operand. */
162 class hsa_op_immed : public hsa_op_with_type
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);
171 /* Value as represented by middle end. */
172 tree m_tree_value;
174 /* Integer value representation. */
175 HOST_WIDE_INT m_int_value;
177 /* Brig data representation. */
178 char *m_brig_repr;
180 /* Brig data representation size in bytes. */
181 unsigned m_brig_repr_size;
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);
192 /* Report whether or not P is a an immediate operand. */
194 template <>
195 template <>
196 inline bool
197 is_a_helper <hsa_op_immed *>::test (hsa_op_base *p)
199 return p->m_kind == BRIG_KIND_OPERAND_CONSTANT_BYTES;
202 /* HSA register operand. */
204 class hsa_op_reg : public hsa_op_with_type
206 friend class hsa_insn_basic;
207 friend class hsa_insn_phi;
208 public:
209 hsa_op_reg (BrigType16_t t);
210 void *operator new (size_t);
212 /* Verify register operand. */
213 void verify_ssa ();
215 /* If NON-NULL, gimple SSA that we come from. NULL if none. */
216 tree m_gimple_ssa;
218 /* Defining instruction while still in the SSA. */
219 hsa_insn_basic *m_def_insn;
221 /* If the register allocator decides to spill the register, this is the
222 appropriate spill symbol. */
223 hsa_symbol *m_spill_sym;
225 /* Number of this register structure in the order in which they were
226 allocated. */
227 int m_order;
228 int m_lr_begin, m_lr_end;
230 /* Zero if the register is not yet allocated. After, allocation, this must
231 be 'c', 's', 'd' or 'q'. */
232 char m_reg_class;
233 /* If allocated, the number of the HW register (within its HSA register
234 class). */
235 char m_hard_num;
237 private:
238 /* Make the default constructor inaccessible. */
239 hsa_op_reg () : hsa_op_with_type (BRIG_KIND_NONE, BRIG_TYPE_NONE) {}
240 /* All objects are deallocated by destroying their pool, so make delete
241 inaccessible too. */
242 void operator delete (void *) {}
243 /* Set definition where the register is defined. */
244 void set_definition (hsa_insn_basic *insn);
245 /* Uses of the value while still in SSA. */
246 auto_vec <hsa_insn_basic_p> m_uses;
249 typedef class hsa_op_reg *hsa_op_reg_p;
251 /* Report whether or not P is a register operand. */
253 template <>
254 template <>
255 inline bool
256 is_a_helper <hsa_op_reg *>::test (hsa_op_base *p)
258 return p->m_kind == BRIG_KIND_OPERAND_REGISTER;
261 /* Report whether or not P is a register operand. */
263 template <>
264 template <>
265 inline bool
266 is_a_helper <hsa_op_reg *>::test (hsa_op_with_type *p)
268 return p->m_kind == BRIG_KIND_OPERAND_REGISTER;
271 /* An address HSA operand. */
273 class hsa_op_address : public hsa_op_base
275 public:
276 /* set up a new address operand consisting of base symbol SYM, register R and
277 immediate OFFSET. If the machine model is not large and offset is 64 bit,
278 the upper, 32 bits have to be zero. */
279 hsa_op_address (hsa_symbol *sym, hsa_op_reg *reg,
280 HOST_WIDE_INT offset = 0);
282 void *operator new (size_t);
284 /* Set up a new address operand consisting of base symbol SYM and
285 immediate OFFSET. If the machine model is not large and offset is 64 bit,
286 the upper, 32 bits have to be zero. */
287 hsa_op_address (hsa_symbol *sym, HOST_WIDE_INT offset = 0);
289 /* Set up a new address operand consisting of register R and
290 immediate OFFSET. If the machine model is not large and offset is 64 bit,
291 the upper, 32 bits have to be zero. */
292 hsa_op_address (hsa_op_reg *reg, HOST_WIDE_INT offset = 0);
294 /* Symbol base of the address. Can be NULL if there is none. */
295 hsa_symbol *m_symbol;
297 /* Register offset. Can be NULL if there is none. */
298 hsa_op_reg *m_reg;
300 /* Immediate byte offset. */
301 HOST_WIDE_INT m_imm_offset;
303 private:
304 /* Make the default constructor inaccessible. */
305 hsa_op_address () : hsa_op_base (BRIG_KIND_NONE) {}
306 /* All objects are deallocated by destroying their pool, so make delete
307 inaccessible too. */
308 void operator delete (void *) {}
311 /* Report whether or not P is an address operand. */
313 template <>
314 template <>
315 inline bool
316 is_a_helper <hsa_op_address *>::test (hsa_op_base *p)
318 return p->m_kind == BRIG_KIND_OPERAND_ADDRESS;
321 /* A reference to code HSA operand. It can be either reference
322 to a start of a BB or a start of a function. */
324 class hsa_op_code_ref : public hsa_op_base
326 public:
327 hsa_op_code_ref ();
329 /* Offset in the code section that this refers to. */
330 unsigned m_directive_offset;
333 /* Report whether or not P is a code reference operand. */
335 template <>
336 template <>
337 inline bool
338 is_a_helper <hsa_op_code_ref *>::test (hsa_op_base *p)
340 return p->m_kind == BRIG_KIND_OPERAND_CODE_REF;
343 /* Code list HSA operand. */
345 class hsa_op_code_list: public hsa_op_base
347 public:
348 hsa_op_code_list (unsigned elements);
349 void *operator new (size_t);
351 /* Offset to variable-sized array in hsa_data section, where
352 are offsets to entries in the hsa_code section. */
353 auto_vec<unsigned> m_offsets;
354 private:
355 /* Make the default constructor inaccessible. */
356 hsa_op_code_list () : hsa_op_base (BRIG_KIND_NONE) {}
357 /* All objects are deallocated by destroying their pool, so make delete
358 inaccessible too. */
359 void operator delete (void *) {}
362 /* Report whether or not P is a code list operand. */
364 template <>
365 template <>
366 inline bool
367 is_a_helper <hsa_op_code_list *>::test (hsa_op_base *p)
369 return p->m_kind == BRIG_KIND_OPERAND_CODE_LIST;
372 /* Operand list HSA operand. */
374 class hsa_op_operand_list: public hsa_op_base
376 public:
377 hsa_op_operand_list (unsigned elements);
378 ~hsa_op_operand_list ();
379 void *operator new (size_t);
381 /* Offset to variable-sized array in hsa_data section, where
382 are offsets to entries in the hsa_code section. */
383 auto_vec<unsigned> m_offsets;
384 private:
385 /* Make the default constructor inaccessible. */
386 hsa_op_operand_list () : hsa_op_base (BRIG_KIND_NONE) {}
387 /* All objects are deallocated by destroying their pool, so make delete
388 inaccessible too. */
389 void operator delete (void *) {}
392 /* Report whether or not P is a code list operand. */
394 template <>
395 template <>
396 inline bool
397 is_a_helper <hsa_op_operand_list *>::test (hsa_op_base *p)
399 return p->m_kind == BRIG_KIND_OPERAND_OPERAND_LIST;
402 /* Opcodes of instructions that are not part of HSA but that we use to
403 represent it nevertheless. */
405 #define HSA_OPCODE_PHI (-1)
406 #define HSA_OPCODE_ARG_BLOCK (-2)
408 /* The number of operand pointers we can directly in an instruction. */
409 #define HSA_BRIG_INT_STORAGE_OPERANDS 5
411 /* Class representing an HSA instruction. Unlike typical ancestors for
412 specialized classes, this one is also directly used for all instructions
413 that are then represented as BrigInstBasic. */
415 class hsa_insn_basic
417 public:
418 hsa_insn_basic (unsigned nops, int opc);
419 hsa_insn_basic (unsigned nops, int opc, BrigType16_t t,
420 hsa_op_base *arg0 = NULL,
421 hsa_op_base *arg1 = NULL,
422 hsa_op_base *arg2 = NULL,
423 hsa_op_base *arg3 = NULL);
425 void *operator new (size_t);
426 void set_op (int index, hsa_op_base *op);
427 hsa_op_base *get_op (int index);
428 hsa_op_base **get_op_addr (int index);
429 unsigned int operand_count ();
430 void verify ();
431 unsigned input_count ();
432 unsigned num_used_ops ();
433 void set_output_in_type (hsa_op_reg *dest, unsigned op_index, hsa_bb *hbb);
434 bool op_output_p (unsigned opnum);
436 /* The previous and next instruction in the basic block. */
437 hsa_insn_basic *m_prev, *m_next;
439 /* Basic block this instruction belongs to. */
440 basic_block m_bb;
442 /* Operand code distinguishing different types of instructions. Eventually
443 these should only be BRIG_INST_* values from the BrigOpcode16_t range but
444 initially we use negative values for PHI nodes and such. */
445 int m_opcode;
447 /* Linearized number assigned to the instruction by HSA RA. */
448 int m_number;
450 /* Type of the destination of the operations. */
451 BrigType16_t m_type;
453 /* BRIG offset of the instruction in code section. */
454 unsigned int m_brig_offset;
456 private:
457 /* Make the default constructor inaccessible. */
458 hsa_insn_basic () {}
459 /* All objects are deallocated by destroying their pool, so make delete
460 inaccessible too. */
461 void operator delete (void *) {}
462 /* The individual operands. All instructions but PHI nodes have five or
463 fewer instructions and so will fit the internal storage. */
464 /* TODO: Vast majority of instructions have three or fewer operands, so we
465 may actually try reducing it. */
466 auto_vec<hsa_op_base *, HSA_BRIG_INT_STORAGE_OPERANDS> m_operands;
469 /* Class representing a PHI node of the SSA form of HSA virtual
470 registers. */
472 class hsa_insn_phi : public hsa_insn_basic
474 public:
475 hsa_insn_phi (unsigned nops, hsa_op_reg *dst);
477 void *operator new (size_t);
479 /* Destination. */
480 hsa_op_reg *m_dest;
482 private:
483 /* Make the default constructor inaccessible. */
484 hsa_insn_phi () : hsa_insn_basic (1, HSA_OPCODE_PHI) {}
485 /* All objects are deallocated by destroying their pool, so make delete
486 inaccessible too. */
487 void operator delete (void *) {}
490 /* Report whether or not P is a PHI node. */
492 template <>
493 template <>
494 inline bool
495 is_a_helper <hsa_insn_phi *>::test (hsa_insn_basic *p)
497 return p->m_opcode == HSA_OPCODE_PHI;
500 /* HSA instruction for branches. Currently we explicitely represent only
501 conditional branches. */
503 class hsa_insn_br : public hsa_insn_basic
505 public:
506 hsa_insn_br (hsa_op_reg *ctrl);
508 void *operator new (size_t);
510 /* Width as described in HSA documentation. */
511 BrigWidth8_t m_width;
512 private:
513 /* Make the default constructor inaccessible. */
514 hsa_insn_br () : hsa_insn_basic (1, BRIG_OPCODE_CBR) {}
515 /* All objects are deallocated by destroying their pool, so make delete
516 inaccessible too. */
517 void operator delete (void *) {}
520 /* Report whether P is a branching instruction. */
522 template <>
523 template <>
524 inline bool
525 is_a_helper <hsa_insn_br *>::test (hsa_insn_basic *p)
527 return p->m_opcode == BRIG_OPCODE_BR
528 || p->m_opcode == BRIG_OPCODE_CBR;
531 /* HSA instruction for switch branches. */
533 class hsa_insn_sbr : public hsa_insn_basic
535 public:
536 hsa_insn_sbr (hsa_op_reg *index, unsigned jump_count);
538 /* Default destructor. */
539 ~hsa_insn_sbr ();
541 void *operator new (size_t);
543 void replace_all_labels (basic_block old_bb, basic_block new_bb);
545 /* Width as described in HSA documentation. */
546 BrigWidth8_t m_width;
548 /* Jump table. */
549 vec <basic_block> m_jump_table;
551 /* Default label basic block. */
552 basic_block m_default_bb;
554 /* Code list for label references. */
555 hsa_op_code_list *m_label_code_list;
557 private:
558 /* Make the default constructor inaccessible. */
559 hsa_insn_sbr () : hsa_insn_basic (1, BRIG_OPCODE_SBR) {}
560 /* All objects are deallocated by destroying their pool, so make delete
561 inaccessible too. */
562 void operator delete (void *) {}
565 /* Report whether P is a switch branching instruction. */
567 template <>
568 template <>
569 inline bool
570 is_a_helper <hsa_insn_sbr *>::test (hsa_insn_basic *p)
572 return p->m_opcode == BRIG_OPCODE_SBR;
575 /* HSA instruction for comparisons. */
577 class hsa_insn_cmp : public hsa_insn_basic
579 public:
580 hsa_insn_cmp (BrigCompareOperation8_t cmp, BrigType16_t t,
581 hsa_op_base *arg0 = NULL, hsa_op_base *arg1 = NULL,
582 hsa_op_base *arg2 = NULL);
584 void *operator new (size_t);
586 /* Source type should be derived from operand types. */
588 /* The comparison operation. */
589 BrigCompareOperation8_t m_compare;
591 /* TODO: Modifiers and packing control are missing but so are everywhere
592 else. */
593 private:
594 /* Make the default constructor inaccessible. */
595 hsa_insn_cmp () : hsa_insn_basic (1, BRIG_OPCODE_CMP) {}
596 /* All objects are deallocated by destroying their pool, so make delete
597 inaccessible too. */
598 void operator delete (void *) {}
601 /* Report whether or not P is a comparison instruction. */
603 template <>
604 template <>
605 inline bool
606 is_a_helper <hsa_insn_cmp *>::test (hsa_insn_basic *p)
608 return p->m_opcode == BRIG_OPCODE_CMP;
611 /* HSA instruction for memory operations. */
613 class hsa_insn_mem : public hsa_insn_basic
615 public:
616 hsa_insn_mem (int opc, BrigType16_t t, hsa_op_base *arg0, hsa_op_base *arg1);
618 void *operator new (size_t);
620 /* Set alignment to VALUE. */
622 void set_align (BrigAlignment8_t value);
624 /* The segment is of the memory access is either the segment of the symbol in
625 the address operand or flat address is there is no symbol there. */
627 /* Required alignment of the memory operation. */
628 BrigAlignment8_t m_align;
630 /* HSA equiv class, basically an alias set number. */
631 uint8_t m_equiv_class;
633 /* TODO: Add width modifier, perhaps also other things. */
634 protected:
635 hsa_insn_mem (unsigned nops, int opc, BrigType16_t t,
636 hsa_op_base *arg0 = NULL, hsa_op_base *arg1 = NULL,
637 hsa_op_base *arg2 = NULL, hsa_op_base *arg3 = NULL);
639 private:
640 /* Make the default constructor inaccessible. */
641 hsa_insn_mem () : hsa_insn_basic (1, BRIG_OPCODE_LD) {}
642 /* All objects are deallocated by destroying their pool, so make delete
643 inaccessible too. */
644 void operator delete (void *) {}
647 /* Report whether or not P is a memory instruction. */
649 template <>
650 template <>
651 inline bool
652 is_a_helper <hsa_insn_mem *>::test (hsa_insn_basic *p)
654 return (p->m_opcode == BRIG_OPCODE_LD
655 || p->m_opcode == BRIG_OPCODE_ST);
658 /* HSA instruction for atomic operations. */
660 class hsa_insn_atomic : public hsa_insn_mem
662 public:
663 hsa_insn_atomic (int nops, int opc, enum BrigAtomicOperation aop,
664 BrigType16_t t, BrigMemoryOrder memorder,
665 hsa_op_base *arg0 = NULL, hsa_op_base *arg1 = NULL,
666 hsa_op_base *arg2 = NULL, hsa_op_base *arg3 = NULL);
667 void *operator new (size_t);
669 /* The operation itself. */
670 enum BrigAtomicOperation m_atomicop;
672 /* Things like acquire/release/aligned. */
673 enum BrigMemoryOrder m_memoryorder;
675 /* Scope of the atomic operation. */
676 enum BrigMemoryScope m_memoryscope;
678 private:
679 /* Make the default constructor inaccessible. */
680 hsa_insn_atomic () : hsa_insn_mem (1, BRIG_KIND_NONE, BRIG_TYPE_NONE) {}
681 /* All objects are deallocated by destroying their pool, so make delete
682 inaccessible too. */
683 void operator delete (void *) {}
686 /* Report whether or not P is an atomic instruction. */
688 template <>
689 template <>
690 inline bool
691 is_a_helper <hsa_insn_atomic *>::test (hsa_insn_basic *p)
693 return (p->m_opcode == BRIG_OPCODE_ATOMIC
694 || p->m_opcode == BRIG_OPCODE_ATOMICNORET);
697 /* HSA instruction for signal operations. */
699 class hsa_insn_signal : public hsa_insn_atomic
701 public:
702 hsa_insn_signal (int nops, int opc, enum BrigAtomicOperation sop,
703 BrigType16_t t, hsa_op_base *arg0 = NULL,
704 hsa_op_base *arg1 = NULL,
705 hsa_op_base *arg2 = NULL, hsa_op_base *arg3 = NULL);
707 void *operator new (size_t);
709 private:
710 /* All objects are deallocated by destroying their pool, so make delete
711 inaccessible too. */
712 void operator delete (void *) {}
715 /* Report whether or not P is a signal instruction. */
717 template <>
718 template <>
719 inline bool
720 is_a_helper <hsa_insn_signal *>::test (hsa_insn_basic *p)
722 return (p->m_opcode == BRIG_OPCODE_SIGNAL
723 || p->m_opcode == BRIG_OPCODE_SIGNALNORET);
726 /* HSA instruction to convert between flat addressing and segments. */
728 class hsa_insn_seg : public hsa_insn_basic
730 public:
731 hsa_insn_seg (int opc, BrigType16_t destt, BrigType16_t srct,
732 BrigSegment8_t seg, hsa_op_base *arg0, hsa_op_base *arg1);
734 void *operator new (size_t);
736 /* Source type. Depends on the source addressing/segment. */
737 BrigType16_t m_src_type;
738 /* The segment we are converting from or to. */
739 BrigSegment8_t m_segment;
740 private:
741 /* Make the default constructor inaccessible. */
742 hsa_insn_seg () : hsa_insn_basic (1, BRIG_OPCODE_STOF) {}
743 /* All objects are deallocated by destroying their pool, so make delete
744 inaccessible too. */
745 void operator delete (void *) {}
748 /* Report whether or not P is a segment conversion instruction. */
750 template <>
751 template <>
752 inline bool
753 is_a_helper <hsa_insn_seg *>::test (hsa_insn_basic *p)
755 return (p->m_opcode == BRIG_OPCODE_STOF
756 || p->m_opcode == BRIG_OPCODE_FTOS);
759 /* Class for internal functions for purpose of HSA emission. */
761 class hsa_internal_fn
763 public:
764 hsa_internal_fn (enum internal_fn fn, unsigned type_bit_size):
765 m_fn (fn), m_type_bit_size (type_bit_size), m_offset (0) {}
767 hsa_internal_fn (const hsa_internal_fn *f):
768 m_fn (f->m_fn), m_type_bit_size (f->m_type_bit_size),
769 m_offset (f->m_offset) {}
771 /* Return arity of the internal function. */
772 unsigned get_arity ();
774 /* Return BRIG type of N-th argument, if -1 is passed, return value type
775 is received. */
776 BrigType16_t get_argument_type (int n);
778 /* Return function name. The memory must be released by a caller. */
779 char *name ();
781 /* Internal function. */
782 enum internal_fn m_fn;
784 /* Bit width of return type. */
785 unsigned m_type_bit_size;
787 /* BRIG offset of declaration of the function. */
788 BrigCodeOffset32_t m_offset;
791 /* HSA instruction for function call. */
793 class hsa_insn_call : public hsa_insn_basic
795 public:
796 hsa_insn_call (tree callee);
797 hsa_insn_call (hsa_internal_fn *fn);
799 /* Default destructor. */
800 ~hsa_insn_call ();
802 void *operator new (size_t);
804 /* Called function. */
805 tree m_called_function;
807 /* Called internal function. */
808 hsa_internal_fn *m_called_internal_fn;
810 /* Input formal arguments. */
811 auto_vec <hsa_symbol *> m_input_args;
813 /* Input arguments store instructions. */
814 auto_vec <hsa_insn_mem *> m_input_arg_insns;
816 /* Output argument, can be NULL for void functions. */
817 hsa_symbol *m_output_arg;
819 /* Called function code reference. */
820 hsa_op_code_ref m_func;
822 /* Code list for arguments of the function. */
823 hsa_op_code_list *m_args_code_list;
825 /* Code list for result of the function. */
826 hsa_op_code_list *m_result_code_list;
827 private:
828 /* Make the default constructor inaccessible. */
829 hsa_insn_call () : hsa_insn_basic (0, BRIG_OPCODE_CALL) {}
830 /* All objects are deallocated by destroying their pool, so make delete
831 inaccessible too. */
832 void operator delete (void *) {}
835 /* Report whether or not P is a call instruction. */
837 template <>
838 template <>
839 inline bool
840 is_a_helper <hsa_insn_call *>::test (hsa_insn_basic *p)
842 return (p->m_opcode == BRIG_OPCODE_CALL);
845 /* HSA call instruction block encapsulates definition of arguments,
846 result type, corresponding loads and a possible store.
847 Moreover, it contains a single call instruction.
848 Emission of the instruction will produce multiple
849 HSAIL instructions. */
851 class hsa_insn_arg_block : public hsa_insn_basic
853 public:
854 hsa_insn_arg_block (BrigKind brig_kind, hsa_insn_call * call);
856 void *operator new (size_t);
858 /* Kind of argument block. */
859 BrigKind m_kind;
861 /* Call instruction. */
862 hsa_insn_call *m_call_insn;
863 private:
864 /* All objects are deallocated by destroying their pool, so make delete
865 inaccessible too. */
866 void operator delete (void *) {}
869 /* Report whether or not P is a call block instruction. */
871 template <>
872 template <>
873 inline bool
874 is_a_helper <hsa_insn_arg_block *>::test (hsa_insn_basic *p)
876 return (p->m_opcode == HSA_OPCODE_ARG_BLOCK);
879 /* HSA comment instruction. */
881 class hsa_insn_comment: public hsa_insn_basic
883 public:
884 /* Constructor of class representing the comment in HSAIL. */
885 hsa_insn_comment (const char *s);
887 /* Default destructor. */
888 ~hsa_insn_comment ();
890 void *operator new (size_t);
892 char *m_comment;
895 /* Report whether or not P is a call block instruction. */
897 template <>
898 template <>
899 inline bool
900 is_a_helper <hsa_insn_comment *>::test (hsa_insn_basic *p)
902 return (p->m_opcode == BRIG_KIND_DIRECTIVE_COMMENT);
905 /* HSA queue instruction. */
907 class hsa_insn_queue: public hsa_insn_basic
909 public:
910 hsa_insn_queue (int nops, BrigOpcode opcode);
912 /* Destructor. */
913 ~hsa_insn_queue ();
916 /* Report whether or not P is a queue instruction. */
918 template <>
919 template <>
920 inline bool
921 is_a_helper <hsa_insn_queue *>::test (hsa_insn_basic *p)
923 return (p->m_opcode == BRIG_OPCODE_ADDQUEUEWRITEINDEX);
926 /* HSA source type instruction. */
928 class hsa_insn_srctype: public hsa_insn_basic
930 public:
931 hsa_insn_srctype (int nops, BrigOpcode opcode, BrigType16_t destt,
932 BrigType16_t srct, hsa_op_base *arg0, hsa_op_base *arg1,
933 hsa_op_base *arg2);
935 /* Pool allocator. */
936 void *operator new (size_t);
938 /* Source type. */
939 BrigType16_t m_source_type;
941 /* Destructor. */
942 ~hsa_insn_srctype ();
945 /* Report whether or not P is a source type instruction. */
947 template <>
948 template <>
949 inline bool
950 is_a_helper <hsa_insn_srctype *>::test (hsa_insn_basic *p)
952 return (p->m_opcode == BRIG_OPCODE_POPCOUNT
953 || p->m_opcode == BRIG_OPCODE_FIRSTBIT
954 || p->m_opcode == BRIG_OPCODE_LASTBIT);
957 /* HSA packed instruction. */
959 class hsa_insn_packed : public hsa_insn_srctype
961 public:
962 hsa_insn_packed (int nops, BrigOpcode opcode, BrigType16_t destt,
963 BrigType16_t srct, hsa_op_base *arg0, hsa_op_base *arg1,
964 hsa_op_base *arg2);
966 /* Pool allocator. */
967 void *operator new (size_t);
969 /* Operand list for an operand of the instruction. */
970 hsa_op_operand_list *m_operand_list;
972 /* Destructor. */
973 ~hsa_insn_packed ();
976 /* Report whether or not P is a combine instruction. */
978 template <>
979 template <>
980 inline bool
981 is_a_helper <hsa_insn_packed *>::test (hsa_insn_basic *p)
983 return (p->m_opcode == BRIG_OPCODE_COMBINE
984 || p->m_opcode == BRIG_OPCODE_EXPAND);
987 /* HSA convert instruction. */
989 class hsa_insn_cvt: public hsa_insn_basic
991 public:
992 hsa_insn_cvt (hsa_op_with_type *dest, hsa_op_with_type *src);
994 /* Pool allocator. */
995 void *operator new (size_t);
998 /* Report whether or not P is a convert instruction. */
1000 template <>
1001 template <>
1002 inline bool
1003 is_a_helper <hsa_insn_cvt *>::test (hsa_insn_basic *p)
1005 return (p->m_opcode == BRIG_OPCODE_CVT);
1008 /* HSA alloca instruction. */
1010 class hsa_insn_alloca: public hsa_insn_basic
1012 public:
1013 hsa_insn_alloca (hsa_op_with_type *dest, hsa_op_with_type *size,
1014 unsigned alignment = 0);
1016 /* Required alignment of the allocation. */
1017 BrigAlignment8_t m_align;
1019 /* Pool allocator. */
1020 void *operator new (size_t);
1023 /* Report whether or not P is an alloca instruction. */
1025 template <>
1026 template <>
1027 inline bool
1028 is_a_helper <hsa_insn_alloca *>::test (hsa_insn_basic *p)
1030 return (p->m_opcode == BRIG_OPCODE_ALLOCA);
1033 /* Basic block of HSA instructions. */
1035 class hsa_bb
1037 public:
1038 hsa_bb (basic_block cfg_bb);
1039 hsa_bb (basic_block cfg_bb, int idx);
1040 ~hsa_bb ();
1042 /* Append an instruction INSN into the basic block. */
1043 void append_insn (hsa_insn_basic *insn);
1045 /* The real CFG BB that this HBB belongs to. */
1046 basic_block m_bb;
1048 /* The operand that refers to the label to this BB. */
1049 hsa_op_code_ref m_label_ref;
1051 /* The first and last instruction. */
1052 hsa_insn_basic *m_first_insn, *m_last_insn;
1053 /* The first and last phi node. */
1054 hsa_insn_phi *m_first_phi, *m_last_phi;
1056 /* Just a number to construct names from. */
1057 int m_index;
1059 bitmap m_liveout, m_livein;
1060 private:
1061 /* Make the default constructor inaccessible. */
1062 hsa_bb ();
1063 /* All objects are deallocated by destroying their pool, so make delete
1064 inaccessible too. */
1065 void operator delete (void *) {}
1068 /* Return the corresponding HSA basic block structure for the given control
1069 flow basic_block BB. */
1071 static inline hsa_bb *
1072 hsa_bb_for_bb (basic_block bb)
1074 return (struct hsa_bb *) bb->aux;
1077 /* Class for hashing local hsa_symbols. */
1079 struct hsa_noop_symbol_hasher : nofree_ptr_hash <hsa_symbol>
1081 static inline hashval_t hash (const value_type);
1082 static inline bool equal (const value_type, const compare_type);
1085 /* Hash hsa_symbol. */
1087 inline hashval_t
1088 hsa_noop_symbol_hasher::hash (const value_type item)
1090 return DECL_UID (item->m_decl);
1093 /* Return true if the DECL_UIDs of decls both symbols refer to are equal. */
1095 inline bool
1096 hsa_noop_symbol_hasher::equal (const value_type a, const compare_type b)
1098 return (DECL_UID (a->m_decl) == DECL_UID (b->m_decl));
1101 /* Structure that encapsulates intermediate representation of a HSA
1102 function. */
1104 class hsa_function_representation
1106 public:
1107 hsa_function_representation (tree fdecl, bool kernel_p,
1108 unsigned ssa_names_count);
1109 hsa_function_representation (hsa_internal_fn *fn);
1110 ~hsa_function_representation ();
1112 /* Builds a shadow register that is utilized to a kernel dispatch. */
1113 hsa_op_reg *get_shadow_reg ();
1115 /* Return true if we are in a function that has kernel dispatch
1116 shadow register. */
1117 bool has_shadow_reg_p ();
1119 /* The entry/exit blocks don't contain incoming code,
1120 but the HSA generator might use them to put code into,
1121 so we need hsa_bb instances of them. */
1122 void init_extra_bbs ();
1124 /* Return linkage of the representation. */
1125 BrigLinkage8_t get_linkage ();
1127 /* Create a private symbol of requested TYPE. */
1128 hsa_symbol *create_hsa_temporary (BrigType16_t type);
1130 /* Lookup or create a HSA pseudo register for a given gimple SSA name. */
1131 hsa_op_reg *reg_for_gimple_ssa (tree ssa);
1133 /* Name of the function. */
1134 char *m_name;
1136 /* Number of allocated register structures. */
1137 int m_reg_count;
1139 /* Input arguments. */
1140 vec <hsa_symbol *> m_input_args;
1142 /* Output argument or NULL if there is none. */
1143 hsa_symbol *m_output_arg;
1145 /* Hash table of local variable symbols. */
1146 hash_table <hsa_noop_symbol_hasher> *m_local_symbols;
1148 /* Hash map for string constants. */
1149 hash_map <tree, hsa_symbol *> m_string_constants_map;
1151 /* Vector of pointers to spill symbols. */
1152 vec <struct hsa_symbol *> m_spill_symbols;
1154 /* Vector of pointers to global variables and transformed string constants
1155 that are used by the function. */
1156 vec <struct hsa_symbol *> m_global_symbols;
1158 /* Private function artificial variables. */
1159 vec <struct hsa_symbol *> m_private_variables;
1161 /* Vector of called function declarations. */
1162 vec <tree> m_called_functions;
1164 /* Vector of used internal functions. */
1165 vec <hsa_internal_fn *> m_called_internal_fns;
1167 /* Number of HBB BBs. */
1168 int m_hbb_count;
1170 /* Whether or not we could check and enforce SSA properties. */
1171 bool m_in_ssa;
1173 /* True if the function is kernel function. */
1174 bool m_kern_p;
1176 /* True if the function representation is a declaration. */
1177 bool m_declaration_p;
1179 /* Function declaration tree. */
1180 tree m_decl;
1182 /* Internal function info is used for declarations of internal functions. */
1183 hsa_internal_fn *m_internal_fn;
1185 /* Runtime shadow register. */
1186 hsa_op_reg *m_shadow_reg;
1188 /* Number of kernel dispatched which take place in the function. */
1189 unsigned m_kernel_dispatch_count;
1191 /* If the function representation contains a kernel dispatch,
1192 OMP data size is necessary memory that is used for copying before
1193 a kernel dispatch. */
1194 unsigned m_maximum_omp_data_size;
1196 /* Return true if there's an HSA-specific warning already seen. */
1197 bool m_seen_error;
1199 /* Counter for temporary symbols created in the function representation. */
1200 unsigned m_temp_symbol_count;
1202 /* SSA names mapping. */
1203 vec <hsa_op_reg_p> m_ssa_map;
1206 enum hsa_function_kind
1208 HSA_NONE,
1209 HSA_KERNEL,
1210 HSA_FUNCTION
1213 struct hsa_function_summary
1215 /* Default constructor. */
1216 hsa_function_summary ();
1218 /* Kind of GPU/host function. */
1219 hsa_function_kind m_kind;
1221 /* Pointer to a cgraph node which is a HSA implementation of the function.
1222 In case of the function is a HSA function, the binded function points
1223 to the host function. */
1224 cgraph_node *m_binded_function;
1226 /* Identifies if the function is an HSA function or a host function. */
1227 bool m_gpu_implementation_p;
1229 /* True if the function is a gridified kernel. */
1230 bool m_gridified_kernel_p;
1233 inline
1234 hsa_function_summary::hsa_function_summary (): m_kind (HSA_NONE),
1235 m_binded_function (NULL), m_gpu_implementation_p (false)
1239 /* Function summary for HSA functions. */
1240 class hsa_summary_t: public function_summary <hsa_function_summary *>
1242 public:
1243 hsa_summary_t (symbol_table *table):
1244 function_summary<hsa_function_summary *> (table) { }
1246 /* Couple GPU and HOST as gpu-specific and host-specific implementation of
1247 the same function. KIND determines whether GPU is a host-invokable kernel
1248 or gpu-callable function and GRIDIFIED_KERNEL_P is set if the function was
1249 gridified in OMP. */
1251 void link_functions (cgraph_node *gpu, cgraph_node *host,
1252 hsa_function_kind kind, bool gridified_kernel_p);
1255 /* OMP simple builtin describes behavior that should be done for
1256 the routine. */
1257 class omp_simple_builtin
1259 public:
1260 omp_simple_builtin (const char *name, const char *warning_message,
1261 bool sorry, hsa_op_immed *return_value = NULL):
1262 m_name (name), m_warning_message (warning_message), m_sorry (sorry),
1263 m_return_value (return_value)
1266 /* Generate HSAIL instructions for the builtin or produce warning message. */
1267 void generate (gimple *stmt, hsa_bb *hbb);
1269 /* Name of function. */
1270 const char *m_name;
1272 /* Warning message. */
1273 const char *m_warning_message;
1275 /* Flag if we should sorry after the warning message is printed. */
1276 bool m_sorry;
1278 /* Return value of the function. */
1279 hsa_op_immed *m_return_value;
1281 /* Emission function. */
1282 void (*m_emit_func) (gimple *stmt, hsa_bb *);
1285 /* Class for hashing hsa_internal_fn. */
1287 struct hsa_internal_fn_hasher: free_ptr_hash <hsa_internal_fn>
1289 static inline hashval_t hash (const value_type);
1290 static inline bool equal (const value_type, const compare_type);
1293 /* Hash hsa_symbol. */
1295 inline hashval_t
1296 hsa_internal_fn_hasher::hash (const value_type item)
1298 return item->m_fn;
1301 /* Return true if the DECL_UIDs of decls both symbols refer to are equal. */
1303 inline bool
1304 hsa_internal_fn_hasher::equal (const value_type a, const compare_type b)
1306 return a->m_fn == b->m_fn && a->m_type_bit_size == b->m_type_bit_size;
1309 /* in hsa.c */
1310 extern struct hsa_function_representation *hsa_cfun;
1311 extern hash_map <tree, vec <const char *> *> *hsa_decl_kernel_dependencies;
1312 extern hsa_summary_t *hsa_summaries;
1313 extern hsa_symbol *hsa_num_threads;
1314 extern unsigned hsa_kernel_calls_counter;
1315 extern hash_set <tree> *hsa_failed_functions;
1316 extern hash_table <hsa_noop_symbol_hasher> *hsa_global_variable_symbols;
1318 bool hsa_callable_function_p (tree fndecl);
1319 void hsa_init_compilation_unit_data (void);
1320 void hsa_deinit_compilation_unit_data (void);
1321 bool hsa_machine_large_p (void);
1322 bool hsa_full_profile_p (void);
1323 bool hsa_opcode_floating_bit_insn_p (BrigOpcode16_t);
1324 unsigned hsa_type_bit_size (BrigType16_t t);
1325 BrigType16_t hsa_bittype_for_bitsize (unsigned bitsize);
1326 BrigType16_t hsa_uint_for_bitsize (unsigned bitsize);
1327 BrigType16_t hsa_float_for_bitsize (unsigned bitsize);
1328 BrigType16_t hsa_bittype_for_type (BrigType16_t t);
1329 bool hsa_type_float_p (BrigType16_t type);
1330 bool hsa_type_integer_p (BrigType16_t type);
1331 bool hsa_btype_p (BrigType16_t type);
1332 BrigAlignment8_t hsa_alignment_encoding (unsigned n);
1333 BrigAlignment8_t hsa_natural_alignment (BrigType16_t type);
1334 void hsa_destroy_operand (hsa_op_base *op);
1335 void hsa_destroy_insn (hsa_insn_basic *insn);
1336 void hsa_add_kern_decl_mapping (tree decl, char *name, unsigned, bool);
1337 unsigned hsa_get_number_decl_kernel_mappings (void);
1338 tree hsa_get_decl_kernel_mapping_decl (unsigned i);
1339 char *hsa_get_decl_kernel_mapping_name (unsigned i);
1340 unsigned hsa_get_decl_kernel_mapping_omp_size (unsigned i);
1341 bool hsa_get_decl_kernel_mapping_gridified (unsigned i);
1342 void hsa_free_decl_kernel_mapping (void);
1343 void hsa_add_kernel_dependency (tree caller, const char *called_function);
1344 void hsa_sanitize_name (char *p);
1345 char *hsa_brig_function_name (const char *p);
1346 const char *hsa_get_declaration_name (tree decl);
1347 void hsa_register_kernel (cgraph_node *host);
1348 void hsa_register_kernel (cgraph_node *gpu, cgraph_node *host);
1349 bool hsa_seen_error (void);
1350 void hsa_fail_cfun (void);
1352 /* In hsa-gen.c. */
1353 void hsa_build_append_simple_mov (hsa_op_reg *, hsa_op_base *, hsa_bb *);
1354 hsa_symbol *hsa_get_spill_symbol (BrigType16_t);
1355 hsa_symbol *hsa_get_string_cst_symbol (BrigType16_t);
1356 hsa_op_reg *hsa_spill_in (hsa_insn_basic *, hsa_op_reg *, hsa_op_reg **);
1357 hsa_op_reg *hsa_spill_out (hsa_insn_basic *, hsa_op_reg *, hsa_op_reg **);
1358 hsa_bb *hsa_init_new_bb (basic_block);
1359 hsa_function_representation *hsa_generate_function_declaration (tree decl);
1360 hsa_function_representation *hsa_generate_internal_fn_decl (hsa_internal_fn *);
1361 tree hsa_get_host_function (tree decl);
1363 /* In hsa-regalloc.c. */
1364 void hsa_regalloc (void);
1366 /* In hsa-brig.c. */
1367 extern hash_table <hsa_internal_fn_hasher> *hsa_emitted_internal_decls;
1368 void hsa_brig_emit_function (void);
1369 void hsa_output_brig (void);
1370 unsigned hsa_get_imm_brig_type_len (BrigType16_t type);
1371 void hsa_brig_emit_omp_symbols (void);
1373 /* In hsa-dump.c. */
1374 const char *hsa_seg_name (BrigSegment8_t);
1375 void dump_hsa_insn (FILE *f, hsa_insn_basic *insn);
1376 void dump_hsa_bb (FILE *, hsa_bb *);
1377 void dump_hsa_cfun (FILE *);
1378 DEBUG_FUNCTION void debug_hsa_operand (hsa_op_base *opc);
1379 DEBUG_FUNCTION void debug_hsa_insn (hsa_insn_basic *insn);
1381 union hsa_bytes
1383 uint8_t b8;
1384 uint16_t b16;
1385 uint32_t b32;
1386 uint64_t b64;
1389 /* Return true if a function DECL is an HSA implementation. */
1391 static inline bool
1392 hsa_gpu_implementation_p (tree decl)
1394 if (hsa_summaries == NULL)
1395 return false;
1397 hsa_function_summary *s = hsa_summaries->get (cgraph_node::get_create (decl));
1399 return s->m_gpu_implementation_p;
1402 #endif /* HSA_H */