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