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)));
269 fun
= (verbose
) ? "sign_extract" : "sxt";
275 fun
= (verbose
) ? "zero_extract" : "zxt";
281 fun
= (verbose
) ? "sign_extend" : "sxn";
285 fun
= (verbose
) ? "zero_extend" : "zxn";
289 fun
= (verbose
) ? "float_extend" : "fxn";
293 fun
= (verbose
) ? "trunc" : "trn";
297 fun
= (verbose
) ? "float_trunc" : "ftr";
301 fun
= (verbose
) ? "float" : "flt";
305 fun
= (verbose
) ? "uns_float" : "ufl";
313 fun
= (verbose
) ? "uns_fix" : "ufx";
334 op
[0] = XEXP (XEXP (x
, 1), 0);
336 op
[1] = XEXP (XEXP (x
, 1), 1);
340 op
[0] = XEXP (XEXP (x
, 1), 0);
342 op
[1] = XEXP (XEXP (x
, 1), 1);
364 op
[0] = TRAP_CONDITION (x
);
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
, "[");
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
);
387 cur
= safe_concat (buf
, cur
, "] ");
388 sprintf (tmp
, "%d", XINT (x
, 1));
389 cur
= safe_concat (buf
, cur
, tmp
);
393 /* If (verbose) debug_rtx (x); */
394 st
[0] = GET_RTX_NAME (GET_CODE (x
));
398 /* Print this as a function? */
401 cur
= safe_concat (buf
, cur
, fun
);
402 cur
= safe_concat (buf
, cur
, "(");
405 for (i
= 0; i
< 4; i
++)
408 cur
= safe_concat (buf
, cur
, st
[i
]);
413 cur
= safe_concat (buf
, cur
, ",");
415 print_value (tmp
, op
[i
], verbose
);
416 cur
= safe_concat (buf
, cur
, tmp
);
421 cur
= safe_concat (buf
, cur
, ")");
424 /* Prints rtxes, I customarily classified as values. They're constants,
425 registers, labels, symbols and memory accesses. */
428 print_value (char *buf
, const_rtx x
, int verbose
)
435 safe_concat (buf
, buf
, "(nil)");
438 switch (GET_CODE (x
))
441 sprintf (t
, HOST_WIDE_INT_PRINT_HEX
,
442 (unsigned HOST_WIDE_INT
) INTVAL (x
));
443 cur
= safe_concat (buf
, cur
, t
);
446 if (FLOAT_MODE_P (GET_MODE (x
)))
447 real_to_decimal (t
, CONST_DOUBLE_REAL_VALUE (x
), sizeof (t
), 0, 1);
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
);
456 fixed_to_decimal (t
, CONST_FIXED_VALUE (x
), sizeof (t
));
457 cur
= safe_concat (buf
, cur
, t
);
460 cur
= safe_concat (buf
, cur
, "\"");
461 cur
= safe_concat (buf
, cur
, XSTR (x
, 0));
462 cur
= safe_concat (buf
, cur
, "\"");
465 cur
= safe_concat (buf
, cur
, "`");
466 cur
= safe_concat (buf
, cur
, XSTR (x
, 0));
467 cur
= safe_concat (buf
, cur
, "'");
470 sprintf (t
, "L%d", INSN_UID (XEXP (x
, 0)));
471 cur
= safe_concat (buf
, cur
, t
);
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
, ")");
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
, ")");
486 if (REGNO (x
) < FIRST_PSEUDO_REGISTER
)
488 int c
= reg_names
[REGNO (x
)][0];
490 cur
= safe_concat (buf
, cur
, "%");
492 cur
= safe_concat (buf
, cur
, reg_names
[REGNO (x
)]);
496 sprintf (t
, "r%d", REGNO (x
));
497 cur
= safe_concat (buf
, cur
, t
);
500 #ifdef INSN_SCHEDULING
501 && !current_sched_info
505 sprintf (t
, ":%s", GET_MODE_NAME (GET_MODE (x
)));
506 cur
= safe_concat (buf
, cur
, t
);
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
);
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
, ")");
522 cur
= safe_concat (buf
, cur
, "scratch");
525 cur
= safe_concat (buf
, cur
, "cc0");
528 cur
= safe_concat (buf
, cur
, "pc");
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
, "]");
537 sprintf (t
, "D#%i", DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x
)));
538 cur
= safe_concat (buf
, cur
, t
);
541 print_exp (t
, x
, verbose
);
542 cur
= safe_concat (buf
, cur
, t
);
547 /* The next step in insn detalization, its pattern recognition. */
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
))
557 print_value (t1
, SET_DEST (x
), verbose
);
558 print_value (t2
, SET_SRC (x
), verbose
);
559 sprintf (buf
, "%s=%s", t1
, t2
);
562 sprintf (buf
, "return");
565 sprintf (buf
, "simple_return");
568 print_exp (buf
, x
, verbose
);
571 print_value (t1
, XEXP (x
, 0), verbose
);
572 sprintf (buf
, "clobber %s", t1
);
575 print_value (t1
, XEXP (x
, 0), verbose
);
576 sprintf (buf
, "use %s", t1
);
579 print_value (t1
, PAT_VAR_LOCATION_LOC (x
), verbose
);
580 sprintf (buf
, "loc %s", t1
);
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
)
590 print_value (t1
+ 1, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
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
);
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
);
608 sprintf (buf
, "%s}", t1
);
612 /* Should never see SEQUENCE codes until after reorg. */
615 sprintf (buf
, "asm {%s}", XSTR (x
, 0));
620 print_value (buf
, XEXP (x
, 0), verbose
);
623 print_value (t1
, TRAP_CONDITION (x
), verbose
);
624 sprintf (buf
, "trap_if %s", t1
);
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
);
637 sprintf (buf
, "%s}", t1
);
640 case UNSPEC_VOLATILE
:
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
);
651 sprintf (buf
, "%s}", t1
);
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 ...) */
667 print_insn (char *buf
, const_rtx x
, int verbose
)
672 switch (GET_CODE (x
))
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),
682 sprintf (buf
, " %4d %s", INSN_UID (x
), t
);
687 const char *name
= "?";
689 if (DECL_P (INSN_VAR_LOCATION_DECL (insn
)))
691 tree id
= DECL_NAME (INSN_VAR_LOCATION_DECL (insn
));
694 name
= IDENTIFIER_POINTER (id
);
695 else if (TREE_CODE (INSN_VAR_LOCATION_DECL (insn
))
698 sprintf (idbuf
, "D#%i",
699 DEBUG_TEMP_UID (INSN_VAR_LOCATION_DECL (insn
)));
704 sprintf (idbuf
, "D.%i",
705 DECL_UID (INSN_VAR_LOCATION_DECL (insn
)));
709 if (VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (insn
)))
710 sprintf (buf
, " %4d: debug %s optimized away", INSN_UID (insn
), name
);
713 print_pattern (t
, INSN_VAR_LOCATION_LOC (insn
), verbose
);
714 sprintf (buf
, " %4d: debug %s => %s", INSN_UID (insn
), name
, t
);
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),
727 sprintf (buf
, " %4d %s", INSN_UID (x
), t
);
731 if (GET_CODE (x
) == PARALLEL
)
733 x
= XVECEXP (x
, 0, 0);
734 print_pattern (t
, x
, verbose
);
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
);
743 sprintf (buf
, " %4d %s", INSN_UID (insn
), t
);
746 sprintf (buf
, "L%d:", INSN_UID (x
));
749 sprintf (buf
, "i%4d: barrier", INSN_UID (x
));
752 sprintf (buf
, " %4d %s", INSN_UID (x
),
753 GET_NOTE_INSN_NAME (NOTE_KIND (x
)));
756 sprintf (buf
, "i%4d <What %s?>", INSN_UID (x
),
757 GET_RTX_NAME (GET_CODE (x
)));
761 /* Emit a slim dump of X (an insn) to the file F, including any register
762 note attached to the instruction. */
764 dump_insn_slim (FILE *f
, const_rtx x
)
766 char t
[BUF_LEN
+ 32];
769 print_insn (t
, x
, 1);
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 extern void debug_insn_slim (const_rtx
);
784 debug_insn_slim (const_rtx x
)
786 dump_insn_slim (stderr
, x
);
789 /* Same as above, but stop at LAST or when COUNT == 0.
790 If COUNT < 0 it will stop only at LAST or NULL rtx. */
791 extern void debug_rtl_slim (FILE *, const_rtx
, const_rtx
, int, int);
793 debug_rtl_slim (FILE *f
, const_rtx first
, const_rtx last
,
794 int count
, int flags ATTRIBUTE_UNUSED
)
796 const_rtx insn
, tail
;
798 tail
= last
? NEXT_INSN (last
) : NULL_RTX
;
800 (insn
!= NULL
) && (insn
!= tail
) && (count
!= 0);
801 insn
= NEXT_INSN (insn
))
803 dump_insn_slim (f
, insn
);
809 extern void debug_bb_slim (basic_block
);
811 debug_bb_slim (basic_block bb
)
813 dump_bb (stderr
, bb
, 0, TDF_SLIM
| TDF_BLOCKS
);
816 extern void debug_bb_n_slim (int);
818 debug_bb_n_slim (int n
)
820 basic_block bb
= BASIC_BLOCK (n
);