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"
29 #include "tree.h" /* FIXME: To dump INSN_VAR_LOCATION_DECL. */
31 #include "hard-reg-set.h"
32 #include "basic-block.h"
33 #include "insn-attr.h"
34 #include "sched-int.h"
35 #include "dumpfile.h" /* for the TDF_* flags */
37 static char *safe_concat (char *, char *, const char *);
42 safe_concat (char *buf
, char *cur
, const char *str
)
44 char *end
= buf
+ BUF_LEN
- 2; /* Leave room for null. */
53 while (cur
< end
&& (c
= *str
++) != '\0')
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. */
65 print_exp (char *buf
, const_rtx x
, int verbose
)
70 const char *fun
= (char *) 0;
75 for (i
= 0; i
< 4; i
++)
85 if (CONST_INT_P (XEXP (x
, 1))
86 && INTVAL (XEXP (x
, 1)) < 0)
89 op
[1] = GEN_INT (-INTVAL (XEXP (x
, 1)));
246 fun
= (verbose
) ? "sign_extract" : "sxt";
252 fun
= (verbose
) ? "zero_extract" : "zxt";
258 fun
= (verbose
) ? "sign_extend" : "sxn";
262 fun
= (verbose
) ? "zero_extend" : "zxn";
266 fun
= (verbose
) ? "float_extend" : "fxn";
270 fun
= (verbose
) ? "trunc" : "trn";
274 fun
= (verbose
) ? "float_trunc" : "ftr";
278 fun
= (verbose
) ? "float" : "flt";
282 fun
= (verbose
) ? "uns_float" : "ufl";
290 fun
= (verbose
) ? "uns_fix" : "ufx";
311 op
[0] = XEXP (XEXP (x
, 1), 0);
313 op
[1] = XEXP (XEXP (x
, 1), 1);
317 op
[0] = XEXP (XEXP (x
, 1), 0);
319 op
[1] = XEXP (XEXP (x
, 1), 1);
341 op
[0] = TRAP_CONDITION (x
);
350 case UNSPEC_VOLATILE
:
352 cur
= safe_concat (buf
, cur
, "unspec");
353 if (GET_CODE (x
) == UNSPEC_VOLATILE
)
354 cur
= safe_concat (buf
, cur
, "/v");
355 cur
= safe_concat (buf
, cur
, "[");
357 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
359 print_pattern (tmp
, XVECEXP (x
, 0, i
), verbose
);
360 cur
= safe_concat (buf
, cur
, sep
);
361 cur
= safe_concat (buf
, cur
, tmp
);
364 cur
= safe_concat (buf
, cur
, "] ");
365 sprintf (tmp
, "%d", XINT (x
, 1));
366 cur
= safe_concat (buf
, cur
, tmp
);
371 /* Most unhandled codes can be printed as pseudo-functions. */
372 if (GET_RTX_CLASS (GET_CODE (x
)) == RTX_UNARY
)
374 fun
= GET_RTX_NAME (GET_CODE (x
));
377 else if (GET_RTX_CLASS (GET_CODE (x
)) == RTX_COMPARE
378 || GET_RTX_CLASS (GET_CODE (x
)) == RTX_COMM_COMPARE
379 || GET_RTX_CLASS (GET_CODE (x
)) == RTX_BIN_ARITH
380 || GET_RTX_CLASS (GET_CODE (x
)) == RTX_COMM_ARITH
)
382 fun
= GET_RTX_NAME (GET_CODE (x
));
386 else if (GET_RTX_CLASS (GET_CODE (x
)) == RTX_TERNARY
)
388 fun
= GET_RTX_NAME (GET_CODE (x
));
394 /* Give up, just print the RTX name. */
395 st
[0] = GET_RTX_NAME (GET_CODE (x
));
400 /* Print this as a function? */
403 cur
= safe_concat (buf
, cur
, fun
);
404 cur
= safe_concat (buf
, cur
, "(");
407 for (i
= 0; i
< 4; i
++)
410 cur
= safe_concat (buf
, cur
, st
[i
]);
415 cur
= safe_concat (buf
, cur
, ",");
417 print_value (tmp
, op
[i
], verbose
);
418 cur
= safe_concat (buf
, cur
, tmp
);
423 cur
= safe_concat (buf
, cur
, ")");
426 /* Prints rtxes, I customarily classified as values. They're constants,
427 registers, labels, symbols and memory accesses. */
430 print_value (char *buf
, const_rtx x
, int verbose
)
437 safe_concat (buf
, buf
, "(nil)");
440 switch (GET_CODE (x
))
443 sprintf (t
, HOST_WIDE_INT_PRINT_HEX
,
444 (unsigned HOST_WIDE_INT
) INTVAL (x
));
445 cur
= safe_concat (buf
, cur
, t
);
448 if (FLOAT_MODE_P (GET_MODE (x
)))
449 real_to_decimal (t
, CONST_DOUBLE_REAL_VALUE (x
), sizeof (t
), 0, 1);
452 "<" HOST_WIDE_INT_PRINT_HEX
"," HOST_WIDE_INT_PRINT_HEX
">",
453 (unsigned HOST_WIDE_INT
) CONST_DOUBLE_LOW (x
),
454 (unsigned HOST_WIDE_INT
) CONST_DOUBLE_HIGH (x
));
455 cur
= safe_concat (buf
, cur
, t
);
458 fixed_to_decimal (t
, CONST_FIXED_VALUE (x
), sizeof (t
));
459 cur
= safe_concat (buf
, cur
, t
);
462 cur
= safe_concat (buf
, cur
, "\"");
463 cur
= safe_concat (buf
, cur
, XSTR (x
, 0));
464 cur
= safe_concat (buf
, cur
, "\"");
467 cur
= safe_concat (buf
, cur
, "`");
468 cur
= safe_concat (buf
, cur
, XSTR (x
, 0));
469 cur
= safe_concat (buf
, cur
, "'");
472 sprintf (t
, "L%d", INSN_UID (XEXP (x
, 0)));
473 cur
= safe_concat (buf
, cur
, t
);
476 print_value (t
, XEXP (x
, 0), verbose
);
477 cur
= safe_concat (buf
, cur
, "const(");
478 cur
= safe_concat (buf
, cur
, t
);
479 cur
= safe_concat (buf
, cur
, ")");
482 print_value (t
, XEXP (x
, 0), verbose
);
483 cur
= safe_concat (buf
, cur
, "high(");
484 cur
= safe_concat (buf
, cur
, t
);
485 cur
= safe_concat (buf
, cur
, ")");
488 if (REGNO (x
) < FIRST_PSEUDO_REGISTER
)
490 int c
= reg_names
[REGNO (x
)][0];
492 cur
= safe_concat (buf
, cur
, "%");
494 cur
= safe_concat (buf
, cur
, reg_names
[REGNO (x
)]);
498 sprintf (t
, "r%d", REGNO (x
));
499 cur
= safe_concat (buf
, cur
, t
);
502 #ifdef INSN_SCHEDULING
503 && !current_sched_info
507 sprintf (t
, ":%s", GET_MODE_NAME (GET_MODE (x
)));
508 cur
= safe_concat (buf
, cur
, t
);
512 print_value (t
, SUBREG_REG (x
), verbose
);
513 cur
= safe_concat (buf
, cur
, t
);
514 sprintf (t
, "#%d", SUBREG_BYTE (x
));
515 cur
= safe_concat (buf
, cur
, t
);
517 case STRICT_LOW_PART
:
518 print_value (t
, XEXP (x
, 0), verbose
);
519 cur
= safe_concat (buf
, cur
, "strict_low_part(");
520 cur
= safe_concat (buf
, cur
, t
);
521 cur
= safe_concat (buf
, cur
, ")");
524 cur
= safe_concat (buf
, cur
, "scratch");
527 cur
= safe_concat (buf
, cur
, "cc0");
530 cur
= safe_concat (buf
, cur
, "pc");
533 print_value (t
, XEXP (x
, 0), verbose
);
534 cur
= safe_concat (buf
, cur
, "[");
535 cur
= safe_concat (buf
, cur
, t
);
536 cur
= safe_concat (buf
, cur
, "]");
539 sprintf (t
, "D#%i", DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x
)));
540 cur
= safe_concat (buf
, cur
, t
);
543 print_exp (t
, x
, verbose
);
544 cur
= safe_concat (buf
, cur
, t
);
549 /* Print X, an RTL value node, to file F in slim format. Include
550 additional information if VERBOSE is nonzero.
552 Value nodes are constants, registers, labels, symbols and
556 print_value_slim (FILE *f
, const_rtx x
, int verbose
)
560 print_value (buf
, x
, verbose
);
561 fprintf (f
, "%s", buf
);
564 /* The next step in insn detalization, its pattern recognition. */
567 print_pattern (char *buf
, const_rtx x
, int verbose
)
569 char t1
[BUF_LEN
], t2
[BUF_LEN
], t3
[BUF_LEN
];
573 sprintf (buf
, "(nil)");
577 switch (GET_CODE (x
))
580 print_value (t1
, SET_DEST (x
), verbose
);
581 print_value (t2
, SET_SRC (x
), verbose
);
582 sprintf (buf
, "%s=%s", t1
, t2
);
587 sprintf (buf
, GET_RTX_NAME (GET_CODE (x
)));
590 print_exp (buf
, x
, verbose
);
593 print_value (t1
, XEXP (x
, 0), verbose
);
594 sprintf (buf
, "clobber %s", t1
);
597 print_value (t1
, XEXP (x
, 0), verbose
);
598 sprintf (buf
, "use %s", t1
);
601 print_value (t1
, PAT_VAR_LOCATION_LOC (x
), verbose
);
602 sprintf (buf
, "loc %s", t1
);
605 if (GET_CODE (COND_EXEC_TEST (x
)) == NE
606 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
607 print_value (t1
, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
608 else if (GET_CODE (COND_EXEC_TEST (x
)) == EQ
609 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
612 print_value (t1
+ 1, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
615 print_value (t1
, COND_EXEC_TEST (x
), verbose
);
616 print_pattern (t2
, COND_EXEC_CODE (x
), verbose
);
617 sprintf (buf
, "(%s) %s", t1
, t2
);
624 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
626 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
627 sprintf (t3
, "%s%s;", t1
, t2
);
630 sprintf (buf
, "%s}", t1
);
637 sprintf (t1
, "sequence{");
638 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
640 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
641 sprintf (t3
, "%s%s;", t1
, t2
);
644 sprintf (buf
, "%s}", t1
);
648 sprintf (buf
, "asm {%s}", XSTR (x
, 0));
653 print_value (buf
, XEXP (x
, 0), verbose
);
656 print_value (t1
, TRAP_CONDITION (x
), verbose
);
657 sprintf (buf
, "trap_if %s", t1
);
663 sprintf (t1
, "unspec{");
664 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
666 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
667 sprintf (t3
, "%s%s;", t1
, t2
);
670 sprintf (buf
, "%s}", t1
);
673 case UNSPEC_VOLATILE
:
677 sprintf (t1
, "unspec/v{");
678 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
680 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
681 sprintf (t3
, "%s%s;", t1
, t2
);
684 sprintf (buf
, "%s}", t1
);
688 print_value (buf
, x
, verbose
);
690 } /* print_pattern */
692 /* This is the main function in rtl visualization mechanism. It
693 accepts an rtx and tries to recognize it as an insn, then prints it
694 properly in human readable form, resembling assembler mnemonics.
695 For every insn it prints its UID and BB the insn belongs too.
696 (Probably the last "option" should be extended somehow, since it
697 depends now on sched.c inner variables ...) */
700 print_insn (char *buf
, const_rtx x
, int verbose
)
705 switch (GET_CODE (x
))
708 print_pattern (t
, PATTERN (x
), verbose
);
709 #ifdef INSN_SCHEDULING
710 if (verbose
&& current_sched_info
)
711 sprintf (buf
, "%s: %s", (*current_sched_info
->print_insn
) (x
, 1),
715 sprintf (buf
, " %4d %s", INSN_UID (x
), t
);
720 const char *name
= "?";
722 if (DECL_P (INSN_VAR_LOCATION_DECL (insn
)))
724 tree id
= DECL_NAME (INSN_VAR_LOCATION_DECL (insn
));
727 name
= IDENTIFIER_POINTER (id
);
728 else if (TREE_CODE (INSN_VAR_LOCATION_DECL (insn
))
731 sprintf (idbuf
, "D#%i",
732 DEBUG_TEMP_UID (INSN_VAR_LOCATION_DECL (insn
)));
737 sprintf (idbuf
, "D.%i",
738 DECL_UID (INSN_VAR_LOCATION_DECL (insn
)));
742 if (VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (insn
)))
743 sprintf (buf
, " %4d: debug %s optimized away", INSN_UID (insn
), name
);
746 print_pattern (t
, INSN_VAR_LOCATION_LOC (insn
), verbose
);
747 sprintf (buf
, " %4d: debug %s => %s", INSN_UID (insn
), name
, t
);
753 print_pattern (t
, PATTERN (x
), verbose
);
754 #ifdef INSN_SCHEDULING
755 if (verbose
&& current_sched_info
)
756 sprintf (buf
, "%s: jump %s", (*current_sched_info
->print_insn
) (x
, 1),
760 sprintf (buf
, " %4d %s", INSN_UID (x
), t
);
764 if (GET_CODE (x
) == PARALLEL
)
766 x
= XVECEXP (x
, 0, 0);
767 print_pattern (t
, x
, verbose
);
770 strcpy (t
, "call <...>");
771 #ifdef INSN_SCHEDULING
772 if (verbose
&& current_sched_info
)
773 sprintf (buf
, "%s: %s", (*current_sched_info
->print_insn
) (insn
, 1), t
);
776 sprintf (buf
, " %4d %s", INSN_UID (insn
), t
);
779 sprintf (buf
, "L%d:", INSN_UID (x
));
782 sprintf (buf
, "i%4d: barrier", INSN_UID (x
));
785 sprintf (buf
, " %4d %s", INSN_UID (x
),
786 GET_NOTE_INSN_NAME (NOTE_KIND (x
)));
789 sprintf (buf
, "i%4d <What %s?>", INSN_UID (x
),
790 GET_RTX_NAME (GET_CODE (x
)));
794 /* Emit a slim dump of X (an insn) to the file F, including any register
795 note attached to the instruction. */
797 dump_insn_slim (FILE *f
, const_rtx x
)
799 char t
[BUF_LEN
+ 32];
802 print_insn (t
, x
, 1);
803 fputs (print_rtx_head
, f
);
806 if (INSN_P (x
) && REG_NOTES (x
))
807 for (note
= REG_NOTES (x
); note
; note
= XEXP (note
, 1))
809 fputs (print_rtx_head
, f
);
810 print_pattern (t
, XEXP (note
, 0), 1);
811 fprintf (f
, " %s: %s\n",
812 GET_REG_NOTE_NAME (REG_NOTE_KIND (note
)), t
);
816 /* Emit a slim dump of X (an insn) to stderr. */
817 extern void debug_insn_slim (const_rtx
);
819 debug_insn_slim (const_rtx x
)
821 dump_insn_slim (stderr
, x
);
824 /* Same as above, but stop at LAST or when COUNT == 0.
825 If COUNT < 0 it will stop only at LAST or NULL rtx. */
826 extern void debug_rtl_slim (FILE *, const_rtx
, const_rtx
, int, int);
828 debug_rtl_slim (FILE *f
, const_rtx first
, const_rtx last
,
829 int count
, int flags ATTRIBUTE_UNUSED
)
831 const_rtx insn
, tail
;
833 tail
= last
? NEXT_INSN (last
) : NULL_RTX
;
835 (insn
!= NULL
) && (insn
!= tail
) && (count
!= 0);
836 insn
= NEXT_INSN (insn
))
838 dump_insn_slim (f
, insn
);
844 extern void debug_bb_slim (basic_block
);
846 debug_bb_slim (basic_block bb
)
848 dump_bb (stderr
, bb
, 0, TDF_SLIM
| TDF_BLOCKS
);
851 extern void debug_bb_n_slim (int);
853 debug_bb_n_slim (int n
)
855 basic_block bb
= BASIC_BLOCK (n
);