cp-tree.h (LOOKUP_SEEN_P, [...]): New.
[gcc.git] / gcc / hsa-common.c
1 /* Implementation of commonly needed HSAIL related functions and methods.
2 Copyright (C) 2013-2017 Free Software Foundation, Inc.
3 Contributed by Martin Jambor <mjambor@suse.cz> and
4 Martin Liska <mliska@suse.cz>.
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
12
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "is-a.h"
27 #include "hash-set.h"
28 #include "hash-map.h"
29 #include "vec.h"
30 #include "tree.h"
31 #include "dumpfile.h"
32 #include "gimple-pretty-print.h"
33 #include "diagnostic-core.h"
34 #include "alloc-pool.h"
35 #include "cgraph.h"
36 #include "print-tree.h"
37 #include "stringpool.h"
38 #include "symbol-summary.h"
39 #include "hsa-common.h"
40 #include "internal-fn.h"
41 #include "ctype.h"
42 #include "builtins.h"
43
44 /* Structure containing intermediate HSA representation of the generated
45 function. */
46 class hsa_function_representation *hsa_cfun;
47
48 /* Element of the mapping vector between a host decl and an HSA kernel. */
49
50 struct GTY(()) hsa_decl_kernel_map_element
51 {
52 /* The decl of the host function. */
53 tree decl;
54 /* Name of the HSA kernel in BRIG. */
55 char * GTY((skip)) name;
56 /* Size of OMP data, if the kernel contains a kernel dispatch. */
57 unsigned omp_data_size;
58 /* True if the function is gridified kernel. */
59 bool gridified_kernel_p;
60 };
61
62 /* Mapping between decls and corresponding HSA kernels in this compilation
63 unit. */
64
65 static GTY (()) vec<hsa_decl_kernel_map_element, va_gc>
66 *hsa_decl_kernel_mapping;
67
68 /* Mapping between decls and corresponding HSA kernels
69 called by the function. */
70 hash_map <tree, vec <const char *> *> *hsa_decl_kernel_dependencies;
71
72 /* Hash function to lookup a symbol for a decl. */
73 hash_table <hsa_noop_symbol_hasher> *hsa_global_variable_symbols;
74
75 /* HSA summaries. */
76 hsa_summary_t *hsa_summaries = NULL;
77
78 /* HSA number of threads. */
79 hsa_symbol *hsa_num_threads = NULL;
80
81 /* HSA function that cannot be expanded to HSAIL. */
82 hash_set <tree> *hsa_failed_functions = NULL;
83
84 /* True if compilation unit-wide data are already allocated and initialized. */
85 static bool compilation_unit_data_initialized;
86
87 /* Return true if FNDECL represents an HSA-callable function. */
88
89 bool
90 hsa_callable_function_p (tree fndecl)
91 {
92 return (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl))
93 && !lookup_attribute ("oacc function", DECL_ATTRIBUTES (fndecl)));
94 }
95
96 /* Allocate HSA structures that are are used when dealing with different
97 functions. */
98
99 void
100 hsa_init_compilation_unit_data (void)
101 {
102 if (compilation_unit_data_initialized)
103 return;
104
105 compilation_unit_data_initialized = true;
106
107 hsa_global_variable_symbols = new hash_table <hsa_noop_symbol_hasher> (8);
108 hsa_failed_functions = new hash_set <tree> ();
109 hsa_emitted_internal_decls = new hash_table <hsa_internal_fn_hasher> (2);
110 }
111
112 /* Free data structures that are used when dealing with different
113 functions. */
114
115 void
116 hsa_deinit_compilation_unit_data (void)
117 {
118 gcc_assert (compilation_unit_data_initialized);
119
120 delete hsa_failed_functions;
121 delete hsa_emitted_internal_decls;
122
123 for (hash_table <hsa_noop_symbol_hasher>::iterator it
124 = hsa_global_variable_symbols->begin ();
125 it != hsa_global_variable_symbols->end ();
126 ++it)
127 {
128 hsa_symbol *sym = *it;
129 delete sym;
130 }
131
132 delete hsa_global_variable_symbols;
133
134 if (hsa_num_threads)
135 {
136 delete hsa_num_threads;
137 hsa_num_threads = NULL;
138 }
139
140 compilation_unit_data_initialized = false;
141 }
142
143 /* Return true if we are generating large HSA machine model. */
144
145 bool
146 hsa_machine_large_p (void)
147 {
148 /* FIXME: I suppose this is technically wrong but should work for me now. */
149 return (GET_MODE_BITSIZE (Pmode) == 64);
150 }
151
152 /* Return the HSA profile we are using. */
153
154 bool
155 hsa_full_profile_p (void)
156 {
157 return true;
158 }
159
160 /* Return true if a register in operand number OPNUM of instruction
161 is an output. False if it is an input. */
162
163 bool
164 hsa_insn_basic::op_output_p (unsigned opnum)
165 {
166 switch (m_opcode)
167 {
168 case HSA_OPCODE_PHI:
169 case BRIG_OPCODE_CBR:
170 case BRIG_OPCODE_SBR:
171 case BRIG_OPCODE_ST:
172 case BRIG_OPCODE_SIGNALNORET:
173 case BRIG_OPCODE_DEBUGTRAP:
174 /* FIXME: There are probably missing cases here, double check. */
175 return false;
176 case BRIG_OPCODE_EXPAND:
177 /* Example: expand_v4_b32_b128 (dest0, dest1, dest2, dest3), src0. */
178 return opnum < operand_count () - 1;
179 default:
180 return opnum == 0;
181 }
182 }
183
184 /* Return true if OPCODE is an floating-point bit instruction opcode. */
185
186 bool
187 hsa_opcode_floating_bit_insn_p (BrigOpcode16_t opcode)
188 {
189 switch (opcode)
190 {
191 case BRIG_OPCODE_NEG:
192 case BRIG_OPCODE_ABS:
193 case BRIG_OPCODE_CLASS:
194 case BRIG_OPCODE_COPYSIGN:
195 return true;
196 default:
197 return false;
198 }
199 }
200
201 /* Return the number of destination operands for this INSN. */
202
203 unsigned
204 hsa_insn_basic::input_count ()
205 {
206 switch (m_opcode)
207 {
208 default:
209 return 1;
210
211 case BRIG_OPCODE_NOP:
212 return 0;
213
214 case BRIG_OPCODE_EXPAND:
215 return 2;
216
217 case BRIG_OPCODE_LD:
218 /* ld_v[234] not yet handled. */
219 return 1;
220
221 case BRIG_OPCODE_ST:
222 return 0;
223
224 case BRIG_OPCODE_ATOMICNORET:
225 return 0;
226
227 case BRIG_OPCODE_SIGNAL:
228 return 1;
229
230 case BRIG_OPCODE_SIGNALNORET:
231 return 0;
232
233 case BRIG_OPCODE_MEMFENCE:
234 return 0;
235
236 case BRIG_OPCODE_RDIMAGE:
237 case BRIG_OPCODE_LDIMAGE:
238 case BRIG_OPCODE_STIMAGE:
239 case BRIG_OPCODE_QUERYIMAGE:
240 case BRIG_OPCODE_QUERYSAMPLER:
241 sorry ("HSA image ops not handled");
242 return 0;
243
244 case BRIG_OPCODE_CBR:
245 case BRIG_OPCODE_BR:
246 return 0;
247
248 case BRIG_OPCODE_SBR:
249 return 0; /* ??? */
250
251 case BRIG_OPCODE_WAVEBARRIER:
252 return 0; /* ??? */
253
254 case BRIG_OPCODE_BARRIER:
255 case BRIG_OPCODE_ARRIVEFBAR:
256 case BRIG_OPCODE_INITFBAR:
257 case BRIG_OPCODE_JOINFBAR:
258 case BRIG_OPCODE_LEAVEFBAR:
259 case BRIG_OPCODE_RELEASEFBAR:
260 case BRIG_OPCODE_WAITFBAR:
261 return 0;
262
263 case BRIG_OPCODE_LDF:
264 return 1;
265
266 case BRIG_OPCODE_ACTIVELANECOUNT:
267 case BRIG_OPCODE_ACTIVELANEID:
268 case BRIG_OPCODE_ACTIVELANEMASK:
269 case BRIG_OPCODE_ACTIVELANEPERMUTE:
270 return 1; /* ??? */
271
272 case BRIG_OPCODE_CALL:
273 case BRIG_OPCODE_SCALL:
274 case BRIG_OPCODE_ICALL:
275 return 0;
276
277 case BRIG_OPCODE_RET:
278 return 0;
279
280 case BRIG_OPCODE_ALLOCA:
281 return 1;
282
283 case BRIG_OPCODE_CLEARDETECTEXCEPT:
284 return 0;
285
286 case BRIG_OPCODE_SETDETECTEXCEPT:
287 return 0;
288
289 case BRIG_OPCODE_PACKETCOMPLETIONSIG:
290 case BRIG_OPCODE_PACKETID:
291 case BRIG_OPCODE_CASQUEUEWRITEINDEX:
292 case BRIG_OPCODE_LDQUEUEREADINDEX:
293 case BRIG_OPCODE_LDQUEUEWRITEINDEX:
294 case BRIG_OPCODE_STQUEUEREADINDEX:
295 case BRIG_OPCODE_STQUEUEWRITEINDEX:
296 return 1; /* ??? */
297
298 case BRIG_OPCODE_ADDQUEUEWRITEINDEX:
299 return 1;
300
301 case BRIG_OPCODE_DEBUGTRAP:
302 return 0;
303
304 case BRIG_OPCODE_GROUPBASEPTR:
305 case BRIG_OPCODE_KERNARGBASEPTR:
306 return 1; /* ??? */
307
308 case HSA_OPCODE_ARG_BLOCK:
309 return 0;
310
311 case BRIG_KIND_DIRECTIVE_COMMENT:
312 return 0;
313 }
314 }
315
316 /* Return the number of source operands for this INSN. */
317
318 unsigned
319 hsa_insn_basic::num_used_ops ()
320 {
321 gcc_checking_assert (input_count () <= operand_count ());
322
323 return operand_count () - input_count ();
324 }
325
326 /* Set alignment to VALUE. */
327
328 void
329 hsa_insn_mem::set_align (BrigAlignment8_t value)
330 {
331 /* TODO: Perhaps remove this dump later on: */
332 if (dump_file && (dump_flags & TDF_DETAILS) && value < m_align)
333 {
334 fprintf (dump_file, "Decreasing alignment to %u in instruction ", value);
335 dump_hsa_insn (dump_file, this);
336 }
337 m_align = value;
338 }
339
340 /* Return size of HSA type T in bits. */
341
342 unsigned
343 hsa_type_bit_size (BrigType16_t t)
344 {
345 switch (t)
346 {
347 case BRIG_TYPE_B1:
348 return 1;
349
350 case BRIG_TYPE_U8:
351 case BRIG_TYPE_S8:
352 case BRIG_TYPE_B8:
353 return 8;
354
355 case BRIG_TYPE_U16:
356 case BRIG_TYPE_S16:
357 case BRIG_TYPE_B16:
358 case BRIG_TYPE_F16:
359 return 16;
360
361 case BRIG_TYPE_U32:
362 case BRIG_TYPE_S32:
363 case BRIG_TYPE_B32:
364 case BRIG_TYPE_F32:
365 case BRIG_TYPE_U8X4:
366 case BRIG_TYPE_U16X2:
367 case BRIG_TYPE_S8X4:
368 case BRIG_TYPE_S16X2:
369 case BRIG_TYPE_F16X2:
370 return 32;
371
372 case BRIG_TYPE_U64:
373 case BRIG_TYPE_S64:
374 case BRIG_TYPE_F64:
375 case BRIG_TYPE_B64:
376 case BRIG_TYPE_U8X8:
377 case BRIG_TYPE_U16X4:
378 case BRIG_TYPE_U32X2:
379 case BRIG_TYPE_S8X8:
380 case BRIG_TYPE_S16X4:
381 case BRIG_TYPE_S32X2:
382 case BRIG_TYPE_F16X4:
383 case BRIG_TYPE_F32X2:
384
385 return 64;
386
387 case BRIG_TYPE_B128:
388 case BRIG_TYPE_U8X16:
389 case BRIG_TYPE_U16X8:
390 case BRIG_TYPE_U32X4:
391 case BRIG_TYPE_U64X2:
392 case BRIG_TYPE_S8X16:
393 case BRIG_TYPE_S16X8:
394 case BRIG_TYPE_S32X4:
395 case BRIG_TYPE_S64X2:
396 case BRIG_TYPE_F16X8:
397 case BRIG_TYPE_F32X4:
398 case BRIG_TYPE_F64X2:
399 return 128;
400
401 default:
402 gcc_assert (hsa_seen_error ());
403 return t;
404 }
405 }
406
407 /* Return BRIG bit-type with BITSIZE length. */
408
409 BrigType16_t
410 hsa_bittype_for_bitsize (unsigned bitsize)
411 {
412 switch (bitsize)
413 {
414 case 1:
415 return BRIG_TYPE_B1;
416 case 8:
417 return BRIG_TYPE_B8;
418 case 16:
419 return BRIG_TYPE_B16;
420 case 32:
421 return BRIG_TYPE_B32;
422 case 64:
423 return BRIG_TYPE_B64;
424 case 128:
425 return BRIG_TYPE_B128;
426 default:
427 gcc_unreachable ();
428 }
429 }
430
431 /* Return BRIG unsigned int type with BITSIZE length. */
432
433 BrigType16_t
434 hsa_uint_for_bitsize (unsigned bitsize)
435 {
436 switch (bitsize)
437 {
438 case 8:
439 return BRIG_TYPE_U8;
440 case 16:
441 return BRIG_TYPE_U16;
442 case 32:
443 return BRIG_TYPE_U32;
444 case 64:
445 return BRIG_TYPE_U64;
446 default:
447 gcc_unreachable ();
448 }
449 }
450
451 /* Return BRIG float type with BITSIZE length. */
452
453 BrigType16_t
454 hsa_float_for_bitsize (unsigned bitsize)
455 {
456 switch (bitsize)
457 {
458 case 16:
459 return BRIG_TYPE_F16;
460 case 32:
461 return BRIG_TYPE_F32;
462 case 64:
463 return BRIG_TYPE_F64;
464 default:
465 gcc_unreachable ();
466 }
467 }
468
469 /* Return HSA bit-type with the same size as the type T. */
470
471 BrigType16_t
472 hsa_bittype_for_type (BrigType16_t t)
473 {
474 return hsa_bittype_for_bitsize (hsa_type_bit_size (t));
475 }
476
477 /* Return HSA unsigned integer type with the same size as the type T. */
478
479 BrigType16_t
480 hsa_unsigned_type_for_type (BrigType16_t t)
481 {
482 return hsa_uint_for_bitsize (hsa_type_bit_size (t));
483 }
484
485 /* Return true if TYPE is a packed HSA type. */
486
487 bool
488 hsa_type_packed_p (BrigType16_t type)
489 {
490 return (type & BRIG_TYPE_PACK_MASK) != BRIG_TYPE_PACK_NONE;
491 }
492
493 /* Return true if and only if TYPE is a floating point number type. */
494
495 bool
496 hsa_type_float_p (BrigType16_t type)
497 {
498 switch (type & BRIG_TYPE_BASE_MASK)
499 {
500 case BRIG_TYPE_F16:
501 case BRIG_TYPE_F32:
502 case BRIG_TYPE_F64:
503 return true;
504 default:
505 return false;
506 }
507 }
508
509 /* Return true if and only if TYPE is an integer number type. */
510
511 bool
512 hsa_type_integer_p (BrigType16_t type)
513 {
514 switch (type & BRIG_TYPE_BASE_MASK)
515 {
516 case BRIG_TYPE_U8:
517 case BRIG_TYPE_U16:
518 case BRIG_TYPE_U32:
519 case BRIG_TYPE_U64:
520 case BRIG_TYPE_S8:
521 case BRIG_TYPE_S16:
522 case BRIG_TYPE_S32:
523 case BRIG_TYPE_S64:
524 return true;
525 default:
526 return false;
527 }
528 }
529
530 /* Return true if and only if TYPE is an bit-type. */
531
532 bool
533 hsa_btype_p (BrigType16_t type)
534 {
535 switch (type & BRIG_TYPE_BASE_MASK)
536 {
537 case BRIG_TYPE_B8:
538 case BRIG_TYPE_B16:
539 case BRIG_TYPE_B32:
540 case BRIG_TYPE_B64:
541 case BRIG_TYPE_B128:
542 return true;
543 default:
544 return false;
545 }
546 }
547
548
549 /* Return HSA alignment encoding alignment to N bits. */
550
551 BrigAlignment8_t
552 hsa_alignment_encoding (unsigned n)
553 {
554 gcc_assert (n >= 8 && !(n & (n - 1)));
555 if (n >= 256)
556 return BRIG_ALIGNMENT_32;
557
558 switch (n)
559 {
560 case 8:
561 return BRIG_ALIGNMENT_1;
562 case 16:
563 return BRIG_ALIGNMENT_2;
564 case 32:
565 return BRIG_ALIGNMENT_4;
566 case 64:
567 return BRIG_ALIGNMENT_8;
568 case 128:
569 return BRIG_ALIGNMENT_16;
570 default:
571 gcc_unreachable ();
572 }
573 }
574
575 /* Return HSA alignment encoding alignment of T got
576 by get_object_alignment. */
577
578 BrigAlignment8_t
579 hsa_object_alignment (tree t)
580 {
581 return hsa_alignment_encoding (get_object_alignment (t));
582 }
583
584 /* Return byte alignment for given BrigAlignment8_t value. */
585
586 unsigned
587 hsa_byte_alignment (BrigAlignment8_t alignment)
588 {
589 gcc_assert (alignment != BRIG_ALIGNMENT_NONE);
590
591 return 1 << (alignment - 1);
592 }
593
594 /* Return natural alignment of HSA TYPE. */
595
596 BrigAlignment8_t
597 hsa_natural_alignment (BrigType16_t type)
598 {
599 return hsa_alignment_encoding (hsa_type_bit_size (type & ~BRIG_TYPE_ARRAY));
600 }
601
602 /* Call the correct destructor of a HSA instruction. */
603
604 void
605 hsa_destroy_insn (hsa_insn_basic *insn)
606 {
607 if (hsa_insn_phi *phi = dyn_cast <hsa_insn_phi *> (insn))
608 phi->~hsa_insn_phi ();
609 else if (hsa_insn_cbr *br = dyn_cast <hsa_insn_cbr *> (insn))
610 br->~hsa_insn_cbr ();
611 else if (hsa_insn_cmp *cmp = dyn_cast <hsa_insn_cmp *> (insn))
612 cmp->~hsa_insn_cmp ();
613 else if (hsa_insn_mem *mem = dyn_cast <hsa_insn_mem *> (insn))
614 mem->~hsa_insn_mem ();
615 else if (hsa_insn_atomic *atomic = dyn_cast <hsa_insn_atomic *> (insn))
616 atomic->~hsa_insn_atomic ();
617 else if (hsa_insn_seg *seg = dyn_cast <hsa_insn_seg *> (insn))
618 seg->~hsa_insn_seg ();
619 else if (hsa_insn_call *call = dyn_cast <hsa_insn_call *> (insn))
620 call->~hsa_insn_call ();
621 else if (hsa_insn_arg_block *block = dyn_cast <hsa_insn_arg_block *> (insn))
622 block->~hsa_insn_arg_block ();
623 else if (hsa_insn_sbr *sbr = dyn_cast <hsa_insn_sbr *> (insn))
624 sbr->~hsa_insn_sbr ();
625 else if (hsa_insn_br *br = dyn_cast <hsa_insn_br *> (insn))
626 br->~hsa_insn_br ();
627 else if (hsa_insn_comment *comment = dyn_cast <hsa_insn_comment *> (insn))
628 comment->~hsa_insn_comment ();
629 else
630 insn->~hsa_insn_basic ();
631 }
632
633 /* Call the correct destructor of a HSA operand. */
634
635 void
636 hsa_destroy_operand (hsa_op_base *op)
637 {
638 if (hsa_op_code_list *list = dyn_cast <hsa_op_code_list *> (op))
639 list->~hsa_op_code_list ();
640 else if (hsa_op_operand_list *list = dyn_cast <hsa_op_operand_list *> (op))
641 list->~hsa_op_operand_list ();
642 else if (hsa_op_reg *reg = dyn_cast <hsa_op_reg *> (op))
643 reg->~hsa_op_reg ();
644 else if (hsa_op_immed *immed = dyn_cast <hsa_op_immed *> (op))
645 immed->~hsa_op_immed ();
646 else
647 op->~hsa_op_base ();
648 }
649
650 /* Create a mapping between the original function DECL and kernel name NAME. */
651
652 void
653 hsa_add_kern_decl_mapping (tree decl, char *name, unsigned omp_data_size,
654 bool gridified_kernel_p)
655 {
656 hsa_decl_kernel_map_element dkm;
657 dkm.decl = decl;
658 dkm.name = name;
659 dkm.omp_data_size = omp_data_size;
660 dkm.gridified_kernel_p = gridified_kernel_p;
661 vec_safe_push (hsa_decl_kernel_mapping, dkm);
662 }
663
664 /* Return the number of kernel decl name mappings. */
665
666 unsigned
667 hsa_get_number_decl_kernel_mappings (void)
668 {
669 return vec_safe_length (hsa_decl_kernel_mapping);
670 }
671
672 /* Return the decl in the Ith kernel decl name mapping. */
673
674 tree
675 hsa_get_decl_kernel_mapping_decl (unsigned i)
676 {
677 return (*hsa_decl_kernel_mapping)[i].decl;
678 }
679
680 /* Return the name in the Ith kernel decl name mapping. */
681
682 char *
683 hsa_get_decl_kernel_mapping_name (unsigned i)
684 {
685 return (*hsa_decl_kernel_mapping)[i].name;
686 }
687
688 /* Return maximum OMP size for kernel decl name mapping. */
689
690 unsigned
691 hsa_get_decl_kernel_mapping_omp_size (unsigned i)
692 {
693 return (*hsa_decl_kernel_mapping)[i].omp_data_size;
694 }
695
696 /* Return if the function is gridified kernel in decl name mapping. */
697
698 bool
699 hsa_get_decl_kernel_mapping_gridified (unsigned i)
700 {
701 return (*hsa_decl_kernel_mapping)[i].gridified_kernel_p;
702 }
703
704 /* Free the mapping between original decls and kernel names. */
705
706 void
707 hsa_free_decl_kernel_mapping (void)
708 {
709 if (hsa_decl_kernel_mapping == NULL)
710 return;
711
712 for (unsigned i = 0; i < hsa_decl_kernel_mapping->length (); ++i)
713 free ((*hsa_decl_kernel_mapping)[i].name);
714 ggc_free (hsa_decl_kernel_mapping);
715 }
716
717 /* Add new kernel dependency. */
718
719 void
720 hsa_add_kernel_dependency (tree caller, const char *called_function)
721 {
722 if (hsa_decl_kernel_dependencies == NULL)
723 hsa_decl_kernel_dependencies = new hash_map<tree, vec<const char *> *> ();
724
725 vec <const char *> *s = NULL;
726 vec <const char *> **slot = hsa_decl_kernel_dependencies->get (caller);
727 if (slot == NULL)
728 {
729 s = new vec <const char *> ();
730 hsa_decl_kernel_dependencies->put (caller, s);
731 }
732 else
733 s = *slot;
734
735 s->safe_push (called_function);
736 }
737
738 /* Expansion to HSA needs a few gc roots to hold types, constructors etc. In
739 order to minimize the number of GTY roots, we'll root them all in the
740 following array. The individual elements should only be accessed by the
741 very simple getters (of a pointer-to-tree) below. */
742
743 static GTY(()) tree hsa_tree_gt_roots[3];
744
745 tree *
746 hsa_get_ctor_statements (void)
747 {
748 return &hsa_tree_gt_roots[0];
749 }
750
751 tree *
752 hsa_get_dtor_statements (void)
753 {
754 return &hsa_tree_gt_roots[1];
755 }
756
757 tree *
758 hsa_get_kernel_dispatch_type (void)
759 {
760 return &hsa_tree_gt_roots[2];
761 }
762
763 /* Modify the name P in-place so that it is a valid HSA identifier. */
764
765 void
766 hsa_sanitize_name (char *p)
767 {
768 for (; *p; p++)
769 if (*p == '.' || *p == '-')
770 *p = '_';
771 }
772
773 /* Clone the name P, set trailing ampersand and sanitize the name. */
774
775 char *
776 hsa_brig_function_name (const char *p)
777 {
778 unsigned len = strlen (p);
779 char *buf = XNEWVEC (char, len + 2);
780
781 buf[0] = '&';
782 buf[len + 1] = '\0';
783 memcpy (buf + 1, p, len);
784
785 hsa_sanitize_name (buf);
786 return buf;
787 }
788
789 /* Add a flatten attribute and disable vectorization for gpu implementation
790 function decl GDECL. */
791
792 void hsa_summary_t::process_gpu_implementation_attributes (tree gdecl)
793 {
794 DECL_ATTRIBUTES (gdecl)
795 = tree_cons (get_identifier ("flatten"), NULL_TREE,
796 DECL_ATTRIBUTES (gdecl));
797
798 tree fn_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (gdecl);
799 if (fn_opts == NULL_TREE)
800 fn_opts = optimization_default_node;
801 fn_opts = copy_node (fn_opts);
802 TREE_OPTIMIZATION (fn_opts)->x_flag_tree_loop_vectorize = false;
803 TREE_OPTIMIZATION (fn_opts)->x_flag_tree_slp_vectorize = false;
804 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (gdecl) = fn_opts;
805 }
806
807 void
808 hsa_summary_t::link_functions (cgraph_node *gpu, cgraph_node *host,
809 hsa_function_kind kind, bool gridified_kernel_p)
810 {
811 hsa_function_summary *gpu_summary = get (gpu);
812 hsa_function_summary *host_summary = get (host);
813
814 gpu_summary->m_kind = kind;
815 host_summary->m_kind = kind;
816
817 gpu_summary->m_gpu_implementation_p = true;
818 host_summary->m_gpu_implementation_p = false;
819
820 gpu_summary->m_gridified_kernel_p = gridified_kernel_p;
821 host_summary->m_gridified_kernel_p = gridified_kernel_p;
822
823 gpu_summary->m_bound_function = host;
824 host_summary->m_bound_function = gpu;
825
826 process_gpu_implementation_attributes (gpu->decl);
827
828 /* Create reference between a kernel and a corresponding host implementation
829 to quarantee LTO streaming to a same LTRANS. */
830 if (kind == HSA_KERNEL)
831 gpu->create_reference (host, IPA_REF_ADDR);
832 }
833
834 /* Add a HOST function to HSA summaries. */
835
836 void
837 hsa_register_kernel (cgraph_node *host)
838 {
839 if (hsa_summaries == NULL)
840 hsa_summaries = new hsa_summary_t (symtab);
841 hsa_function_summary *s = hsa_summaries->get (host);
842 s->m_kind = HSA_KERNEL;
843 }
844
845 /* Add a pair of functions to HSA summaries. GPU is an HSA implementation of
846 a HOST function. */
847
848 void
849 hsa_register_kernel (cgraph_node *gpu, cgraph_node *host)
850 {
851 if (hsa_summaries == NULL)
852 hsa_summaries = new hsa_summary_t (symtab);
853 hsa_summaries->link_functions (gpu, host, HSA_KERNEL, true);
854 }
855
856 /* Return true if expansion of the current HSA function has already failed. */
857
858 bool
859 hsa_seen_error (void)
860 {
861 return hsa_cfun->m_seen_error;
862 }
863
864 /* Mark current HSA function as failed. */
865
866 void
867 hsa_fail_cfun (void)
868 {
869 hsa_failed_functions->add (hsa_cfun->m_decl);
870 hsa_cfun->m_seen_error = true;
871 }
872
873 char *
874 hsa_internal_fn::name ()
875 {
876 char *name = xstrdup (internal_fn_name (m_fn));
877 for (char *ptr = name; *ptr; ptr++)
878 *ptr = TOLOWER (*ptr);
879
880 const char *suffix = NULL;
881 if (m_type_bit_size == 32)
882 suffix = "f";
883
884 if (suffix)
885 {
886 char *name2 = concat (name, suffix, NULL);
887 free (name);
888 name = name2;
889 }
890
891 hsa_sanitize_name (name);
892 return name;
893 }
894
895 unsigned
896 hsa_internal_fn::get_arity ()
897 {
898 switch (m_fn)
899 {
900 case IFN_ACOS:
901 case IFN_ASIN:
902 case IFN_ATAN:
903 case IFN_COS:
904 case IFN_EXP:
905 case IFN_EXP10:
906 case IFN_EXP2:
907 case IFN_EXPM1:
908 case IFN_LOG:
909 case IFN_LOG10:
910 case IFN_LOG1P:
911 case IFN_LOG2:
912 case IFN_LOGB:
913 case IFN_SIGNIFICAND:
914 case IFN_SIN:
915 case IFN_SQRT:
916 case IFN_TAN:
917 case IFN_CEIL:
918 case IFN_FLOOR:
919 case IFN_NEARBYINT:
920 case IFN_RINT:
921 case IFN_ROUND:
922 case IFN_TRUNC:
923 return 1;
924 case IFN_ATAN2:
925 case IFN_COPYSIGN:
926 case IFN_FMOD:
927 case IFN_POW:
928 case IFN_REMAINDER:
929 case IFN_SCALB:
930 case IFN_LDEXP:
931 return 2;
932 case IFN_CLRSB:
933 case IFN_CLZ:
934 case IFN_CTZ:
935 case IFN_FFS:
936 case IFN_PARITY:
937 case IFN_POPCOUNT:
938 default:
939 /* As we produce sorry message for unknown internal functions,
940 reaching this label is definitely a bug. */
941 gcc_unreachable ();
942 }
943 }
944
945 BrigType16_t
946 hsa_internal_fn::get_argument_type (int n)
947 {
948 switch (m_fn)
949 {
950 case IFN_ACOS:
951 case IFN_ASIN:
952 case IFN_ATAN:
953 case IFN_COS:
954 case IFN_EXP:
955 case IFN_EXP10:
956 case IFN_EXP2:
957 case IFN_EXPM1:
958 case IFN_LOG:
959 case IFN_LOG10:
960 case IFN_LOG1P:
961 case IFN_LOG2:
962 case IFN_LOGB:
963 case IFN_SIGNIFICAND:
964 case IFN_SIN:
965 case IFN_SQRT:
966 case IFN_TAN:
967 case IFN_CEIL:
968 case IFN_FLOOR:
969 case IFN_NEARBYINT:
970 case IFN_RINT:
971 case IFN_ROUND:
972 case IFN_TRUNC:
973 case IFN_ATAN2:
974 case IFN_COPYSIGN:
975 case IFN_FMOD:
976 case IFN_POW:
977 case IFN_REMAINDER:
978 case IFN_SCALB:
979 return hsa_float_for_bitsize (m_type_bit_size);
980 case IFN_LDEXP:
981 {
982 if (n == -1 || n == 0)
983 return hsa_float_for_bitsize (m_type_bit_size);
984 else
985 return BRIG_TYPE_S32;
986 }
987 default:
988 /* As we produce sorry message for unknown internal functions,
989 reaching this label is definitely a bug. */
990 gcc_unreachable ();
991 }
992 }
993
994 #include "gt-hsa-common.h"