OSDN Git Service

Change copyright header to refer to version 3 of the GNU General Public License and...
[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 *, rtx, int);
37 static void print_value (char *, rtx, int);
38 static void print_pattern (char *, 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, 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, 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, INTVAL (x));
438       cur = safe_concat (buf, cur, t);
439       break;
440     case CONST_DOUBLE:
441       if (FLOAT_MODE_P (GET_MODE (x)))
442         real_to_decimal (t, CONST_DOUBLE_REAL_VALUE (x), sizeof (t), 0, 1);
443       else
444         sprintf (t,
445                  "<" HOST_WIDE_INT_PRINT_HEX "," HOST_WIDE_INT_PRINT_HEX ">",
446                  (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x),
447                  (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (x));
448       cur = safe_concat (buf, cur, t);
449       break;
450     case CONST_STRING:
451       cur = safe_concat (buf, cur, "\"");
452       cur = safe_concat (buf, cur, XSTR (x, 0));
453       cur = safe_concat (buf, cur, "\"");
454       break;
455     case SYMBOL_REF:
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 LABEL_REF:
461       sprintf (t, "L%d", INSN_UID (XEXP (x, 0)));
462       cur = safe_concat (buf, cur, t);
463       break;
464     case CONST:
465       print_value (t, XEXP (x, 0), verbose);
466       cur = safe_concat (buf, cur, "const(");
467       cur = safe_concat (buf, cur, t);
468       cur = safe_concat (buf, cur, ")");
469       break;
470     case HIGH:
471       print_value (t, XEXP (x, 0), verbose);
472       cur = safe_concat (buf, cur, "high(");
473       cur = safe_concat (buf, cur, t);
474       cur = safe_concat (buf, cur, ")");
475       break;
476     case REG:
477       if (REGNO (x) < FIRST_PSEUDO_REGISTER)
478         {
479           int c = reg_names[REGNO (x)][0];
480           if (ISDIGIT (c))
481             cur = safe_concat (buf, cur, "%");
482
483           cur = safe_concat (buf, cur, reg_names[REGNO (x)]);
484         }
485       else
486         {
487           sprintf (t, "r%d", REGNO (x));
488           cur = safe_concat (buf, cur, t);
489         }
490       if (verbose
491 #ifdef INSN_SCHEDULING
492           && !current_sched_info
493 #endif
494          )
495         {
496           sprintf (t, ":%s", GET_MODE_NAME (GET_MODE (x)));
497           cur = safe_concat (buf, cur, t);
498         }
499       break;
500     case SUBREG:
501       print_value (t, SUBREG_REG (x), verbose);
502       cur = safe_concat (buf, cur, t);
503       sprintf (t, "#%d", SUBREG_BYTE (x));
504       cur = safe_concat (buf, cur, t);
505       break;
506     case SCRATCH:
507       cur = safe_concat (buf, cur, "scratch");
508       break;
509     case CC0:
510       cur = safe_concat (buf, cur, "cc0");
511       break;
512     case PC:
513       cur = safe_concat (buf, cur, "pc");
514       break;
515     case MEM:
516       print_value (t, XEXP (x, 0), verbose);
517       cur = safe_concat (buf, cur, "[");
518       cur = safe_concat (buf, cur, t);
519       cur = safe_concat (buf, cur, "]");
520       break;
521     default:
522       print_exp (t, x, verbose);
523       cur = safe_concat (buf, cur, t);
524       break;
525     }
526 }                               /* print_value */
527
528 /* The next step in insn detalization, its pattern recognition.  */
529
530 static void
531 print_pattern (char *buf, rtx x, int verbose)
532 {
533   char t1[BUF_LEN], t2[BUF_LEN], t3[BUF_LEN];
534
535   switch (GET_CODE (x))
536     {
537     case SET:
538       print_value (t1, SET_DEST (x), verbose);
539       print_value (t2, SET_SRC (x), verbose);
540       sprintf (buf, "%s=%s", t1, t2);
541       break;
542     case RETURN:
543       sprintf (buf, "return");
544       break;
545     case CALL:
546       print_exp (buf, x, verbose);
547       break;
548     case CLOBBER:
549       print_value (t1, XEXP (x, 0), verbose);
550       sprintf (buf, "clobber %s", t1);
551       break;
552     case USE:
553       print_value (t1, XEXP (x, 0), verbose);
554       sprintf (buf, "use %s", t1);
555       break;
556     case COND_EXEC:
557       if (GET_CODE (COND_EXEC_TEST (x)) == NE
558           && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
559         print_value (t1, XEXP (COND_EXEC_TEST (x), 0), verbose);
560       else if (GET_CODE (COND_EXEC_TEST (x)) == EQ
561                && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
562         {
563           t1[0] = '!';
564           print_value (t1 + 1, XEXP (COND_EXEC_TEST (x), 0), verbose);
565         }
566       else
567         print_value (t1, COND_EXEC_TEST (x), verbose);
568       print_pattern (t2, COND_EXEC_CODE (x), verbose);
569       sprintf (buf, "(%s) %s", t1, t2);
570       break;
571     case PARALLEL:
572       {
573         int i;
574
575         sprintf (t1, "{");
576         for (i = 0; i < XVECLEN (x, 0); i++)
577           {
578             print_pattern (t2, XVECEXP (x, 0, i), verbose);
579             sprintf (t3, "%s%s;", t1, t2);
580             strcpy (t1, t3);
581           }
582         sprintf (buf, "%s}", t1);
583       }
584       break;
585     case SEQUENCE:
586       /* Should never see SEQUENCE codes until after reorg.  */
587       gcc_unreachable ();
588     case ASM_INPUT:
589       sprintf (buf, "asm {%s}", XSTR (x, 0));
590       break;
591     case ADDR_VEC:
592       break;
593     case ADDR_DIFF_VEC:
594       print_value (buf, XEXP (x, 0), verbose);
595       break;
596     case TRAP_IF:
597       print_value (t1, TRAP_CONDITION (x), verbose);
598       sprintf (buf, "trap_if %s", t1);
599       break;
600     case UNSPEC:
601       {
602         int i;
603
604         sprintf (t1, "unspec{");
605         for (i = 0; i < XVECLEN (x, 0); i++)
606           {
607             print_pattern (t2, XVECEXP (x, 0, i), verbose);
608             sprintf (t3, "%s%s;", t1, t2);
609             strcpy (t1, t3);
610           }
611         sprintf (buf, "%s}", t1);
612       }
613       break;
614     case UNSPEC_VOLATILE:
615       {
616         int i;
617
618         sprintf (t1, "unspec/v{");
619         for (i = 0; i < XVECLEN (x, 0); i++)
620           {
621             print_pattern (t2, XVECEXP (x, 0, i), verbose);
622             sprintf (t3, "%s%s;", t1, t2);
623             strcpy (t1, t3);
624           }
625         sprintf (buf, "%s}", t1);
626       }
627       break;
628     default:
629       print_value (buf, x, verbose);
630     }
631 }                               /* print_pattern */
632
633 /* This is the main function in rtl visualization mechanism. It
634    accepts an rtx and tries to recognize it as an insn, then prints it
635    properly in human readable form, resembling assembler mnemonics.
636    For every insn it prints its UID and BB the insn belongs too.
637    (Probably the last "option" should be extended somehow, since it
638    depends now on sched.c inner variables ...)  */
639
640 void
641 print_insn (char *buf, rtx x, int verbose)
642 {
643   char t[BUF_LEN];
644   rtx insn = x;
645
646   switch (GET_CODE (x))
647     {
648     case INSN:
649       print_pattern (t, PATTERN (x), verbose);
650 #ifdef INSN_SCHEDULING
651       if (verbose && current_sched_info)
652         sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1),
653                  t);
654       else
655 #endif
656         sprintf (buf, " %4d %s", INSN_UID (x), t);
657       break;
658     case JUMP_INSN:
659       print_pattern (t, PATTERN (x), verbose);
660 #ifdef INSN_SCHEDULING
661       if (verbose && current_sched_info)
662         sprintf (buf, "%s: jump %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     case CALL_INSN:
669       x = PATTERN (insn);
670       if (GET_CODE (x) == PARALLEL)
671         {
672           x = XVECEXP (x, 0, 0);
673           print_pattern (t, x, verbose);
674         }
675       else
676         strcpy (t, "call <...>");
677 #ifdef INSN_SCHEDULING
678       if (verbose && current_sched_info)
679         sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1), t);
680       else
681 #endif
682         sprintf (buf, " %4d %s", INSN_UID (insn), t);
683       break;
684     case CODE_LABEL:
685       sprintf (buf, "L%d:", INSN_UID (x));
686       break;
687     case BARRIER:
688       sprintf (buf, "i%4d: barrier", INSN_UID (x));
689       break;
690     case NOTE:
691       sprintf (buf, " %4d %s", INSN_UID (x),
692                GET_NOTE_INSN_NAME (NOTE_KIND (x)));
693       break;
694     default:
695       sprintf (buf, "i%4d  <What %s?>", INSN_UID (x),
696                GET_RTX_NAME (GET_CODE (x)));
697     }
698 }                               /* print_insn */
699
700
701 /* Emit a slim dump of X (an insn) to the file F, including any register
702    note attached to the instruction.  */
703 void
704 dump_insn_slim (FILE *f, rtx x)
705 {
706   char t[BUF_LEN + 32];
707   rtx note;
708
709   print_insn (t, x, 1);
710   fputs (t, f);
711   putc ('\n', f);
712   if (INSN_P (x) && REG_NOTES (x))
713     for (note = REG_NOTES (x); note; note = XEXP (note, 1))
714       {
715         print_value (t, XEXP (note, 0), 1);
716         fprintf (f, "      %s: %s\n",
717                  GET_REG_NOTE_NAME (REG_NOTE_KIND (note)), t);
718       }
719 }
720
721 /* Emit a slim dump of X (an insn) to stderr.  */
722 void
723 debug_insn_slim (rtx x)
724 {
725   dump_insn_slim (stderr, x);
726 }
727
728 /* Provide a slim dump the instruction chain starting at FIRST to F, honoring
729    the dump flags given in FLAGS.  Currently, TDF_BLOCKS and TDF_DETAILS
730    include more information on the basic blocks.  */
731 void
732 print_rtl_slim_with_bb (FILE *f, rtx first, int flags)
733 {
734   basic_block current_bb = NULL;
735   rtx insn;
736
737   for (insn = first; NULL != insn; insn = NEXT_INSN (insn))
738     {
739       if ((flags & TDF_BLOCKS)
740           && (INSN_P (insn) || GET_CODE (insn) == NOTE)
741           && BLOCK_FOR_INSN (insn)
742           && !current_bb)
743         {
744           current_bb = BLOCK_FOR_INSN (insn);
745           dump_bb_info (current_bb, true, false, flags, ";; ", f);
746         }
747
748       dump_insn_slim (f, insn);
749
750       if ((flags & TDF_BLOCKS)
751           && current_bb
752           && insn == BB_END (current_bb))
753         {
754           dump_bb_info (current_bb, false, true, flags, ";; ", f);
755           current_bb = NULL;
756         }
757     }
758 }
759