xref: /freebsd-11-stable/contrib/gcc/sched-vis.c (revision 6cec9cad762b6476313fb1f8e931a1647822db6b)
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 
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 *
safe_concat(char * buf,char * cur,const char * str)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
print_exp(char * buf,rtx x,int verbose)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
print_value(char * buf,rtx x,int verbose)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
print_pattern(char * buf,rtx x,int verbose)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
print_insn(char * buf,rtx x,int verbose)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
dump_insn_slim(FILE * f,rtx x)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
debug_insn_slim(rtx x)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
print_rtl_slim_with_bb(FILE * f,rtx first,int flags)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 
757