OSDN Git Service

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