2017-01-22 Matthias Klose <doko@ubuntu.com>
[platform/upstream/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"