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