xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/hsa-common.c (revision d90047b5d07facf36e6c01dcc0bded8997ce9cc2)
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"
995