]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/hsa.c
* decl.c (start_preparsed_function): Remove unnecessary bracing.
[thirdparty/gcc.git] / gcc / hsa.c
CommitLineData
56686608 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
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.h"
40#include "internal-fn.h"
41#include "ctype.h"
42
43/* Structure containing intermediate HSA representation of the generated
44 function. */
45class hsa_function_representation *hsa_cfun;
46
47/* Element of the mapping vector between a host decl and an HSA kernel. */
48
49struct 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
64static 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. */
69hash_map <tree, vec <const char *> *> *hsa_decl_kernel_dependencies;
70
71/* Hash function to lookup a symbol for a decl. */
72hash_table <hsa_noop_symbol_hasher> *hsa_global_variable_symbols;
73
74/* HSA summaries. */
75hsa_summary_t *hsa_summaries = NULL;
76
77/* HSA number of threads. */
78hsa_symbol *hsa_num_threads = NULL;
79
80/* HSA function that cannot be expanded to HSAIL. */
81hash_set <tree> *hsa_failed_functions = NULL;
82
83/* True if compilation unit-wide data are already allocated and initialized. */
84static bool compilation_unit_data_initialized;
85
86/* Return true if FNDECL represents an HSA-callable function. */
87
88bool
89hsa_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
98void
99hsa_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
114void
115hsa_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
144bool
145hsa_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
153bool
154hsa_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
162bool
163hsa_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
184bool
185hsa_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
201unsigned
202hsa_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
316unsigned
317hsa_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
326void
327hsa_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
340unsigned
341hsa_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
407BrigType16_t
408hsa_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
431BrigType16_t
432hsa_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
451BrigType16_t
452hsa_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
469BrigType16_t
470hsa_bittype_for_type (BrigType16_t t)
471{
472 return hsa_bittype_for_bitsize (hsa_type_bit_size (t));
473}
474
0d1b26a7 475/* Return HSA unsigned integer type with the same size as the type T. */
476
477BrigType16_t
478hsa_unsigned_type_for_type (BrigType16_t t)
479{
480 return hsa_uint_for_bitsize (hsa_type_bit_size (t));
481}
482
bcd6e034 483/* Return true if TYPE is a packed HSA type. */
484
485bool
486hsa_type_packed_p (BrigType16_t type)
487{
488 return (type & BRIG_TYPE_PACK_MASK) != BRIG_TYPE_PACK_NONE;
489}
490
56686608 491/* Return true if and only if TYPE is a floating point number type. */
492
493bool
494hsa_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
509bool
510hsa_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
530bool
531hsa_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
549BrigAlignment8_t
550hsa_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
575BrigAlignment8_t
576hsa_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
583void
584hsa_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
612void
613hsa_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
629void
630hsa_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
643unsigned
644hsa_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
651tree
652hsa_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
659char *
660hsa_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
667unsigned
668hsa_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
675bool
676hsa_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
683void
684hsa_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
696void
697hsa_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
e2f980b8 715/* Expansion to HSA needs a few gc roots to hold types, constructors etc. In
716 order to minimize the number of GTY roots, we'll root them all in the
717 following array. The individual elements should only be accessed by the
718 very simple getters (of a pointer-to-tree) below. */
719
720static GTY(()) tree hsa_tree_gt_roots[3];
721
722tree *
723hsa_get_ctor_statements (void)
724{
725 return &hsa_tree_gt_roots[0];
726}
727
728tree *
729hsa_get_dtor_statements (void)
730{
731 return &hsa_tree_gt_roots[1];
732}
733
734tree *
735hsa_get_kernel_dispatch_type (void)
736{
737 return &hsa_tree_gt_roots[2];
738}
739
56686608 740/* Modify the name P in-place so that it is a valid HSA identifier. */
741
742void
743hsa_sanitize_name (char *p)
744{
745 for (; *p; p++)
746 if (*p == '.' || *p == '-')
747 *p = '_';
748}
749
750/* Clone the name P, set trailing ampersand and sanitize the name. */
751
752char *
753hsa_brig_function_name (const char *p)
754{
755 unsigned len = strlen (p);
756 char *buf = XNEWVEC (char, len + 2);
757
758 buf[0] = '&';
759 buf[len + 1] = '\0';
760 memcpy (buf + 1, p, len);
761
762 hsa_sanitize_name (buf);
763 return buf;
764}
765
766/* Return declaration name if exists. */
767
768const char *
769hsa_get_declaration_name (tree decl)
770{
771 if (!DECL_NAME (decl))
772 {
773 char buf[64];
774 snprintf (buf, 64, "__hsa_anonymous_%i", DECL_UID (decl));
775 const char *ggc_str = ggc_strdup (buf);
776 return ggc_str;
777 }
778
779 tree name_tree;
780 if (TREE_CODE (decl) == FUNCTION_DECL
781 || (TREE_CODE (decl) == VAR_DECL && is_global_var (decl)))
782 name_tree = DECL_ASSEMBLER_NAME (decl);
783 else
784 name_tree = DECL_NAME (decl);
785
786 const char *name = IDENTIFIER_POINTER (name_tree);
787 /* User-defined assembly names have prepended asterisk symbol. */
788 if (name[0] == '*')
789 name++;
790
791 return name;
792}
793
794void
795hsa_summary_t::link_functions (cgraph_node *gpu, cgraph_node *host,
796 hsa_function_kind kind, bool gridified_kernel_p)
797{
798 hsa_function_summary *gpu_summary = get (gpu);
799 hsa_function_summary *host_summary = get (host);
800
801 gpu_summary->m_kind = kind;
802 host_summary->m_kind = kind;
803
804 gpu_summary->m_gpu_implementation_p = true;
805 host_summary->m_gpu_implementation_p = false;
806
807 gpu_summary->m_gridified_kernel_p = gridified_kernel_p;
808 host_summary->m_gridified_kernel_p = gridified_kernel_p;
809
810 gpu_summary->m_binded_function = host;
811 host_summary->m_binded_function = gpu;
812
813 tree gdecl = gpu->decl;
814 DECL_ATTRIBUTES (gdecl)
815 = tree_cons (get_identifier ("flatten"), NULL_TREE,
816 DECL_ATTRIBUTES (gdecl));
817
818 tree fn_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (gdecl);
819 if (fn_opts == NULL_TREE)
820 fn_opts = optimization_default_node;
821 fn_opts = copy_node (fn_opts);
822 TREE_OPTIMIZATION (fn_opts)->x_flag_tree_loop_vectorize = false;
823 TREE_OPTIMIZATION (fn_opts)->x_flag_tree_slp_vectorize = false;
824 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (gdecl) = fn_opts;
874e154a 825
826 /* Create reference between a kernel and a corresponding host implementation
827 to quarantee LTO streaming to a same LTRANS. */
828 if (kind == HSA_KERNEL)
829 gpu->create_reference (host, IPA_REF_ADDR);
56686608 830}
831
832/* Add a HOST function to HSA summaries. */
833
834void
835hsa_register_kernel (cgraph_node *host)
836{
837 if (hsa_summaries == NULL)
838 hsa_summaries = new hsa_summary_t (symtab);
839 hsa_function_summary *s = hsa_summaries->get (host);
840 s->m_kind = HSA_KERNEL;
841}
842
843/* Add a pair of functions to HSA summaries. GPU is an HSA implementation of
844 a HOST function. */
845
846void
847hsa_register_kernel (cgraph_node *gpu, cgraph_node *host)
848{
849 if (hsa_summaries == NULL)
850 hsa_summaries = new hsa_summary_t (symtab);
851 hsa_summaries->link_functions (gpu, host, HSA_KERNEL, true);
852}
853
854/* Return true if expansion of the current HSA function has already failed. */
855
856bool
857hsa_seen_error (void)
858{
859 return hsa_cfun->m_seen_error;
860}
861
862/* Mark current HSA function as failed. */
863
864void
865hsa_fail_cfun (void)
866{
867 hsa_failed_functions->add (hsa_cfun->m_decl);
868 hsa_cfun->m_seen_error = true;
869}
870
871char *
872hsa_internal_fn::name ()
873{
874 char *name = xstrdup (internal_fn_name (m_fn));
875 for (char *ptr = name; *ptr; ptr++)
876 *ptr = TOLOWER (*ptr);
877
878 const char *suffix = NULL;
879 if (m_type_bit_size == 32)
880 suffix = "f";
881
882 if (suffix)
883 {
884 char *name2 = concat (name, suffix, NULL);
885 free (name);
886 name = name2;
887 }
888
889 hsa_sanitize_name (name);
890 return name;
891}
892
893unsigned
894hsa_internal_fn::get_arity ()
895{
896 switch (m_fn)
897 {
898 case IFN_ACOS:
899 case IFN_ASIN:
900 case IFN_ATAN:
901 case IFN_COS:
902 case IFN_EXP:
903 case IFN_EXP10:
904 case IFN_EXP2:
905 case IFN_EXPM1:
906 case IFN_LOG:
907 case IFN_LOG10:
908 case IFN_LOG1P:
909 case IFN_LOG2:
910 case IFN_LOGB:
911 case IFN_SIGNIFICAND:
912 case IFN_SIN:
913 case IFN_SQRT:
914 case IFN_TAN:
915 case IFN_CEIL:
916 case IFN_FLOOR:
917 case IFN_NEARBYINT:
918 case IFN_RINT:
919 case IFN_ROUND:
920 case IFN_TRUNC:
921 return 1;
922 case IFN_ATAN2:
923 case IFN_COPYSIGN:
924 case IFN_FMOD:
925 case IFN_POW:
926 case IFN_REMAINDER:
927 case IFN_SCALB:
928 case IFN_LDEXP:
929 return 2;
930 break;
931 case IFN_CLRSB:
932 case IFN_CLZ:
933 case IFN_CTZ:
934 case IFN_FFS:
935 case IFN_PARITY:
936 case IFN_POPCOUNT:
937 default:
938 /* As we produce sorry message for unknown internal functions,
939 reaching this label is definitely a bug. */
940 gcc_unreachable ();
941 }
942}
943
944BrigType16_t
945hsa_internal_fn::get_argument_type (int n)
946{
947 switch (m_fn)
948 {
949 case IFN_ACOS:
950 case IFN_ASIN:
951 case IFN_ATAN:
952 case IFN_COS:
953 case IFN_EXP:
954 case IFN_EXP10:
955 case IFN_EXP2:
956 case IFN_EXPM1:
957 case IFN_LOG:
958 case IFN_LOG10:
959 case IFN_LOG1P:
960 case IFN_LOG2:
961 case IFN_LOGB:
962 case IFN_SIGNIFICAND:
963 case IFN_SIN:
964 case IFN_SQRT:
965 case IFN_TAN:
966 case IFN_CEIL:
967 case IFN_FLOOR:
968 case IFN_NEARBYINT:
969 case IFN_RINT:
970 case IFN_ROUND:
971 case IFN_TRUNC:
972 case IFN_ATAN2:
973 case IFN_COPYSIGN:
974 case IFN_FMOD:
975 case IFN_POW:
976 case IFN_REMAINDER:
977 case IFN_SCALB:
978 return hsa_float_for_bitsize (m_type_bit_size);
979 case IFN_LDEXP:
980 {
981 if (n == -1 || n == 0)
982 return hsa_float_for_bitsize (m_type_bit_size);
983 else
984 return BRIG_TYPE_S32;
985 }
986 default:
987 /* As we produce sorry message for unknown internal functions,
988 reaching this label is definitely a bug. */
989 gcc_unreachable ();
990 }
991}
992
993#include "gt-hsa.h"