/* Printing of RTL in "slim", mnemonic like form.
- Copyright (C) 1992-2013 Free Software Foundation, Inc.
+ Copyright (C) 1992-2015 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
and currently maintained by, Jim Wilson (wilson@cygnus.com)
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
+#include "alias.h"
+#include "symtab.h"
#include "tree.h" /* FIXME: To dump INSN_VAR_LOCATION_DECL. */
+#include "predict.h"
+#include "hard-reg-set.h"
+#include "function.h"
+#include "dominance.h"
+#include "cfg.h"
#include "basic-block.h"
#include "dumpfile.h" /* for the TDF_* flags */
#include "pretty-print.h"
It is also possible to obtain a string for a single pattern as a string
pointer, via str_pattern_slim, but this usage is discouraged. */
-/* A pretty-printer for slim rtl printing. */
-static bool rtl_slim_pp_initialized = false;
-static pretty_printer rtl_slim_pp;
-
/* For insns we print patterns, and for some patterns we print insns... */
-static void print_insn_with_notes (pretty_printer *, const_rtx);
+static void print_insn_with_notes (pretty_printer *, const rtx_insn *);
/* This recognizes rtx'en classified as expressions. These are always
represent some action on values or results of other expression, that
pp_string (pp, "unspec");
if (GET_CODE (x) == UNSPEC_VOLATILE)
pp_string (pp, "/v");
- pp_character (pp, '[');
+ pp_left_bracket (pp);
for (i = 0; i < XVECLEN (x, 0); i++)
{
if (i != 0)
- pp_character (pp, ',');
+ pp_comma (pp);
print_pattern (pp, XVECEXP (x, 0, i), verbose);
}
pp_string (pp, "] ");
if (fun)
{
pp_string (pp, fun);
- pp_character (pp, '(');
+ pp_left_paren (pp);
}
for (i = 0; i < 4; i++)
if (op[i])
{
if (fun && i != 0)
- pp_character (pp, ',');
+ pp_comma (pp);
print_value (pp, op[i], verbose);
}
}
if (fun)
- pp_character (pp, ')');
+ pp_right_paren (pp);
} /* print_exp */
/* Prints rtxes, I customarily classified as values. They're constants,
pp_scalar (pp, HOST_WIDE_INT_PRINT_HEX,
(unsigned HOST_WIDE_INT) INTVAL (x));
break;
+
+ case CONST_WIDE_INT:
+ {
+ const char *sep = "<";
+ int i;
+ for (i = CONST_WIDE_INT_NUNITS (x) - 1; i >= 0; i--)
+ {
+ pp_string (pp, sep);
+ sep = ",";
+ sprintf (tmp, HOST_WIDE_INT_PRINT_HEX,
+ (unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (x, i));
+ pp_string (pp, tmp);
+ }
+ pp_greater (pp);
+ }
+ break;
+
case CONST_DOUBLE:
if (FLOAT_MODE_P (GET_MODE (x)))
{
pp_printf (pp, "`%s'", XSTR (x, 0));
break;
case LABEL_REF:
- pp_printf (pp, "L%d", INSN_UID (XEXP (x, 0)));
+ pp_printf (pp, "L%d", INSN_UID (LABEL_REF_LABEL (x)));
break;
case CONST:
case HIGH:
case STRICT_LOW_PART:
pp_printf (pp, "%s(", GET_RTX_NAME (GET_CODE (x)));
print_value (pp, XEXP (x, 0), verbose);
- pp_character (pp, ')');
+ pp_right_paren (pp);
break;
case REG:
if (REGNO (x) < FIRST_PSEUDO_REGISTER)
{
if (ISDIGIT (reg_names[REGNO (x)][0]))
- pp_character (pp, '%');
+ pp_modulo (pp);
pp_string (pp, reg_names[REGNO (x)]);
}
else
pp_string (pp, GET_RTX_NAME (GET_CODE (x)));
break;
case MEM:
- pp_character (pp, '[');
+ pp_left_bracket (pp);
print_value (pp, XEXP (x, 0), verbose);
- pp_character (pp, ']');
+ pp_right_bracket (pp);
break;
case DEBUG_EXPR:
pp_printf (pp, "D#%i", DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x)));
{
case SET:
print_value (pp, SET_DEST (x), verbose);
- pp_character (pp, '=');
+ pp_equal (pp);
print_value (pp, SET_SRC (x), verbose);
break;
case RETURN:
print_value (pp, PAT_VAR_LOCATION_LOC (x), verbose);
break;
case COND_EXEC:
- pp_character (pp, '(');
+ pp_left_paren (pp);
if (GET_CODE (COND_EXEC_TEST (x)) == NE
&& XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
print_value (pp, XEXP (COND_EXEC_TEST (x), 0), verbose);
else if (GET_CODE (COND_EXEC_TEST (x)) == EQ
&& XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
{
- pp_character (pp, '!');
+ pp_exclamation (pp);
print_value (pp, XEXP (COND_EXEC_TEST (x), 0), verbose);
}
else
{
int i;
- pp_character (pp, '{');
+ pp_left_brace (pp);
for (i = 0; i < XVECLEN (x, 0); i++)
{
print_pattern (pp, XVECEXP (x, 0, i), verbose);
- pp_character (pp, ';');
+ pp_semicolon (pp);
}
- pp_character (pp, '}');
+ pp_right_brace (pp);
}
break;
case SEQUENCE:
{
+ const rtx_sequence *seq = as_a <const rtx_sequence *> (x);
pp_string (pp, "sequence{");
- if (INSN_P (XVECEXP (x, 0, 0)))
+ if (INSN_P (seq->element (0)))
{
/* Print the sequence insns indented. */
const char * save_print_rtx_head = print_rtx_head;
sizeof (indented_print_rtx_head),
"%s ", print_rtx_head);
print_rtx_head = indented_print_rtx_head;
- for (int i = 0; i < XVECLEN (x, 0); i++)
- print_insn_with_notes (pp, XVECEXP (x, 0, i));
+ for (int i = 0; i < seq->len (); i++)
+ print_insn_with_notes (pp, seq->insn (i));
pp_printf (pp, "%s ", save_print_rtx_head);
print_rtx_head = save_print_rtx_head;
}
else
{
- for (int i = 0; i < XVECLEN (x, 0); i++)
+ for (int i = 0; i < seq->len (); i++)
{
- print_pattern (pp, XVECEXP (x, 0, i), verbose);
- pp_character (pp, ';');
+ print_pattern (pp, seq->element (i), verbose);
+ pp_semicolon (pp);
}
}
- pp_character (pp, '}');
+ pp_right_brace (pp);
}
break;
case ASM_INPUT:
pp_printf (pp, "asm {%s}", XSTR (x, 0));
break;
case ADDR_VEC:
- /* Fall through. */
+ for (int i = 0; i < XVECLEN (x, 0); i++)
+ {
+ print_value (pp, XVECEXP (x, 0, i), verbose);
+ pp_semicolon (pp);
+ }
+ break;
case ADDR_DIFF_VEC:
- print_value (pp, XEXP (x, 0), verbose);
+ for (int i = 0; i < XVECLEN (x, 1); i++)
+ {
+ print_value (pp, XVECEXP (x, 1, i), verbose);
+ pp_semicolon (pp);
+ }
break;
case TRAP_IF:
pp_string (pp, "trap_if ");
with their INSN_UIDs. */
void
-print_insn (pretty_printer *pp, const_rtx x, int verbose)
+print_insn (pretty_printer *pp, const rtx_insn *x, int verbose)
{
if (verbose)
{
case JUMP_TABLE_DATA:
pp_string (pp, "jump_table_data{\n");
print_pattern (pp, PATTERN (x), verbose);
- pp_string (pp, "}");
+ pp_right_brace (pp);
break;
case BARRIER:
pp_string (pp, "barrier");
case NOTE_INSN_VAR_LOCATION:
case NOTE_INSN_CALL_ARG_LOCATION:
- pp_character (pp, '{');
+ pp_left_brace (pp);
print_pattern (pp, NOTE_VAR_LOCATION (x), verbose);
- pp_character (pp, '}');
+ pp_right_brace (pp);
break;
default:
note attached to the instruction. */
static void
-print_insn_with_notes (pretty_printer *pp, const_rtx x)
+print_insn_with_notes (pretty_printer *pp, const rtx_insn *x)
{
pp_string (pp, print_rtx_head);
print_insn (pp, x, 1);
{
pp_printf (pp, "%s %s ", print_rtx_head,
GET_REG_NOTE_NAME (REG_NOTE_KIND (note)));
- print_pattern (pp, XEXP (note, 0), 1);
+ if (GET_CODE (note) == INT_LIST)
+ pp_printf (pp, "%d", XINT (note, 0));
+ else
+ print_pattern (pp, XEXP (note, 0), 1);
pp_newline (pp);
}
}
-/* Return a pretty-print buffer set up to print to file F. */
-
-static pretty_printer *
-init_rtl_slim_pretty_print (FILE *f)
-{
- if (! rtl_slim_pp_initialized)
- {
- pp_construct (&rtl_slim_pp, /*prefix=*/NULL, /*linewidth=*/0);
- rtl_slim_pp_initialized = true;
- }
- else
- /* Clean out any data that str_insn_slim may have left here. */
- pp_clear_output_area (&rtl_slim_pp);
-
- rtl_slim_pp.buffer->stream = f;
- return &rtl_slim_pp;
-}
-
/* Print X, an RTL value node, to file F in slim format. Include
additional information if VERBOSE is nonzero.
void
dump_value_slim (FILE *f, const_rtx x, int verbose)
{
- pretty_printer *pp = init_rtl_slim_pretty_print (f);
- print_value (pp, x, verbose);
- pp_flush (pp);
+ pretty_printer rtl_slim_pp;
+ rtl_slim_pp.buffer->stream = f;
+ print_value (&rtl_slim_pp, x, verbose);
+ pp_flush (&rtl_slim_pp);
}
/* Emit a slim dump of X (an insn) to the file F, including any register
note attached to the instruction. */
void
-dump_insn_slim (FILE *f, const_rtx x)
+dump_insn_slim (FILE *f, const rtx_insn *x)
{
- pretty_printer *pp = init_rtl_slim_pretty_print (f);
- print_insn_with_notes (pp, x);
- pp_flush (pp);
+ pretty_printer rtl_slim_pp;
+ rtl_slim_pp.buffer->stream = f;
+ print_insn_with_notes (&rtl_slim_pp, x);
+ pp_flush (&rtl_slim_pp);
}
/* Same as above, but stop at LAST or when COUNT == 0.
If COUNT < 0 it will stop only at LAST or NULL rtx. */
void
-dump_rtl_slim (FILE *f, const_rtx first, const_rtx last,
+dump_rtl_slim (FILE *f, const rtx_insn *first, const rtx_insn *last,
int count, int flags ATTRIBUTE_UNUSED)
{
- const_rtx insn, tail;
- pretty_printer *pp = init_rtl_slim_pretty_print (f);
+ const rtx_insn *insn, *tail;
+ pretty_printer rtl_slim_pp;
+ rtl_slim_pp.buffer->stream = f;
- tail = last ? NEXT_INSN (last) : NULL_RTX;
+ tail = last ? NEXT_INSN (last) : NULL;
for (insn = first;
(insn != NULL) && (insn != tail) && (count != 0);
insn = NEXT_INSN (insn))
{
- print_insn_with_notes (pp, insn);
+ print_insn_with_notes (&rtl_slim_pp, insn);
if (count > 0)
count--;
}
- pp_flush (pp);
+ pp_flush (&rtl_slim_pp);
}
/* Dumps basic block BB to pretty-printer PP in slim form and without and
void
rtl_dump_bb_for_graph (pretty_printer *pp, basic_block bb)
{
- rtx insn;
+ rtx_insn *insn;
bool first = true;
/* TODO: inter-bb stuff. */
{
if (! first)
{
- pp_character (pp, '|');
+ pp_bar (pp);
pp_write_text_to_stream (pp);
}
first = false;
const char *
str_pattern_slim (const_rtx x)
{
- pretty_printer *pp = init_rtl_slim_pretty_print (NULL);
- print_pattern (pp, x, 0);
- return pp_base_formatted_text (pp);
+ pretty_printer rtl_slim_pp;
+ print_pattern (&rtl_slim_pp, x, 0);
+ return ggc_strdup (pp_formatted_text (&rtl_slim_pp));
}
/* Emit a slim dump of X (an insn) to stderr. */
-extern void debug_insn_slim (const_rtx);
+extern void debug_insn_slim (const rtx_insn *);
DEBUG_FUNCTION void
-debug_insn_slim (const_rtx x)
+debug_insn_slim (const rtx_insn *x)
{
dump_insn_slim (stderr, x);
}
/* Same as above, but using dump_rtl_slim. */
-extern void debug_rtl_slim (FILE *, const_rtx, const_rtx, int, int);
+extern void debug_rtl_slim (FILE *, const rtx_insn *, const rtx_insn *,
+ int, int);
DEBUG_FUNCTION void
-debug_rtl_slim (const_rtx first, const_rtx last, int count, int flags)
+debug_rtl_slim (const rtx_insn *first, const rtx_insn *last, int count,
+ int flags)
{
dump_rtl_slim (stderr, first, last, count, flags);
}
DEBUG_FUNCTION void
debug_bb_n_slim (int n)
{
- basic_block bb = BASIC_BLOCK (n);
+ basic_block bb = BASIC_BLOCK_FOR_FN (cfun, n);
debug_bb_slim (bb);
}