nv50/ir/nir: make use of SYSTEM_VALUE_MAX when iterating read sysvals
[mesa.git] / src / gallium / drivers / nouveau / codegen / nv50_ir_print.cpp
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
26 #include <inttypes.h>
27
28 namespace nv50_ir {
29
30 enum TextStyle
31 {
32 TXT_DEFAULT,
33 TXT_GPR,
34 TXT_REGISTER,
35 TXT_FLAGS,
36 TXT_MEM,
37 TXT_IMMD,
38 TXT_BRA,
39 TXT_INSN
40 };
41
42 static const char *_colour[8] =
43 {
44 "\x1b[00m",
45 "\x1b[34m",
46 "\x1b[35m",
47 "\x1b[35m",
48 "\x1b[36m",
49 "\x1b[33m",
50 "\x1b[37m",
51 "\x1b[32m"
52 };
53
54 static const char *_nocolour[8] =
55 {
56 "", "", "", "", "", "", "", ""
57 };
58
59 static const char **colour;
60
61 static void init_colours()
62 {
63 if (getenv("NV50_PROG_DEBUG_NO_COLORS") != NULL)
64 colour = _nocolour;
65 else
66 colour = _colour;
67 }
68
69 const char *operationStr[OP_LAST + 1] =
70 {
71 "nop",
72 "phi",
73 "union",
74 "split",
75 "merge",
76 "consec",
77 "mov",
78 "ld",
79 "st",
80 "add",
81 "sub",
82 "mul",
83 "div",
84 "mod",
85 "mad",
86 "fma",
87 "sad",
88 "shladd",
89 "xmad",
90 "abs",
91 "neg",
92 "not",
93 "and",
94 "or",
95 "xor",
96 "shl",
97 "shr",
98 "max",
99 "min",
100 "sat",
101 "ceil",
102 "floor",
103 "trunc",
104 "cvt",
105 "set and",
106 "set or",
107 "set xor",
108 "set",
109 "selp",
110 "slct",
111 "rcp",
112 "rsq",
113 "lg2",
114 "sin",
115 "cos",
116 "ex2",
117 "exp",
118 "log",
119 "presin",
120 "preex2",
121 "sqrt",
122 "pow",
123 "bra",
124 "call",
125 "ret",
126 "cont",
127 "break",
128 "preret",
129 "precont",
130 "prebreak",
131 "brkpt",
132 "joinat",
133 "join",
134 "discard",
135 "exit",
136 "membar",
137 "vfetch",
138 "pfetch",
139 "afetch",
140 "export",
141 "linterp",
142 "pinterp",
143 "emit",
144 "restart",
145 "tex",
146 "texbias",
147 "texlod",
148 "texfetch",
149 "texquery",
150 "texgrad",
151 "texgather",
152 "texquerylod",
153 "texcsaa",
154 "texprep",
155 "suldb",
156 "suldp",
157 "sustb",
158 "sustp",
159 "suredb",
160 "suredp",
161 "sulea",
162 "subfm",
163 "suclamp",
164 "sueau",
165 "suq",
166 "madsp",
167 "texbar",
168 "dfdx",
169 "dfdy",
170 "rdsv",
171 "wrsv",
172 "pixld",
173 "quadop",
174 "quadon",
175 "quadpop",
176 "popcnt",
177 "insbf",
178 "extbf",
179 "bfind",
180 "permt",
181 "atom",
182 "bar",
183 "vadd",
184 "vavg",
185 "vmin",
186 "vmax",
187 "vsad",
188 "vset",
189 "vshr",
190 "vshl",
191 "vsel",
192 "cctl",
193 "shfl",
194 "vote",
195 "bufq",
196 "(invalid)"
197 };
198
199 static const char *atomSubOpStr[] =
200 {
201 "add", "min", "max", "inc", "dec", "and", "or", "xor", "cas", "exch"
202 };
203
204 static const char *ldstSubOpStr[] =
205 {
206 "", "lock", "unlock"
207 };
208
209 static const char *subfmOpStr[] =
210 {
211 "", "3d"
212 };
213
214 static const char *shflOpStr[] =
215 {
216 "idx", "up", "down", "bfly"
217 };
218
219 static const char *pixldOpStr[] =
220 {
221 "count", "covmask", "covered", "offset", "cent_offset", "sampleid"
222 };
223
224 static const char *rcprsqOpStr[] =
225 {
226 "", "64h"
227 };
228
229 static const char *emitOpStr[] =
230 {
231 "", "restart"
232 };
233
234 static const char *cctlOpStr[] =
235 {
236 "", "", "", "", "", "iv", "ivall"
237 };
238
239 static const char *barOpStr[] =
240 {
241 "sync", "arrive", "red and", "red or", "red popc"
242 };
243
244 static const char *xmadOpCModeStr[] =
245 {
246 "clo", "chi", "csfu", "cbcc"
247 };
248
249 static const char *DataTypeStr[] =
250 {
251 "-",
252 "u8", "s8",
253 "u16", "s16",
254 "u32", "s32",
255 "u64", "s64",
256 "f16", "f32", "f64",
257 "b96", "b128"
258 };
259
260 static const char *RoundModeStr[] =
261 {
262 "", "rm", "rz", "rp", "rni", "rmi", "rzi", "rpi"
263 };
264
265 static const char *CondCodeStr[] =
266 {
267 "never",
268 "lt",
269 "eq",
270 "le",
271 "gt",
272 "ne",
273 "ge",
274 "",
275 "(invalid)",
276 "ltu",
277 "equ",
278 "leu",
279 "gtu",
280 "neu",
281 "geu",
282 "",
283 "no",
284 "nc",
285 "ns",
286 "na",
287 "a",
288 "s",
289 "c",
290 "o"
291 };
292
293 static const char *SemanticStr[SV_LAST + 1] =
294 {
295 "POSITION",
296 "VERTEX_ID",
297 "INSTANCE_ID",
298 "INVOCATION_ID",
299 "PRIMITIVE_ID",
300 "VERTEX_COUNT",
301 "LAYER",
302 "VIEWPORT_INDEX",
303 "Y_DIR",
304 "FACE",
305 "POINT_SIZE",
306 "POINT_COORD",
307 "CLIP_DISTANCE",
308 "SAMPLE_INDEX",
309 "SAMPLE_POS",
310 "SAMPLE_MASK",
311 "TESS_OUTER",
312 "TESS_INNER",
313 "TESS_COORD",
314 "TID",
315 "COMBINED_TID",
316 "CTAID",
317 "NTID",
318 "GRIDID",
319 "NCTAID",
320 "LANEID",
321 "PHYSID",
322 "NPHYSID",
323 "CLOCK",
324 "LBASE",
325 "SBASE",
326 "VERTEX_STRIDE",
327 "INVOCATION_INFO",
328 "THREAD_KILL",
329 "BASEVERTEX",
330 "BASEINSTANCE",
331 "DRAWID",
332 "WORK_DIM",
333 "LANEMASK_EQ",
334 "LANEMASK_LT",
335 "LANEMASK_LE",
336 "LANEMASK_GT",
337 "LANEMASK_GE",
338 "?",
339 "(INVALID)"
340 };
341
342 static const char *interpStr[16] =
343 {
344 "pass",
345 "mul",
346 "flat",
347 "sc",
348 "cent pass",
349 "cent mul",
350 "cent flat",
351 "cent sc",
352 "off pass",
353 "off mul",
354 "off flat",
355 "off sc",
356 "samp pass",
357 "samp mul",
358 "samp flat",
359 "samp sc"
360 };
361
362 static const char *texMaskStr[16] =
363 {
364 "____",
365 "r___",
366 "_g__",
367 "rg__",
368 "__b_",
369 "r_b_",
370 "_gb_",
371 "rgb_",
372 "___a",
373 "r__a",
374 "_g_a",
375 "rg_a",
376 "__ba",
377 "r_ba",
378 "_gba",
379 "rgba",
380 };
381
382 static const char *gatherCompStr[4] =
383 {
384 "r", "g", "b", "a",
385 };
386
387 #define PRINT(args...) \
388 do { \
389 pos += snprintf(&buf[pos], size - pos, args); \
390 } while(0)
391
392 #define SPACE_PRINT(cond, args...) \
393 do { \
394 if (cond) \
395 buf[pos++] = ' '; \
396 pos += snprintf(&buf[pos], size - pos, args); \
397 } while(0)
398
399 #define SPACE() \
400 do { \
401 if (pos < size) \
402 buf[pos++] = ' '; \
403 } while(0)
404
405 int Modifier::print(char *buf, size_t size) const
406 {
407 size_t pos = 0;
408
409 if (bits)
410 PRINT("%s", colour[TXT_INSN]);
411
412 size_t base = pos;
413
414 if (bits & NV50_IR_MOD_NOT)
415 PRINT("not");
416 if (bits & NV50_IR_MOD_SAT)
417 SPACE_PRINT(pos > base && pos < size, "sat");
418 if (bits & NV50_IR_MOD_NEG)
419 SPACE_PRINT(pos > base && pos < size, "neg");
420 if (bits & NV50_IR_MOD_ABS)
421 SPACE_PRINT(pos > base && pos < size, "abs");
422
423 return pos;
424 }
425
426 int LValue::print(char *buf, size_t size, DataType ty) const
427 {
428 const char *postFix = "";
429 size_t pos = 0;
430 int idx = join->reg.data.id >= 0 ? join->reg.data.id : id;
431 char p = join->reg.data.id >= 0 ? '$' : '%';
432 char r;
433 int col = TXT_DEFAULT;
434
435 switch (reg.file) {
436 case FILE_GPR:
437 r = 'r'; col = TXT_GPR;
438 if (reg.size == 2) {
439 if (p == '$') {
440 postFix = (idx & 1) ? "h" : "l";
441 idx /= 2;
442 } else {
443 postFix = "s";
444 }
445 } else
446 if (reg.size == 8) {
447 postFix = "d";
448 } else
449 if (reg.size == 16) {
450 postFix = "q";
451 } else
452 if (reg.size == 12) {
453 postFix = "t";
454 }
455 break;
456 case FILE_PREDICATE:
457 r = 'p'; col = TXT_REGISTER;
458 if (reg.size == 2)
459 postFix = "d";
460 else
461 if (reg.size == 4)
462 postFix = "q";
463 break;
464 case FILE_FLAGS:
465 r = 'c'; col = TXT_FLAGS;
466 break;
467 case FILE_ADDRESS:
468 r = 'a'; col = TXT_REGISTER;
469 break;
470 default:
471 assert(!"invalid file for lvalue");
472 r = '?';
473 break;
474 }
475
476 PRINT("%s%c%c%i%s", colour[col], p, r, idx, postFix);
477
478 return pos;
479 }
480
481 int ImmediateValue::print(char *buf, size_t size, DataType ty) const
482 {
483 size_t pos = 0;
484
485 PRINT("%s", colour[TXT_IMMD]);
486
487 switch (ty) {
488 case TYPE_F32: PRINT("%f", reg.data.f32); break;
489 case TYPE_F64: PRINT("%f", reg.data.f64); break;
490 case TYPE_U8: PRINT("0x%02x", reg.data.u8); break;
491 case TYPE_S8: PRINT("%i", reg.data.s8); break;
492 case TYPE_U16: PRINT("0x%04x", reg.data.u16); break;
493 case TYPE_S16: PRINT("%i", reg.data.s16); break;
494 case TYPE_U32: PRINT("0x%08x", reg.data.u32); break;
495 case TYPE_S32: PRINT("%i", reg.data.s32); break;
496 case TYPE_U64:
497 case TYPE_S64:
498 default:
499 PRINT("0x%016" PRIx64, reg.data.u64);
500 break;
501 }
502 return pos;
503 }
504
505 int Symbol::print(char *buf, size_t size, DataType ty) const
506 {
507 return print(buf, size, NULL, NULL, ty);
508 }
509
510 int Symbol::print(char *buf, size_t size,
511 Value *rel, Value *dimRel, DataType ty) const
512 {
513 size_t pos = 0;
514 char c;
515
516 if (ty == TYPE_NONE)
517 ty = typeOfSize(reg.size);
518
519 if (reg.file == FILE_SYSTEM_VALUE) {
520 PRINT("%ssv[%s%s:%i%s", colour[TXT_MEM],
521 colour[TXT_REGISTER],
522 SemanticStr[reg.data.sv.sv], reg.data.sv.index, colour[TXT_MEM]);
523 if (rel) {
524 PRINT("%s+", colour[TXT_DEFAULT]);
525 pos += rel->print(&buf[pos], size - pos);
526 }
527 PRINT("%s]", colour[TXT_MEM]);
528 return pos;
529 }
530
531 switch (reg.file) {
532 case FILE_MEMORY_CONST: c = 'c'; break;
533 case FILE_SHADER_INPUT: c = 'a'; break;
534 case FILE_SHADER_OUTPUT: c = 'o'; break;
535 case FILE_MEMORY_BUFFER: c = 'b'; break; // Only used before lowering
536 case FILE_MEMORY_GLOBAL: c = 'g'; break;
537 case FILE_MEMORY_SHARED: c = 's'; break;
538 case FILE_MEMORY_LOCAL: c = 'l'; break;
539 default:
540 assert(!"invalid file");
541 c = '?';
542 break;
543 }
544
545 if (c == 'c')
546 PRINT("%s%c%i[", colour[TXT_MEM], c, reg.fileIndex);
547 else
548 PRINT("%s%c[", colour[TXT_MEM], c);
549
550 if (dimRel) {
551 pos += dimRel->print(&buf[pos], size - pos, TYPE_S32);
552 PRINT("%s][", colour[TXT_MEM]);
553 }
554
555 if (rel) {
556 pos += rel->print(&buf[pos], size - pos);
557 PRINT("%s%c", colour[TXT_DEFAULT], (reg.data.offset < 0) ? '-' : '+');
558 } else {
559 assert(reg.data.offset >= 0);
560 }
561 PRINT("%s0x%x%s]", colour[TXT_IMMD], abs(reg.data.offset), colour[TXT_MEM]);
562
563 return pos;
564 }
565
566 void Instruction::print() const
567 {
568 #define BUFSZ 512
569
570 const size_t size = BUFSZ;
571
572 char buf[BUFSZ];
573 int s, d;
574 size_t pos = 0;
575
576 PRINT("%s", colour[TXT_INSN]);
577
578 if (join)
579 PRINT("join ");
580
581 if (predSrc >= 0) {
582 const size_t pre = pos;
583 if (getSrc(predSrc)->reg.file == FILE_PREDICATE) {
584 if (cc == CC_NOT_P)
585 PRINT("not");
586 } else {
587 PRINT("%s", CondCodeStr[cc]);
588 }
589 if (pos > pre)
590 SPACE();
591 pos += getSrc(predSrc)->print(&buf[pos], BUFSZ - pos);
592 PRINT(" %s", colour[TXT_INSN]);
593 }
594
595 if (saturate)
596 PRINT("sat ");
597
598 if (asFlow()) {
599 PRINT("%s", operationStr[op]);
600 if (asFlow()->indirect)
601 PRINT(" ind");
602 if (asFlow()->absolute)
603 PRINT(" abs");
604 if (op == OP_CALL && asFlow()->builtin) {
605 PRINT(" %sBUILTIN:%i", colour[TXT_BRA], asFlow()->target.builtin);
606 } else
607 if (op == OP_CALL && asFlow()->target.fn) {
608 PRINT(" %s%s:%i", colour[TXT_BRA],
609 asFlow()->target.fn->getName(),
610 asFlow()->target.fn->getLabel());
611 } else
612 if (asFlow()->target.bb)
613 PRINT(" %sBB:%i", colour[TXT_BRA], asFlow()->target.bb->getId());
614 } else {
615 if (asTex())
616 PRINT("%s%s ", operationStr[op], asTex()->tex.scalar ? "s" : "");
617 else
618 PRINT("%s ", operationStr[op]);
619 if (op == OP_LINTERP || op == OP_PINTERP)
620 PRINT("%s ", interpStr[ipa]);
621 switch (op) {
622 case OP_SUREDP:
623 case OP_SUREDB:
624 case OP_ATOM:
625 if (subOp < ARRAY_SIZE(atomSubOpStr))
626 PRINT("%s ", atomSubOpStr[subOp]);
627 break;
628 case OP_LOAD:
629 case OP_STORE:
630 if (subOp < ARRAY_SIZE(ldstSubOpStr))
631 PRINT("%s ", ldstSubOpStr[subOp]);
632 break;
633 case OP_SUBFM:
634 if (subOp < ARRAY_SIZE(subfmOpStr))
635 PRINT("%s ", subfmOpStr[subOp]);
636 break;
637 case OP_SHFL:
638 if (subOp < ARRAY_SIZE(shflOpStr))
639 PRINT("%s ", shflOpStr[subOp]);
640 break;
641 case OP_PIXLD:
642 if (subOp < ARRAY_SIZE(pixldOpStr))
643 PRINT("%s ", pixldOpStr[subOp]);
644 break;
645 case OP_RCP:
646 case OP_RSQ:
647 if (subOp < ARRAY_SIZE(rcprsqOpStr))
648 PRINT("%s ", rcprsqOpStr[subOp]);
649 break;
650 case OP_EMIT:
651 if (subOp < ARRAY_SIZE(emitOpStr))
652 PRINT("%s ", emitOpStr[subOp]);
653 break;
654 case OP_CCTL:
655 if (subOp < ARRAY_SIZE(cctlOpStr))
656 PRINT("%s ", cctlOpStr[subOp]);
657 break;
658 case OP_BAR:
659 if (subOp < ARRAY_SIZE(barOpStr))
660 PRINT("%s ", barOpStr[subOp]);
661 break;
662 case OP_XMAD: {
663 if (subOp & NV50_IR_SUBOP_XMAD_PSL)
664 PRINT("psl ");
665 if (subOp & NV50_IR_SUBOP_XMAD_MRG)
666 PRINT("mrg ");
667 unsigned cmode = (subOp & NV50_IR_SUBOP_XMAD_CMODE_MASK);
668 cmode >>= NV50_IR_SUBOP_XMAD_CMODE_SHIFT;
669 if (cmode && cmode <= ARRAY_SIZE(xmadOpCModeStr))
670 PRINT("%s ", xmadOpCModeStr[cmode - 1]);
671 for (int i = 0; i < 2; i++)
672 PRINT("h%d ", (subOp & NV50_IR_SUBOP_XMAD_H1(i)) ? 1 : 0);
673 break;
674 }
675 default:
676 if (subOp)
677 PRINT("(SUBOP:%u) ", subOp);
678 break;
679 }
680 if (perPatch)
681 PRINT("patch ");
682 if (asTex()) {
683 PRINT("%s %s$r%u $s%u ", asTex()->tex.target.getName(),
684 colour[TXT_MEM], asTex()->tex.r, asTex()->tex.s);
685 if (op == OP_TXG)
686 PRINT("%s ", gatherCompStr[asTex()->tex.gatherComp]);
687 PRINT("%s %s", texMaskStr[asTex()->tex.mask], colour[TXT_INSN]);
688 }
689
690 if (postFactor)
691 PRINT("x2^%i ", postFactor);
692 PRINT("%s%s", dnz ? "dnz " : (ftz ? "ftz " : ""), DataTypeStr[dType]);
693 }
694
695 if (rnd != ROUND_N)
696 PRINT(" %s", RoundModeStr[rnd]);
697
698 if (defExists(1))
699 PRINT(" {");
700 for (d = 0; defExists(d); ++d) {
701 SPACE();
702 pos += getDef(d)->print(&buf[pos], size - pos);
703 }
704 if (d > 1)
705 PRINT(" %s}", colour[TXT_INSN]);
706 else
707 if (!d && !asFlow())
708 PRINT(" %s#", colour[TXT_INSN]);
709
710 if (asCmp())
711 PRINT(" %s%s", colour[TXT_INSN], CondCodeStr[asCmp()->setCond]);
712
713 if (sType != dType)
714 PRINT(" %s%s", colour[TXT_INSN], DataTypeStr[sType]);
715
716 for (s = 0; srcExists(s); ++s) {
717 if (s == predSrc || src(s).usedAsPtr)
718 continue;
719 const size_t pre = pos;
720 SPACE();
721 pos += src(s).mod.print(&buf[pos], BUFSZ - pos);
722 if (pos > pre + 1)
723 SPACE();
724 if (src(s).isIndirect(0) || src(s).isIndirect(1))
725 pos += getSrc(s)->asSym()->print(&buf[pos], BUFSZ - pos,
726 getIndirect(s, 0),
727 getIndirect(s, 1));
728 else
729 pos += getSrc(s)->print(&buf[pos], BUFSZ - pos, sType);
730 }
731 if (exit)
732 PRINT("%s exit", colour[TXT_INSN]);
733
734 PRINT("%s", colour[TXT_DEFAULT]);
735
736 buf[MIN2(pos, BUFSZ - 1)] = 0;
737
738 INFO("%s (%u)\n", buf, encSize);
739 }
740
741 class PrintPass : public Pass
742 {
743 public:
744 PrintPass(bool omitLineNum) : serial(0), omit_serial(omitLineNum) { }
745
746 virtual bool visit(Function *);
747 virtual bool visit(BasicBlock *);
748 virtual bool visit(Instruction *);
749
750 private:
751 int serial;
752 bool omit_serial;
753 };
754
755 bool
756 PrintPass::visit(Function *fn)
757 {
758 char str[16];
759
760 INFO("\n%s:%i (", fn->getName(), fn->getLabel());
761
762 if (!fn->outs.empty())
763 INFO("out");
764 for (std::deque<ValueRef>::iterator it = fn->outs.begin();
765 it != fn->outs.end();
766 ++it) {
767 it->get()->print(str, sizeof(str), typeOfSize(it->get()->reg.size));
768 INFO(" %s", str);
769 }
770
771 if (!fn->ins.empty())
772 INFO("%s%sin", colour[TXT_DEFAULT], fn->outs.empty() ? "" : ", ");
773 for (std::deque<ValueDef>::iterator it = fn->ins.begin();
774 it != fn->ins.end();
775 ++it) {
776 it->get()->print(str, sizeof(str), typeOfSize(it->get()->reg.size));
777 INFO(" %s", str);
778 }
779 INFO("%s)\n", colour[TXT_DEFAULT]);
780
781 return true;
782 }
783
784 bool
785 PrintPass::visit(BasicBlock *bb)
786 {
787 #if 0
788 INFO("---\n");
789 for (Graph::EdgeIterator ei = bb->cfg.incident(); !ei.end(); ei.next())
790 INFO(" <- BB:%i (%s)\n",
791 BasicBlock::get(ei.getNode())->getId(),
792 ei.getEdge()->typeStr());
793 #endif
794 INFO("BB:%i (%u instructions) - ", bb->getId(), bb->getInsnCount());
795
796 if (bb->idom())
797 INFO("idom = BB:%i, ", bb->idom()->getId());
798
799 INFO("df = { ");
800 for (DLList::Iterator df = bb->getDF().iterator(); !df.end(); df.next())
801 INFO("BB:%i ", BasicBlock::get(df)->getId());
802
803 INFO("}\n");
804
805 for (Graph::EdgeIterator ei = bb->cfg.outgoing(); !ei.end(); ei.next())
806 INFO(" -> BB:%i (%s)\n",
807 BasicBlock::get(ei.getNode())->getId(),
808 ei.getEdge()->typeStr());
809
810 return true;
811 }
812
813 bool
814 PrintPass::visit(Instruction *insn)
815 {
816 if (omit_serial)
817 INFO(" ");
818 else
819 INFO("%3i: ", serial);
820 serial++;
821 insn->print();
822 return true;
823 }
824
825 void
826 Function::print()
827 {
828 PrintPass pass(prog->driver->omitLineNum);
829 pass.run(this, true, false);
830 }
831
832 void
833 Program::print()
834 {
835 PrintPass pass(driver->omitLineNum);
836 init_colours();
837 pass.run(this, true, false);
838 }
839
840 void
841 Function::printLiveIntervals() const
842 {
843 INFO("printing live intervals ...\n");
844
845 for (ArrayList::Iterator it = allLValues.iterator(); !it.end(); it.next()) {
846 const Value *lval = Value::get(it)->asLValue();
847 if (lval && !lval->livei.isEmpty()) {
848 INFO("livei(%%%i): ", lval->id);
849 lval->livei.print();
850 }
851 }
852 }
853
854 } // namespace nv50_ir