1 /* Instruction scheduling pass.
2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
4 Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
5 and currently maintained by, Jim Wilson (wilson@cygnus.com)
7 This file is part of GCC.
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
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
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/>. */
25 #include "coretypes.h"
29 #include "hard-reg-set.h"
30 #include "basic-block.h"
31 #include "insn-attr.h"
32 #include "sched-int.h"
33 #include "tree-pass.h"
35 static char *safe_concat (char *, char *, const char *);
40 safe_concat (char *buf
, char *cur
, const char *str
)
42 char *end
= buf
+ BUF_LEN
- 2; /* Leave room for null. */
51 while (cur
< end
&& (c
= *str
++) != '\0')
58 /* This recognizes rtx, I classified as expressions. These are always
59 represent some action on values or results of other expression, that
60 may be stored in objects representing values. */
63 print_exp (char *buf
, const_rtx x
, int verbose
)
68 const char *fun
= (char *) 0;
73 for (i
= 0; i
< 4; i
++)
83 if (CONST_INT_P (XEXP (x
, 1))
84 && INTVAL (XEXP (x
, 1)) < 0)
87 op
[1] = GEN_INT (-INTVAL (XEXP (x
, 1)));
267 fun
= (verbose
) ? "sign_extract" : "sxt";
273 fun
= (verbose
) ? "zero_extract" : "zxt";
279 fun
= (verbose
) ? "sign_extend" : "sxn";
283 fun
= (verbose
) ? "zero_extend" : "zxn";
287 fun
= (verbose
) ? "float_extend" : "fxn";
291 fun
= (verbose
) ? "trunc" : "trn";
295 fun
= (verbose
) ? "float_trunc" : "ftr";
299 fun
= (verbose
) ? "float" : "flt";
303 fun
= (verbose
) ? "uns_float" : "ufl";
311 fun
= (verbose
) ? "uns_fix" : "ufx";
332 op
[0] = XEXP (XEXP (x
, 1), 0);
334 op
[1] = XEXP (XEXP (x
, 1), 1);
338 op
[0] = XEXP (XEXP (x
, 1), 0);
340 op
[1] = XEXP (XEXP (x
, 1), 1);
362 op
[0] = TRAP_CONDITION (x
);
371 case UNSPEC_VOLATILE
:
373 cur
= safe_concat (buf
, cur
, "unspec");
374 if (GET_CODE (x
) == UNSPEC_VOLATILE
)
375 cur
= safe_concat (buf
, cur
, "/v");
376 cur
= safe_concat (buf
, cur
, "[");
378 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
380 print_pattern (tmp
, XVECEXP (x
, 0, i
), verbose
);
381 cur
= safe_concat (buf
, cur
, sep
);
382 cur
= safe_concat (buf
, cur
, tmp
);
385 cur
= safe_concat (buf
, cur
, "] ");
386 sprintf (tmp
, "%d", XINT (x
, 1));
387 cur
= safe_concat (buf
, cur
, tmp
);
391 /* If (verbose) debug_rtx (x); */
392 st
[0] = GET_RTX_NAME (GET_CODE (x
));
396 /* Print this as a function? */
399 cur
= safe_concat (buf
, cur
, fun
);
400 cur
= safe_concat (buf
, cur
, "(");
403 for (i
= 0; i
< 4; i
++)
406 cur
= safe_concat (buf
, cur
, st
[i
]);
411 cur
= safe_concat (buf
, cur
, ",");
413 print_value (tmp
, op
[i
], verbose
);
414 cur
= safe_concat (buf
, cur
, tmp
);
419 cur
= safe_concat (buf
, cur
, ")");
422 /* Prints rtxes, I customarily classified as values. They're constants,
423 registers, labels, symbols and memory accesses. */
426 print_value (char *buf
, const_rtx x
, int verbose
)
433 safe_concat (buf
, buf
, "(nil)");
436 switch (GET_CODE (x
))
439 sprintf (t
, HOST_WIDE_INT_PRINT_HEX
,
440 (unsigned HOST_WIDE_INT
) INTVAL (x
));
441 cur
= safe_concat (buf
, cur
, t
);
444 if (FLOAT_MODE_P (GET_MODE (x
)))
445 real_to_decimal (t
, CONST_DOUBLE_REAL_VALUE (x
), sizeof (t
), 0, 1);
448 "<" HOST_WIDE_INT_PRINT_HEX
"," HOST_WIDE_INT_PRINT_HEX
">",
449 (unsigned HOST_WIDE_INT
) CONST_DOUBLE_LOW (x
),
450 (unsigned HOST_WIDE_INT
) CONST_DOUBLE_HIGH (x
));
451 cur
= safe_concat (buf
, cur
, t
);
454 fixed_to_decimal (t
, CONST_FIXED_VALUE (x
), sizeof (t
));
455 cur
= safe_concat (buf
, cur
, t
);
458 cur
= safe_concat (buf
, cur
, "\"");
459 cur
= safe_concat (buf
, cur
, XSTR (x
, 0));
460 cur
= safe_concat (buf
, cur
, "\"");
463 cur
= safe_concat (buf
, cur
, "`");
464 cur
= safe_concat (buf
, cur
, XSTR (x
, 0));
465 cur
= safe_concat (buf
, cur
, "'");
468 sprintf (t
, "L%d", INSN_UID (XEXP (x
, 0)));
469 cur
= safe_concat (buf
, cur
, t
);
472 print_value (t
, XEXP (x
, 0), verbose
);
473 cur
= safe_concat (buf
, cur
, "const(");
474 cur
= safe_concat (buf
, cur
, t
);
475 cur
= safe_concat (buf
, cur
, ")");
478 print_value (t
, XEXP (x
, 0), verbose
);
479 cur
= safe_concat (buf
, cur
, "high(");
480 cur
= safe_concat (buf
, cur
, t
);
481 cur
= safe_concat (buf
, cur
, ")");
484 if (REGNO (x
) < FIRST_PSEUDO_REGISTER
)
486 int c
= reg_names
[REGNO (x
)][0];
488 cur
= safe_concat (buf
, cur
, "%");
490 cur
= safe_concat (buf
, cur
, reg_names
[REGNO (x
)]);
494 sprintf (t
, "r%d", REGNO (x
));
495 cur
= safe_concat (buf
, cur
, t
);
498 #ifdef INSN_SCHEDULING
499 && !current_sched_info
503 sprintf (t
, ":%s", GET_MODE_NAME (GET_MODE (x
)));
504 cur
= safe_concat (buf
, cur
, t
);
508 print_value (t
, SUBREG_REG (x
), verbose
);
509 cur
= safe_concat (buf
, cur
, t
);
510 sprintf (t
, "#%d", SUBREG_BYTE (x
));
511 cur
= safe_concat (buf
, cur
, t
);
514 cur
= safe_concat (buf
, cur
, "scratch");
517 cur
= safe_concat (buf
, cur
, "cc0");
520 cur
= safe_concat (buf
, cur
, "pc");
523 print_value (t
, XEXP (x
, 0), verbose
);
524 cur
= safe_concat (buf
, cur
, "[");
525 cur
= safe_concat (buf
, cur
, t
);
526 cur
= safe_concat (buf
, cur
, "]");
529 sprintf (t
, "D#%i", DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x
)));
530 cur
= safe_concat (buf
, cur
, t
);
533 print_exp (t
, x
, verbose
);
534 cur
= safe_concat (buf
, cur
, t
);
539 /* The next step in insn detalization, its pattern recognition. */
542 print_pattern (char *buf
, const_rtx x
, int verbose
)
544 char t1
[BUF_LEN
], t2
[BUF_LEN
], t3
[BUF_LEN
];
546 switch (GET_CODE (x
))
549 print_value (t1
, SET_DEST (x
), verbose
);
550 print_value (t2
, SET_SRC (x
), verbose
);
551 sprintf (buf
, "%s=%s", t1
, t2
);
554 sprintf (buf
, "return");
557 print_exp (buf
, x
, verbose
);
560 print_value (t1
, XEXP (x
, 0), verbose
);
561 sprintf (buf
, "clobber %s", t1
);
564 print_value (t1
, XEXP (x
, 0), verbose
);
565 sprintf (buf
, "use %s", t1
);
568 print_value (t1
, PAT_VAR_LOCATION_LOC (x
), verbose
);
569 sprintf (buf
, "loc %s", t1
);
572 if (GET_CODE (COND_EXEC_TEST (x
)) == NE
573 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
574 print_value (t1
, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
575 else if (GET_CODE (COND_EXEC_TEST (x
)) == EQ
576 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
579 print_value (t1
+ 1, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
582 print_value (t1
, COND_EXEC_TEST (x
), verbose
);
583 print_pattern (t2
, COND_EXEC_CODE (x
), verbose
);
584 sprintf (buf
, "(%s) %s", t1
, t2
);
591 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
593 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
594 sprintf (t3
, "%s%s;", t1
, t2
);
597 sprintf (buf
, "%s}", t1
);
601 /* Should never see SEQUENCE codes until after reorg. */
604 sprintf (buf
, "asm {%s}", XSTR (x
, 0));
609 print_value (buf
, XEXP (x
, 0), verbose
);
612 print_value (t1
, TRAP_CONDITION (x
), verbose
);
613 sprintf (buf
, "trap_if %s", t1
);
619 sprintf (t1
, "unspec{");
620 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
622 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
623 sprintf (t3
, "%s%s;", t1
, t2
);
626 sprintf (buf
, "%s}", t1
);
629 case UNSPEC_VOLATILE
:
633 sprintf (t1
, "unspec/v{");
634 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
636 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
637 sprintf (t3
, "%s%s;", t1
, t2
);
640 sprintf (buf
, "%s}", t1
);
644 print_value (buf
, x
, verbose
);
646 } /* print_pattern */
648 /* This is the main function in rtl visualization mechanism. It
649 accepts an rtx and tries to recognize it as an insn, then prints it
650 properly in human readable form, resembling assembler mnemonics.
651 For every insn it prints its UID and BB the insn belongs too.
652 (Probably the last "option" should be extended somehow, since it
653 depends now on sched.c inner variables ...) */
656 print_insn (char *buf
, const_rtx x
, int verbose
)
661 switch (GET_CODE (x
))
664 print_pattern (t
, PATTERN (x
), verbose
);
665 #ifdef INSN_SCHEDULING
666 if (verbose
&& current_sched_info
)
667 sprintf (buf
, "%s: %s", (*current_sched_info
->print_insn
) (x
, 1),
671 sprintf (buf
, " %4d %s", INSN_UID (x
), t
);
676 const char *name
= "?";
678 if (DECL_P (INSN_VAR_LOCATION_DECL (insn
)))
680 tree id
= DECL_NAME (INSN_VAR_LOCATION_DECL (insn
));
683 name
= IDENTIFIER_POINTER (id
);
684 else if (TREE_CODE (INSN_VAR_LOCATION_DECL (insn
))
687 sprintf (idbuf
, "D#%i",
688 DEBUG_TEMP_UID (INSN_VAR_LOCATION_DECL (insn
)));
693 sprintf (idbuf
, "D.%i",
694 DECL_UID (INSN_VAR_LOCATION_DECL (insn
)));
698 if (VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (insn
)))
699 sprintf (buf
, " %4d: debug %s optimized away", INSN_UID (insn
), name
);
702 print_pattern (t
, INSN_VAR_LOCATION_LOC (insn
), verbose
);
703 sprintf (buf
, " %4d: debug %s => %s", INSN_UID (insn
), name
, t
);
709 print_pattern (t
, PATTERN (x
), verbose
);
710 #ifdef INSN_SCHEDULING
711 if (verbose
&& current_sched_info
)
712 sprintf (buf
, "%s: jump %s", (*current_sched_info
->print_insn
) (x
, 1),
716 sprintf (buf
, " %4d %s", INSN_UID (x
), t
);
720 if (GET_CODE (x
) == PARALLEL
)
722 x
= XVECEXP (x
, 0, 0);
723 print_pattern (t
, x
, verbose
);
726 strcpy (t
, "call <...>");
727 #ifdef INSN_SCHEDULING
728 if (verbose
&& current_sched_info
)
729 sprintf (buf
, "%s: %s", (*current_sched_info
->print_insn
) (insn
, 1), t
);
732 sprintf (buf
, " %4d %s", INSN_UID (insn
), t
);
735 sprintf (buf
, "L%d:", INSN_UID (x
));
738 sprintf (buf
, "i%4d: barrier", INSN_UID (x
));
741 sprintf (buf
, " %4d %s", INSN_UID (x
),
742 GET_NOTE_INSN_NAME (NOTE_KIND (x
)));
745 sprintf (buf
, "i%4d <What %s?>", INSN_UID (x
),
746 GET_RTX_NAME (GET_CODE (x
)));
750 /* Emit a slim dump of X (an insn) to the file F, including any register
751 note attached to the instruction. */
753 dump_insn_slim (FILE *f
, rtx x
)
755 char t
[BUF_LEN
+ 32];
758 print_insn (t
, x
, 1);
761 if (INSN_P (x
) && REG_NOTES (x
))
762 for (note
= REG_NOTES (x
); note
; note
= XEXP (note
, 1))
764 print_value (t
, XEXP (note
, 0), 1);
765 fprintf (f
, " %s: %s\n",
766 GET_REG_NOTE_NAME (REG_NOTE_KIND (note
)), t
);
770 /* Emit a slim dump of X (an insn) to stderr. */
772 debug_insn_slim (rtx x
)
774 dump_insn_slim (stderr
, x
);
777 /* Provide a slim dump the instruction chain starting at FIRST to F, honoring
778 the dump flags given in FLAGS. Currently, TDF_BLOCKS and TDF_DETAILS
779 include more information on the basic blocks. */
781 print_rtl_slim_with_bb (FILE *f
, rtx first
, int flags
)
783 print_rtl_slim (f
, first
, NULL
, -1, flags
);
786 /* Same as above, but stop at LAST or when COUNT == 0.
787 If COUNT < 0 it will stop only at LAST or NULL rtx. */
789 print_rtl_slim (FILE *f
, rtx first
, rtx last
, int count
, int flags
)
791 basic_block current_bb
= NULL
;
794 tail
= last
? NEXT_INSN (last
) : NULL_RTX
;
796 (insn
!= NULL
) && (insn
!= tail
) && (count
!= 0);
797 insn
= NEXT_INSN (insn
))
799 if ((flags
& TDF_BLOCKS
)
800 && (INSN_P (insn
) || NOTE_P (insn
))
801 && BLOCK_FOR_INSN (insn
)
804 current_bb
= BLOCK_FOR_INSN (insn
);
805 dump_bb_info (current_bb
, true, false, flags
, ";; ", f
);
808 dump_insn_slim (f
, insn
);
810 if ((flags
& TDF_BLOCKS
)
812 && insn
== BB_END (current_bb
))
814 dump_bb_info (current_bb
, false, true, flags
, ";; ", f
);
823 debug_bb_slim (struct basic_block_def
*bb
)
825 print_rtl_slim (stderr
, BB_HEAD (bb
), BB_END (bb
), -1, 32);
829 debug_bb_n_slim (int n
)
831 struct basic_block_def
*bb
= BASIC_BLOCK (n
);