OSDN Git Service

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