OSDN Git Service

gcc:
[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   switch (GET_CODE (x))
432     {
433     case CONST_INT:
434       sprintf (t, HOST_WIDE_INT_PRINT_HEX,
435                (unsigned HOST_WIDE_INT) INTVAL (x));
436       cur = safe_concat (buf, cur, t);
437       break;
438     case CONST_DOUBLE:
439       if (FLOAT_MODE_P (GET_MODE (x)))
440         real_to_decimal (t, CONST_DOUBLE_REAL_VALUE (x), sizeof (t), 0, 1);
441       else
442         sprintf (t,
443                  "<" HOST_WIDE_INT_PRINT_HEX "," HOST_WIDE_INT_PRINT_HEX ">",
444                  (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x),
445                  (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (x));
446       cur = safe_concat (buf, cur, t);
447       break;
448     case CONST_FIXED:
449       fixed_to_decimal (t, CONST_FIXED_VALUE (x), sizeof (t));
450       cur = safe_concat (buf, cur, t);
451       break;
452     case CONST_STRING:
453       cur = safe_concat (buf, cur, "\"");
454       cur = safe_concat (buf, cur, XSTR (x, 0));
455       cur = safe_concat (buf, cur, "\"");
456       break;
457     case SYMBOL_REF:
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 LABEL_REF:
463       sprintf (t, "L%d", INSN_UID (XEXP (x, 0)));
464       cur = safe_concat (buf, cur, t);
465       break;
466     case CONST:
467       print_value (t, XEXP (x, 0), verbose);
468       cur = safe_concat (buf, cur, "const(");
469       cur = safe_concat (buf, cur, t);
470       cur = safe_concat (buf, cur, ")");
471       break;
472     case HIGH:
473       print_value (t, XEXP (x, 0), verbose);
474       cur = safe_concat (buf, cur, "high(");
475       cur = safe_concat (buf, cur, t);
476       cur = safe_concat (buf, cur, ")");
477       break;
478     case REG:
479       if (REGNO (x) < FIRST_PSEUDO_REGISTER)
480         {
481           int c = reg_names[REGNO (x)][0];
482           if (ISDIGIT (c))
483             cur = safe_concat (buf, cur, "%");
484
485           cur = safe_concat (buf, cur, reg_names[REGNO (x)]);
486         }
487       else
488         {
489           sprintf (t, "r%d", REGNO (x));
490           cur = safe_concat (buf, cur, t);
491         }
492       if (verbose
493 #ifdef INSN_SCHEDULING
494           && !current_sched_info
495 #endif
496          )
497         {
498           sprintf (t, ":%s", GET_MODE_NAME (GET_MODE (x)));
499           cur = safe_concat (buf, cur, t);
500         }
501       break;
502     case SUBREG:
503       print_value (t, SUBREG_REG (x), verbose);
504       cur = safe_concat (buf, cur, t);
505       sprintf (t, "#%d", SUBREG_BYTE (x));
506       cur = safe_concat (buf, cur, t);
507       break;
508     case SCRATCH:
509       cur = safe_concat (buf, cur, "scratch");
510       break;
511     case CC0:
512       cur = safe_concat (buf, cur, "cc0");
513       break;
514     case PC:
515       cur = safe_concat (buf, cur, "pc");
516       break;
517     case MEM:
518       print_value (t, XEXP (x, 0), verbose);
519       cur = safe_concat (buf, cur, "[");
520       cur = safe_concat (buf, cur, t);
521       cur = safe_concat (buf, cur, "]");
522       break;
523     case DEBUG_EXPR:
524       sprintf (t, "D#%i", DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x)));
525       cur = safe_concat (buf, cur, t);
526       break;
527     default:
528       print_exp (t, x, verbose);
529       cur = safe_concat (buf, cur, t);
530       break;
531     }
532 }                               /* print_value */
533
534 /* The next step in insn detalization, its pattern recognition.  */
535
536 void
537 print_pattern (char *buf, const_rtx x, int verbose)
538 {
539   char t1[BUF_LEN], t2[BUF_LEN], t3[BUF_LEN];
540
541   switch (GET_CODE (x))
542     {
543     case SET:
544       print_value (t1, SET_DEST (x), verbose);
545       print_value (t2, SET_SRC (x), verbose);
546       sprintf (buf, "%s=%s", t1, t2);
547       break;
548     case RETURN:
549       sprintf (buf, "return");
550       break;
551     case CALL:
552       print_exp (buf, x, verbose);
553       break;
554     case CLOBBER:
555       print_value (t1, XEXP (x, 0), verbose);
556       sprintf (buf, "clobber %s", t1);
557       break;
558     case USE:
559       print_value (t1, XEXP (x, 0), verbose);
560       sprintf (buf, "use %s", t1);
561       break;
562     case VAR_LOCATION:
563       print_value (t1, PAT_VAR_LOCATION_LOC (x), verbose);
564       sprintf (buf, "loc %s", t1);
565       break;
566     case COND_EXEC:
567       if (GET_CODE (COND_EXEC_TEST (x)) == NE
568           && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
569         print_value (t1, XEXP (COND_EXEC_TEST (x), 0), verbose);
570       else if (GET_CODE (COND_EXEC_TEST (x)) == EQ
571                && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
572         {
573           t1[0] = '!';
574           print_value (t1 + 1, XEXP (COND_EXEC_TEST (x), 0), verbose);
575         }
576       else
577         print_value (t1, COND_EXEC_TEST (x), verbose);
578       print_pattern (t2, COND_EXEC_CODE (x), verbose);
579       sprintf (buf, "(%s) %s", t1, t2);
580       break;
581     case PARALLEL:
582       {
583         int i;
584
585         sprintf (t1, "{");
586         for (i = 0; i < XVECLEN (x, 0); i++)
587           {
588             print_pattern (t2, XVECEXP (x, 0, i), verbose);
589             sprintf (t3, "%s%s;", t1, t2);
590             strcpy (t1, t3);
591           }
592         sprintf (buf, "%s}", t1);
593       }
594       break;
595     case SEQUENCE:
596       /* Should never see SEQUENCE codes until after reorg.  */
597       gcc_unreachable ();
598     case ASM_INPUT:
599       sprintf (buf, "asm {%s}", XSTR (x, 0));
600       break;
601     case ADDR_VEC:
602       break;
603     case ADDR_DIFF_VEC:
604       print_value (buf, XEXP (x, 0), verbose);
605       break;
606     case TRAP_IF:
607       print_value (t1, TRAP_CONDITION (x), verbose);
608       sprintf (buf, "trap_if %s", t1);
609       break;
610     case UNSPEC:
611       {
612         int i;
613
614         sprintf (t1, "unspec{");
615         for (i = 0; i < XVECLEN (x, 0); i++)
616           {
617             print_pattern (t2, XVECEXP (x, 0, i), verbose);
618             sprintf (t3, "%s%s;", t1, t2);
619             strcpy (t1, t3);
620           }
621         sprintf (buf, "%s}", t1);
622       }
623       break;
624     case UNSPEC_VOLATILE:
625       {
626         int i;
627
628         sprintf (t1, "unspec/v{");
629         for (i = 0; i < XVECLEN (x, 0); i++)
630           {
631             print_pattern (t2, XVECEXP (x, 0, i), verbose);
632             sprintf (t3, "%s%s;", t1, t2);
633             strcpy (t1, t3);
634           }
635         sprintf (buf, "%s}", t1);
636       }
637       break;
638     default:
639       print_value (buf, x, verbose);
640     }
641 }                               /* print_pattern */
642
643 /* This is the main function in rtl visualization mechanism. It
644    accepts an rtx and tries to recognize it as an insn, then prints it
645    properly in human readable form, resembling assembler mnemonics.
646    For every insn it prints its UID and BB the insn belongs too.
647    (Probably the last "option" should be extended somehow, since it
648    depends now on sched.c inner variables ...)  */
649
650 void
651 print_insn (char *buf, const_rtx x, int verbose)
652 {
653   char t[BUF_LEN];
654   const_rtx insn = x;
655
656   switch (GET_CODE (x))
657     {
658     case INSN:
659       print_pattern (t, PATTERN (x), verbose);
660 #ifdef INSN_SCHEDULING
661       if (verbose && current_sched_info)
662         sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1),
663                  t);
664       else
665 #endif
666         sprintf (buf, " %4d %s", INSN_UID (x), t);
667       break;
668
669     case DEBUG_INSN:
670       {
671         const char *name = "?";
672
673         if (DECL_P (INSN_VAR_LOCATION_DECL (insn)))
674           {
675             tree id = DECL_NAME (INSN_VAR_LOCATION_DECL (insn));
676             char idbuf[32];
677             if (id)
678               name = IDENTIFIER_POINTER (id);
679             else if (TREE_CODE (INSN_VAR_LOCATION_DECL (insn))
680                      == DEBUG_EXPR_DECL)
681               {
682                 sprintf (idbuf, "D#%i",
683                          DEBUG_TEMP_UID (INSN_VAR_LOCATION_DECL (insn)));
684                 name = idbuf;
685               }
686             else
687               {
688                 sprintf (idbuf, "D.%i",
689                          DECL_UID (INSN_VAR_LOCATION_DECL (insn)));
690                 name = idbuf;
691               }
692           }
693         if (VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (insn)))
694           sprintf (buf, " %4d: debug %s optimized away", INSN_UID (insn), name);
695         else
696           {
697             print_pattern (t, INSN_VAR_LOCATION_LOC (insn), verbose);
698             sprintf (buf, " %4d: debug %s => %s", INSN_UID (insn), name, t);
699           }
700       }
701       break;
702
703     case JUMP_INSN:
704       print_pattern (t, PATTERN (x), verbose);
705 #ifdef INSN_SCHEDULING
706       if (verbose && current_sched_info)
707         sprintf (buf, "%s: jump %s", (*current_sched_info->print_insn) (x, 1),
708                  t);
709       else
710 #endif
711         sprintf (buf, " %4d %s", INSN_UID (x), t);
712       break;
713     case CALL_INSN:
714       x = PATTERN (insn);
715       if (GET_CODE (x) == PARALLEL)
716         {
717           x = XVECEXP (x, 0, 0);
718           print_pattern (t, x, verbose);
719         }
720       else
721         strcpy (t, "call <...>");
722 #ifdef INSN_SCHEDULING
723       if (verbose && current_sched_info)
724         sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (insn, 1), t);
725       else
726 #endif
727         sprintf (buf, " %4d %s", INSN_UID (insn), t);
728       break;
729     case CODE_LABEL:
730       sprintf (buf, "L%d:", INSN_UID (x));
731       break;
732     case BARRIER:
733       sprintf (buf, "i%4d: barrier", INSN_UID (x));
734       break;
735     case NOTE:
736       sprintf (buf, " %4d %s", INSN_UID (x),
737                GET_NOTE_INSN_NAME (NOTE_KIND (x)));
738       break;
739     default:
740       sprintf (buf, "i%4d  <What %s?>", INSN_UID (x),
741                GET_RTX_NAME (GET_CODE (x)));
742     }
743 }                               /* print_insn */
744
745 /* Emit a slim dump of X (an insn) to the file F, including any register
746    note attached to the instruction.  */
747 void
748 dump_insn_slim (FILE *f, rtx x)
749 {
750   char t[BUF_LEN + 32];
751   rtx note;
752
753   print_insn (t, x, 1);
754   fputs (t, f);
755   putc ('\n', f);
756   if (INSN_P (x) && REG_NOTES (x))
757     for (note = REG_NOTES (x); note; note = XEXP (note, 1))
758       {
759         print_value (t, XEXP (note, 0), 1);
760         fprintf (f, "      %s: %s\n",
761                  GET_REG_NOTE_NAME (REG_NOTE_KIND (note)), t);
762       }
763 }
764
765 /* Emit a slim dump of X (an insn) to stderr.  */
766 void
767 debug_insn_slim (rtx x)
768 {
769   dump_insn_slim (stderr, x);
770 }
771
772 /* Provide a slim dump the instruction chain starting at FIRST to F, honoring
773    the dump flags given in FLAGS.  Currently, TDF_BLOCKS and TDF_DETAILS
774    include more information on the basic blocks.  */
775 void
776 print_rtl_slim_with_bb (FILE *f, rtx first, int flags)
777 {
778   print_rtl_slim (f, first, NULL, -1, flags);
779 }
780
781 /* Same as above, but stop at LAST or when COUNT == 0.
782    If COUNT < 0 it will stop only at LAST or NULL rtx.  */
783 void
784 print_rtl_slim (FILE *f, rtx first, rtx last, int count, int flags)
785 {
786   basic_block current_bb = NULL;
787   rtx insn, tail;
788
789   tail = last ? NEXT_INSN (last) : NULL_RTX;
790   for (insn = first;
791        (insn != NULL) && (insn != tail) && (count != 0);
792        insn = NEXT_INSN (insn))
793     {
794       if ((flags & TDF_BLOCKS)
795           && (INSN_P (insn) || NOTE_P (insn))
796           && BLOCK_FOR_INSN (insn)
797           && !current_bb)
798         {
799           current_bb = BLOCK_FOR_INSN (insn);
800           dump_bb_info (current_bb, true, false, flags, ";; ", f);
801         }
802
803       dump_insn_slim (f, insn);
804
805       if ((flags & TDF_BLOCKS)
806           && current_bb
807           && insn == BB_END (current_bb))
808         {
809           dump_bb_info (current_bb, false, true, flags, ";; ", f);
810           current_bb = NULL;
811         }
812       if (count > 0)
813         count--;
814     }
815 }
816
817 void
818 debug_bb_slim (struct basic_block_def *bb)
819 {
820   print_rtl_slim (stderr, BB_HEAD (bb), BB_END (bb), -1, 32);
821 }
822
823 void
824 debug_bb_n_slim (int n)
825 {
826   struct basic_block_def *bb = BASIC_BLOCK (n);
827   debug_bb_slim (bb);
828 }
829