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
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
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/>. */
26 #include "coretypes.h"
30 #include "hard-reg-set.h"
31 #include "basic-block.h"
32 #include "insn-attr.h"
33 #include "sched-int.h"
34 #include "tree-pass.h"
36 static char *safe_concat (char *, char *, const char *);
41 safe_concat (char *buf
, char *cur
, const char *str
)
43 char *end
= buf
+ BUF_LEN
- 2; /* Leave room for null. */
52 while (cur
< end
&& (c
= *str
++) != '\0')
59 /* This recognizes rtx, I classified as expressions. These are always
60 represent some action on values or results of other expression, that
61 may be stored in objects representing values. */
64 print_exp (char *buf
, const_rtx x
, int verbose
)
69 const char *fun
= (char *) 0;
74 for (i
= 0; i
< 4; i
++)
84 if (CONST_INT_P (XEXP (x
, 1))
85 && INTVAL (XEXP (x
, 1)) < 0)
88 op
[1] = GEN_INT (-INTVAL (XEXP (x
, 1)));
268 fun
= (verbose
) ? "sign_extract" : "sxt";
274 fun
= (verbose
) ? "zero_extract" : "zxt";
280 fun
= (verbose
) ? "sign_extend" : "sxn";
284 fun
= (verbose
) ? "zero_extend" : "zxn";
288 fun
= (verbose
) ? "float_extend" : "fxn";
292 fun
= (verbose
) ? "trunc" : "trn";
296 fun
= (verbose
) ? "float_trunc" : "ftr";
300 fun
= (verbose
) ? "float" : "flt";
304 fun
= (verbose
) ? "uns_float" : "ufl";
312 fun
= (verbose
) ? "uns_fix" : "ufx";
333 op
[0] = XEXP (XEXP (x
, 1), 0);
335 op
[1] = XEXP (XEXP (x
, 1), 1);
339 op
[0] = XEXP (XEXP (x
, 1), 0);
341 op
[1] = XEXP (XEXP (x
, 1), 1);
363 op
[0] = TRAP_CONDITION (x
);
372 case UNSPEC_VOLATILE
:
374 cur
= safe_concat (buf
, cur
, "unspec");
375 if (GET_CODE (x
) == UNSPEC_VOLATILE
)
376 cur
= safe_concat (buf
, cur
, "/v");
377 cur
= safe_concat (buf
, cur
, "[");
379 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
381 print_pattern (tmp
, XVECEXP (x
, 0, i
), verbose
);
382 cur
= safe_concat (buf
, cur
, sep
);
383 cur
= safe_concat (buf
, cur
, tmp
);
386 cur
= safe_concat (buf
, cur
, "] ");
387 sprintf (tmp
, "%d", XINT (x
, 1));
388 cur
= safe_concat (buf
, cur
, tmp
);
392 /* If (verbose) debug_rtx (x); */
393 st
[0] = GET_RTX_NAME (GET_CODE (x
));
397 /* Print this as a function? */
400 cur
= safe_concat (buf
, cur
, fun
);
401 cur
= safe_concat (buf
, cur
, "(");
404 for (i
= 0; i
< 4; i
++)
407 cur
= safe_concat (buf
, cur
, st
[i
]);
412 cur
= safe_concat (buf
, cur
, ",");
414 print_value (tmp
, op
[i
], verbose
);
415 cur
= safe_concat (buf
, cur
, tmp
);
420 cur
= safe_concat (buf
, cur
, ")");
423 /* Prints rtxes, I customarily classified as values. They're constants,
424 registers, labels, symbols and memory accesses. */
427 print_value (char *buf
, const_rtx x
, int verbose
)
434 safe_concat (buf
, buf
, "(nil)");
437 switch (GET_CODE (x
))
440 sprintf (t
, HOST_WIDE_INT_PRINT_HEX
,
441 (unsigned HOST_WIDE_INT
) INTVAL (x
));
442 cur
= safe_concat (buf
, cur
, t
);
445 if (FLOAT_MODE_P (GET_MODE (x
)))
446 real_to_decimal (t
, CONST_DOUBLE_REAL_VALUE (x
), sizeof (t
), 0, 1);
449 "<" HOST_WIDE_INT_PRINT_HEX
"," HOST_WIDE_INT_PRINT_HEX
">",
450 (unsigned HOST_WIDE_INT
) CONST_DOUBLE_LOW (x
),
451 (unsigned HOST_WIDE_INT
) CONST_DOUBLE_HIGH (x
));
452 cur
= safe_concat (buf
, cur
, t
);
455 fixed_to_decimal (t
, CONST_FIXED_VALUE (x
), sizeof (t
));
456 cur
= safe_concat (buf
, cur
, t
);
459 cur
= safe_concat (buf
, cur
, "\"");
460 cur
= safe_concat (buf
, cur
, XSTR (x
, 0));
461 cur
= safe_concat (buf
, cur
, "\"");
464 cur
= safe_concat (buf
, cur
, "`");
465 cur
= safe_concat (buf
, cur
, XSTR (x
, 0));
466 cur
= safe_concat (buf
, cur
, "'");
469 sprintf (t
, "L%d", INSN_UID (XEXP (x
, 0)));
470 cur
= safe_concat (buf
, cur
, t
);
473 print_value (t
, XEXP (x
, 0), verbose
);
474 cur
= safe_concat (buf
, cur
, "const(");
475 cur
= safe_concat (buf
, cur
, t
);
476 cur
= safe_concat (buf
, cur
, ")");
479 print_value (t
, XEXP (x
, 0), verbose
);
480 cur
= safe_concat (buf
, cur
, "high(");
481 cur
= safe_concat (buf
, cur
, t
);
482 cur
= safe_concat (buf
, cur
, ")");
485 if (REGNO (x
) < FIRST_PSEUDO_REGISTER
)
487 int c
= reg_names
[REGNO (x
)][0];
489 cur
= safe_concat (buf
, cur
, "%");
491 cur
= safe_concat (buf
, cur
, reg_names
[REGNO (x
)]);
495 sprintf (t
, "r%d", REGNO (x
));
496 cur
= safe_concat (buf
, cur
, t
);
499 #ifdef INSN_SCHEDULING
500 && !current_sched_info
504 sprintf (t
, ":%s", GET_MODE_NAME (GET_MODE (x
)));
505 cur
= safe_concat (buf
, cur
, t
);
509 print_value (t
, SUBREG_REG (x
), verbose
);
510 cur
= safe_concat (buf
, cur
, t
);
511 sprintf (t
, "#%d", SUBREG_BYTE (x
));
512 cur
= safe_concat (buf
, cur
, t
);
514 case STRICT_LOW_PART
:
515 print_value (t
, XEXP (x
, 0), verbose
);
516 cur
= safe_concat (buf
, cur
, "strict_low_part(");
517 cur
= safe_concat (buf
, cur
, t
);
518 cur
= safe_concat (buf
, cur
, ")");
521 cur
= safe_concat (buf
, cur
, "scratch");
524 cur
= safe_concat (buf
, cur
, "cc0");
527 cur
= safe_concat (buf
, cur
, "pc");
530 print_value (t
, XEXP (x
, 0), verbose
);
531 cur
= safe_concat (buf
, cur
, "[");
532 cur
= safe_concat (buf
, cur
, t
);
533 cur
= safe_concat (buf
, cur
, "]");
536 sprintf (t
, "D#%i", DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x
)));
537 cur
= safe_concat (buf
, cur
, t
);
540 print_exp (t
, x
, verbose
);
541 cur
= safe_concat (buf
, cur
, t
);
546 /* The next step in insn detalization, its pattern recognition. */
549 print_pattern (char *buf
, const_rtx x
, int verbose
)
551 char t1
[BUF_LEN
], t2
[BUF_LEN
], t3
[BUF_LEN
];
553 switch (GET_CODE (x
))
556 print_value (t1
, SET_DEST (x
), verbose
);
557 print_value (t2
, SET_SRC (x
), verbose
);
558 sprintf (buf
, "%s=%s", t1
, t2
);
561 sprintf (buf
, "return");
564 sprintf (buf
, "simple_return");
567 print_exp (buf
, x
, verbose
);
570 print_value (t1
, XEXP (x
, 0), verbose
);
571 sprintf (buf
, "clobber %s", t1
);
574 print_value (t1
, XEXP (x
, 0), verbose
);
575 sprintf (buf
, "use %s", t1
);
578 print_value (t1
, PAT_VAR_LOCATION_LOC (x
), verbose
);
579 sprintf (buf
, "loc %s", t1
);
582 if (GET_CODE (COND_EXEC_TEST (x
)) == NE
583 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
584 print_value (t1
, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
585 else if (GET_CODE (COND_EXEC_TEST (x
)) == EQ
586 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
589 print_value (t1
+ 1, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
592 print_value (t1
, COND_EXEC_TEST (x
), verbose
);
593 print_pattern (t2
, COND_EXEC_CODE (x
), verbose
);
594 sprintf (buf
, "(%s) %s", t1
, t2
);
601 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
603 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
604 sprintf (t3
, "%s%s;", t1
, t2
);
607 sprintf (buf
, "%s}", t1
);
611 /* Should never see SEQUENCE codes until after reorg. */
614 sprintf (buf
, "asm {%s}", XSTR (x
, 0));
619 print_value (buf
, XEXP (x
, 0), verbose
);
622 print_value (t1
, TRAP_CONDITION (x
), verbose
);
623 sprintf (buf
, "trap_if %s", t1
);
629 sprintf (t1
, "unspec{");
630 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
632 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
633 sprintf (t3
, "%s%s;", t1
, t2
);
636 sprintf (buf
, "%s}", t1
);
639 case UNSPEC_VOLATILE
:
643 sprintf (t1
, "unspec/v{");
644 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
646 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
647 sprintf (t3
, "%s%s;", t1
, t2
);
650 sprintf (buf
, "%s}", t1
);
654 print_value (buf
, x
, verbose
);
656 } /* print_pattern */
658 /* This is the main function in rtl visualization mechanism. It
659 accepts an rtx and tries to recognize it as an insn, then prints it
660 properly in human readable form, resembling assembler mnemonics.
661 For every insn it prints its UID and BB the insn belongs too.
662 (Probably the last "option" should be extended somehow, since it
663 depends now on sched.c inner variables ...) */
666 print_insn (char *buf
, const_rtx x
, int verbose
)
671 switch (GET_CODE (x
))
674 print_pattern (t
, PATTERN (x
), verbose
);
675 #ifdef INSN_SCHEDULING
676 if (verbose
&& current_sched_info
)
677 sprintf (buf
, "%s: %s", (*current_sched_info
->print_insn
) (x
, 1),
681 sprintf (buf
, " %4d %s", INSN_UID (x
), t
);
686 const char *name
= "?";
688 if (DECL_P (INSN_VAR_LOCATION_DECL (insn
)))
690 tree id
= DECL_NAME (INSN_VAR_LOCATION_DECL (insn
));
693 name
= IDENTIFIER_POINTER (id
);
694 else if (TREE_CODE (INSN_VAR_LOCATION_DECL (insn
))
697 sprintf (idbuf
, "D#%i",
698 DEBUG_TEMP_UID (INSN_VAR_LOCATION_DECL (insn
)));
703 sprintf (idbuf
, "D.%i",
704 DECL_UID (INSN_VAR_LOCATION_DECL (insn
)));
708 if (VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (insn
)))
709 sprintf (buf
, " %4d: debug %s optimized away", INSN_UID (insn
), name
);
712 print_pattern (t
, INSN_VAR_LOCATION_LOC (insn
), verbose
);
713 sprintf (buf
, " %4d: debug %s => %s", INSN_UID (insn
), name
, t
);
719 print_pattern (t
, PATTERN (x
), verbose
);
720 #ifdef INSN_SCHEDULING
721 if (verbose
&& current_sched_info
)
722 sprintf (buf
, "%s: jump %s", (*current_sched_info
->print_insn
) (x
, 1),
726 sprintf (buf
, " %4d %s", INSN_UID (x
), t
);
730 if (GET_CODE (x
) == PARALLEL
)
732 x
= XVECEXP (x
, 0, 0);
733 print_pattern (t
, x
, verbose
);
736 strcpy (t
, "call <...>");
737 #ifdef INSN_SCHEDULING
738 if (verbose
&& current_sched_info
)
739 sprintf (buf
, "%s: %s", (*current_sched_info
->print_insn
) (insn
, 1), t
);
742 sprintf (buf
, " %4d %s", INSN_UID (insn
), t
);
745 sprintf (buf
, "L%d:", INSN_UID (x
));
748 sprintf (buf
, "i%4d: barrier", INSN_UID (x
));
751 sprintf (buf
, " %4d %s", INSN_UID (x
),
752 GET_NOTE_INSN_NAME (NOTE_KIND (x
)));
755 sprintf (buf
, "i%4d <What %s?>", INSN_UID (x
),
756 GET_RTX_NAME (GET_CODE (x
)));
760 /* Emit a slim dump of X (an insn) to the file F, including any register
761 note attached to the instruction. */
763 dump_insn_slim (FILE *f
, rtx x
)
765 char t
[BUF_LEN
+ 32];
768 print_insn (t
, x
, 1);
771 if (INSN_P (x
) && REG_NOTES (x
))
772 for (note
= REG_NOTES (x
); note
; note
= XEXP (note
, 1))
774 print_value (t
, XEXP (note
, 0), 1);
775 fprintf (f
, " %s: %s\n",
776 GET_REG_NOTE_NAME (REG_NOTE_KIND (note
)), t
);
780 /* Emit a slim dump of X (an insn) to stderr. */
782 debug_insn_slim (rtx x
)
784 dump_insn_slim (stderr
, x
);
787 /* Provide a slim dump the instruction chain starting at FIRST to F, honoring
788 the dump flags given in FLAGS. Currently, TDF_BLOCKS and TDF_DETAILS
789 include more information on the basic blocks. */
791 print_rtl_slim_with_bb (FILE *f
, rtx first
, int flags
)
793 print_rtl_slim (f
, first
, NULL
, -1, flags
);
796 /* Same as above, but stop at LAST or when COUNT == 0.
797 If COUNT < 0 it will stop only at LAST or NULL rtx. */
799 print_rtl_slim (FILE *f
, rtx first
, rtx last
, int count
, int flags
)
801 basic_block current_bb
= NULL
;
804 tail
= last
? NEXT_INSN (last
) : NULL_RTX
;
806 (insn
!= NULL
) && (insn
!= tail
) && (count
!= 0);
807 insn
= NEXT_INSN (insn
))
809 if ((flags
& TDF_BLOCKS
)
810 && (INSN_P (insn
) || NOTE_P (insn
))
811 && BLOCK_FOR_INSN (insn
)
814 current_bb
= BLOCK_FOR_INSN (insn
);
815 dump_bb_info (current_bb
, true, false, flags
, ";; ", f
);
818 dump_insn_slim (f
, insn
);
820 if ((flags
& TDF_BLOCKS
)
822 && insn
== BB_END (current_bb
))
824 dump_bb_info (current_bb
, false, true, flags
, ";; ", f
);
833 debug_bb_slim (struct basic_block_def
*bb
)
835 print_rtl_slim (stderr
, BB_HEAD (bb
), BB_END (bb
), -1, 32);
839 debug_bb_n_slim (int n
)
841 struct basic_block_def
*bb
= BASIC_BLOCK (n
);