2012-07-09 Tom de Vries <tom@codesourcery.com>
[official-gcc.git] / gcc / sched-vis.c
blob2b4d6240cb801bc1794ce96c46d5f20c599d7772
1 /* Instruction scheduling pass.
2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010
4 Free Software Foundation, Inc.
5 Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
6 and currently maintained by, Jim Wilson (wilson@cygnus.com)
8 This file is part of GCC.
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
13 version.
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 for more details.
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3. If not see
22 <http://www.gnu.org/licenses/>. */
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "rtl.h"
29 #include "tree.h" /* FIXME: To dump INSN_VAR_LOCATION_DECL. */
30 #include "obstack.h"
31 #include "hard-reg-set.h"
32 #include "basic-block.h"
33 #include "insn-attr.h"
34 #include "sched-int.h"
35 #include "tree-pass.h"
37 static char *safe_concat (char *, char *, const char *);
39 #define BUF_LEN 2048
41 static char *
42 safe_concat (char *buf, char *cur, const char *str)
44 char *end = buf + BUF_LEN - 2; /* Leave room for null. */
45 int c;
47 if (cur > end)
49 *end = '\0';
50 return end;
53 while (cur < end && (c = *str++) != '\0')
54 *cur++ = c;
56 *cur = '\0';
57 return cur;
60 /* This recognizes rtx, I classified as expressions. These are always
61 represent some action on values or results of other expression, that
62 may be stored in objects representing values. */
64 static void
65 print_exp (char *buf, const_rtx x, int verbose)
67 char tmp[BUF_LEN];
68 const char *st[4];
69 char *cur = buf;
70 const char *fun = (char *) 0;
71 const char *sep;
72 rtx op[4];
73 int i;
75 for (i = 0; i < 4; i++)
77 st[i] = (char *) 0;
78 op[i] = NULL_RTX;
81 switch (GET_CODE (x))
83 case PLUS:
84 op[0] = XEXP (x, 0);
85 if (CONST_INT_P (XEXP (x, 1))
86 && INTVAL (XEXP (x, 1)) < 0)
88 st[1] = "-";
89 op[1] = GEN_INT (-INTVAL (XEXP (x, 1)));
91 else
93 st[1] = "+";
94 op[1] = XEXP (x, 1);
96 break;
97 case LO_SUM:
98 op[0] = XEXP (x, 0);
99 st[1] = "+low(";
100 op[1] = XEXP (x, 1);
101 st[2] = ")";
102 break;
103 case MINUS:
104 op[0] = XEXP (x, 0);
105 st[1] = "-";
106 op[1] = XEXP (x, 1);
107 break;
108 case COMPARE:
109 fun = "cmp";
110 op[0] = XEXP (x, 0);
111 op[1] = XEXP (x, 1);
112 break;
113 case NEG:
114 st[0] = "-";
115 op[0] = XEXP (x, 0);
116 break;
117 case MULT:
118 op[0] = XEXP (x, 0);
119 st[1] = "*";
120 op[1] = XEXP (x, 1);
121 break;
122 case DIV:
123 op[0] = XEXP (x, 0);
124 st[1] = "/";
125 op[1] = XEXP (x, 1);
126 break;
127 case UDIV:
128 fun = "udiv";
129 op[0] = XEXP (x, 0);
130 op[1] = XEXP (x, 1);
131 break;
132 case MOD:
133 op[0] = XEXP (x, 0);
134 st[1] = "%";
135 op[1] = XEXP (x, 1);
136 break;
137 case UMOD:
138 fun = "umod";
139 op[0] = XEXP (x, 0);
140 op[1] = XEXP (x, 1);
141 break;
142 case SMIN:
143 fun = "smin";
144 op[0] = XEXP (x, 0);
145 op[1] = XEXP (x, 1);
146 break;
147 case SMAX:
148 fun = "smax";
149 op[0] = XEXP (x, 0);
150 op[1] = XEXP (x, 1);
151 break;
152 case UMIN:
153 fun = "umin";
154 op[0] = XEXP (x, 0);
155 op[1] = XEXP (x, 1);
156 break;
157 case UMAX:
158 fun = "umax";
159 op[0] = XEXP (x, 0);
160 op[1] = XEXP (x, 1);
161 break;
162 case NOT:
163 st[0] = "!";
164 op[0] = XEXP (x, 0);
165 break;
166 case AND:
167 op[0] = XEXP (x, 0);
168 st[1] = "&";
169 op[1] = XEXP (x, 1);
170 break;
171 case IOR:
172 op[0] = XEXP (x, 0);
173 st[1] = "|";
174 op[1] = XEXP (x, 1);
175 break;
176 case XOR:
177 op[0] = XEXP (x, 0);
178 st[1] = "^";
179 op[1] = XEXP (x, 1);
180 break;
181 case ASHIFT:
182 op[0] = XEXP (x, 0);
183 st[1] = "<<";
184 op[1] = XEXP (x, 1);
185 break;
186 case LSHIFTRT:
187 op[0] = XEXP (x, 0);
188 st[1] = " 0>>";
189 op[1] = XEXP (x, 1);
190 break;
191 case ASHIFTRT:
192 op[0] = XEXP (x, 0);
193 st[1] = ">>";
194 op[1] = XEXP (x, 1);
195 break;
196 case ROTATE:
197 op[0] = XEXP (x, 0);
198 st[1] = "<-<";
199 op[1] = XEXP (x, 1);
200 break;
201 case ROTATERT:
202 op[0] = XEXP (x, 0);
203 st[1] = ">->";
204 op[1] = XEXP (x, 1);
205 break;
206 case ABS:
207 fun = "abs";
208 op[0] = XEXP (x, 0);
209 break;
210 case SQRT:
211 fun = "sqrt";
212 op[0] = XEXP (x, 0);
213 break;
214 case FFS:
215 fun = "ffs";
216 op[0] = XEXP (x, 0);
217 break;
218 case EQ:
219 op[0] = XEXP (x, 0);
220 st[1] = "==";
221 op[1] = XEXP (x, 1);
222 break;
223 case NE:
224 op[0] = XEXP (x, 0);
225 st[1] = "!=";
226 op[1] = XEXP (x, 1);
227 break;
228 case GT:
229 op[0] = XEXP (x, 0);
230 st[1] = ">";
231 op[1] = XEXP (x, 1);
232 break;
233 case GTU:
234 fun = "gtu";
235 op[0] = XEXP (x, 0);
236 op[1] = XEXP (x, 1);
237 break;
238 case LT:
239 op[0] = XEXP (x, 0);
240 st[1] = "<";
241 op[1] = XEXP (x, 1);
242 break;
243 case LTU:
244 fun = "ltu";
245 op[0] = XEXP (x, 0);
246 op[1] = XEXP (x, 1);
247 break;
248 case GE:
249 op[0] = XEXP (x, 0);
250 st[1] = ">=";
251 op[1] = XEXP (x, 1);
252 break;
253 case GEU:
254 fun = "geu";
255 op[0] = XEXP (x, 0);
256 op[1] = XEXP (x, 1);
257 break;
258 case LE:
259 op[0] = XEXP (x, 0);
260 st[1] = "<=";
261 op[1] = XEXP (x, 1);
262 break;
263 case LEU:
264 fun = "leu";
265 op[0] = XEXP (x, 0);
266 op[1] = XEXP (x, 1);
267 break;
268 case SIGN_EXTRACT:
269 fun = (verbose) ? "sign_extract" : "sxt";
270 op[0] = XEXP (x, 0);
271 op[1] = XEXP (x, 1);
272 op[2] = XEXP (x, 2);
273 break;
274 case ZERO_EXTRACT:
275 fun = (verbose) ? "zero_extract" : "zxt";
276 op[0] = XEXP (x, 0);
277 op[1] = XEXP (x, 1);
278 op[2] = XEXP (x, 2);
279 break;
280 case SIGN_EXTEND:
281 fun = (verbose) ? "sign_extend" : "sxn";
282 op[0] = XEXP (x, 0);
283 break;
284 case ZERO_EXTEND:
285 fun = (verbose) ? "zero_extend" : "zxn";
286 op[0] = XEXP (x, 0);
287 break;
288 case FLOAT_EXTEND:
289 fun = (verbose) ? "float_extend" : "fxn";
290 op[0] = XEXP (x, 0);
291 break;
292 case TRUNCATE:
293 fun = (verbose) ? "trunc" : "trn";
294 op[0] = XEXP (x, 0);
295 break;
296 case FLOAT_TRUNCATE:
297 fun = (verbose) ? "float_trunc" : "ftr";
298 op[0] = XEXP (x, 0);
299 break;
300 case FLOAT:
301 fun = (verbose) ? "float" : "flt";
302 op[0] = XEXP (x, 0);
303 break;
304 case UNSIGNED_FLOAT:
305 fun = (verbose) ? "uns_float" : "ufl";
306 op[0] = XEXP (x, 0);
307 break;
308 case FIX:
309 fun = "fix";
310 op[0] = XEXP (x, 0);
311 break;
312 case UNSIGNED_FIX:
313 fun = (verbose) ? "uns_fix" : "ufx";
314 op[0] = XEXP (x, 0);
315 break;
316 case PRE_DEC:
317 st[0] = "--";
318 op[0] = XEXP (x, 0);
319 break;
320 case PRE_INC:
321 st[0] = "++";
322 op[0] = XEXP (x, 0);
323 break;
324 case POST_DEC:
325 op[0] = XEXP (x, 0);
326 st[1] = "--";
327 break;
328 case POST_INC:
329 op[0] = XEXP (x, 0);
330 st[1] = "++";
331 break;
332 case PRE_MODIFY:
333 st[0] = "pre ";
334 op[0] = XEXP (XEXP (x, 1), 0);
335 st[1] = "+=";
336 op[1] = XEXP (XEXP (x, 1), 1);
337 break;
338 case POST_MODIFY:
339 st[0] = "post ";
340 op[0] = XEXP (XEXP (x, 1), 0);
341 st[1] = "+=";
342 op[1] = XEXP (XEXP (x, 1), 1);
343 break;
344 case CALL:
345 st[0] = "call ";
346 op[0] = XEXP (x, 0);
347 if (verbose)
349 st[1] = " argc:";
350 op[1] = XEXP (x, 1);
352 break;
353 case IF_THEN_ELSE:
354 st[0] = "{(";
355 op[0] = XEXP (x, 0);
356 st[1] = ")?";
357 op[1] = XEXP (x, 1);
358 st[2] = ":";
359 op[2] = XEXP (x, 2);
360 st[3] = "}";
361 break;
362 case TRAP_IF:
363 fun = "trap_if";
364 op[0] = TRAP_CONDITION (x);
365 break;
366 case PREFETCH:
367 fun = "prefetch";
368 op[0] = XEXP (x, 0);
369 op[1] = XEXP (x, 1);
370 op[2] = XEXP (x, 2);
371 break;
372 case UNSPEC:
373 case UNSPEC_VOLATILE:
375 cur = safe_concat (buf, cur, "unspec");
376 if (GET_CODE (x) == UNSPEC_VOLATILE)
377 cur = safe_concat (buf, cur, "/v");
378 cur = safe_concat (buf, cur, "[");
379 sep = "";
380 for (i = 0; i < XVECLEN (x, 0); i++)
382 print_pattern (tmp, XVECEXP (x, 0, i), verbose);
383 cur = safe_concat (buf, cur, sep);
384 cur = safe_concat (buf, cur, tmp);
385 sep = ",";
387 cur = safe_concat (buf, cur, "] ");
388 sprintf (tmp, "%d", XINT (x, 1));
389 cur = safe_concat (buf, cur, tmp);
391 break;
392 default:
393 /* If (verbose) debug_rtx (x); */
394 st[0] = GET_RTX_NAME (GET_CODE (x));
395 break;
398 /* Print this as a function? */
399 if (fun)
401 cur = safe_concat (buf, cur, fun);
402 cur = safe_concat (buf, cur, "(");
405 for (i = 0; i < 4; i++)
407 if (st[i])
408 cur = safe_concat (buf, cur, st[i]);
410 if (op[i])
412 if (fun && i != 0)
413 cur = safe_concat (buf, cur, ",");
415 print_value (tmp, op[i], verbose);
416 cur = safe_concat (buf, cur, tmp);
420 if (fun)
421 cur = safe_concat (buf, cur, ")");
422 } /* print_exp */
424 /* Prints rtxes, I customarily classified as values. They're constants,
425 registers, labels, symbols and memory accesses. */
427 void
428 print_value (char *buf, const_rtx x, int verbose)
430 char t[BUF_LEN];
431 char *cur = buf;
433 if (!x)
435 safe_concat (buf, buf, "(nil)");
436 return;
438 switch (GET_CODE (x))
440 case CONST_INT:
441 sprintf (t, HOST_WIDE_INT_PRINT_HEX,
442 (unsigned HOST_WIDE_INT) INTVAL (x));
443 cur = safe_concat (buf, cur, t);
444 break;
445 case CONST_DOUBLE:
446 if (FLOAT_MODE_P (GET_MODE (x)))
447 real_to_decimal (t, CONST_DOUBLE_REAL_VALUE (x), sizeof (t), 0, 1);
448 else
449 sprintf (t,
450 "<" HOST_WIDE_INT_PRINT_HEX "," HOST_WIDE_INT_PRINT_HEX ">",
451 (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x),
452 (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (x));
453 cur = safe_concat (buf, cur, t);
454 break;
455 case CONST_FIXED:
456 fixed_to_decimal (t, CONST_FIXED_VALUE (x), sizeof (t));
457 cur = safe_concat (buf, cur, t);
458 break;
459 case CONST_STRING:
460 cur = safe_concat (buf, cur, "\"");
461 cur = safe_concat (buf, cur, XSTR (x, 0));
462 cur = safe_concat (buf, cur, "\"");
463 break;
464 case SYMBOL_REF:
465 cur = safe_concat (buf, cur, "`");
466 cur = safe_concat (buf, cur, XSTR (x, 0));
467 cur = safe_concat (buf, cur, "'");
468 break;
469 case LABEL_REF:
470 sprintf (t, "L%d", INSN_UID (XEXP (x, 0)));
471 cur = safe_concat (buf, cur, t);
472 break;
473 case CONST:
474 print_value (t, XEXP (x, 0), verbose);
475 cur = safe_concat (buf, cur, "const(");
476 cur = safe_concat (buf, cur, t);
477 cur = safe_concat (buf, cur, ")");
478 break;
479 case HIGH:
480 print_value (t, XEXP (x, 0), verbose);
481 cur = safe_concat (buf, cur, "high(");
482 cur = safe_concat (buf, cur, t);
483 cur = safe_concat (buf, cur, ")");
484 break;
485 case REG:
486 if (REGNO (x) < FIRST_PSEUDO_REGISTER)
488 int c = reg_names[REGNO (x)][0];
489 if (ISDIGIT (c))
490 cur = safe_concat (buf, cur, "%");
492 cur = safe_concat (buf, cur, reg_names[REGNO (x)]);
494 else
496 sprintf (t, "r%d", REGNO (x));
497 cur = safe_concat (buf, cur, t);
499 if (verbose
500 #ifdef INSN_SCHEDULING
501 && !current_sched_info
502 #endif
505 sprintf (t, ":%s", GET_MODE_NAME (GET_MODE (x)));
506 cur = safe_concat (buf, cur, t);
508 break;
509 case SUBREG:
510 print_value (t, SUBREG_REG (x), verbose);
511 cur = safe_concat (buf, cur, t);
512 sprintf (t, "#%d", SUBREG_BYTE (x));
513 cur = safe_concat (buf, cur, t);
514 break;
515 case STRICT_LOW_PART:
516 print_value (t, XEXP (x, 0), verbose);
517 cur = safe_concat (buf, cur, "strict_low_part(");
518 cur = safe_concat (buf, cur, t);
519 cur = safe_concat (buf, cur, ")");
520 break;
521 case SCRATCH:
522 cur = safe_concat (buf, cur, "scratch");
523 break;
524 case CC0:
525 cur = safe_concat (buf, cur, "cc0");
526 break;
527 case PC:
528 cur = safe_concat (buf, cur, "pc");
529 break;
530 case MEM:
531 print_value (t, XEXP (x, 0), verbose);
532 cur = safe_concat (buf, cur, "[");
533 cur = safe_concat (buf, cur, t);
534 cur = safe_concat (buf, cur, "]");
535 break;
536 case DEBUG_EXPR:
537 sprintf (t, "D#%i", DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x)));
538 cur = safe_concat (buf, cur, t);
539 break;
540 default:
541 print_exp (t, x, verbose);
542 cur = safe_concat (buf, cur, t);
543 break;
545 } /* print_value */
547 /* The next step in insn detalization, its pattern recognition. */
549 void
550 print_pattern (char *buf, const_rtx x, int verbose)
552 char t1[BUF_LEN], t2[BUF_LEN], t3[BUF_LEN];
554 switch (GET_CODE (x))
556 case SET:
557 print_value (t1, SET_DEST (x), verbose);
558 print_value (t2, SET_SRC (x), verbose);
559 sprintf (buf, "%s=%s", t1, t2);
560 break;
561 case RETURN:
562 sprintf (buf, "return");
563 break;
564 case SIMPLE_RETURN:
565 sprintf (buf, "simple_return");
566 break;
567 case CALL:
568 print_exp (buf, x, verbose);
569 break;
570 case CLOBBER:
571 print_value (t1, XEXP (x, 0), verbose);
572 sprintf (buf, "clobber %s", t1);
573 break;
574 case USE:
575 print_value (t1, XEXP (x, 0), verbose);
576 sprintf (buf, "use %s", t1);
577 break;
578 case VAR_LOCATION:
579 print_value (t1, PAT_VAR_LOCATION_LOC (x), verbose);
580 sprintf (buf, "loc %s", t1);
581 break;
582 case COND_EXEC:
583 if (GET_CODE (COND_EXEC_TEST (x)) == NE
584 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
585 print_value (t1, XEXP (COND_EXEC_TEST (x), 0), verbose);
586 else if (GET_CODE (COND_EXEC_TEST (x)) == EQ
587 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
589 t1[0] = '!';
590 print_value (t1 + 1, XEXP (COND_EXEC_TEST (x), 0), verbose);
592 else
593 print_value (t1, COND_EXEC_TEST (x), verbose);
594 print_pattern (t2, COND_EXEC_CODE (x), verbose);
595 sprintf (buf, "(%s) %s", t1, t2);
596 break;
597 case PARALLEL:
599 int i;
601 sprintf (t1, "{");
602 for (i = 0; i < XVECLEN (x, 0); i++)
604 print_pattern (t2, XVECEXP (x, 0, i), verbose);
605 sprintf (t3, "%s%s;", t1, t2);
606 strcpy (t1, t3);
608 sprintf (buf, "%s}", t1);
610 break;
611 case SEQUENCE:
612 /* Should never see SEQUENCE codes until after reorg. */
613 gcc_unreachable ();
614 case ASM_INPUT:
615 sprintf (buf, "asm {%s}", XSTR (x, 0));
616 break;
617 case ADDR_VEC:
618 /* Fall through. */
619 case ADDR_DIFF_VEC:
620 print_value (buf, XEXP (x, 0), verbose);
621 break;
622 case TRAP_IF:
623 print_value (t1, TRAP_CONDITION (x), verbose);
624 sprintf (buf, "trap_if %s", t1);
625 break;
626 case UNSPEC:
628 int i;
630 sprintf (t1, "unspec{");
631 for (i = 0; i < XVECLEN (x, 0); i++)
633 print_pattern (t2, XVECEXP (x, 0, i), verbose);
634 sprintf (t3, "%s%s;", t1, t2);
635 strcpy (t1, t3);
637 sprintf (buf, "%s}", t1);
639 break;
640 case UNSPEC_VOLATILE:
642 int i;
644 sprintf (t1, "unspec/v{");
645 for (i = 0; i < XVECLEN (x, 0); i++)
647 print_pattern (t2, XVECEXP (x, 0, i), verbose);
648 sprintf (t3, "%s%s;", t1, t2);
649 strcpy (t1, t3);
651 sprintf (buf, "%s}", t1);
653 break;
654 default:
655 print_value (buf, x, verbose);
657 } /* print_pattern */
659 /* This is the main function in rtl visualization mechanism. It
660 accepts an rtx and tries to recognize it as an insn, then prints it
661 properly in human readable form, resembling assembler mnemonics.
662 For every insn it prints its UID and BB the insn belongs too.
663 (Probably the last "option" should be extended somehow, since it
664 depends now on sched.c inner variables ...) */
666 void
667 print_insn (char *buf, const_rtx x, int verbose)
669 char t[BUF_LEN];
670 const_rtx insn = x;
672 switch (GET_CODE (x))
674 case INSN:
675 print_pattern (t, PATTERN (x), verbose);
676 #ifdef INSN_SCHEDULING
677 if (verbose && current_sched_info)
678 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1),
680 else
681 #endif
682 sprintf (buf, " %4d %s", INSN_UID (x), t);
683 break;
685 case DEBUG_INSN:
687 const char *name = "?";
689 if (DECL_P (INSN_VAR_LOCATION_DECL (insn)))
691 tree id = DECL_NAME (INSN_VAR_LOCATION_DECL (insn));
692 char idbuf[32];
693 if (id)
694 name = IDENTIFIER_POINTER (id);
695 else if (TREE_CODE (INSN_VAR_LOCATION_DECL (insn))
696 == DEBUG_EXPR_DECL)
698 sprintf (idbuf, "D#%i",
699 DEBUG_TEMP_UID (INSN_VAR_LOCATION_DECL (insn)));
700 name = idbuf;
702 else
704 sprintf (idbuf, "D.%i",
705 DECL_UID (INSN_VAR_LOCATION_DECL (insn)));
706 name = idbuf;
709 if (VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (insn)))
710 sprintf (buf, " %4d: debug %s optimized away", INSN_UID (insn), name);
711 else
713 print_pattern (t, INSN_VAR_LOCATION_LOC (insn), verbose);
714 sprintf (buf, " %4d: debug %s => %s", INSN_UID (insn), name, t);
717 break;
719 case JUMP_INSN:
720 print_pattern (t, PATTERN (x), verbose);
721 #ifdef INSN_SCHEDULING
722 if (verbose && current_sched_info)
723 sprintf (buf, "%s: jump %s", (*current_sched_info->print_insn) (x, 1),
725 else
726 #endif
727 sprintf (buf, " %4d %s", INSN_UID (x), t);
728 break;
729 case CALL_INSN:
730 x = PATTERN (insn);
731 if (GET_CODE (x) == PARALLEL)
733 x = XVECEXP (x, 0, 0);
734 print_pattern (t, x, verbose);
736 else
737 strcpy (t, "call <...>");
738 #ifdef INSN_SCHEDULING
739 if (verbose && current_sched_info)
740 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (insn, 1), t);
741 else
742 #endif
743 sprintf (buf, " %4d %s", INSN_UID (insn), t);
744 break;
745 case CODE_LABEL:
746 sprintf (buf, "L%d:", INSN_UID (x));
747 break;
748 case BARRIER:
749 sprintf (buf, "i%4d: barrier", INSN_UID (x));
750 break;
751 case NOTE:
752 sprintf (buf, " %4d %s", INSN_UID (x),
753 GET_NOTE_INSN_NAME (NOTE_KIND (x)));
754 break;
755 default:
756 sprintf (buf, "i%4d <What %s?>", INSN_UID (x),
757 GET_RTX_NAME (GET_CODE (x)));
759 } /* print_insn */
761 /* Emit a slim dump of X (an insn) to the file F, including any register
762 note attached to the instruction. */
763 void
764 dump_insn_slim (FILE *f, rtx x)
766 char t[BUF_LEN + 32];
767 rtx note;
769 print_insn (t, x, 1);
770 fputs (t, f);
771 putc ('\n', f);
772 if (INSN_P (x) && REG_NOTES (x))
773 for (note = REG_NOTES (x); note; note = XEXP (note, 1))
775 print_value (t, XEXP (note, 0), 1);
776 fprintf (f, " %s: %s\n",
777 GET_REG_NOTE_NAME (REG_NOTE_KIND (note)), t);
781 /* Emit a slim dump of X (an insn) to stderr. */
782 DEBUG_FUNCTION void
783 debug_insn_slim (rtx x)
785 dump_insn_slim (stderr, x);
788 /* Provide a slim dump the instruction chain starting at FIRST to F, honoring
789 the dump flags given in FLAGS. Currently, TDF_BLOCKS and TDF_DETAILS
790 include more information on the basic blocks. */
791 void
792 print_rtl_slim_with_bb (FILE *f, rtx first, int flags)
794 print_rtl_slim (f, first, NULL, -1, flags);
797 /* Same as above, but stop at LAST or when COUNT == 0.
798 If COUNT < 0 it will stop only at LAST or NULL rtx. */
799 void
800 print_rtl_slim (FILE *f, rtx first, rtx last, int count, int flags)
802 basic_block current_bb = NULL;
803 rtx insn, tail;
805 tail = last ? NEXT_INSN (last) : NULL_RTX;
806 for (insn = first;
807 (insn != NULL) && (insn != tail) && (count != 0);
808 insn = NEXT_INSN (insn))
810 bool verbose = ((flags & TDF_DETAILS) != 0);
812 if ((flags & TDF_BLOCKS)
813 && (INSN_P (insn) || NOTE_P (insn))
814 && BLOCK_FOR_INSN (insn)
815 && !current_bb)
817 current_bb = BLOCK_FOR_INSN (insn);
818 dump_bb_info (current_bb, true, false, verbose, ";; ", f);
821 dump_insn_slim (f, insn);
823 if ((flags & TDF_BLOCKS)
824 && current_bb
825 && insn == BB_END (current_bb))
827 dump_bb_info (current_bb, false, true, verbose, ";; ", f);
828 current_bb = NULL;
830 if (count > 0)
831 count--;
835 DEBUG_FUNCTION void
836 debug_bb_slim (struct basic_block_def *bb)
838 print_rtl_slim (stderr, BB_HEAD (bb), BB_END (bb), -1, 32);
841 DEBUG_FUNCTION void
842 debug_bb_n_slim (int n)
844 struct basic_block_def *bb = BASIC_BLOCK (n);
845 debug_bb_slim (bb);