1 /*
2 * Copyright 2011 Christoph Bumiller
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22
23 #include "codegen/nv50_ir.h"
24 #include "codegen/nv50_ir_target.h"
25 #include "codegen/nv50_ir_driver.h"
26
27 #include <inttypes.h>
28
29 namespace nv50_ir {
30
31 enum TextStyle
32 {
33 TXT_DEFAULT,
34 TXT_GPR,
35 TXT_REGISTER,
36 TXT_FLAGS,
37 TXT_MEM,
38 TXT_IMMD,
39 TXT_BRA,
40 TXT_INSN
41 };
42
43 static const char *_colour[8] =
44 {
45 "\x1b[00m",
46 "\x1b[34m",
47 "\x1b[35m",
48 "\x1b[35m",
49 "\x1b[36m",
50 "\x1b[33m",
51 "\x1b[37m",
52 "\x1b[32m"
53 };
54
55 static const char *_nocolour[8] =
56 {
57 "", "", "", "", "", "", "", ""
58 };
59
60 static const char **colour;
61
init_colours()62 static void init_colours()
63 {
64 if (getenv("NV50_PROG_DEBUG_NO_COLORS") != NULL)
65 colour = _nocolour;
66 else
67 colour = _colour;
68 }
69
70 const char *operationStr[OP_LAST + 1] =
71 {
72 "nop",
73 "phi",
74 "union",
75 "split",
76 "merge",
77 "consec",
78 "mov",
79 "ld",
80 "st",
81 "add",
82 "sub",
83 "mul",
84 "div",
85 "mod",
86 "mad",
87 "fma",
88 "sad",
89 "shladd",
90 "xmad",
91 "abs",
92 "neg",
93 "not",
94 "and",
95 "or",
96 "xor",
97 "lop3 lut",
98 "shl",
99 "shr",
100 "shf",
101 "max",
102 "min",
103 "sat",
104 "ceil",
105 "floor",
106 "trunc",
107 "cvt",
108 "set and",
109 "set or",
110 "set xor",
111 "set",
112 "selp",
113 "slct",
114 "rcp",
115 "rsq",
116 "lg2",
117 "sin",
118 "cos",
119 "ex2",
120 "exp",
121 "log",
122 "presin",
123 "preex2",
124 "sqrt",
125 "pow",
126 "bra",
127 "call",
128 "ret",
129 "cont",
130 "break",
131 "preret",
132 "precont",
133 "prebreak",
134 "brkpt",
135 "joinat",
136 "join",
137 "discard",
138 "exit",
139 "membar",
140 "vfetch",
141 "pfetch",
142 "afetch",
143 "export",
144 "linterp",
145 "pinterp",
146 "emit",
147 "restart",
148 "final",
149 "tex",
150 "texbias",
151 "texlod",
152 "texfetch",
153 "texquery",
154 "texgrad",
155 "texgather",
156 "texquerylod",
157 "texcsaa",
158 "texprep",
159 "suldb",
160 "suldp",
161 "sustb",
162 "sustp",
163 "suredb",
164 "suredp",
165 "sulea",
166 "subfm",
167 "suclamp",
168 "sueau",
169 "suq",
170 "madsp",
171 "texbar",
172 "dfdx",
173 "dfdy",
174 "rdsv",
175 "wrsv",
176 "pixld",
177 "quadop",
178 "quadon",
179 "quadpop",
180 "popcnt",
181 "insbf",
182 "extbf",
183 "bfind",
184 "brev",
185 "bmsk",
186 "permt",
187 "sgxt",
188 "atom",
189 "bar",
190 "vadd",
191 "vavg",
192 "vmin",
193 "vmax",
194 "vsad",
195 "vset",
196 "vshr",
197 "vshl",
198 "vsel",
199 "cctl",
200 "shfl",
201 "vote",
202 "bufq",
203 "warpsync",
204 "(invalid)"
205 };
206
207 static const char *atomSubOpStr[] =
208 {
209 "add", "min", "max", "inc", "dec", "and", "or", "xor", "cas", "exch"
210 };
211
212 static const char *ldstSubOpStr[] =
213 {
214 "", "lock", "unlock"
215 };
216
217 static const char *subfmOpStr[] =
218 {
219 "", "3d"
220 };
221
222 static const char *shflOpStr[] =
223 {
224 "idx", "up", "down", "bfly"
225 };
226
227 static const char *pixldOpStr[] =
228 {
229 "count", "covmask", "covered", "offset", "cent_offset", "sampleid"
230 };
231
232 static const char *rcprsqOpStr[] =
233 {
234 "", "64h"
235 };
236
237 static const char *emitOpStr[] =
238 {
239 "", "restart"
240 };
241
242 static const char *cctlOpStr[] =
243 {
244 "", "", "", "", "", "iv", "ivall"
245 };
246
247 static const char *barOpStr[] =
248 {
249 "sync", "arrive", "red and", "red or", "red popc"
250 };
251
252 static const char *xmadOpCModeStr[] =
253 {
254 "clo", "chi", "csfu", "cbcc"
255 };
256
257 static const char *DataTypeStr[] =
258 {
259 "-",
260 "u8", "s8",
261 "u16", "s16",
262 "u32", "s32",
263 "u64", "s64",
264 "f16", "f32", "f64",
265 "b96", "b128"
266 };
267
268 static const char *RoundModeStr[] =
269 {
270 "", "rm", "rz", "rp", "rni", "rmi", "rzi", "rpi"
271 };
272
273 static const char *CondCodeStr[] =
274 {
275 "never",
276 "lt",
277 "eq",
278 "le",
279 "gt",
280 "ne",
281 "ge",
282 "",
283 "(invalid)",
284 "ltu",
285 "equ",
286 "leu",
287 "gtu",
288 "neu",
289 "geu",
290 "",
291 "no",
292 "nc",
293 "ns",
294 "na",
295 "a",
296 "s",
297 "c",
298 "o"
299 };
300
301 static const char *SemanticStr[] =
302 {
303 "POSITION",
304 "VERTEX_ID",
305 "INSTANCE_ID",
306 "INVOCATION_ID",
307 "PRIMITIVE_ID",
308 "VERTEX_COUNT",
309 "LAYER",
310 "VIEWPORT_INDEX",
311 "VIEWPORT_MASK",
312 "Y_DIR",
313 "FACE",
314 "POINT_SIZE",
315 "POINT_COORD",
316 "CLIP_DISTANCE",
317 "SAMPLE_INDEX",
318 "SAMPLE_POS",
319 "SAMPLE_MASK",
320 "TESS_OUTER",
321 "TESS_INNER",
322 "TESS_COORD",
323 "TID",
324 "COMBINED_TID",
325 "CTAID",
326 "NTID",
327 "GRIDID",
328 "NCTAID",
329 "LANEID",
330 "PHYSID",
331 "NPHYSID",
332 "CLOCK",
333 "LBASE",
334 "SBASE",
335 "VERTEX_STRIDE",
336 "INVOCATION_INFO",
337 "THREAD_KILL",
338 "BASEVERTEX",
339 "BASEINSTANCE",
340 "DRAWID",
341 "WORK_DIM",
342 "LANEMASK_EQ",
343 "LANEMASK_LT",
344 "LANEMASK_LE",
345 "LANEMASK_GT",
346 "LANEMASK_GE",
347 "?",
348 "(INVALID)"
349 };
350
351 static const char *interpStr[16] =
352 {
353 "pass",
354 "mul",
355 "flat",
356 "sc",
357 "cent pass",
358 "cent mul",
359 "cent flat",
360 "cent sc",
361 "off pass",
362 "off mul",
363 "off flat",
364 "off sc",
365 "samp pass",
366 "samp mul",
367 "samp flat",
368 "samp sc"
369 };
370
371 static const char *texMaskStr[16] =
372 {
373 "____",
374 "r___",
375 "_g__",
376 "rg__",
377 "__b_",
378 "r_b_",
379 "_gb_",
380 "rgb_",
381 "___a",
382 "r__a",
383 "_g_a",
384 "rg_a",
385 "__ba",
386 "r_ba",
387 "_gba",
388 "rgba",
389 };
390
391 static const char *gatherCompStr[4] =
392 {
393 "r", "g", "b", "a",
394 };
395
396 #define PRINT(args...) \
397 do { \
398 pos += snprintf(&buf[pos], size - pos, args); \
399 } while(0)
400
401 #define SPACE_PRINT(cond, args...) \
402 do { \
403 if (cond) \
404 buf[pos++] = ' '; \
405 pos += snprintf(&buf[pos], size - pos, args); \
406 } while(0)
407
408 #define SPACE() \
409 do { \
410 if (pos < size) \
411 buf[pos++] = ' '; \
412 } while(0)
413
print(char * buf,size_t size) const414 int Modifier::print(char *buf, size_t size) const
415 {
416 size_t pos = 0;
417
418 if (bits)
419 PRINT("%s", colour[TXT_INSN]);
420
421 size_t base = pos;
422
423 if (bits & NV50_IR_MOD_NOT)
424 PRINT("not");
425 if (bits & NV50_IR_MOD_SAT)
426 SPACE_PRINT(pos > base && pos < size, "sat");
427 if (bits & NV50_IR_MOD_NEG)
428 SPACE_PRINT(pos > base && pos < size, "neg");
429 if (bits & NV50_IR_MOD_ABS)
430 SPACE_PRINT(pos > base && pos < size, "abs");
431
432 return pos;
433 }
434
print(char * buf,size_t size,DataType ty) const435 int LValue::print(char *buf, size_t size, DataType ty) const
436 {
437 const char *postFix = "";
438 size_t pos = 0;
439 int idx = join->reg.data.id >= 0 ? join->reg.data.id : id;
440 char p = join->reg.data.id >= 0 ? '$' : '%';
441 char r;
442 int col = TXT_DEFAULT;
443
444 switch (reg.file) {
445 case FILE_GPR:
446 r = 'r'; col = TXT_GPR;
447 if (reg.size == 2) {
448 if (p == '$') {
449 postFix = (idx & 1) ? "h" : "l";
450 idx /= 2;
451 } else {
452 postFix = "s";
453 }
454 } else
455 if (reg.size == 8) {
456 postFix = "d";
457 } else
458 if (reg.size == 16) {
459 postFix = "q";
460 } else
461 if (reg.size == 12) {
462 postFix = "t";
463 }
464 break;
465 case FILE_PREDICATE:
466 r = 'p'; col = TXT_REGISTER;
467 if (reg.size == 2)
468 postFix = "d";
469 else
470 if (reg.size == 4)
471 postFix = "q";
472 break;
473 case FILE_FLAGS:
474 r = 'c'; col = TXT_FLAGS;
475 break;
476 case FILE_ADDRESS:
477 r = 'a'; col = TXT_REGISTER;
478 break;
479 default:
480 assert(!"invalid file for lvalue");
481 r = '?';
482 break;
483 }
484
485 PRINT("%s%c%c%i%s", colour[col], p, r, idx, postFix);
486
487 return pos;
488 }
489
print(char * buf,size_t size,DataType ty) const490 int ImmediateValue::print(char *buf, size_t size, DataType ty) const
491 {
492 size_t pos = 0;
493
494 PRINT("%s", colour[TXT_IMMD]);
495
496 switch (ty) {
497 case TYPE_F32: PRINT("%f", reg.data.f32); break;
498 case TYPE_F64: PRINT("%f", reg.data.f64); break;
499 case TYPE_U8: PRINT("0x%02x", reg.data.u8); break;
500 case TYPE_S8: PRINT("%i", reg.data.s8); break;
501 case TYPE_U16: PRINT("0x%04x", reg.data.u16); break;
502 case TYPE_S16: PRINT("%i", reg.data.s16); break;
503 case TYPE_U32: PRINT("0x%08x", reg.data.u32); break;
504 case TYPE_S32: PRINT("%i", reg.data.s32); break;
505 case TYPE_U64:
506 case TYPE_S64:
507 default:
508 PRINT("0x%016" PRIx64, reg.data.u64);
509 break;
510 }
511 return pos;
512 }
513
print(char * buf,size_t size,DataType ty) const514 int Symbol::print(char *buf, size_t size, DataType ty) const
515 {
516 return print(buf, size, NULL, NULL, ty);
517 }
518
print(char * buf,size_t size,Value * rel,Value * dimRel,DataType ty) const519 int Symbol::print(char *buf, size_t size,
520 Value *rel, Value *dimRel, DataType ty) const
521 {
522 STATIC_ASSERT(ARRAY_SIZE(SemanticStr) == SV_LAST + 1);
523
524 size_t pos = 0;
525 char c;
526
527 if (ty == TYPE_NONE)
528 ty = typeOfSize(reg.size);
529
530 if (reg.file == FILE_SYSTEM_VALUE) {
531 PRINT("%ssv[%s%s:%i%s", colour[TXT_MEM],
532 colour[TXT_REGISTER],
533 SemanticStr[reg.data.sv.sv], reg.data.sv.index, colour[TXT_MEM]);
534 if (rel) {
535 PRINT("%s+", colour[TXT_DEFAULT]);
536 pos += rel->print(&buf[pos], size - pos);
537 }
538 PRINT("%s]", colour[TXT_MEM]);
539 return pos;
540 }
541
542 switch (reg.file) {
543 case FILE_MEMORY_CONST: c = 'c'; break;
544 case FILE_SHADER_INPUT: c = 'a'; break;
545 case FILE_SHADER_OUTPUT: c = 'o'; break;
546 case FILE_MEMORY_BUFFER: c = 'b'; break; // Only used before lowering
547 case FILE_MEMORY_GLOBAL: c = 'g'; break;
548 case FILE_MEMORY_SHARED: c = 's'; break;
549 case FILE_MEMORY_LOCAL: c = 'l'; break;
550 default:
551 assert(!"invalid file");
552 c = '?';
553 break;
554 }
555
556 if (c == 'c')
557 PRINT("%s%c%i[", colour[TXT_MEM], c, reg.fileIndex);
558 else
559 PRINT("%s%c[", colour[TXT_MEM], c);
560
561 if (dimRel) {
562 pos += dimRel->print(&buf[pos], size - pos, TYPE_S32);
563 PRINT("%s][", colour[TXT_MEM]);
564 }
565
566 if (rel) {
567 pos += rel->print(&buf[pos], size - pos);
568 PRINT("%s%c", colour[TXT_DEFAULT], (reg.data.offset < 0) ? '-' : '+');
569 } else {
570 assert(reg.data.offset >= 0);
571 }
572 PRINT("%s0x%x%s]", colour[TXT_IMMD], abs(reg.data.offset), colour[TXT_MEM]);
573
574 return pos;
575 }
576
print() const577 void Instruction::print() const
578 {
579 #define BUFSZ 512
580
581 const size_t size = BUFSZ;
582
583 char buf[BUFSZ];
584 int s, d;
585 size_t pos = 0;
586
587 PRINT("%s", colour[TXT_INSN]);
588
589 if (join)
590 PRINT("join ");
591
592 if (predSrc >= 0) {
593 const size_t pre = pos;
594 if (getSrc(predSrc)->reg.file == FILE_PREDICATE) {
595 if (cc == CC_NOT_P)
596 PRINT("not");
597 } else {
598 PRINT("%s", CondCodeStr[cc]);
599 }
600 if (pos > pre)
601 SPACE();
602 pos += getSrc(predSrc)->print(&buf[pos], BUFSZ - pos);
603 PRINT(" %s", colour[TXT_INSN]);
604 }
605
606 if (saturate)
607 PRINT("sat ");
608
609 if (asFlow()) {
610 PRINT("%s", operationStr[op]);
611 if (asFlow()->indirect)
612 PRINT(" ind");
613 if (asFlow()->absolute)
614 PRINT(" abs");
615 if (op == OP_CALL && asFlow()->builtin) {
616 PRINT(" %sBUILTIN:%i", colour[TXT_BRA], asFlow()->target.builtin);
617 } else
618 if (op == OP_CALL && asFlow()->target.fn) {
619 PRINT(" %s%s:%i", colour[TXT_BRA],
620 asFlow()->target.fn->getName(),
621 asFlow()->target.fn->getLabel());
622 } else
623 if (asFlow()->target.bb)
624 PRINT(" %sBB:%i", colour[TXT_BRA], asFlow()->target.bb->getId());
625 } else {
626 if (asTex())
627 PRINT("%s%s ", operationStr[op], asTex()->tex.scalar ? "s" : "");
628 else
629 PRINT("%s ", operationStr[op]);
630 if (op == OP_LINTERP || op == OP_PINTERP)
631 PRINT("%s ", interpStr[ipa]);
632 switch (op) {
633 case OP_SUREDP:
634 case OP_SUREDB:
635 case OP_ATOM:
636 if (subOp < ARRAY_SIZE(atomSubOpStr))
637 PRINT("%s ", atomSubOpStr[subOp]);
638 break;
639 case OP_LOAD:
640 case OP_STORE:
641 if (subOp < ARRAY_SIZE(ldstSubOpStr))
642 PRINT("%s ", ldstSubOpStr[subOp]);
643 break;
644 case OP_SUBFM:
645 if (subOp < ARRAY_SIZE(subfmOpStr))
646 PRINT("%s ", subfmOpStr[subOp]);
647 break;
648 case OP_SHFL:
649 if (subOp < ARRAY_SIZE(shflOpStr))
650 PRINT("%s ", shflOpStr[subOp]);
651 break;
652 case OP_PIXLD:
653 if (subOp < ARRAY_SIZE(pixldOpStr))
654 PRINT("%s ", pixldOpStr[subOp]);
655 break;
656 case OP_RCP:
657 case OP_RSQ:
658 if (subOp < ARRAY_SIZE(rcprsqOpStr))
659 PRINT("%s ", rcprsqOpStr[subOp]);
660 break;
661 case OP_EMIT:
662 if (subOp < ARRAY_SIZE(emitOpStr))
663 PRINT("%s ", emitOpStr[subOp]);
664 break;
665 case OP_CCTL:
666 if (subOp < ARRAY_SIZE(cctlOpStr))
667 PRINT("%s ", cctlOpStr[subOp]);
668 break;
669 case OP_BAR:
670 if (subOp < ARRAY_SIZE(barOpStr))
671 PRINT("%s ", barOpStr[subOp]);
672 break;
673 case OP_XMAD: {
674 if (subOp & NV50_IR_SUBOP_XMAD_PSL)
675 PRINT("psl ");
676 if (subOp & NV50_IR_SUBOP_XMAD_MRG)
677 PRINT("mrg ");
678 unsigned cmode = (subOp & NV50_IR_SUBOP_XMAD_CMODE_MASK);
679 cmode >>= NV50_IR_SUBOP_XMAD_CMODE_SHIFT;
680 if (cmode && cmode <= ARRAY_SIZE(xmadOpCModeStr))
681 PRINT("%s ", xmadOpCModeStr[cmode - 1]);
682 for (int i = 0; i < 2; i++)
683 PRINT("h%d ", (subOp & NV50_IR_SUBOP_XMAD_H1(i)) ? 1 : 0);
684 break;
685 }
686 default:
687 if (subOp)
688 PRINT("(SUBOP:%u) ", subOp);
689 break;
690 }
691 if (perPatch)
692 PRINT("patch ");
693 if (asTex()) {
694 PRINT("%s %s$r%u $s%u ", asTex()->tex.target.getName(),
695 colour[TXT_MEM], asTex()->tex.r, asTex()->tex.s);
696 if (op == OP_TXG)
697 PRINT("%s ", gatherCompStr[asTex()->tex.gatherComp]);
698 PRINT("%s %s", texMaskStr[asTex()->tex.mask], colour[TXT_INSN]);
699 }
700
701 if (postFactor)
702 PRINT("x2^%i ", postFactor);
703 PRINT("%s%s", dnz ? "dnz " : (ftz ? "ftz " : ""), DataTypeStr[dType]);
704 }
705
706 if (rnd != ROUND_N)
707 PRINT(" %s", RoundModeStr[rnd]);
708
709 if (defExists(1))
710 PRINT(" {");
711 for (d = 0; defExists(d); ++d) {
712 SPACE();
713 pos += getDef(d)->print(&buf[pos], size - pos);
714 }
715 if (d > 1)
716 PRINT(" %s}", colour[TXT_INSN]);
717 else
718 if (!d && !asFlow())
719 PRINT(" %s#", colour[TXT_INSN]);
720
721 if (asCmp())
722 PRINT(" %s%s", colour[TXT_INSN], CondCodeStr[asCmp()->setCond]);
723
724 if (sType != dType)
725 PRINT(" %s%s", colour[TXT_INSN], DataTypeStr[sType]);
726
727 for (s = 0; srcExists(s); ++s) {
728 if (s == predSrc || src(s).usedAsPtr)
729 continue;
730 const size_t pre = pos;
731 SPACE();
732 pos += src(s).mod.print(&buf[pos], BUFSZ - pos);
733 if (pos > pre + 1)
734 SPACE();
735 if (src(s).isIndirect(0) || src(s).isIndirect(1))
736 pos += getSrc(s)->asSym()->print(&buf[pos], BUFSZ - pos,
737 getIndirect(s, 0),
738 getIndirect(s, 1));
739 else
740 pos += getSrc(s)->print(&buf[pos], BUFSZ - pos, sType);
741 }
742 if (exit)
743 PRINT("%s exit", colour[TXT_INSN]);
744
745 PRINT("%s", colour[TXT_DEFAULT]);
746
747 buf[MIN2(pos, BUFSZ - 1)] = 0;
748
749 INFO("%s (%u)\n", buf, encSize);
750 }
751
752 class PrintPass : public Pass
753 {
754 public:
PrintPass(bool omitLineNum)755 PrintPass(bool omitLineNum) : serial(0), omit_serial(omitLineNum) { }
756
757 virtual bool visit(Function *);
758 virtual bool visit(BasicBlock *);
759 virtual bool visit(Instruction *);
760
761 private:
762 int serial;
763 bool omit_serial;
764 };
765
766 bool
visit(Function * fn)767 PrintPass::visit(Function *fn)
768 {
769 char str[16];
770
771 INFO("\n%s:%i (", fn->getName(), fn->getLabel());
772
773 if (!fn->outs.empty())
774 INFO("out");
775 for (std::deque<ValueRef>::iterator it = fn->outs.begin();
776 it != fn->outs.end();
777 ++it) {
778 it->get()->print(str, sizeof(str), typeOfSize(it->get()->reg.size));
779 INFO(" %s", str);
780 }
781
782 if (!fn->ins.empty())
783 INFO("%s%sin", colour[TXT_DEFAULT], fn->outs.empty() ? "" : ", ");
784 for (std::deque<ValueDef>::iterator it = fn->ins.begin();
785 it != fn->ins.end();
786 ++it) {
787 it->get()->print(str, sizeof(str), typeOfSize(it->get()->reg.size));
788 INFO(" %s", str);
789 }
790 INFO("%s)\n", colour[TXT_DEFAULT]);
791
792 return true;
793 }
794
795 bool
visit(BasicBlock * bb)796 PrintPass::visit(BasicBlock *bb)
797 {
798 #if 0
799 INFO("---\n");
800 for (Graph::EdgeIterator ei = bb->cfg.incident(); !ei.end(); ei.next())
801 INFO(" <- BB:%i (%s)\n",
802 BasicBlock::get(ei.getNode())->getId(),
803 ei.getEdge()->typeStr());
804 #endif
805 INFO("BB:%i (%u instructions) - ", bb->getId(), bb->getInsnCount());
806
807 if (bb->idom())
808 INFO("idom = BB:%i, ", bb->idom()->getId());
809
810 INFO("df = { ");
811 for (DLList::Iterator df = bb->getDF().iterator(); !df.end(); df.next())
812 INFO("BB:%i ", BasicBlock::get(df)->getId());
813
814 INFO("}\n");
815
816 for (Graph::EdgeIterator ei = bb->cfg.outgoing(); !ei.end(); ei.next())
817 INFO(" -> BB:%i (%s)\n",
818 BasicBlock::get(ei.getNode())->getId(),
819 ei.getEdge()->typeStr());
820
821 return true;
822 }
823
824 bool
visit(Instruction * insn)825 PrintPass::visit(Instruction *insn)
826 {
827 if (omit_serial)
828 INFO(" ");
829 else
830 INFO("%3i: ", serial);
831 serial++;
832 insn->print();
833 return true;
834 }
835
836 void
print()837 Function::print()
838 {
839 PrintPass pass(prog->driver->omitLineNum);
840 pass.run(this, true, false);
841 }
842
843 void
print()844 Program::print()
845 {
846 PrintPass pass(driver->omitLineNum);
847 init_colours();
848 pass.run(this, true, false);
849 }
850
851 void
printLiveIntervals() const852 Function::printLiveIntervals() const
853 {
854 INFO("printing live intervals ...\n");
855
856 for (ArrayList::Iterator it = allLValues.iterator(); !it.end(); it.next()) {
857 const Value *lval = Value::get(it)->asLValue();
858 if (lval && !lval->livei.isEmpty()) {
859 INFO("livei(%%%i): ", lval->id);
860 lval->livei.print();
861 }
862 }
863 }
864
865 } // namespace nv50_ir
866
867 extern void
nv50_ir_prog_info_out_print(struct nv50_ir_prog_info_out * info_out)868 nv50_ir_prog_info_out_print(struct nv50_ir_prog_info_out *info_out)
869 {
870 int i;
871
872 INFO("{\n");
873 INFO(" \"target\":\"%d\",\n", info_out->target);
874 INFO(" \"type\":\"%d\",\n", info_out->type);
875
876 // Bin
877 INFO(" \"bin\":{\n");
878 INFO(" \"maxGPR\":\"%d\",\n", info_out->bin.maxGPR);
879 INFO(" \"tlsSpace\":\"%d\",\n", info_out->bin.tlsSpace);
880 INFO(" \"smemSize\":\"%d\",\n", info_out->bin.smemSize);
881 INFO(" \"codeSize\":\"%d\",\n", info_out->bin.codeSize);
882 INFO(" \"instructions\":\"%d\",\n", info_out->bin.instructions);
883
884 // RelocInfo
885 INFO(" \"RelocInfo\":");
886 if (!info_out->bin.relocData) {
887 INFO("\"NULL\",\n");
888 } else {
889 nv50_ir::RelocInfo *reloc = (nv50_ir::RelocInfo *)info_out->bin.relocData;
890 INFO("{\n");
891 INFO(" \"codePos\":\"%d\",\n", reloc->codePos);
892 INFO(" \"libPos\":\"%d\",\n", reloc->libPos);
893 INFO(" \"dataPos\":\"%d\",\n", reloc->dataPos);
894 INFO(" \"count\":\"%d\",\n", reloc->count);
895 INFO(" \"RelocEntry\":[\n");
896 for (unsigned int i = 0; i < reloc->count; i++) {
897 INFO(" {\"data\":\"%d\",\t\"mask\":\"%d\",\t\"offset\":\"%d\",\t\"bitPos\":\"%d\",\t\"type\":\"%d\"}",
898 reloc->entry[i].data, reloc->entry[i].mask, reloc->entry[i].offset, reloc->entry[i].bitPos, reloc->entry[i].type
899 );
900 }
901 INFO("\n");
902 INFO(" ]\n");
903 INFO(" },\n");
904 }
905
906 // FixupInfo
907 INFO(" \"FixupInfo\":");
908 if (!info_out->bin.fixupData) {
909 INFO("\"NULL\"\n");
910 } else {
911 nv50_ir::FixupInfo *fixup = (nv50_ir::FixupInfo *)info_out->bin.fixupData;
912 INFO("{\n");
913 INFO(" \"count\":\"%d\"\n", fixup->count);
914 INFO(" \"FixupEntry\":[\n");
915 for (unsigned int i = 0; i < fixup->count; i++) {
916 INFO(" {\"apply\":\"%p\",\t\"ipa\":\"%d\",\t\"reg\":\"%d\",\t\"loc\":\"%d\"}\n",
917 fixup->entry[i].apply, fixup->entry[i].ipa, fixup->entry[i].reg, fixup->entry[i].loc);
918 }
919 INFO("\n");
920 INFO(" ]\n");
921 INFO(" }\n");
922
923 INFO(" },\n");
924 }
925
926 if (info_out->numSysVals) {
927 INFO(" \"sv\":[\n");
928 for (i = 0; i < info_out->numSysVals; i++) {
929 if (&(info_out->sv[i])) {
930 INFO(" {\"id\":\"%d\", \"sn\":\"%d\", \"si\":\"%d\"}\n",
931 info_out->sv[i].id, info_out->sv[i].sn, info_out->sv[i].si);
932 }
933 }
934 INFO("\n ],\n");
935 }
936 if (info_out->numInputs) {
937 INFO(" \"in\":[\n");
938 for (i = 0; i < info_out->numInputs; i++) {
939 if (&(info_out->in[i])) {
940 INFO(" {\"id\":\"%d\",\t\"sn\":\"%d\",\t\"si\":\"%d\"}\n",
941 info_out->in[i].id, info_out->in[i].sn, info_out->in[i].si);
942 }
943 }
944 INFO("\n ],\n");
945 }
946 if (info_out->numOutputs) {
947 INFO(" \"out\":[\n");
948 for (i = 0; i < info_out->numOutputs; i++) {
949 if (&(info_out->out[i])) {
950 INFO(" {\"id\":\"%d\",\t\"sn\":\"%d\",\t\"si\":\"%d\"}\n",
951 info_out->out[i].id, info_out->out[i].sn, info_out->out[i].si);
952 }
953 }
954 INFO("\n ],\n");
955 }
956
957 INFO(" \"numInputs\":\"%d\",\n", info_out->numInputs);
958 INFO(" \"numOutputs\":\"%d\",\n", info_out->numOutputs);
959 INFO(" \"numPatchConstants\":\"%d\",\n", info_out->numPatchConstants);
960 INFO(" \"numSysVals\":\"%d\",\n", info_out->numSysVals);
961
962 INFO(" \"prop\":{\n");
963 switch (info_out->type) {
964 case PIPE_SHADER_VERTEX:
965 INFO(" \"vp\": {\"usesDrawParameters\":\"%s\"}\n",
966 info_out->prop.vp.usesDrawParameters ? "true" : "false");
967 break;
968 case PIPE_SHADER_TESS_CTRL:
969 case PIPE_SHADER_TESS_EVAL:
970 INFO(" \"tp\":{\n");
971 INFO(" \"outputPatchSize\":\"%d\"\n", info_out->prop.tp.outputPatchSize);
972 INFO(" \"partitioning\":\"%d\"\n", info_out->prop.tp.partitioning);
973 INFO(" \"winding\":\"%d\"\n", info_out->prop.tp.winding);
974 INFO(" \"domain\":\"%d\"\n", info_out->prop.tp.domain);
975 INFO(" \"outputPrim\":\"%d\"\n", info_out->prop.tp.outputPrim);
976 break;
977 case PIPE_SHADER_GEOMETRY:
978 INFO(" \"gp\":{\n");
979 INFO(" \"outputPrim\":\"%d\"\n", info_out->prop.gp.outputPrim);
980 INFO(" \"instancesCount\":\"%d\"\n", info_out->prop.gp.instanceCount);
981 INFO(" \"maxVertices\":\"%d\"\n", info_out->prop.gp.maxVertices);
982 break;
983 case PIPE_SHADER_FRAGMENT:
984 INFO(" \"fp\":{\n");
985 INFO(" \"numColourResults\":\"%d\"\n", info_out->prop.fp.numColourResults);
986 INFO(" \"writesDepth\":\"%s\"\n", info_out->prop.fp.writesDepth ? "true" : "false");
987 INFO(" \"earlyFragTests\":\"%s\"\n", info_out->prop.fp.earlyFragTests ? "true" : "false");
988 INFO(" \"postDepthCoverage\":\"%s\"\n", info_out->prop.fp.postDepthCoverage ? "true" : "false");
989 INFO(" \"usesDiscard\":\"%s\"\n", info_out->prop.fp.usesDiscard ? "true" : "false");
990 INFO(" \"usesSampleMaskIn\":\"%s\"\n", info_out->prop.fp.usesSampleMaskIn ? "true" : "false");
991 INFO(" \"readsFramebuffer\":\"%s\"\n", info_out->prop.fp.readsFramebuffer ? "true" : "false");
992 INFO(" \"readsSampleLocations\":\"%s\"\n", info_out->prop.fp.readsSampleLocations ? "true" : "false");
993 INFO(" \"separateFragData\":\"%s\"\n", info_out->prop.fp.separateFragData ? "true" : "false");
994 break;
995 default:
996 assert("!unhandled pipe shader type\n");
997 }
998 INFO(" }\n");
999 INFO(" }\n");
1000
1001 INFO(" \"io\":{\n");
1002 INFO(" \"clipDistances\":\"%d\"\n", info_out->io.clipDistances);
1003 INFO(" \"cullDistances\":\"%d\"\n", info_out->io.cullDistances);
1004 INFO(" \"genUserClip\":\"%d\"\n", info_out->io.genUserClip);
1005 INFO(" \"instanceId\":\"%d\"\n", info_out->io.instanceId);
1006 INFO(" \"vertexId\":\"%d\"\n", info_out->io.vertexId);
1007 INFO(" \"edgeFlagIn\":\"%d\"\n", info_out->io.edgeFlagIn);
1008 INFO(" \"edgeFlagOut\":\"%d\"\n", info_out->io.edgeFlagOut);
1009 INFO(" \"fragDepth\":\"%d\"\n", info_out->io.fragDepth);
1010 INFO(" \"sampleMask\":\"%d\"\n", info_out->io.sampleMask);
1011 INFO(" \"globalAccess\":\"%d\"\n", info_out->io.globalAccess);
1012 INFO(" \"fp64\":\"%s\"\n", info_out->io.fp64 ? "true" : "false");
1013 INFO(" \"layer_viewport_relative\":\"%s\"\n", info_out->io.layer_viewport_relative ? "true" : "false");
1014 INFO(" \"}\n");
1015 INFO(" \"numBarriers\":\"%d\"\n", info_out->numBarriers);
1016 INFO(" \"driverPriv\":\"%p\"\n", info_out->driverPriv);
1017
1018 INFO("}\n");
1019 }
1020