1 /* Infrastructure to dump our HSAIL IL
2    Copyright (C) 2013-2020 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 "vec.h"
28 #include "tree.h"
29 #include "basic-block.h"
30 #include "function.h"
31 #include "cfg.h"
32 #include "dumpfile.h"
33 #include "gimple-pretty-print.h"
34 #include "cgraph.h"
35 #include "print-tree.h"
36 #include "alloc-pool.h"
37 #include "symbol-summary.h"
38 #include "hsa-common.h"
39 
40 /* Return textual name of TYPE.  */
41 
42 static const char *
hsa_type_name(BrigType16_t type)43 hsa_type_name (BrigType16_t type)
44 {
45   switch (type)
46     {
47     case BRIG_TYPE_NONE:
48       return "none";
49     case BRIG_TYPE_U8:
50       return "u8";
51     case BRIG_TYPE_U16:
52       return "u16";
53     case BRIG_TYPE_U32:
54       return "u32";
55     case BRIG_TYPE_U64:
56       return "u64";
57     case BRIG_TYPE_S8:
58       return "s8";
59     case BRIG_TYPE_S16:
60       return "s16";
61     case BRIG_TYPE_S32:
62       return "s32";
63     case BRIG_TYPE_S64:
64       return "s64";
65     case BRIG_TYPE_F16:
66       return "f16";
67     case BRIG_TYPE_F32:
68       return "f32";
69     case BRIG_TYPE_F64:
70       return "f64";
71     case BRIG_TYPE_B1:
72       return "b1";
73     case BRIG_TYPE_B8:
74       return "b8";
75     case BRIG_TYPE_B16:
76       return "b16";
77     case BRIG_TYPE_B32:
78       return "b32";
79     case BRIG_TYPE_B64:
80       return "b64";
81     case BRIG_TYPE_B128:
82       return "b128";
83     case BRIG_TYPE_SAMP:
84       return "samp";
85     case BRIG_TYPE_ROIMG:
86       return "roimg";
87     case BRIG_TYPE_WOIMG:
88       return "woimg";
89     case BRIG_TYPE_RWIMG:
90       return "rwimg";
91     case BRIG_TYPE_SIG32:
92       return "sig32";
93     case BRIG_TYPE_SIG64:
94       return "sig64";
95     case BRIG_TYPE_U8X4:
96       return "u8x4";
97     case BRIG_TYPE_U8X8:
98       return "u8x8";
99     case BRIG_TYPE_U8X16:
100       return "u8x16";
101     case BRIG_TYPE_U16X2:
102       return "u16x2";
103     case BRIG_TYPE_U16X4:
104       return "u16x4";
105     case BRIG_TYPE_U16X8:
106       return "u16x8";
107     case BRIG_TYPE_U32X2:
108       return "u32x2";
109     case BRIG_TYPE_U32X4:
110       return "u32x4";
111     case BRIG_TYPE_U64X2:
112       return "u64x2";
113     case BRIG_TYPE_S8X4:
114       return "s8x4";
115     case BRIG_TYPE_S8X8:
116       return "s8x8";
117     case BRIG_TYPE_S8X16:
118       return "s8x16";
119     case BRIG_TYPE_S16X2:
120       return "s16x2";
121     case BRIG_TYPE_S16X4:
122       return "s16x4";
123     case BRIG_TYPE_S16X8:
124       return "s16x8";
125     case BRIG_TYPE_S32X2:
126       return "s32x2";
127     case BRIG_TYPE_S32X4:
128       return "s32x4";
129     case BRIG_TYPE_S64X2:
130       return "s64x2";
131     case BRIG_TYPE_F16X2:
132       return "f16x2";
133     case BRIG_TYPE_F16X4:
134       return "f16x4";
135     case BRIG_TYPE_F16X8:
136       return "f16x8";
137     case BRIG_TYPE_F32X2:
138       return "f32x2";
139     case BRIG_TYPE_F32X4:
140       return "f32x4";
141     case BRIG_TYPE_F64X2:
142       return "f64x2";
143     default:
144       return "UNKNOWN_TYPE";
145     }
146 }
147 
148 /* Return textual name of OPCODE.  */
149 
150 static const char *
hsa_opcode_name(BrigOpcode16_t opcode)151 hsa_opcode_name (BrigOpcode16_t opcode)
152 {
153   switch (opcode)
154     {
155     case BRIG_OPCODE_NOP:
156       return "nop";
157     case BRIG_OPCODE_ABS:
158       return "abs";
159     case BRIG_OPCODE_ADD:
160       return "add";
161     case BRIG_OPCODE_BORROW:
162       return "borrow";
163     case BRIG_OPCODE_CARRY:
164       return "carry";
165     case BRIG_OPCODE_CEIL:
166       return "ceil";
167     case BRIG_OPCODE_COPYSIGN:
168       return "copysign";
169     case BRIG_OPCODE_DIV:
170       return "div";
171     case BRIG_OPCODE_FLOOR:
172       return "floor";
173     case BRIG_OPCODE_FMA:
174       return "fma";
175     case BRIG_OPCODE_FRACT:
176       return "fract";
177     case BRIG_OPCODE_MAD:
178       return "mad";
179     case BRIG_OPCODE_MAX:
180       return "max";
181     case BRIG_OPCODE_MIN:
182       return "min";
183     case BRIG_OPCODE_MUL:
184       return "mul";
185     case BRIG_OPCODE_MULHI:
186       return "mulhi";
187     case BRIG_OPCODE_NEG:
188       return "neg";
189     case BRIG_OPCODE_REM:
190       return "rem";
191     case BRIG_OPCODE_RINT:
192       return "rint";
193     case BRIG_OPCODE_SQRT:
194       return "sqrt";
195     case BRIG_OPCODE_SUB:
196       return "sub";
197     case BRIG_OPCODE_TRUNC:
198       return "trunc";
199     case BRIG_OPCODE_MAD24:
200       return "mad24";
201     case BRIG_OPCODE_MAD24HI:
202       return "mad24hi";
203     case BRIG_OPCODE_MUL24:
204       return "mul24";
205     case BRIG_OPCODE_MUL24HI:
206       return "mul24hi";
207     case BRIG_OPCODE_SHL:
208       return "shl";
209     case BRIG_OPCODE_SHR:
210       return "shr";
211     case BRIG_OPCODE_AND:
212       return "and";
213     case BRIG_OPCODE_NOT:
214       return "not";
215     case BRIG_OPCODE_OR:
216       return "or";
217     case BRIG_OPCODE_POPCOUNT:
218       return "popcount";
219     case BRIG_OPCODE_XOR:
220       return "xor";
221     case BRIG_OPCODE_BITEXTRACT:
222       return "bitextract";
223     case BRIG_OPCODE_BITINSERT:
224       return "bitinsert";
225     case BRIG_OPCODE_BITMASK:
226       return "bitmask";
227     case BRIG_OPCODE_BITREV:
228       return "bitrev";
229     case BRIG_OPCODE_BITSELECT:
230       return "bitselect";
231     case BRIG_OPCODE_FIRSTBIT:
232       return "firstbit";
233     case BRIG_OPCODE_LASTBIT:
234       return "lastbit";
235     case BRIG_OPCODE_COMBINE:
236       return "combine";
237     case BRIG_OPCODE_EXPAND:
238       return "expand";
239     case BRIG_OPCODE_LDA:
240       return "lda";
241     case BRIG_OPCODE_MOV:
242       return "mov";
243     case BRIG_OPCODE_SHUFFLE:
244       return "shuffle";
245     case BRIG_OPCODE_UNPACKHI:
246       return "unpackhi";
247     case BRIG_OPCODE_UNPACKLO:
248       return "unpacklo";
249     case BRIG_OPCODE_PACK:
250       return "pack";
251     case BRIG_OPCODE_UNPACK:
252       return "unpack";
253     case BRIG_OPCODE_CMOV:
254       return "cmov";
255     case BRIG_OPCODE_CLASS:
256       return "class";
257     case BRIG_OPCODE_NCOS:
258       return "ncos";
259     case BRIG_OPCODE_NEXP2:
260       return "nexp2";
261     case BRIG_OPCODE_NFMA:
262       return "nfma";
263     case BRIG_OPCODE_NLOG2:
264       return "nlog2";
265     case BRIG_OPCODE_NRCP:
266       return "nrcp";
267     case BRIG_OPCODE_NRSQRT:
268       return "nrsqrt";
269     case BRIG_OPCODE_NSIN:
270       return "nsin";
271     case BRIG_OPCODE_NSQRT:
272       return "nsqrt";
273     case BRIG_OPCODE_BITALIGN:
274       return "bitalign";
275     case BRIG_OPCODE_BYTEALIGN:
276       return "bytealign";
277     case BRIG_OPCODE_PACKCVT:
278       return "packcvt";
279     case BRIG_OPCODE_UNPACKCVT:
280       return "unpackcvt";
281     case BRIG_OPCODE_LERP:
282       return "lerp";
283     case BRIG_OPCODE_SAD:
284       return "sad";
285     case BRIG_OPCODE_SADHI:
286       return "sadhi";
287     case BRIG_OPCODE_SEGMENTP:
288       return "segmentp";
289     case BRIG_OPCODE_FTOS:
290       return "ftos";
291     case BRIG_OPCODE_STOF:
292       return "stof";
293     case BRIG_OPCODE_CMP:
294       return "cmp";
295     case BRIG_OPCODE_CVT:
296       return "cvt";
297     case BRIG_OPCODE_LD:
298       return "ld";
299     case BRIG_OPCODE_ST:
300       return "st";
301     case BRIG_OPCODE_ATOMIC:
302       return "atomic";
303     case BRIG_OPCODE_ATOMICNORET:
304       return "atomicnoret";
305     case BRIG_OPCODE_SIGNAL:
306       return "signal";
307     case BRIG_OPCODE_SIGNALNORET:
308       return "signalnoret";
309     case BRIG_OPCODE_MEMFENCE:
310       return "memfence";
311     case BRIG_OPCODE_RDIMAGE:
312       return "rdimage";
313     case BRIG_OPCODE_LDIMAGE:
314       return "ldimage";
315     case BRIG_OPCODE_STIMAGE:
316       return "stimage";
317     case BRIG_OPCODE_QUERYIMAGE:
318       return "queryimage";
319     case BRIG_OPCODE_QUERYSAMPLER:
320       return "querysampler";
321     case BRIG_OPCODE_CBR:
322       return "cbr";
323     case BRIG_OPCODE_BR:
324       return "br";
325     case BRIG_OPCODE_SBR:
326       return "sbr";
327     case BRIG_OPCODE_BARRIER:
328       return "barrier";
329     case BRIG_OPCODE_WAVEBARRIER:
330       return "wavebarrier";
331     case BRIG_OPCODE_ARRIVEFBAR:
332       return "arrivefbar";
333     case BRIG_OPCODE_INITFBAR:
334       return "initfbar";
335     case BRIG_OPCODE_JOINFBAR:
336       return "joinfbar";
337     case BRIG_OPCODE_LEAVEFBAR:
338       return "leavefbar";
339     case BRIG_OPCODE_RELEASEFBAR:
340       return "releasefbar";
341     case BRIG_OPCODE_WAITFBAR:
342       return "waitfbar";
343     case BRIG_OPCODE_LDF:
344       return "ldf";
345     case BRIG_OPCODE_ACTIVELANECOUNT:
346       return "activelanecount";
347     case BRIG_OPCODE_ACTIVELANEID:
348       return "activelaneid";
349     case BRIG_OPCODE_ACTIVELANEMASK:
350       return "activelanemask";
351     case BRIG_OPCODE_CALL:
352       return "call";
353     case BRIG_OPCODE_SCALL:
354       return "scall";
355     case BRIG_OPCODE_ICALL:
356       return "icall";
357     case BRIG_OPCODE_RET:
358       return "ret";
359     case BRIG_OPCODE_ALLOCA:
360       return "alloca";
361     case BRIG_OPCODE_CURRENTWORKGROUPSIZE:
362       return "currentworkgroupsize";
363     case BRIG_OPCODE_DIM:
364       return "dim";
365     case BRIG_OPCODE_GRIDGROUPS:
366       return "gridgroups";
367     case BRIG_OPCODE_GRIDSIZE:
368       return "gridsize";
369     case BRIG_OPCODE_PACKETCOMPLETIONSIG:
370       return "packetcompletionsig";
371     case BRIG_OPCODE_PACKETID:
372       return "packetid";
373     case BRIG_OPCODE_WORKGROUPID:
374       return "workgroupid";
375     case BRIG_OPCODE_WORKGROUPSIZE:
376       return "workgroupsize";
377     case BRIG_OPCODE_WORKITEMABSID:
378       return "workitemabsid";
379     case BRIG_OPCODE_WORKITEMFLATABSID:
380       return "workitemflatabsid";
381     case BRIG_OPCODE_WORKITEMFLATID:
382       return "workitemflatid";
383     case BRIG_OPCODE_WORKITEMID:
384       return "workitemid";
385     case BRIG_OPCODE_CLEARDETECTEXCEPT:
386       return "cleardetectexcept";
387     case BRIG_OPCODE_GETDETECTEXCEPT:
388       return "getdetectexcept";
389     case BRIG_OPCODE_SETDETECTEXCEPT:
390       return "setdetectexcept";
391     case BRIG_OPCODE_ADDQUEUEWRITEINDEX:
392       return "addqueuewriteindex";
393     case BRIG_OPCODE_CASQUEUEWRITEINDEX:
394       return "casqueuewriteindex";
395     case BRIG_OPCODE_LDQUEUEREADINDEX:
396       return "ldqueuereadindex";
397     case BRIG_OPCODE_LDQUEUEWRITEINDEX:
398       return "ldqueuewriteindex";
399     case BRIG_OPCODE_STQUEUEREADINDEX:
400       return "stqueuereadindex";
401     case BRIG_OPCODE_STQUEUEWRITEINDEX:
402       return "stqueuewriteindex";
403     case BRIG_OPCODE_CLOCK:
404       return "clock";
405     case BRIG_OPCODE_CUID:
406       return "cuid";
407     case BRIG_OPCODE_DEBUGTRAP:
408       return "debugtrap";
409     case BRIG_OPCODE_GROUPBASEPTR:
410       return "groupbaseptr";
411     case BRIG_OPCODE_KERNARGBASEPTR:
412       return "kernargbaseptr";
413     case BRIG_OPCODE_LANEID:
414       return "laneid";
415     case BRIG_OPCODE_MAXCUID:
416       return "maxcuid";
417     case BRIG_OPCODE_MAXWAVEID:
418       return "maxwaveid";
419     case BRIG_OPCODE_NULLPTR:
420       return "nullptr";
421     case BRIG_OPCODE_WAVEID:
422       return "waveid";
423     default:
424       return "UNKNOWN_OPCODE";
425     }
426 }
427 
428 /* Return textual name of SEG.  */
429 
430 const char *
hsa_seg_name(BrigSegment8_t seg)431 hsa_seg_name (BrigSegment8_t seg)
432 {
433   switch (seg)
434     {
435     case BRIG_SEGMENT_NONE:
436       return "none";
437     case BRIG_SEGMENT_FLAT:
438       return "flat";
439     case BRIG_SEGMENT_GLOBAL:
440       return "global";
441     case BRIG_SEGMENT_READONLY:
442       return "readonly";
443     case BRIG_SEGMENT_KERNARG:
444       return "kernarg";
445     case BRIG_SEGMENT_GROUP:
446       return "group";
447     case BRIG_SEGMENT_PRIVATE:
448       return "private";
449     case BRIG_SEGMENT_SPILL:
450       return "spill";
451     case BRIG_SEGMENT_ARG:
452       return "arg";
453     default:
454       return "UNKNOWN_SEGMENT";
455     }
456 }
457 
458 /* Return textual name of CMPOP.  */
459 
460 static const char *
hsa_cmpop_name(BrigCompareOperation8_t cmpop)461 hsa_cmpop_name (BrigCompareOperation8_t cmpop)
462 {
463   switch (cmpop)
464     {
465     case BRIG_COMPARE_EQ:
466       return "eq";
467     case BRIG_COMPARE_NE:
468       return "ne";
469     case BRIG_COMPARE_LT:
470       return "lt";
471     case BRIG_COMPARE_LE:
472       return "le";
473     case BRIG_COMPARE_GT:
474       return "gt";
475     case BRIG_COMPARE_GE:
476       return "ge";
477     case BRIG_COMPARE_EQU:
478       return "equ";
479     case BRIG_COMPARE_NEU:
480       return "neu";
481     case BRIG_COMPARE_LTU:
482       return "ltu";
483     case BRIG_COMPARE_LEU:
484       return "leu";
485     case BRIG_COMPARE_GTU:
486       return "gtu";
487     case BRIG_COMPARE_GEU:
488       return "geu";
489     case BRIG_COMPARE_NUM:
490       return "num";
491     case BRIG_COMPARE_NAN:
492       return "nan";
493     case BRIG_COMPARE_SEQ:
494       return "seq";
495     case BRIG_COMPARE_SNE:
496       return "sne";
497     case BRIG_COMPARE_SLT:
498       return "slt";
499     case BRIG_COMPARE_SLE:
500       return "sle";
501     case BRIG_COMPARE_SGT:
502       return "sgt";
503     case BRIG_COMPARE_SGE:
504       return "sge";
505     case BRIG_COMPARE_SGEU:
506       return "sgeu";
507     case BRIG_COMPARE_SEQU:
508       return "sequ";
509     case BRIG_COMPARE_SNEU:
510       return "sneu";
511     case BRIG_COMPARE_SLTU:
512       return "sltu";
513     case BRIG_COMPARE_SLEU:
514       return "sleu";
515     case BRIG_COMPARE_SNUM:
516       return "snum";
517     case BRIG_COMPARE_SNAN:
518       return "snan";
519     case BRIG_COMPARE_SGTU:
520       return "sgtu";
521     default:
522       return "UNKNOWN_COMPARISON";
523     }
524 }
525 
526 /* Return textual name for memory order.  */
527 
528 static const char *
hsa_memsem_name(enum BrigMemoryOrder mo)529 hsa_memsem_name (enum BrigMemoryOrder mo)
530 {
531   switch (mo)
532     {
533     case BRIG_MEMORY_ORDER_NONE:
534       return "";
535     case BRIG_MEMORY_ORDER_RELAXED:
536       return "rlx";
537     case BRIG_MEMORY_ORDER_SC_ACQUIRE:
538       return "scacq";
539     case BRIG_MEMORY_ORDER_SC_RELEASE:
540       return "screl";
541     case BRIG_MEMORY_ORDER_SC_ACQUIRE_RELEASE:
542       return "scar";
543     default:
544       return "UNKNOWN_MEMORY_ORDER";
545     }
546 }
547 
548 /* Return textual name for memory scope.  */
549 
550 static const char *
hsa_memscope_name(enum BrigMemoryScope scope)551 hsa_memscope_name (enum BrigMemoryScope scope)
552 {
553   switch (scope)
554     {
555     case BRIG_MEMORY_SCOPE_NONE:
556       return "";
557     case BRIG_MEMORY_SCOPE_WORKITEM:
558       return "wi";
559     case BRIG_MEMORY_SCOPE_WAVEFRONT:
560       return "wave";
561     case BRIG_MEMORY_SCOPE_WORKGROUP:
562       return "wg";
563     case BRIG_MEMORY_SCOPE_AGENT:
564       return "agent";
565     case BRIG_MEMORY_SCOPE_SYSTEM:
566       return "sys";
567     default:
568       return "UNKNOWN_SCOPE";
569     }
570 }
571 
572 /* Return textual name for atomic operation.  */
573 
574 static const char *
hsa_m_atomicop_name(enum BrigAtomicOperation op)575 hsa_m_atomicop_name (enum BrigAtomicOperation op)
576 {
577   switch (op)
578     {
579     case BRIG_ATOMIC_ADD:
580       return "add";
581     case BRIG_ATOMIC_AND:
582       return "and";
583     case BRIG_ATOMIC_CAS:
584       return "cas";
585     case BRIG_ATOMIC_EXCH:
586       return "exch";
587     case BRIG_ATOMIC_LD:
588       return "ld";
589     case BRIG_ATOMIC_MAX:
590       return "max";
591     case BRIG_ATOMIC_MIN:
592       return "min";
593     case BRIG_ATOMIC_OR:
594       return "or";
595     case BRIG_ATOMIC_ST:
596       return "st";
597     case BRIG_ATOMIC_SUB:
598       return "sub";
599     case BRIG_ATOMIC_WRAPDEC:
600       return "wrapdec";
601     case BRIG_ATOMIC_WRAPINC:
602       return "wrapinc";
603     case BRIG_ATOMIC_XOR:
604       return "xor";
605     case BRIG_ATOMIC_WAIT_EQ:
606       return "wait_eq";
607     case BRIG_ATOMIC_WAIT_NE:
608       return "wait_ne";
609     case BRIG_ATOMIC_WAIT_LT:
610       return "wait_lt";
611     case BRIG_ATOMIC_WAIT_GTE:
612       return "wait_gte";
613     case BRIG_ATOMIC_WAITTIMEOUT_EQ:
614       return "waittimeout_eq";
615     case BRIG_ATOMIC_WAITTIMEOUT_NE:
616       return "waittimeout_ne";
617     case BRIG_ATOMIC_WAITTIMEOUT_LT:
618       return "waittimeout_lt";
619     case BRIG_ATOMIC_WAITTIMEOUT_GTE:
620       return "waittimeout_gte";
621     default:
622       return "UNKNOWN_ATOMIC_OP";
623     }
624 }
625 
626 /* Return textual name for atomic operation.  */
627 
628 static const char *
hsa_width_specifier_name(BrigWidth8_t width)629 hsa_width_specifier_name (BrigWidth8_t width)
630 {
631   switch (width)
632     {
633     case BRIG_WIDTH_NONE:
634       return "none";
635     case BRIG_WIDTH_1:
636       return "1";
637     case BRIG_WIDTH_2:
638       return "2";
639     case BRIG_WIDTH_4:
640       return "4";
641     case BRIG_WIDTH_8:
642       return "8";
643     case BRIG_WIDTH_16:
644       return "16";
645     case BRIG_WIDTH_32:
646       return "32";
647     case BRIG_WIDTH_64:
648       return "64";
649     case BRIG_WIDTH_128:
650       return "128";
651     case BRIG_WIDTH_256:
652       return "256";
653     case BRIG_WIDTH_512:
654       return "512";
655     case BRIG_WIDTH_1024:
656       return "1024";
657     case BRIG_WIDTH_2048:
658       return "2048";
659     case BRIG_WIDTH_4096:
660       return "4096";
661     case BRIG_WIDTH_8192:
662       return "8192";
663     case BRIG_WIDTH_16384:
664       return "16384";
665     case BRIG_WIDTH_32768:
666       return "32768";
667     case BRIG_WIDTH_65536:
668       return "65536";
669     case BRIG_WIDTH_131072:
670       return "131072";
671     case BRIG_WIDTH_262144:
672       return "262144";
673     case BRIG_WIDTH_524288:
674       return "524288";
675     case BRIG_WIDTH_1048576:
676       return "1048576";
677     case BRIG_WIDTH_2097152:
678       return "2097152";
679     case BRIG_WIDTH_4194304:
680       return "4194304";
681     case BRIG_WIDTH_8388608:
682       return "8388608";
683     case BRIG_WIDTH_16777216:
684       return "16777216";
685     case BRIG_WIDTH_33554432:
686       return "33554432";
687     case BRIG_WIDTH_67108864:
688       return "67108864";
689     case BRIG_WIDTH_134217728:
690       return "134217728";
691     case BRIG_WIDTH_268435456:
692       return "268435456";
693     case BRIG_WIDTH_536870912:
694       return "536870912";
695     case BRIG_WIDTH_1073741824:
696       return "1073741824";
697     case BRIG_WIDTH_2147483648:
698       return "2147483648";
699     case BRIG_WIDTH_WAVESIZE:
700       return "wavesize";
701     case BRIG_WIDTH_ALL:
702       return "all";
703     default:
704       return "UNKNOWN_WIDTH";
705     }
706 }
707 
708 /* Dump textual representation of HSA IL register REG to file F.  */
709 
710 static void
711 dump_hsa_reg (FILE *f, hsa_op_reg *reg, bool dump_type = false)
712 {
713   if (reg->m_reg_class)
714     fprintf (f, "$%c%i", reg->m_reg_class, reg->m_hard_num);
715   else
716     fprintf (f, "$_%i", reg->m_order);
717   if (dump_type)
718     fprintf (f, " (%s)", hsa_type_name (reg->m_type));
719 }
720 
721 /* Dump textual representation of HSA IL immediate operand IMM to file F.  */
722 
723 static void
dump_hsa_immed(FILE * f,hsa_op_immed * imm)724 dump_hsa_immed (FILE *f, hsa_op_immed *imm)
725 {
726   bool unsigned_int_type
727     = (BRIG_TYPE_U8 | BRIG_TYPE_U16 | BRIG_TYPE_U32 | BRIG_TYPE_U64)
728     & imm->m_type;
729 
730   if (imm->m_tree_value)
731     print_generic_expr (f, imm->m_tree_value);
732   else
733     {
734       if (unsigned_int_type)
735 	fprintf (f, HOST_WIDE_INT_PRINT_DEC, imm->m_int_value);
736       else
737 	fprintf (f, HOST_WIDE_INT_PRINT_UNSIGNED,
738 		 (unsigned HOST_WIDE_INT) imm->m_int_value);
739     }
740 
741   fprintf (f, " (%s)", hsa_type_name (imm->m_type));
742 }
743 
744 /* Dump textual representation of HSA IL address operand ADDR to file F.  */
745 
746 static void
dump_hsa_address(FILE * f,hsa_op_address * addr)747 dump_hsa_address (FILE *f, hsa_op_address *addr)
748 {
749   bool sth = false;
750 
751   if (addr->m_symbol)
752     {
753       sth = true;
754       if (addr->m_symbol->m_name)
755 	fprintf (f, "[%%%s]", addr->m_symbol->m_name);
756       else
757 	fprintf (f, "[%%__%s_%i]", hsa_seg_name (addr->m_symbol->m_segment),
758 		 addr->m_symbol->m_name_number);
759     }
760 
761   if (addr->m_reg)
762     {
763       fprintf (f, "[");
764       dump_hsa_reg (f, addr->m_reg);
765       if (addr->m_imm_offset != 0)
766 	fprintf (f, " + " HOST_WIDE_INT_PRINT_DEC "]", addr->m_imm_offset);
767       else
768 	fprintf (f, "]");
769     }
770   else if (!sth || addr->m_imm_offset != 0)
771     fprintf (f, "[" HOST_WIDE_INT_PRINT_DEC "]", addr->m_imm_offset);
772 }
773 
774 /* Dump textual representation of HSA IL symbol SYMBOL to file F.  */
775 
776 static void
dump_hsa_symbol(FILE * f,hsa_symbol * symbol)777 dump_hsa_symbol (FILE *f, hsa_symbol *symbol)
778 {
779   const char *name;
780   char buf[64];
781   if (symbol->m_name)
782     name = symbol->m_name;
783   else
784     {
785       sprintf (buf, "__%s_%i", hsa_seg_name (symbol->m_segment),
786 	       symbol->m_name_number);
787 
788       name = buf;
789     }
790 
791   fprintf (f, "align(%u) %s_%s %s", hsa_byte_alignment (symbol->m_align),
792 	   hsa_seg_name (symbol->m_segment),
793 	   hsa_type_name (symbol->m_type & ~BRIG_TYPE_ARRAY_MASK), name);
794 
795   if (symbol->m_type & BRIG_TYPE_ARRAY_MASK)
796     fprintf (f, "[%lu]", (unsigned long) symbol->m_dim);
797 
798   if (symbol->m_directive_offset)
799     fprintf (f, "             /* BRIG offset: %u */", symbol->m_directive_offset);
800 }
801 
802 /* Dump textual representation of HSA IL operand OP to file F.  */
803 
804 static void
805 dump_hsa_operand (FILE *f, hsa_op_base *op, bool dump_reg_type = false)
806 {
807   if (is_a <hsa_op_immed *> (op))
808     dump_hsa_immed (f, as_a <hsa_op_immed *> (op));
809   else if (is_a <hsa_op_reg *> (op))
810     dump_hsa_reg (f, as_a <hsa_op_reg *> (op), dump_reg_type);
811   else if (is_a <hsa_op_address *> (op))
812     dump_hsa_address (f, as_a <hsa_op_address *> (op));
813   else
814     fprintf (f, "UNKNOWN_OP_KIND");
815 }
816 
817 /* Dump textual representation of HSA IL operands in VEC to file F.  */
818 
819 static void
820 dump_hsa_operands (FILE *f, hsa_insn_basic *insn, int start = 0,
821 		   int end = -1, bool dump_reg_type = false)
822 {
823   if (end == -1)
824     end = insn->operand_count ();
825 
826   for (int i = start; i < end; i++)
827     {
828       dump_hsa_operand (f, insn->get_op (i), dump_reg_type);
829       if (i != end - 1)
830 	fprintf (f, ", ");
831     }
832 }
833 
834 /* Indent F stream with INDENT spaces.  */
835 
indent_stream(FILE * f,int indent)836 static void indent_stream (FILE *f, int indent)
837 {
838   for (int i = 0; i < indent; i++)
839     fputc (' ', f);
840 }
841 
842 /* Dump textual representation of HSA IL instruction INSN to file F.  Prepend
843    the instruction with *INDENT spaces and adjust the indentation for call
844    instructions as appropriate.  */
845 
846 static void
dump_hsa_insn_1(FILE * f,hsa_insn_basic * insn,int * indent)847 dump_hsa_insn_1 (FILE *f, hsa_insn_basic *insn, int *indent)
848 {
849   gcc_checking_assert (insn);
850 
851   if (insn->m_number)
852     fprintf (f, "%5d: ", insn->m_number);
853 
854   indent_stream (f, *indent);
855 
856   if (is_a <hsa_insn_phi *> (insn))
857     {
858       hsa_insn_phi *phi = as_a <hsa_insn_phi *> (insn);
859       bool first = true;
860       dump_hsa_reg (f, phi->m_dest, true);
861       fprintf (f, " = PHI <");
862       unsigned count = phi->operand_count ();
863       for (unsigned i = 0; i < count; i++)
864 	{
865 	  if (!phi->get_op (i))
866 	    break;
867 	  if (!first)
868 	    fprintf (f, ", ");
869 	  else
870 	    first = false;
871 	  dump_hsa_operand (f, phi->get_op (i), true);
872 	}
873       fprintf (f, ">");
874     }
875   else if (is_a <hsa_insn_signal *> (insn))
876     {
877       hsa_insn_signal *mem = as_a <hsa_insn_signal *> (insn);
878 
879       fprintf (f, "%s", hsa_opcode_name (mem->m_opcode));
880       fprintf (f, "_%s", hsa_m_atomicop_name (mem->m_signalop));
881       if (mem->m_memory_order != BRIG_MEMORY_ORDER_NONE)
882 	fprintf (f, "_%s", hsa_memsem_name (mem->m_memory_order));
883       fprintf (f, "_%s ", hsa_type_name (mem->m_type));
884 
885       dump_hsa_operands (f, mem);
886     }
887 
888   else if (is_a <hsa_insn_atomic *> (insn))
889     {
890       hsa_insn_atomic *mem = as_a <hsa_insn_atomic *> (insn);
891 
892       /* Either operand[0] or operand[1] must be an address operand.  */
893       hsa_op_address *addr = NULL;
894       if (is_a <hsa_op_address *> (mem->get_op (0)))
895 	addr = as_a <hsa_op_address *> (mem->get_op (0));
896       else
897 	addr = as_a <hsa_op_address *> (mem->get_op (1));
898 
899       fprintf (f, "%s", hsa_opcode_name (mem->m_opcode));
900       fprintf (f, "_%s", hsa_m_atomicop_name (mem->m_atomicop));
901       if (addr->m_symbol)
902 	fprintf (f, "_%s", hsa_seg_name (addr->m_symbol->m_segment));
903       if (mem->m_memoryorder != BRIG_MEMORY_ORDER_NONE)
904 	fprintf (f, "_%s", hsa_memsem_name (mem->m_memoryorder));
905       if (mem->m_memoryscope != BRIG_MEMORY_SCOPE_NONE)
906 	fprintf (f, "_%s", hsa_memscope_name (mem->m_memoryscope));
907       fprintf (f, "_%s ", hsa_type_name (mem->m_type));
908 
909       dump_hsa_operands (f, mem);
910     }
911   else if (is_a <hsa_insn_mem *> (insn))
912     {
913       hsa_insn_mem *mem = as_a <hsa_insn_mem *> (insn);
914       hsa_op_address *addr = as_a <hsa_op_address *> (mem->get_op (1));
915 
916       fprintf (f, "%s", hsa_opcode_name (mem->m_opcode));
917       if (addr->m_symbol)
918 	fprintf (f, "_%s", hsa_seg_name (addr->m_symbol->m_segment));
919       if (mem->m_align != BRIG_ALIGNMENT_NONE)
920 	fprintf (f, "_align(%u)", hsa_byte_alignment (mem->m_align));
921       if (mem->m_equiv_class != 0)
922 	fprintf (f, "_equiv(%i)", mem->m_equiv_class);
923       fprintf (f, "_%s ", hsa_type_name (mem->m_type));
924 
925       dump_hsa_operand (f, mem->get_op (0));
926       fprintf (f, ", ");
927       dump_hsa_address (f, addr);
928     }
929   else if (insn->m_opcode == BRIG_OPCODE_LDA)
930     {
931       hsa_op_address *addr = as_a <hsa_op_address *> (insn->get_op (1));
932 
933       fprintf (f, "%s", hsa_opcode_name (insn->m_opcode));
934       if (addr->m_symbol)
935 	fprintf (f, "_%s", hsa_seg_name (addr->m_symbol->m_segment));
936       fprintf (f, "_%s ", hsa_type_name (insn->m_type));
937 
938       dump_hsa_operand (f, insn->get_op (0));
939       fprintf (f, ", ");
940       dump_hsa_address (f, addr);
941     }
942   else if (is_a <hsa_insn_seg *> (insn))
943     {
944       hsa_insn_seg *seg = as_a <hsa_insn_seg *> (insn);
945       fprintf (f, "%s_%s_%s_%s ", hsa_opcode_name (seg->m_opcode),
946 	       hsa_seg_name (seg->m_segment),
947 	       hsa_type_name (seg->m_type), hsa_type_name (seg->m_src_type));
948       dump_hsa_reg (f, as_a <hsa_op_reg *> (seg->get_op (0)));
949       fprintf (f, ", ");
950       dump_hsa_operand (f, seg->get_op (1));
951     }
952   else if (is_a <hsa_insn_cmp *> (insn))
953     {
954       hsa_insn_cmp *cmp = as_a <hsa_insn_cmp *> (insn);
955       BrigType16_t src_type;
956 
957       if (is_a <hsa_op_reg *> (cmp->get_op (1)))
958 	src_type = as_a <hsa_op_reg *> (cmp->get_op (1))->m_type;
959       else
960 	src_type = as_a <hsa_op_immed *> (cmp->get_op (1))->m_type;
961 
962       fprintf (f, "%s_%s_%s_%s ", hsa_opcode_name (cmp->m_opcode),
963 	       hsa_cmpop_name (cmp->m_compare),
964 	       hsa_type_name (cmp->m_type), hsa_type_name (src_type));
965       dump_hsa_reg (f, as_a <hsa_op_reg *> (cmp->get_op (0)));
966       fprintf (f, ", ");
967       dump_hsa_operand (f, cmp->get_op (1));
968       fprintf (f, ", ");
969       dump_hsa_operand (f, cmp->get_op (2));
970     }
971   else if (is_a <hsa_insn_cbr *> (insn))
972     {
973       hsa_insn_cbr *br = as_a <hsa_insn_cbr *> (insn);
974       basic_block target = NULL;
975       edge_iterator ei;
976       edge e;
977 
978       fprintf (f, "%s ", hsa_opcode_name (br->m_opcode));
979       if (br->m_opcode == BRIG_OPCODE_CBR)
980 	{
981 	  dump_hsa_reg (f, as_a <hsa_op_reg *> (br->get_op (0)));
982 	  fprintf (f, ", ");
983 	}
984 
985       FOR_EACH_EDGE (e, ei, br->m_bb->succs)
986 	if (e->flags & EDGE_TRUE_VALUE)
987 	  {
988 	    target = e->dest;
989 	    break;
990 	  }
991       fprintf (f, "BB %i", hsa_bb_for_bb (target)->m_index);
992     }
993   else if (is_a <hsa_insn_sbr *> (insn))
994     {
995       hsa_insn_sbr *sbr = as_a <hsa_insn_sbr *> (insn);
996 
997       fprintf (f, "%s ", hsa_opcode_name (sbr->m_opcode));
998       dump_hsa_reg (f, as_a <hsa_op_reg *> (sbr->get_op (0)));
999       fprintf (f, ", [");
1000 
1001       for (unsigned i = 0; i < sbr->m_jump_table.length (); i++)
1002 	{
1003 	  fprintf (f, "BB %i", hsa_bb_for_bb (sbr->m_jump_table[i])->m_index);
1004 	  if (i != sbr->m_jump_table.length () - 1)
1005 	    fprintf (f, ", ");
1006 	}
1007     }
1008   else if (is_a <hsa_insn_br *> (insn))
1009     {
1010       hsa_insn_br *br = as_a <hsa_insn_br *> (insn);
1011       fprintf (f, "%s_width(%s) ", hsa_opcode_name (br->m_opcode),
1012 	       hsa_width_specifier_name (br->m_width));
1013     }
1014   else if (is_a <hsa_insn_arg_block *> (insn))
1015     {
1016       hsa_insn_arg_block *arg_block = as_a <hsa_insn_arg_block *> (insn);
1017       bool start_p = arg_block->m_kind == BRIG_KIND_DIRECTIVE_ARG_BLOCK_START;
1018       char c = start_p ? '{' : '}';
1019 
1020       if (start_p)
1021 	{
1022 	  *indent += 2;
1023 	  indent_stream (f, 2);
1024 	}
1025 
1026       if (!start_p)
1027 	*indent -= 2;
1028 
1029       fprintf (f, "%c", c);
1030     }
1031   else if (is_a <hsa_insn_call *> (insn))
1032     {
1033       hsa_insn_call *call = as_a <hsa_insn_call *> (insn);
1034       if (call->m_called_function)
1035 	{
1036 	  const char *name = hsa_get_declaration_name (call->m_called_function);
1037 	  fprintf (f, "call &%s", name);
1038 	}
1039       else
1040 	{
1041 	  char *name = call->m_called_internal_fn->name ();
1042 	  fprintf (f, "call &%s", name);
1043 	  free (name);
1044 	}
1045 
1046       if (call->m_output_arg)
1047 	fprintf (f, "(%%res) ");
1048 
1049       fprintf (f, "(");
1050       for (unsigned i = 0; i < call->m_input_args.length (); i++)
1051 	{
1052 	  fprintf (f, "%%__arg_%u", i);
1053 
1054 	  if (i != call->m_input_args.length () - 1)
1055 	    fprintf (f, ", ");
1056 	}
1057       fprintf (f, ")");
1058     }
1059   else if (is_a <hsa_insn_comment *> (insn))
1060     {
1061       hsa_insn_comment *c = as_a <hsa_insn_comment *> (insn);
1062       fprintf (f, "%s", c->m_comment);
1063     }
1064   else if (is_a <hsa_insn_srctype *> (insn))
1065     {
1066       hsa_insn_srctype *srctype = as_a <hsa_insn_srctype *> (insn);
1067 
1068       fprintf (f, "%s_%s_%s ", hsa_opcode_name (srctype->m_opcode),
1069 	       hsa_type_name (srctype->m_type),
1070 	       hsa_type_name (srctype->m_source_type));
1071 
1072       dump_hsa_operands (f, insn);
1073     }
1074   else if (is_a <hsa_insn_packed *> (insn))
1075     {
1076       hsa_insn_packed *packed = as_a <hsa_insn_packed *> (insn);
1077 
1078       fprintf (f, "%s_v%u_%s_%s ", hsa_opcode_name (packed->m_opcode),
1079 	       packed->operand_count () - 1,
1080 	       hsa_type_name (packed->m_type),
1081 	       hsa_type_name (packed->m_source_type));
1082 
1083       if (packed->m_opcode == BRIG_OPCODE_COMBINE)
1084 	{
1085 	  dump_hsa_operand (f, insn->get_op (0));
1086 	  fprintf (f, ", (");
1087 	  dump_hsa_operands (f, insn, 1);
1088 	  fprintf (f, ")");
1089 	}
1090       else if (packed->m_opcode == BRIG_OPCODE_EXPAND)
1091 	{
1092 	  fprintf (f, "(");
1093 	  dump_hsa_operands (f, insn, 0, insn->operand_count () - 1);
1094 	  fprintf (f, "), ");
1095 	  dump_hsa_operand (f, insn->get_op (insn->operand_count () - 1));
1096 
1097 	}
1098       else
1099 	gcc_unreachable ();
1100     }
1101   else if (is_a <hsa_insn_alloca *> (insn))
1102     {
1103       hsa_insn_alloca *alloca = as_a <hsa_insn_alloca *> (insn);
1104 
1105       fprintf (f, "%s_align(%u)_%s ", hsa_opcode_name (insn->m_opcode),
1106 	       hsa_byte_alignment (alloca->m_align),
1107 	       hsa_type_name (insn->m_type));
1108 
1109       dump_hsa_operands (f, insn);
1110     }
1111   else if (hsa_insn_queue *qi = dyn_cast <hsa_insn_queue *> (insn))
1112     {
1113       fprintf (f, "%s_%s_%s_%s ", hsa_opcode_name (qi->m_opcode),
1114 	       hsa_seg_name (qi->m_segment),
1115 	       hsa_memsem_name (qi->m_memory_order),
1116 	       hsa_type_name (qi->m_type));
1117 
1118       dump_hsa_operands (f, qi);
1119     }
1120   else
1121     {
1122       fprintf (f, "%s_%s ", hsa_opcode_name (insn->m_opcode),
1123 	       hsa_type_name (insn->m_type));
1124 
1125       dump_hsa_operands (f, insn);
1126     }
1127 
1128   if (insn->m_brig_offset)
1129     {
1130       fprintf (f, "             /* BRIG offset: %u", insn->m_brig_offset);
1131 
1132       for (unsigned i = 0; i < insn->operand_count (); i++)
1133 	fprintf (f, ", op%u: %u", i, insn->get_op (i)->m_brig_op_offset);
1134 
1135       fprintf (f, " */");
1136     }
1137 
1138   fprintf (f, "\n");
1139 }
1140 
1141 /* Dump textual representation of HSA IL instruction INSN to file F.  */
1142 
1143 void
dump_hsa_insn(FILE * f,hsa_insn_basic * insn)1144 dump_hsa_insn (FILE *f, hsa_insn_basic *insn)
1145 {
1146   int indent = 0;
1147   dump_hsa_insn_1 (f, insn, &indent);
1148 }
1149 
1150 /* Dump textual representation of HSA IL in HBB to file F.  */
1151 
1152 void
dump_hsa_bb(FILE * f,hsa_bb * hbb)1153 dump_hsa_bb (FILE *f, hsa_bb *hbb)
1154 {
1155   hsa_insn_basic *insn;
1156   edge_iterator ei;
1157   edge e;
1158   basic_block true_bb = NULL, other = NULL;
1159 
1160   fprintf (f, "BB %i:\n", hbb->m_index);
1161 
1162   int indent = 2;
1163   for (insn = hbb->m_first_phi; insn; insn = insn->m_next)
1164     dump_hsa_insn_1 (f, insn, &indent);
1165 
1166   for (insn = hbb->m_first_insn; insn; insn = insn->m_next)
1167     dump_hsa_insn_1 (f, insn, &indent);
1168 
1169   if (hbb->m_last_insn && is_a <hsa_insn_sbr *> (hbb->m_last_insn))
1170     goto exit;
1171 
1172   FOR_EACH_EDGE (e, ei, hbb->m_bb->succs)
1173     if (e->flags & EDGE_TRUE_VALUE)
1174       {
1175 	gcc_assert (!true_bb);
1176 	true_bb = e->dest;
1177       }
1178     else
1179       {
1180 	gcc_assert (!other);
1181 	other = e->dest;
1182       }
1183 
1184   if (true_bb)
1185     {
1186       if (!hbb->m_last_insn
1187 	  || hbb->m_last_insn->m_opcode != BRIG_OPCODE_CBR)
1188 	fprintf (f, "WARNING: No branch insn for a true edge. \n");
1189     }
1190   else if (hbb->m_last_insn
1191 	   && hbb->m_last_insn->m_opcode == BRIG_OPCODE_CBR)
1192     fprintf (f, "WARNING: No true edge for a cbr statement\n");
1193 
1194   if (other && other->aux)
1195     fprintf (f, "  Fall-through to BB %i\n",
1196 	     hsa_bb_for_bb (other)->m_index);
1197   else if (hbb->m_last_insn
1198 	   && hbb->m_last_insn->m_opcode != BRIG_OPCODE_RET)
1199     fprintf (f, "  WARNING: Fall through to a BB with no aux!\n");
1200 
1201 exit:
1202   fprintf (f, "\n");
1203 }
1204 
1205 /* Dump textual representation of HSA IL of the current function to file F.  */
1206 
1207 void
dump_hsa_cfun(FILE * f)1208 dump_hsa_cfun (FILE *f)
1209 {
1210   basic_block bb;
1211 
1212   if (hsa_cfun->m_global_symbols.length () > 0)
1213     fprintf (f, "\nHSAIL in global scope\n");
1214 
1215   for (unsigned i = 0; i < hsa_cfun->m_global_symbols.length (); i++)
1216     {
1217       fprintf (f, "  ");
1218       dump_hsa_symbol (f, hsa_cfun->m_global_symbols[i]);
1219       fprintf (f, "\n");
1220     }
1221 
1222   fprintf (f, "\nHSAIL IL for %s\n", hsa_cfun->m_name);
1223 
1224   for (unsigned i = 0; i < hsa_cfun->m_private_variables.length (); i++)
1225     {
1226       fprintf (f, "  ");
1227       dump_hsa_symbol (f, hsa_cfun->m_private_variables[i]);
1228       fprintf (f, "\n");
1229     }
1230 
1231   FOR_ALL_BB_FN (bb, cfun)
1232     {
1233       hsa_bb *hbb = (class hsa_bb *) bb->aux;
1234       dump_hsa_bb (f, hbb);
1235     }
1236 }
1237 
1238 /* Dump textual representation of HSA IL instruction INSN to stderr.  */
1239 
1240 DEBUG_FUNCTION void
debug_hsa_insn(hsa_insn_basic * insn)1241 debug_hsa_insn (hsa_insn_basic *insn)
1242 {
1243   dump_hsa_insn (stderr, insn);
1244 }
1245 
1246 /* Dump textual representation of HSA IL in HBB to stderr.  */
1247 
1248 DEBUG_FUNCTION void
debug_hsa_bb(hsa_bb * hbb)1249 debug_hsa_bb (hsa_bb *hbb)
1250 {
1251   dump_hsa_bb (stderr, hbb);
1252 }
1253 
1254 /* Dump textual representation of HSA IL of the current function to stderr.  */
1255 
1256 DEBUG_FUNCTION void
debug_hsa_cfun(void)1257 debug_hsa_cfun (void)
1258 {
1259   dump_hsa_cfun (stderr);
1260 }
1261 
1262 /* Dump textual representation of an HSA operand to stderr.  */
1263 
1264 DEBUG_FUNCTION void
debug_hsa_operand(hsa_op_base * opc)1265 debug_hsa_operand (hsa_op_base *opc)
1266 {
1267   dump_hsa_operand (stderr, opc, true);
1268   fprintf (stderr, "\n");
1269 }
1270 
1271 /* Dump textual representation of as HSA symbol.  */
1272 
1273 DEBUG_FUNCTION void
debug_hsa_symbol(hsa_symbol * symbol)1274 debug_hsa_symbol (hsa_symbol *symbol)
1275 {
1276   dump_hsa_symbol (stderr, symbol);
1277   fprintf (stderr, "\n");
1278 }
1279