OSDN Git Service

PR go/47113
[pf3gnuchains/gcc-fork.git] / gcc / sched-vis.c
1 /* Instruction scheduling pass.
2    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3    2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
4    Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
5    and currently maintained by, Jim Wilson (wilson@cygnus.com)
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3.  If not see
21 <http://www.gnu.org/licenses/>.  */
22 \f
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "rtl.h"
28 #include "obstack.h"
29 #include "hard-reg-set.h"
30 #include "basic-block.h"
31 #include "insn-attr.h"
32 #include "sched-int.h"
33 #include "tree-pass.h"
34
35 static char *safe_concat (char *, char *, const char *);
36
37 #define BUF_LEN 2048
38
39 static char *
40 safe_concat (char *buf, char *cur, const char *str)
41 {
42   char *end = buf + BUF_LEN - 2;        /* Leave room for null.  */
43   int c;
44
45   if (cur > end)
46     {
47       *end = '\0';
48       return end;
49     }
50
51   while (cur < end && (c = *str++) != '\0')
52     *cur++ = c;
53
54   *cur = '\0';
55   return cur;
56 }
57
58 /* This recognizes rtx, I classified as expressions.  These are always
59    represent some action on values or results of other expression, that
60    may be stored in objects representing values.  */
61
62 static void
63 print_exp (char *buf, const_rtx x, int verbose)
64 {
65   char tmp[BUF_LEN];
66   const char *st[4];
67   char *cur = buf;
68   const char *fun = (char *) 0;
69   const char *sep;
70   rtx op[4];
71   int i;
72
73   for (i = 0; i < 4; i++)
74     {
75       st[i] = (char *) 0;
76       op[i] = NULL_RTX;
77     }
78
79   switch (GET_CODE (x))
80     {
81     case PLUS:
82       op[0] = XEXP (x, 0);
83       if (CONST_INT_P (XEXP (x, 1))
84           && INTVAL (XEXP (x, 1)) < 0)
85         {
86           st[1] = "-";
87           op[1] = GEN_INT (-INTVAL (XEXP (x, 1)));
88         }
89       else
90         {
91           st[1] = "+";
92           op[1] = XEXP (x, 1);
93         }
94       break;
95     case LO_SUM:
96       op[0] = XEXP (x, 0);
97       st[1] = "+low(";
98       op[1] = XEXP (x, 1);
99       st[2] = ")";
100       break;
101     case MINUS:
102       op[0] = XEXP (x, 0);
103       st[1] = "-";
104       op[1] = XEXP (x, 1);
105       break;
106     case COMPARE:
107       fun = "cmp";
108       op[0] = XEXP (x, 0);
109       op[1] = XEXP (x, 1);
110       break;
111     case NEG:
112       st[0] = "-";
113       op[0] = XEXP (x, 0);
114       break;
115     case MULT:
116       op[0] = XEXP (x, 0);
117       st[1] = "*";
118       op[1] = XEXP (x, 1);
119       break;
120     case DIV:
121       op[0] = XEXP (x, 0);
122       st[1] = "/";
123       op[1] = XEXP (x, 1);
124       break;
125     case UDIV:
126       fun = "udiv";
127       op[0] = XEXP (x, 0);
128       op[1] = XEXP (x, 1);
129       break;
130     case MOD:
131       op[0] = XEXP (x, 0);
132       st[1] = "%";
133       op[1] = XEXP (x, 1);
134       break;
135     case UMOD:
136       fun = "umod";
137       op[0] = XEXP (x, 0);
138       op[1] = XEXP (x, 1);
139       break;
140     case SMIN:
141       fun = "smin";
142       op[0] = XEXP (x, 0);
143       op[1] = XEXP (x, 1);
144       break;
145     case SMAX:
146       fun = "smax";
147       op[0] = XEXP (x, 0);
148       op[1] = XEXP (x, 1);
149       break;
150     case UMIN:
151       fun = "umin";
152       op[0] = XEXP (x, 0);
153       op[1] = XEXP (x, 1);
154       break;
155     case UMAX:
156       fun = "umax";
157       op[0] = XEXP (x, 0);
158       op[1] = XEXP (x, 1);
159       break;
160     case NOT:
161       st[0] = "!";
162       op[0] = XEXP (x, 0);
163       break;
164     case AND:
165       op[0] = XEXP (x, 0);
166       st[1] = "&";
167       op[1] = XEXP (x, 1);
168       break;
169     case IOR:
170       op[0] = XEXP (x, 0);
171       st[1] = "|";
172       op[1] = XEXP (x, 1);
173       break;
174     case XOR:
175       op[0] = XEXP (x, 0);
176       st[1] = "^";
177       op[1] = XEXP (x, 1);
178       break;
179     case ASHIFT:
180       op[0] = XEXP (x, 0);
181       st[1] = "<<";
182       op[1] = XEXP (x, 1);
183       break;
184     case LSHIFTRT:
185       op[0] = XEXP (x, 0);
186       st[1] = " 0>>";
187       op[1] = XEXP (x, 1);
188       break;
189     case ASHIFTRT:
190       op[0] = XEXP (x, 0);
191       st[1] = ">>";
192       op[1] = XEXP (x, 1);
193       break;
194     case ROTATE:
195       op[0] = XEXP (x, 0);
196       st[1] = "<-<";
197       op[1] = XEXP (x, 1);
198       break;
199     case ROTATERT:
200       op[0] = XEXP (x, 0);
201       st[1] = ">->";
202       op[1] = XEXP (x, 1);
203       break;
204     case ABS:
205       fun = "abs";
206       op[0] = XEXP (x, 0);
207       break;
208     case SQRT:
209       fun = "sqrt";
210       op[0] = XEXP (x, 0);
211       break;
212     case FFS:
213       fun = "ffs";
214       op[0] = XEXP (x, 0);
215       break;
216     case EQ:
217       op[0] = XEXP (x, 0);
218       st[1] = "==";
219       op[1] = XEXP (x, 1);
220       break;
221     case NE:
222       op[0] = XEXP (x, 0);
223       st[1] = "!=";
224       op[1] = XEXP (x, 1);
225       break;
226     case GT:
227       op[0] = XEXP (x, 0);
228       st[1] = ">";
229       op[1] = XEXP (x, 1);
230       break;
231     case GTU:
232       fun = "gtu";
233       op[0] = XEXP (x, 0);
234       op[1] = XEXP (x, 1);
235       break;
236     case LT:
237       op[0] = XEXP (x, 0);
238       st[1] = "<";
239       op[1] = XEXP (x, 1);
240       break;
241     case LTU:
242       fun = "ltu";
243       op[0] = XEXP (x, 0);
244       op[1] = XEXP (x, 1);
245       break;
246     case GE:
247       op[0] = XEXP (x, 0);
248       st[1] = ">=";
249       op[1] = XEXP (x, 1);
250       break;
251     case GEU:
252       fun = "geu";
253       op[0] = XEXP (x, 0);
254       op[1] = XEXP (x, 1);
255       break;
256     case LE:
257       op[0] = XEXP (x, 0);
258       st[1] = "<=";
259       op[1] = XEXP (x, 1);
260       break;
261     case LEU:
262       fun = "leu";
263       op[0] = XEXP (x, 0);
264       op[1] = XEXP (x, 1);
265       break;
266     case SIGN_EXTRACT:
267       fun = (verbose) ? "sign_extract" : "sxt";
268       op[0] = XEXP (x, 0);
269       op[1] = XEXP (x, 1);
270       op[2] = XEXP (x, 2);
271       break;
272     case ZERO_EXTRACT:
273       fun = (verbose) ? "zero_extract" : "zxt";
274       op[0] = XEXP (x, 0);
275       op[1] = XEXP (x, 1);
276       op[2] = XEXP (x, 2);
277       break;
278     case SIGN_EXTEND:
279       fun = (verbose) ? "sign_extend" : "sxn";
280       op[0] = XEXP (x, 0);
281       break;
282     case ZERO_EXTEND:
283       fun = (verbose) ? "zero_extend" : "zxn";
284       op[0] = XEXP (x, 0);
285       break;
286     case FLOAT_EXTEND:
287       fun = (verbose) ? "float_extend" : "fxn";
288       op[0] = XEXP (x, 0);
289       break;
290     case TRUNCATE:
291       fun = (verbose) ? "trunc" : "trn";
292       op[0] = XEXP (x, 0);
293       break;
294     case FLOAT_TRUNCATE:
295       fun = (verbose) ? "float_trunc" : "ftr";
296       op[0] = XEXP (x, 0);
297       break;
298     case FLOAT:
299       fun = (verbose) ? "float" : "flt";
300       op[0] = XEXP (x, 0);
301       break;
302     case UNSIGNED_FLOAT:
303       fun = (verbose) ? "uns_float" : "ufl";
304       op[0] = XEXP (x, 0);
305       break;
306     case FIX:
307       fun = "fix";
308       op[0] = XEXP (x, 0);
309       break;
310     case UNSIGNED_FIX:
311       fun = (verbose) ? "uns_fix" : "ufx";
312       op[0] = XEXP (x, 0);
313       break;
314     case PRE_DEC:
315       st[0] = "--";
316       op[0] = XEXP (x, 0);
317       break;
318     case PRE_INC:
319       st[0] = "++";
320       op[0] = XEXP (x, 0);
321       break;
322     case POST_DEC:
323       op[0] = XEXP (x, 0);
324       st[1] = "--";
325       break;
326     case POST_INC:
327       op[0] = XEXP (x, 0);
328       st[1] = "++";
329       break;
330     case PRE_MODIFY:
331       st[0] = "pre ";
332       op[0] = XEXP (XEXP (x, 1), 0);
333       st[1] = "+=";
334       op[1] = XEXP (XEXP (x, 1), 1);
335       break;
336     case POST_MODIFY:
337       st[0] = "post ";
338       op[0] = XEXP (XEXP (x, 1), 0);
339       st[1] = "+=";
340       op[1] = XEXP (XEXP (x, 1), 1);
341       break;
342     case CALL:
343       st[0] = "call ";
344       op[0] = XEXP (x, 0);
345       if (verbose)
346         {
347           st[1] = " argc:";
348           op[1] = XEXP (x, 1);
349         }
350       break;
351     case IF_THEN_ELSE:
352       st[0] = "{(";
353       op[0] = XEXP (x, 0);
354       st[1] = ")?";
355       op[1] = XEXP (x, 1);
356       st[2] = ":";
357       op[2] = XEXP (x, 2);
358       st[3] = "}";
359       break;
360     case TRAP_IF:
361       fun = "trap_if";
362       op[0] = TRAP_CONDITION (x);
363       break;
364     case PREFETCH:
365       fun = "prefetch";
366       op[0] = XEXP (x, 0);
367       op[1] = XEXP (x, 1);
368       op[2] = XEXP (x, 2);
369       break;
370     case UNSPEC:
371     case UNSPEC_VOLATILE:
372       {
373         cur = safe_concat (buf, cur, "unspec");
374         if (GET_CODE (x) == UNSPEC_VOLATILE)
375           cur = safe_concat (buf, cur, "/v");
376         cur = safe_concat (buf, cur, "[");
377         sep = "";
378         for (i = 0; i < XVECLEN (x, 0); i++)
379           {
380             print_pattern (tmp, XVECEXP (x, 0, i), verbose);
381             cur = safe_concat (buf, cur, sep);
382             cur = safe_concat (buf, cur, tmp);
383             sep = ",";
384           }
385         cur = safe_concat (buf, cur, "] ");
386         sprintf (tmp, "%d", XINT (x, 1));
387         cur = safe_concat (buf, cur, tmp);
388       }
389       break;
390     default:
391       /* If (verbose) debug_rtx (x);  */
392       st[0] = GET_RTX_NAME (GET_CODE (x));
393       break;
394     }
395
396   /* Print this as a function?  */
397   if (fun)
398     {
399       cur = safe_concat (buf, cur, fun);
400       cur = safe_concat (buf, cur, "(");
401     }
402
403   for (i = 0; i < 4; i++)
404     {
405       if (st[i])
406         cur = safe_concat (buf, cur, st[i]);
407
408       if (op[i])
409         {
410           if (fun && i != 0)
411             cur = safe_concat (buf, cur, ",");
412
413           print_value (tmp, op[i], verbose);
414           cur = safe_concat (buf, cur, tmp);
415         }
416     }
417
418   if (fun)
419     cur = safe_concat (buf, cur, ")");
420 }               /* print_exp */
421
422 /* Prints rtxes, I customarily classified as values.  They're constants,
423    registers, labels, symbols and memory accesses.  */
424
425 void
426 print_value (char *buf, const_rtx x, int verbose)
427 {
428   char t[BUF_LEN];
429   char *cur = buf;
430
431   if (!x)
432     {
433       safe_concat (buf, buf, "(nil)");
434       return;
435     }
436   switch (GET_CODE (x))
437     {
438     case CONST_INT:
439       sprintf (t, HOST_WIDE_INT_PRINT_HEX,
440                (unsigned HOST_WIDE_INT) INTVAL (x));
441       cur = safe_concat (buf, cur, t);
442       break;
443     case CONST_DOUBLE:
444       if (FLOAT_MODE_P (GET_MODE (x)))
445         real_to_decimal (t, CONST_DOUBLE_REAL_VALUE (x), sizeof (t), 0, 1);
446       else
447         sprintf (t,
448                  "<" HOST_WIDE_INT_PRINT_HEX "," HOST_WIDE_INT_PRINT_HEX ">",
449                  (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x),
450                  (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (x));
451       cur = safe_concat (buf, cur, t);
452       break;
453     case CONST_FIXED:
454       fixed_to_decimal (t, CONST_FIXED_VALUE (x), sizeof (t));
455       cur = safe_concat (buf, cur, t);
456       break;
457     case CONST_STRING:
458       cur = safe_concat (buf, cur, "\"");
459       cur = safe_concat (buf, cur, XSTR (x, 0));
460       cur = safe_concat (buf, cur, "\"");
461       break;
462     case SYMBOL_REF:
463       cur = safe_concat (buf, cur, "`");
464       cur = safe_concat (buf, cur, XSTR (x, 0));
465       cur = safe_concat (buf, cur, "'");
466       break;
467     case LABEL_REF:
468       sprintf (t, "L%d", INSN_UID (XEXP (x, 0)));
469       cur = safe_concat (buf, cur, t);
470       break;
471     case CONST:
472       print_value (t, XEXP (x, 0), verbose);
473       cur = safe_concat (buf, cur, "const(");
474       cur = safe_concat (buf, cur, t);
475       cur = safe_concat (buf, cur, ")");
476       break;
477     case HIGH:
478       print_value (t, XEXP (x, 0), verbose);
479       cur = safe_concat (buf, cur, "high(");
480       cur = safe_concat (buf, cur, t);
481       cur = safe_concat (buf, cur, ")");
482       break;
483     case REG:
484       if (REGNO (x) < FIRST_PSEUDO_REGISTER)
485         {
486           int c = reg_names[REGNO (x)][0];
487           if (ISDIGIT (c))
488             cur = safe_concat (buf, cur, "%");
489
490           cur = safe_concat (buf, cur, reg_names[REGNO (x)]);
491         }
492       else
493         {
494           sprintf (t, "r%d", REGNO (x));
495           cur = safe_concat (buf, cur, t);
496         }
497       if (verbose
498 #ifdef INSN_SCHEDULING
499           && !current_sched_info
500 #endif
501          )
502         {
503           sprintf (t, ":%s", GET_MODE_NAME (GET_MODE (x)));
504           cur = safe_concat (buf, cur, t);
505         }
506       break;
507     case SUBREG:
508       print_value (t, SUBREG_REG (x), verbose);
509       cur = safe_concat (buf, cur, t);
510       sprintf (t, "#%d", SUBREG_BYTE (x));
511       cur = safe_concat (buf, cur, t);
512       break;
513     case SCRATCH:
514       cur = safe_concat (buf, cur, "scratch");
515       break;
516     case CC0:
517       cur = safe_concat (buf, cur, "cc0");
518       break;
519     case PC:
520       cur = safe_concat (buf, cur, "pc");
521       break;
522     case MEM:
523       print_value (t, XEXP (x, 0), verbose);
524       cur = safe_concat (buf, cur, "[");
525       cur = safe_concat (buf, cur, t);
526       cur = safe_concat (buf, cur, "]");
527       break;
528     case DEBUG_EXPR:
529       sprintf (t, "D#%i", DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x)));
530       cur = safe_concat (buf, cur, t);
531       break;
532     default:
533       print_exp (t, x, verbose);
534       cur = safe_concat (buf, cur, t);
535       break;
536     }
537 }                               /* print_value */
538
539 /* The next step in insn detalization, its pattern recognition.  */
540
541 void
542 print_pattern (char *buf, const_rtx x, int verbose)
543 {
544   char t1[BUF_LEN], t2[BUF_LEN], t3[BUF_LEN];
545
546   switch (GET_CODE (x))
547     {
548     case SET:
549       print_value (t1, SET_DEST (x), verbose);
550       print_value (t2, SET_SRC (x), verbose);
551       sprintf (buf, "%s=%s", t1, t2);
552       break;
553     case RETURN:
554       sprintf (buf, "return");
555       break;
556     case CALL:
557       print_exp (buf, x, verbose);
558       break;
559     case CLOBBER:
560       print_value (t1, XEXP (x, 0), verbose);
561       sprintf (buf, "clobber %s", t1);
562       break;
563     case USE:
564       print_value (t1, XEXP (x, 0), verbose);
565       sprintf (buf, "use %s", t1);
566       break;
567     case VAR_LOCATION:
568       print_value (t1, PAT_VAR_LOCATION_LOC (x), verbose);
569       sprintf (buf, "loc %s", t1);
570       break;
571     case COND_EXEC:
572       if (GET_CODE (COND_EXEC_TEST (x)) == NE
573           && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
574         print_value (t1, XEXP (COND_EXEC_TEST (x), 0), verbose);
575       else if (GET_CODE (COND_EXEC_TEST (x)) == EQ
576                && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
577         {
578           t1[0] = '!';
579           print_value (t1 + 1, XEXP (COND_EXEC_TEST (x), 0), verbose);
580         }
581       else
582         print_value (t1, COND_EXEC_TEST (x), verbose);
583       print_pattern (t2, COND_EXEC_CODE (x), verbose);
584       sprintf (buf, "(%s) %s", t1, t2);
585       break;
586     case PARALLEL:
587       {
588         int i;
589
590         sprintf (t1, "{");
591         for (i = 0; i < XVECLEN (x, 0); i++)
592           {
593             print_pattern (t2, XVECEXP (x, 0, i), verbose);
594             sprintf (t3, "%s%s;", t1, t2);
595             strcpy (t1, t3);
596           }
597         sprintf (buf, "%s}", t1);
598       }
599       break;
600     case SEQUENCE:
601       /* Should never see SEQUENCE codes until after reorg.  */
602       gcc_unreachable ();
603     case ASM_INPUT:
604       sprintf (buf, "asm {%s}", XSTR (x, 0));
605       break;
606     case ADDR_VEC:
607       /* Fall through.  */
608     case ADDR_DIFF_VEC:
609       print_value (buf, XEXP (x, 0), verbose);
610       break;
611     case TRAP_IF:
612       print_value (t1, TRAP_CONDITION (x), verbose);
613       sprintf (buf, "trap_if %s", t1);
614       break;
615     case UNSPEC:
616       {
617         int i;
618
619         sprintf (t1, "unspec{");
620         for (i = 0; i < XVECLEN (x, 0); i++)
621           {
622             print_pattern (t2, XVECEXP (x, 0, i), verbose);
623             sprintf (t3, "%s%s;", t1, t2);
624             strcpy (t1, t3);
625           }
626         sprintf (buf, "%s}", t1);
627       }
628       break;
629     case UNSPEC_VOLATILE:
630       {
631         int i;
632
633         sprintf (t1, "unspec/v{");
634         for (i = 0; i < XVECLEN (x, 0); i++)
635           {
636             print_pattern (t2, XVECEXP (x, 0, i), verbose);
637             sprintf (t3, "%s%s;", t1, t2);
638             strcpy (t1, t3);
639           }
640         sprintf (buf, "%s}", t1);
641       }
642       break;
643     default:
644       print_value (buf, x, verbose);
645     }
646 }                               /* print_pattern */
647
648 /* This is the main function in rtl visualization mechanism. It
649    accepts an rtx and tries to recognize it as an insn, then prints it
650    properly in human readable form, resembling assembler mnemonics.
651    For every insn it prints its UID and BB the insn belongs too.
652    (Probably the last "option" should be extended somehow, since it
653    depends now on sched.c inner variables ...)  */
654
655 void
656 print_insn (char *buf, const_rtx x, int verbose)
657 {
658   char t[BUF_LEN];
659   const_rtx insn = x;
660
661   switch (GET_CODE (x))
662     {
663     case INSN:
664       print_pattern (t, PATTERN (x), verbose);
665 #ifdef INSN_SCHEDULING
666       if (verbose && current_sched_info)
667         sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1),
668                  t);
669       else
670 #endif
671         sprintf (buf, " %4d %s", INSN_UID (x), t);
672       break;
673
674     case DEBUG_INSN:
675       {
676         const char *name = "?";
677
678         if (DECL_P (INSN_VAR_LOCATION_DECL (insn)))
679           {
680             tree id = DECL_NAME (INSN_VAR_LOCATION_DECL (insn));
681             char idbuf[32];
682             if (id)
683               name = IDENTIFIER_POINTER (id);
684             else if (TREE_CODE (INSN_VAR_LOCATION_DECL (insn))
685                      == DEBUG_EXPR_DECL)
686               {
687                 sprintf (idbuf, "D#%i",
688                          DEBUG_TEMP_UID (INSN_VAR_LOCATION_DECL (insn)));
689                 name = idbuf;
690               }
691             else
692               {
693                 sprintf (idbuf, "D.%i",
694                          DECL_UID (INSN_VAR_LOCATION_DECL (insn)));
695                 name = idbuf;
696               }
697           }
698         if (VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (insn)))
699           sprintf (buf, " %4d: debug %s optimized away", INSN_UID (insn), name);
700         else
701           {
702             print_pattern (t, INSN_VAR_LOCATION_LOC (insn), verbose);
703             sprintf (buf, " %4d: debug %s => %s", INSN_UID (insn), name, t);
704           }
705       }
706       break;
707
708     case JUMP_INSN:
709       print_pattern (t, PATTERN (x), verbose);
710 #ifdef INSN_SCHEDULING
711       if (verbose && current_sched_info)
712         sprintf (buf, "%s: jump %s", (*current_sched_info->print_insn) (x, 1),
713                  t);
714       else
715 #endif
716         sprintf (buf, " %4d %s", INSN_UID (x), t);
717       break;
718     case CALL_INSN:
719       x = PATTERN (insn);
720       if (GET_CODE (x) == PARALLEL)
721         {
722           x = XVECEXP (x, 0, 0);
723           print_pattern (t, x, verbose);
724         }
725       else
726         strcpy (t, "call <...>");
727 #ifdef INSN_SCHEDULING
728       if (verbose && current_sched_info)
729         sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (insn, 1), t);
730       else
731 #endif
732         sprintf (buf, " %4d %s", INSN_UID (insn), t);
733       break;
734     case CODE_LABEL:
735       sprintf (buf, "L%d:", INSN_UID (x));
736       break;
737     case BARRIER:
738       sprintf (buf, "i%4d: barrier", INSN_UID (x));
739       break;
740     case NOTE:
741       sprintf (buf, " %4d %s", INSN_UID (x),
742                GET_NOTE_INSN_NAME (NOTE_KIND (x)));
743       break;
744     default:
745       sprintf (buf, "i%4d  <What %s?>", INSN_UID (x),
746                GET_RTX_NAME (GET_CODE (x)));
747     }
748 }                               /* print_insn */
749
750 /* Emit a slim dump of X (an insn) to the file F, including any register
751    note attached to the instruction.  */
752 void
753 dump_insn_slim (FILE *f, rtx x)
754 {
755   char t[BUF_LEN + 32];
756   rtx note;
757
758   print_insn (t, x, 1);
759   fputs (t, f);
760   putc ('\n', f);
761   if (INSN_P (x) && REG_NOTES (x))
762     for (note = REG_NOTES (x); note; note = XEXP (note, 1))
763       {
764         print_value (t, XEXP (note, 0), 1);
765         fprintf (f, "      %s: %s\n",
766                  GET_REG_NOTE_NAME (REG_NOTE_KIND (note)), t);
767       }
768 }
769
770 /* Emit a slim dump of X (an insn) to stderr.  */
771 DEBUG_FUNCTION void
772 debug_insn_slim (rtx x)
773 {
774   dump_insn_slim (stderr, x);
775 }
776
777 /* Provide a slim dump the instruction chain starting at FIRST to F, honoring
778    the dump flags given in FLAGS.  Currently, TDF_BLOCKS and TDF_DETAILS
779    include more information on the basic blocks.  */
780 void
781 print_rtl_slim_with_bb (FILE *f, rtx first, int flags)
782 {
783   print_rtl_slim (f, first, NULL, -1, flags);
784 }
785
786 /* Same as above, but stop at LAST or when COUNT == 0.
787    If COUNT < 0 it will stop only at LAST or NULL rtx.  */
788 void
789 print_rtl_slim (FILE *f, rtx first, rtx last, int count, int flags)
790 {
791   basic_block current_bb = NULL;
792   rtx insn, tail;
793
794   tail = last ? NEXT_INSN (last) : NULL_RTX;
795   for (insn = first;
796        (insn != NULL) && (insn != tail) && (count != 0);
797        insn = NEXT_INSN (insn))
798     {
799       if ((flags & TDF_BLOCKS)
800           && (INSN_P (insn) || NOTE_P (insn))
801           && BLOCK_FOR_INSN (insn)
802           && !current_bb)
803         {
804           current_bb = BLOCK_FOR_INSN (insn);
805           dump_bb_info (current_bb, true, false, flags, ";; ", f);
806         }
807
808       dump_insn_slim (f, insn);
809
810       if ((flags & TDF_BLOCKS)
811           && current_bb
812           && insn == BB_END (current_bb))
813         {
814           dump_bb_info (current_bb, false, true, flags, ";; ", f);
815           current_bb = NULL;
816         }
817       if (count > 0)
818         count--;
819     }
820 }
821
822 DEBUG_FUNCTION void
823 debug_bb_slim (struct basic_block_def *bb)
824 {
825   print_rtl_slim (stderr, BB_HEAD (bb), BB_END (bb), -1, 32);
826 }
827
828 DEBUG_FUNCTION void
829 debug_bb_n_slim (int n)
830 {
831   struct basic_block_def *bb = BASIC_BLOCK (n);
832   debug_bb_slim (bb);
833 }
834