hsa-common.c revision 1.1.1.1
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
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 3, or (at your option)
11any later version.
12
13GCC is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along 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.  */
46class hsa_function_representation *hsa_cfun;
47
48/* Element of the mapping vector between a host decl and an HSA kernel.  */
49
50struct 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
65static 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.  */
70hash_map <tree, vec <const char *> *> *hsa_decl_kernel_dependencies;
71
72/* Hash function to lookup a symbol for a decl.  */
73hash_table <hsa_noop_symbol_hasher> *hsa_global_variable_symbols;
74
75/* HSA summaries.  */
76hsa_summary_t *hsa_summaries = NULL;
77
78/* HSA number of threads.  */
79hsa_symbol *hsa_num_threads = NULL;
80
81/* HSA function that cannot be expanded to HSAIL.  */
82hash_set <tree> *hsa_failed_functions = NULL;
83
84/* True if compilation unit-wide data are already allocated and initialized.  */
85static bool compilation_unit_data_initialized;
86
87/* Return true if FNDECL represents an HSA-callable function.  */
88
89bool
90hsa_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
99void
100hsa_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
115void
116hsa_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
145bool
146hsa_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
154bool
155hsa_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
163bool
164hsa_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
186bool
187hsa_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
203unsigned
204hsa_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
318unsigned
319hsa_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
328void
329hsa_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
342unsigned
343hsa_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
409BrigType16_t
410hsa_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
433BrigType16_t
434hsa_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
453BrigType16_t
454hsa_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
471BrigType16_t
472hsa_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
479BrigType16_t
480hsa_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
487bool
488hsa_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
495bool
496hsa_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
511bool
512hsa_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
532bool
533hsa_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
551BrigAlignment8_t
552hsa_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
578BrigAlignment8_t
579hsa_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
586unsigned
587hsa_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
596BrigAlignment8_t
597hsa_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
604void
605hsa_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
635void
636hsa_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
652void
653hsa_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
666unsigned
667hsa_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
674tree
675hsa_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
682char *
683hsa_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
690unsigned
691hsa_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
698bool
699hsa_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
706void
707hsa_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
719void
720hsa_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
743static GTY(()) tree hsa_tree_gt_roots[3];
744
745tree *
746hsa_get_ctor_statements (void)
747{
748  return &hsa_tree_gt_roots[0];
749}
750
751tree *
752hsa_get_dtor_statements (void)
753{
754  return &hsa_tree_gt_roots[1];
755}
756
757tree *
758hsa_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
765void
766hsa_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
775char *
776hsa_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
792void 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
807void
808hsa_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
836void
837hsa_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
848void
849hsa_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
858bool
859hsa_seen_error (void)
860{
861  return hsa_cfun->m_seen_error;
862}
863
864/* Mark current HSA function as failed.  */
865
866void
867hsa_fail_cfun (void)
868{
869  hsa_failed_functions->add (hsa_cfun->m_decl);
870  hsa_cfun->m_seen_error = true;
871}
872
873char *
874hsa_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
895unsigned
896hsa_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
945BrigType16_t
946hsa_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