]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/hsa.c
[hsa/69674] Make testsuite libgomp.c/for-3.c compile with -m32
[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
56686608 483/* Return true if and only if TYPE is a floating point number type. */
484
485bool
486hsa_type_float_p (BrigType16_t type)
487{
488 switch (type & BRIG_TYPE_BASE_MASK)
489 {
490 case BRIG_TYPE_F16:
491 case BRIG_TYPE_F32:
492 case BRIG_TYPE_F64:
493 return true;
494 default:
495 return false;
496 }
497}
498
499/* Return true if and only if TYPE is an integer number type. */
500
501bool
502hsa_type_integer_p (BrigType16_t type)
503{
504 switch (type & BRIG_TYPE_BASE_MASK)
505 {
506 case BRIG_TYPE_U8:
507 case BRIG_TYPE_U16:
508 case BRIG_TYPE_U32:
509 case BRIG_TYPE_U64:
510 case BRIG_TYPE_S8:
511 case BRIG_TYPE_S16:
512 case BRIG_TYPE_S32:
513 case BRIG_TYPE_S64:
514 return true;
515 default:
516 return false;
517 }
518}
519
520/* Return true if and only if TYPE is an bit-type. */
521
522bool
523hsa_btype_p (BrigType16_t type)
524{
525 switch (type & BRIG_TYPE_BASE_MASK)
526 {
527 case BRIG_TYPE_B8:
528 case BRIG_TYPE_B16:
529 case BRIG_TYPE_B32:
530 case BRIG_TYPE_B64:
531 case BRIG_TYPE_B128:
532 return true;
533 default:
534 return false;
535 }
536}
537
538
539/* Return HSA alignment encoding alignment to N bits. */
540
541BrigAlignment8_t
542hsa_alignment_encoding (unsigned n)
543{
544 gcc_assert (n >= 8 && !(n & (n - 1)));
545 if (n >= 256)
546 return BRIG_ALIGNMENT_32;
547
548 switch (n)
549 {
550 case 8:
551 return BRIG_ALIGNMENT_1;
552 case 16:
553 return BRIG_ALIGNMENT_2;
554 case 32:
555 return BRIG_ALIGNMENT_4;
556 case 64:
557 return BRIG_ALIGNMENT_8;
558 case 128:
559 return BRIG_ALIGNMENT_16;
560 default:
561 gcc_unreachable ();
562 }
563}
564
565/* Return natural alignment of HSA TYPE. */
566
567BrigAlignment8_t
568hsa_natural_alignment (BrigType16_t type)
569{
570 return hsa_alignment_encoding (hsa_type_bit_size (type & ~BRIG_TYPE_ARRAY));
571}
572
573/* Call the correct destructor of a HSA instruction. */
574
575void
576hsa_destroy_insn (hsa_insn_basic *insn)
577{
578 if (hsa_insn_phi *phi = dyn_cast <hsa_insn_phi *> (insn))
579 phi->~hsa_insn_phi ();
580 else if (hsa_insn_br *br = dyn_cast <hsa_insn_br *> (insn))
581 br->~hsa_insn_br ();
582 else if (hsa_insn_cmp *cmp = dyn_cast <hsa_insn_cmp *> (insn))
583 cmp->~hsa_insn_cmp ();
584 else if (hsa_insn_mem *mem = dyn_cast <hsa_insn_mem *> (insn))
585 mem->~hsa_insn_mem ();
586 else if (hsa_insn_atomic *atomic = dyn_cast <hsa_insn_atomic *> (insn))
587 atomic->~hsa_insn_atomic ();
588 else if (hsa_insn_seg *seg = dyn_cast <hsa_insn_seg *> (insn))
589 seg->~hsa_insn_seg ();
590 else if (hsa_insn_call *call = dyn_cast <hsa_insn_call *> (insn))
591 call->~hsa_insn_call ();
592 else if (hsa_insn_arg_block *block = dyn_cast <hsa_insn_arg_block *> (insn))
593 block->~hsa_insn_arg_block ();
594 else if (hsa_insn_sbr *sbr = dyn_cast <hsa_insn_sbr *> (insn))
595 sbr->~hsa_insn_sbr ();
596 else if (hsa_insn_comment *comment = dyn_cast <hsa_insn_comment *> (insn))
597 comment->~hsa_insn_comment ();
598 else
599 insn->~hsa_insn_basic ();
600}
601
602/* Call the correct destructor of a HSA operand. */
603
604void
605hsa_destroy_operand (hsa_op_base *op)
606{
607 if (hsa_op_code_list *list = dyn_cast <hsa_op_code_list *> (op))
608 list->~hsa_op_code_list ();
609 else if (hsa_op_operand_list *list = dyn_cast <hsa_op_operand_list *> (op))
610 list->~hsa_op_operand_list ();
611 else if (hsa_op_reg *reg = dyn_cast <hsa_op_reg *> (op))
612 reg->~hsa_op_reg ();
613 else if (hsa_op_immed *immed = dyn_cast <hsa_op_immed *> (op))
614 immed->~hsa_op_immed ();
615 else
616 op->~hsa_op_base ();
617}
618
619/* Create a mapping between the original function DECL and kernel name NAME. */
620
621void
622hsa_add_kern_decl_mapping (tree decl, char *name, unsigned omp_data_size,
623 bool gridified_kernel_p)
624{
625 hsa_decl_kernel_map_element dkm;
626 dkm.decl = decl;
627 dkm.name = name;
628 dkm.omp_data_size = omp_data_size;
629 dkm.gridified_kernel_p = gridified_kernel_p;
630 vec_safe_push (hsa_decl_kernel_mapping, dkm);
631}
632
633/* Return the number of kernel decl name mappings. */
634
635unsigned
636hsa_get_number_decl_kernel_mappings (void)
637{
638 return vec_safe_length (hsa_decl_kernel_mapping);
639}
640
641/* Return the decl in the Ith kernel decl name mapping. */
642
643tree
644hsa_get_decl_kernel_mapping_decl (unsigned i)
645{
646 return (*hsa_decl_kernel_mapping)[i].decl;
647}
648
649/* Return the name in the Ith kernel decl name mapping. */
650
651char *
652hsa_get_decl_kernel_mapping_name (unsigned i)
653{
654 return (*hsa_decl_kernel_mapping)[i].name;
655}
656
657/* Return maximum OMP size for kernel decl name mapping. */
658
659unsigned
660hsa_get_decl_kernel_mapping_omp_size (unsigned i)
661{
662 return (*hsa_decl_kernel_mapping)[i].omp_data_size;
663}
664
665/* Return if the function is gridified kernel in decl name mapping. */
666
667bool
668hsa_get_decl_kernel_mapping_gridified (unsigned i)
669{
670 return (*hsa_decl_kernel_mapping)[i].gridified_kernel_p;
671}
672
673/* Free the mapping between original decls and kernel names. */
674
675void
676hsa_free_decl_kernel_mapping (void)
677{
678 if (hsa_decl_kernel_mapping == NULL)
679 return;
680
681 for (unsigned i = 0; i < hsa_decl_kernel_mapping->length (); ++i)
682 free ((*hsa_decl_kernel_mapping)[i].name);
683 ggc_free (hsa_decl_kernel_mapping);
684}
685
686/* Add new kernel dependency. */
687
688void
689hsa_add_kernel_dependency (tree caller, const char *called_function)
690{
691 if (hsa_decl_kernel_dependencies == NULL)
692 hsa_decl_kernel_dependencies = new hash_map<tree, vec<const char *> *> ();
693
694 vec <const char *> *s = NULL;
695 vec <const char *> **slot = hsa_decl_kernel_dependencies->get (caller);
696 if (slot == NULL)
697 {
698 s = new vec <const char *> ();
699 hsa_decl_kernel_dependencies->put (caller, s);
700 }
701 else
702 s = *slot;
703
704 s->safe_push (called_function);
705}
706
707/* Modify the name P in-place so that it is a valid HSA identifier. */
708
709void
710hsa_sanitize_name (char *p)
711{
712 for (; *p; p++)
713 if (*p == '.' || *p == '-')
714 *p = '_';
715}
716
717/* Clone the name P, set trailing ampersand and sanitize the name. */
718
719char *
720hsa_brig_function_name (const char *p)
721{
722 unsigned len = strlen (p);
723 char *buf = XNEWVEC (char, len + 2);
724
725 buf[0] = '&';
726 buf[len + 1] = '\0';
727 memcpy (buf + 1, p, len);
728
729 hsa_sanitize_name (buf);
730 return buf;
731}
732
733/* Return declaration name if exists. */
734
735const char *
736hsa_get_declaration_name (tree decl)
737{
738 if (!DECL_NAME (decl))
739 {
740 char buf[64];
741 snprintf (buf, 64, "__hsa_anonymous_%i", DECL_UID (decl));
742 const char *ggc_str = ggc_strdup (buf);
743 return ggc_str;
744 }
745
746 tree name_tree;
747 if (TREE_CODE (decl) == FUNCTION_DECL
748 || (TREE_CODE (decl) == VAR_DECL && is_global_var (decl)))
749 name_tree = DECL_ASSEMBLER_NAME (decl);
750 else
751 name_tree = DECL_NAME (decl);
752
753 const char *name = IDENTIFIER_POINTER (name_tree);
754 /* User-defined assembly names have prepended asterisk symbol. */
755 if (name[0] == '*')
756 name++;
757
758 return name;
759}
760
761void
762hsa_summary_t::link_functions (cgraph_node *gpu, cgraph_node *host,
763 hsa_function_kind kind, bool gridified_kernel_p)
764{
765 hsa_function_summary *gpu_summary = get (gpu);
766 hsa_function_summary *host_summary = get (host);
767
768 gpu_summary->m_kind = kind;
769 host_summary->m_kind = kind;
770
771 gpu_summary->m_gpu_implementation_p = true;
772 host_summary->m_gpu_implementation_p = false;
773
774 gpu_summary->m_gridified_kernel_p = gridified_kernel_p;
775 host_summary->m_gridified_kernel_p = gridified_kernel_p;
776
777 gpu_summary->m_binded_function = host;
778 host_summary->m_binded_function = gpu;
779
780 tree gdecl = gpu->decl;
781 DECL_ATTRIBUTES (gdecl)
782 = tree_cons (get_identifier ("flatten"), NULL_TREE,
783 DECL_ATTRIBUTES (gdecl));
784
785 tree fn_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (gdecl);
786 if (fn_opts == NULL_TREE)
787 fn_opts = optimization_default_node;
788 fn_opts = copy_node (fn_opts);
789 TREE_OPTIMIZATION (fn_opts)->x_flag_tree_loop_vectorize = false;
790 TREE_OPTIMIZATION (fn_opts)->x_flag_tree_slp_vectorize = false;
791 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (gdecl) = fn_opts;
874e154a 792
793 /* Create reference between a kernel and a corresponding host implementation
794 to quarantee LTO streaming to a same LTRANS. */
795 if (kind == HSA_KERNEL)
796 gpu->create_reference (host, IPA_REF_ADDR);
56686608 797}
798
799/* Add a HOST function to HSA summaries. */
800
801void
802hsa_register_kernel (cgraph_node *host)
803{
804 if (hsa_summaries == NULL)
805 hsa_summaries = new hsa_summary_t (symtab);
806 hsa_function_summary *s = hsa_summaries->get (host);
807 s->m_kind = HSA_KERNEL;
808}
809
810/* Add a pair of functions to HSA summaries. GPU is an HSA implementation of
811 a HOST function. */
812
813void
814hsa_register_kernel (cgraph_node *gpu, cgraph_node *host)
815{
816 if (hsa_summaries == NULL)
817 hsa_summaries = new hsa_summary_t (symtab);
818 hsa_summaries->link_functions (gpu, host, HSA_KERNEL, true);
819}
820
821/* Return true if expansion of the current HSA function has already failed. */
822
823bool
824hsa_seen_error (void)
825{
826 return hsa_cfun->m_seen_error;
827}
828
829/* Mark current HSA function as failed. */
830
831void
832hsa_fail_cfun (void)
833{
834 hsa_failed_functions->add (hsa_cfun->m_decl);
835 hsa_cfun->m_seen_error = true;
836}
837
838char *
839hsa_internal_fn::name ()
840{
841 char *name = xstrdup (internal_fn_name (m_fn));
842 for (char *ptr = name; *ptr; ptr++)
843 *ptr = TOLOWER (*ptr);
844
845 const char *suffix = NULL;
846 if (m_type_bit_size == 32)
847 suffix = "f";
848
849 if (suffix)
850 {
851 char *name2 = concat (name, suffix, NULL);
852 free (name);
853 name = name2;
854 }
855
856 hsa_sanitize_name (name);
857 return name;
858}
859
860unsigned
861hsa_internal_fn::get_arity ()
862{
863 switch (m_fn)
864 {
865 case IFN_ACOS:
866 case IFN_ASIN:
867 case IFN_ATAN:
868 case IFN_COS:
869 case IFN_EXP:
870 case IFN_EXP10:
871 case IFN_EXP2:
872 case IFN_EXPM1:
873 case IFN_LOG:
874 case IFN_LOG10:
875 case IFN_LOG1P:
876 case IFN_LOG2:
877 case IFN_LOGB:
878 case IFN_SIGNIFICAND:
879 case IFN_SIN:
880 case IFN_SQRT:
881 case IFN_TAN:
882 case IFN_CEIL:
883 case IFN_FLOOR:
884 case IFN_NEARBYINT:
885 case IFN_RINT:
886 case IFN_ROUND:
887 case IFN_TRUNC:
888 return 1;
889 case IFN_ATAN2:
890 case IFN_COPYSIGN:
891 case IFN_FMOD:
892 case IFN_POW:
893 case IFN_REMAINDER:
894 case IFN_SCALB:
895 case IFN_LDEXP:
896 return 2;
897 break;
898 case IFN_CLRSB:
899 case IFN_CLZ:
900 case IFN_CTZ:
901 case IFN_FFS:
902 case IFN_PARITY:
903 case IFN_POPCOUNT:
904 default:
905 /* As we produce sorry message for unknown internal functions,
906 reaching this label is definitely a bug. */
907 gcc_unreachable ();
908 }
909}
910
911BrigType16_t
912hsa_internal_fn::get_argument_type (int n)
913{
914 switch (m_fn)
915 {
916 case IFN_ACOS:
917 case IFN_ASIN:
918 case IFN_ATAN:
919 case IFN_COS:
920 case IFN_EXP:
921 case IFN_EXP10:
922 case IFN_EXP2:
923 case IFN_EXPM1:
924 case IFN_LOG:
925 case IFN_LOG10:
926 case IFN_LOG1P:
927 case IFN_LOG2:
928 case IFN_LOGB:
929 case IFN_SIGNIFICAND:
930 case IFN_SIN:
931 case IFN_SQRT:
932 case IFN_TAN:
933 case IFN_CEIL:
934 case IFN_FLOOR:
935 case IFN_NEARBYINT:
936 case IFN_RINT:
937 case IFN_ROUND:
938 case IFN_TRUNC:
939 case IFN_ATAN2:
940 case IFN_COPYSIGN:
941 case IFN_FMOD:
942 case IFN_POW:
943 case IFN_REMAINDER:
944 case IFN_SCALB:
945 return hsa_float_for_bitsize (m_type_bit_size);
946 case IFN_LDEXP:
947 {
948 if (n == -1 || n == 0)
949 return hsa_float_for_bitsize (m_type_bit_size);
950 else
951 return BRIG_TYPE_S32;
952 }
953 default:
954 /* As we produce sorry message for unknown internal functions,
955 reaching this label is definitely a bug. */
956 gcc_unreachable ();
957 }
958}
959
960#include "gt-hsa.h"