/* Print RTL for GCC.
- Copyright (C) 1987, 1988, 1992, 1997, 1998, 1999, 2000, 2002, 2003, 2004
- Free Software Foundation, Inc.
+ Copyright (C) 1987-2015 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
/* This file is compiled twice: once for the generator programs,
once for the compiler. */
/* These headers all define things which are not available in
generator programs. */
#ifndef GENERATOR_FILE
+#include "alias.h"
+#include "symtab.h"
#include "tree.h"
-#include "real.h"
+#include "print-tree.h"
#include "flags.h"
#include "hard-reg-set.h"
+#include "predict.h"
+#include "function.h"
#include "basic-block.h"
+#include "diagnostic.h"
+#include "tree-pretty-print.h"
+#include "alloc-pool.h"
+#include "cselib.h"
+#include "dumpfile.h" /* for dump_flags */
+#include "dwarf2out.h"
#endif
static FILE *outfile;
static int indent;
-static void print_rtx (rtx);
+static bool in_call_function_usage;
+
+static void print_rtx (const_rtx);
/* String printed at beginning of each RTL when it is dumped.
This string is set to ASM_COMMENT_START when the RTL is dumped in
the assembly output file. */
const char *print_rtx_head = "";
-/* Nonzero means suppress output of instruction numbers and line number
- notes in debugging dumps.
+#ifdef GENERATOR_FILE
+/* These are defined from the .opt file when not used in generator
+ programs. */
+
+/* Nonzero means suppress output of instruction numbers
+ in debugging dumps.
This must be defined here so that programs like gencodes can be linked. */
int flag_dump_unnumbered = 0;
+/* Nonzero means suppress output of instruction numbers for previous
+ and next insns in debugging dumps.
+ This must be defined here so that programs like gencodes can be linked. */
+int flag_dump_unnumbered_links = 0;
+#endif
+
/* Nonzero means use simplified format without flags, modes, etc. */
int flag_simple = 0;
-/* Nonzero if we are dumping graphical description. */
-int dump_for_graph;
-
#ifndef GENERATOR_FILE
-static void
-print_decl_name (FILE *outfile, tree node)
-{
- if (DECL_NAME (node))
- fputs (IDENTIFIER_POINTER (DECL_NAME (node)), outfile);
- else
- {
- if (TREE_CODE (node) == LABEL_DECL && LABEL_DECL_UID (node) != -1)
- fprintf (outfile, "L." HOST_WIDE_INT_PRINT_DEC, LABEL_DECL_UID (node));
- else
- {
- char c = TREE_CODE (node) == CONST_DECL ? 'C' : 'D';
- fprintf (outfile, "%c.%u", c, DECL_UID (node));
- }
- }
-}
-
void
-print_mem_expr (FILE *outfile, tree expr)
+print_mem_expr (FILE *outfile, const_tree expr)
{
- if (TREE_CODE (expr) == COMPONENT_REF)
- {
- if (TREE_OPERAND (expr, 0))
- print_mem_expr (outfile, TREE_OPERAND (expr, 0));
- else
- fputs (" <variable>", outfile);
- fputc ('.', outfile);
- print_decl_name (outfile, TREE_OPERAND (expr, 1));
- }
- else if (TREE_CODE (expr) == INDIRECT_REF)
- {
- fputs (" (*", outfile);
- print_mem_expr (outfile, TREE_OPERAND (expr, 0));
- fputs (")", outfile);
- }
- else if (TREE_CODE (expr) == ALIGN_INDIRECT_REF)
- {
- fputs (" (A*", outfile);
- print_mem_expr (outfile, TREE_OPERAND (expr, 0));
- fputs (")", outfile);
- }
- else if (TREE_CODE (expr) == MISALIGNED_INDIRECT_REF)
- {
- fputs (" (M*", outfile);
- print_mem_expr (outfile, TREE_OPERAND (expr, 0));
- fputs (")", outfile);
- }
- else if (TREE_CODE (expr) == RESULT_DECL)
- fputs (" <result>", outfile);
- else
- {
- fputc (' ', outfile);
- print_decl_name (outfile, expr);
- }
+ fputc (' ', outfile);
+ print_generic_expr (outfile, CONST_CAST_TREE (expr), dump_flags);
}
#endif
/* Print IN_RTX onto OUTFILE. This is the recursive part of printing. */
static void
-print_rtx (rtx in_rtx)
+print_rtx (const_rtx in_rtx)
{
int i = 0;
int j;
}
else if (GET_CODE (in_rtx) > NUM_RTX_CODE)
{
- fprintf (outfile, "(??? bad code %d\n)", GET_CODE (in_rtx));
+ fprintf (outfile, "(??? bad code %d\n%s%*s)", GET_CODE (in_rtx),
+ print_rtx_head, indent * 2, "");
sawclose = 1;
return;
}
is_insn = INSN_P (in_rtx);
- /* When printing in VCG format we write INSNs, NOTE, LABEL, and BARRIER
- in separate nodes and therefore have to handle them special here. */
- if (dump_for_graph
- && (is_insn || NOTE_P (in_rtx)
- || LABEL_P (in_rtx) || BARRIER_P (in_rtx)))
- {
- i = 3;
- indent = 0;
- }
+ /* Print name of expression code. */
+ if (flag_simple && CONST_INT_P (in_rtx))
+ fputc ('(', outfile);
else
+ fprintf (outfile, "(%s", GET_RTX_NAME (GET_CODE (in_rtx)));
+
+ if (! flag_simple)
{
- /* Print name of expression code. */
- if (flag_simple && GET_CODE (in_rtx) == CONST_INT)
- fputc ('(', outfile);
- else
- fprintf (outfile, "(%s", GET_RTX_NAME (GET_CODE (in_rtx)));
+ if (RTX_FLAG (in_rtx, in_struct))
+ fputs ("/s", outfile);
- if (! flag_simple)
- {
- if (RTX_FLAG (in_rtx, in_struct))
- fputs ("/s", outfile);
+ if (RTX_FLAG (in_rtx, volatil))
+ fputs ("/v", outfile);
- if (RTX_FLAG (in_rtx, volatil))
- fputs ("/v", outfile);
+ if (RTX_FLAG (in_rtx, unchanging))
+ fputs ("/u", outfile);
- if (RTX_FLAG (in_rtx, unchanging))
- fputs ("/u", outfile);
+ if (RTX_FLAG (in_rtx, frame_related))
+ fputs ("/f", outfile);
- if (RTX_FLAG (in_rtx, frame_related))
- fputs ("/f", outfile);
+ if (RTX_FLAG (in_rtx, jump))
+ fputs ("/j", outfile);
- if (RTX_FLAG (in_rtx, jump))
- fputs ("/j", outfile);
+ if (RTX_FLAG (in_rtx, call))
+ fputs ("/c", outfile);
- if (RTX_FLAG (in_rtx, call))
- fputs ("/c", outfile);
+ if (RTX_FLAG (in_rtx, return_val))
+ fputs ("/i", outfile);
- if (RTX_FLAG (in_rtx, return_val))
- fputs ("/i", outfile);
+ /* Print REG_NOTE names for EXPR_LIST and INSN_LIST. */
+ if ((GET_CODE (in_rtx) == EXPR_LIST
+ || GET_CODE (in_rtx) == INSN_LIST
+ || GET_CODE (in_rtx) == INT_LIST)
+ && (int)GET_MODE (in_rtx) < REG_NOTE_MAX
+ && !in_call_function_usage)
+ fprintf (outfile, ":%s",
+ GET_REG_NOTE_NAME (GET_MODE (in_rtx)));
- /* Print REG_NOTE names for EXPR_LIST and INSN_LIST. */
- if (GET_CODE (in_rtx) == EXPR_LIST
- || GET_CODE (in_rtx) == INSN_LIST)
- fprintf (outfile, ":%s",
- GET_REG_NOTE_NAME (GET_MODE (in_rtx)));
+ /* For other rtl, print the mode if it's not VOID. */
+ else if (GET_MODE (in_rtx) != VOIDmode)
+ fprintf (outfile, ":%s", GET_MODE_NAME (GET_MODE (in_rtx)));
- /* For other rtl, print the mode if it's not VOID. */
- else if (GET_MODE (in_rtx) != VOIDmode)
- fprintf (outfile, ":%s", GET_MODE_NAME (GET_MODE (in_rtx)));
+#ifndef GENERATOR_FILE
+ if (GET_CODE (in_rtx) == VAR_LOCATION)
+ {
+ if (TREE_CODE (PAT_VAR_LOCATION_DECL (in_rtx)) == STRING_CST)
+ fputs (" <debug string placeholder>", outfile);
+ else
+ print_mem_expr (outfile, PAT_VAR_LOCATION_DECL (in_rtx));
+ fputc (' ', outfile);
+ print_rtx (PAT_VAR_LOCATION_LOC (in_rtx));
+ if (PAT_VAR_LOCATION_STATUS (in_rtx)
+ == VAR_INIT_STATUS_UNINITIALIZED)
+ fprintf (outfile, " [uninit]");
+ sawclose = 1;
+ i = GET_RTX_LENGTH (VAR_LOCATION);
}
+#endif
}
#ifndef GENERATOR_FILE
- if (GET_CODE (in_rtx) == CONST_DOUBLE && FLOAT_MODE_P (GET_MODE (in_rtx)))
+ if (CONST_DOUBLE_AS_FLOAT_P (in_rtx))
i = 5;
#endif
+ if (INSN_CHAIN_CODE_P (GET_CODE (in_rtx)))
+ {
+ if (flag_dump_unnumbered)
+ fprintf (outfile, " #");
+ else
+ fprintf (outfile, " %d", INSN_UID (in_rtx));
+ }
+
/* Get the format string and skip the first elements if we have handled
them already. */
format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx)) + i;
string:
if (str == 0)
- fputs (dump_for_graph ? " \\\"\\\"" : " \"\"", outfile);
+ fputs (" \"\"", outfile);
else
- {
- if (dump_for_graph)
- fprintf (outfile, " (\\\"%s\\\")", str);
- else
- fprintf (outfile, " (\"%s\")", str);
- }
+ fprintf (outfile, " (\"%s\")", str);
sawclose = 1;
break;
An exception is the third field of a NOTE, where it indicates
that the field has several different valid contents. */
case '0':
- if (i == 1 && REG_P (in_rtx))
- {
- if (REGNO (in_rtx) != ORIGINAL_REGNO (in_rtx))
- fprintf (outfile, " [%d]", ORIGINAL_REGNO (in_rtx));
- }
#ifndef GENERATOR_FILE
- else if (i == 1 && GET_CODE (in_rtx) == SYMBOL_REF)
+ if (i == 1 && GET_CODE (in_rtx) == SYMBOL_REF)
{
int flags = SYMBOL_REF_FLAGS (in_rtx);
if (flags)
- fprintf (outfile, " [flags 0x%x]", flags);
- }
- else if (i == 2 && GET_CODE (in_rtx) == SYMBOL_REF)
- {
+ fprintf (outfile, " [flags %#x]", flags);
tree decl = SYMBOL_REF_DECL (in_rtx);
if (decl)
- print_node_brief (outfile, "", decl, 0);
+ print_node_brief (outfile, "", decl, dump_flags);
}
-#endif
- else if (i == 4 && NOTE_P (in_rtx))
+ else if (i == 3 && NOTE_P (in_rtx))
{
- switch (NOTE_LINE_NUMBER (in_rtx))
+ switch (NOTE_KIND (in_rtx))
{
case NOTE_INSN_EH_REGION_BEG:
case NOTE_INSN_EH_REGION_END:
case NOTE_INSN_BLOCK_BEG:
case NOTE_INSN_BLOCK_END:
- fprintf (outfile, " ");
- if (flag_dump_unnumbered)
- fprintf (outfile, "#");
- else
- fprintf (outfile, HOST_PTR_PRINTF,
- (char *) NOTE_BLOCK (in_rtx));
+ dump_addr (outfile, " ", NOTE_BLOCK (in_rtx));
sawclose = 1;
break;
case NOTE_INSN_BASIC_BLOCK:
{
-#ifndef GENERATOR_FILE
basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
if (bb != 0)
fprintf (outfile, " [bb %d]", bb->index);
-#endif
break;
}
- case NOTE_INSN_EXPECTED_VALUE:
- indent += 2;
- if (!sawclose)
- fprintf (outfile, " ");
- print_rtx (NOTE_EXPECTED_VALUE (in_rtx));
- indent -= 2;
- break;
-
case NOTE_INSN_DELETED_LABEL:
+ case NOTE_INSN_DELETED_DEBUG_LABEL:
{
const char *label = NOTE_DELETED_LABEL_NAME (in_rtx);
if (label)
case NOTE_INSN_SWITCH_TEXT_SECTIONS:
{
-#ifndef GENERATOR_FILE
basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
if (bb != 0)
fprintf (outfile, " [bb %d]", bb->index);
-#endif
break;
}
-
+
case NOTE_INSN_VAR_LOCATION:
-#ifndef GENERATOR_FILE
- fprintf (outfile, " (");
- print_mem_expr (outfile, NOTE_VAR_LOCATION_DECL (in_rtx));
- fprintf (outfile, " ");
- print_rtx (NOTE_VAR_LOCATION_LOC (in_rtx));
- fprintf (outfile, ")");
-#endif
+ case NOTE_INSN_CALL_ARG_LOCATION:
+ fputc (' ', outfile);
+ print_rtx (NOTE_VAR_LOCATION (in_rtx));
break;
- default:
- {
- const char * const str = X0STR (in_rtx, i);
+ case NOTE_INSN_CFI:
+ fputc ('\n', outfile);
+ output_cfi_directive (outfile, NOTE_CFI (in_rtx));
+ fputc ('\t', outfile);
+ break;
- if (NOTE_LINE_NUMBER (in_rtx) < 0)
- ;
- else if (str == 0)
- fputs (dump_for_graph ? " \\\"\\\"" : " \"\"", outfile);
- else
- {
- if (dump_for_graph)
- fprintf (outfile, " (\\\"%s\\\")", str);
- else
- fprintf (outfile, " (\"%s\")", str);
- }
- break;
- }
+ default:
+ break;
}
}
+ else if (i == 7 && JUMP_P (in_rtx) && JUMP_LABEL (in_rtx) != NULL)
+ {
+ /* Output the JUMP_LABEL reference. */
+ fprintf (outfile, "\n%s%*s -> ", print_rtx_head, indent * 2, "");
+ if (GET_CODE (JUMP_LABEL (in_rtx)) == RETURN)
+ fprintf (outfile, "return");
+ else if (GET_CODE (JUMP_LABEL (in_rtx)) == SIMPLE_RETURN)
+ fprintf (outfile, "simple_return");
+ else
+ fprintf (outfile, "%d", INSN_UID (JUMP_LABEL (in_rtx)));
+ }
+ else if (i == 0 && GET_CODE (in_rtx) == VALUE)
+ {
+ cselib_val *val = CSELIB_VAL_PTR (in_rtx);
+
+ fprintf (outfile, " %u:%u", val->uid, val->hash);
+ dump_addr (outfile, " @", in_rtx);
+ dump_addr (outfile, "/", (void*)val);
+ }
+ else if (i == 0 && GET_CODE (in_rtx) == DEBUG_EXPR)
+ {
+ fprintf (outfile, " D#%i",
+ DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (in_rtx)));
+ }
+ else if (i == 0 && GET_CODE (in_rtx) == ENTRY_VALUE)
+ {
+ indent += 2;
+ if (!sawclose)
+ fprintf (outfile, " ");
+ print_rtx (ENTRY_VALUE_EXP (in_rtx));
+ indent -= 2;
+ }
+#endif
break;
case 'e':
do_e:
indent += 2;
+ if (i == 6 && INSN_P (in_rtx))
+ /* Put REG_NOTES on their own line. */
+ fprintf (outfile, "\n%s%*s",
+ print_rtx_head, indent * 2, "");
if (!sawclose)
fprintf (outfile, " ");
- print_rtx (XEXP (in_rtx, i));
+ if (i == 7 && CALL_P (in_rtx))
+ {
+ in_call_function_usage = true;
+ print_rtx (XEXP (in_rtx, i));
+ in_call_function_usage = false;
+ }
+ else
+ print_rtx (XEXP (in_rtx, i));
indent -= 2;
break;
fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, XWINT (in_rtx, i));
if (! flag_simple)
fprintf (outfile, " [" HOST_WIDE_INT_PRINT_HEX "]",
- XWINT (in_rtx, i));
+ (unsigned HOST_WIDE_INT) XWINT (in_rtx, i));
break;
case 'i':
if (i == 4 && INSN_P (in_rtx))
{
#ifndef GENERATOR_FILE
- /* Pretty-print insn locators. Ignore scoping as it is mostly
+ const rtx_insn *in_insn = as_a <const rtx_insn *> (in_rtx);
+
+ /* Pretty-print insn locations. Ignore scoping as it is mostly
redundant with line number information and do not print anything
when there is no location information available. */
- if (INSN_LOCATOR (in_rtx) && insn_file (in_rtx))
- fprintf(outfile, " %s:%i", insn_file (in_rtx), insn_line (in_rtx));
+ if (INSN_HAS_LOCATION (in_insn))
+ {
+ expanded_location xloc = insn_location (in_insn);
+ fprintf (outfile, " %s:%i", xloc.file, xloc.line);
+ }
#endif
}
- else if (i == 6 && NOTE_P (in_rtx))
+ else if (i == 6 && GET_CODE (in_rtx) == ASM_OPERANDS)
+ {
+#ifndef GENERATOR_FILE
+ if (ASM_OPERANDS_SOURCE_LOCATION (in_rtx) != UNKNOWN_LOCATION)
+ fprintf (outfile, " %s:%i",
+ LOCATION_FILE (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)),
+ LOCATION_LINE (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)));
+#endif
+ }
+ else if (i == 1 && GET_CODE (in_rtx) == ASM_INPUT)
+ {
+#ifndef GENERATOR_FILE
+ if (ASM_INPUT_SOURCE_LOCATION (in_rtx) != UNKNOWN_LOCATION)
+ fprintf (outfile, " %s:%i",
+ LOCATION_FILE (ASM_INPUT_SOURCE_LOCATION (in_rtx)),
+ LOCATION_LINE (ASM_INPUT_SOURCE_LOCATION (in_rtx)));
+#endif
+ }
+ else if (i == 5 && NOTE_P (in_rtx))
{
/* This field is only used for NOTE_INSN_DELETED_LABEL, and
other times often contains garbage from INSN->NOTE death. */
- if (NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_DELETED_LABEL)
+ if (NOTE_KIND (in_rtx) == NOTE_INSN_DELETED_LABEL
+ || NOTE_KIND (in_rtx) == NOTE_INSN_DELETED_DEBUG_LABEL)
fprintf (outfile, " %d", XINT (in_rtx, i));
}
+#if !defined(GENERATOR_FILE) && NUM_UNSPECV_VALUES > 0
+ else if (i == 1
+ && GET_CODE (in_rtx) == UNSPEC_VOLATILE
+ && XINT (in_rtx, 1) >= 0
+ && XINT (in_rtx, 1) < NUM_UNSPECV_VALUES)
+ fprintf (outfile, " %s", unspecv_strings[XINT (in_rtx, 1)]);
+#endif
+#if !defined(GENERATOR_FILE) && NUM_UNSPEC_VALUES > 0
+ else if (i == 1
+ && (GET_CODE (in_rtx) == UNSPEC
+ || GET_CODE (in_rtx) == UNSPEC_VOLATILE)
+ && XINT (in_rtx, 1) >= 0
+ && XINT (in_rtx, 1) < NUM_UNSPEC_VALUES)
+ fprintf (outfile, " %s", unspec_strings[XINT (in_rtx, 1)]);
+#endif
else
{
int value = XINT (in_rtx, i);
const char *name;
-#ifndef GENERATOR_FILE
- if (REG_P (in_rtx) && value < FIRST_PSEUDO_REGISTER)
- fprintf (outfile, " %d %s", REGNO (in_rtx),
- reg_names[REGNO (in_rtx)]);
- else if (REG_P (in_rtx)
- && value <= LAST_VIRTUAL_REGISTER)
- {
- if (value == VIRTUAL_INCOMING_ARGS_REGNUM)
- fprintf (outfile, " %d virtual-incoming-args", value);
- else if (value == VIRTUAL_STACK_VARS_REGNUM)
- fprintf (outfile, " %d virtual-stack-vars", value);
- else if (value == VIRTUAL_STACK_DYNAMIC_REGNUM)
- fprintf (outfile, " %d virtual-stack-dynamic", value);
- else if (value == VIRTUAL_OUTGOING_ARGS_REGNUM)
- fprintf (outfile, " %d virtual-outgoing-args", value);
- else if (value == VIRTUAL_CFA_REGNUM)
- fprintf (outfile, " %d virtual-cfa", value);
- else
- fprintf (outfile, " %d virtual-reg-%d", value,
- value-FIRST_VIRTUAL_REGISTER);
- }
- else
-#endif
- if (flag_dump_unnumbered
- && (is_insn || NOTE_P (in_rtx)))
+ if (flag_dump_unnumbered
+ && (is_insn || NOTE_P (in_rtx)))
fputc ('#', outfile);
else
fprintf (outfile, " %d", value);
-#ifndef GENERATOR_FILE
- if (REG_P (in_rtx) && REG_ATTRS (in_rtx))
- {
- fputs (" [", outfile);
- if (ORIGINAL_REGNO (in_rtx) != REGNO (in_rtx))
- fprintf (outfile, "orig:%i", ORIGINAL_REGNO (in_rtx));
- if (REG_EXPR (in_rtx))
- print_mem_expr (outfile, REG_EXPR (in_rtx));
-
- if (REG_OFFSET (in_rtx))
- fprintf (outfile, "+" HOST_WIDE_INT_PRINT_DEC,
- REG_OFFSET (in_rtx));
- fputs (" ]", outfile);
- }
-#endif
-
if (is_insn && &INSN_CODE (in_rtx) == &XINT (in_rtx, i)
&& XINT (in_rtx, i) >= 0
&& (name = get_insn_name (XINT (in_rtx, i))) != NULL)
}
break;
+ case 'r':
+ {
+ unsigned int regno = REGNO (in_rtx);
+#ifndef GENERATOR_FILE
+ if (regno < FIRST_PSEUDO_REGISTER)
+ fprintf (outfile, " %d %s", regno, reg_names[regno]);
+ else if (regno <= LAST_VIRTUAL_REGISTER)
+ {
+ if (regno == VIRTUAL_INCOMING_ARGS_REGNUM)
+ fprintf (outfile, " %d virtual-incoming-args", regno);
+ else if (regno == VIRTUAL_STACK_VARS_REGNUM)
+ fprintf (outfile, " %d virtual-stack-vars", regno);
+ else if (regno == VIRTUAL_STACK_DYNAMIC_REGNUM)
+ fprintf (outfile, " %d virtual-stack-dynamic", regno);
+ else if (regno == VIRTUAL_OUTGOING_ARGS_REGNUM)
+ fprintf (outfile, " %d virtual-outgoing-args", regno);
+ else if (regno == VIRTUAL_CFA_REGNUM)
+ fprintf (outfile, " %d virtual-cfa", regno);
+ else if (regno == VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM)
+ fprintf (outfile, " %d virtual-preferred-stack-boundary",
+ regno);
+ else
+ fprintf (outfile, " %d virtual-reg-%d", regno,
+ regno-FIRST_VIRTUAL_REGISTER);
+ }
+ else
+#endif
+ if (flag_dump_unnumbered && is_insn)
+ fputc ('#', outfile);
+ else
+ fprintf (outfile, " %d", regno);
+
+#ifndef GENERATOR_FILE
+ if (REG_ATTRS (in_rtx))
+ {
+ fputs (" [", outfile);
+ if (regno != ORIGINAL_REGNO (in_rtx))
+ fprintf (outfile, "orig:%i", ORIGINAL_REGNO (in_rtx));
+ if (REG_EXPR (in_rtx))
+ print_mem_expr (outfile, REG_EXPR (in_rtx));
+
+ if (REG_OFFSET (in_rtx))
+ fprintf (outfile, "+" HOST_WIDE_INT_PRINT_DEC,
+ REG_OFFSET (in_rtx));
+ fputs (" ]", outfile);
+ }
+ if (regno != ORIGINAL_REGNO (in_rtx))
+ fprintf (outfile, " [%d]", ORIGINAL_REGNO (in_rtx));
+#endif
+ break;
+ }
+
/* Print NOTE_INSN names rather than integer codes. */
case 'n':
- if (XINT (in_rtx, i) >= (int) NOTE_INSN_BIAS
- && XINT (in_rtx, i) < (int) NOTE_INSN_MAX)
- fprintf (outfile, " %s", GET_NOTE_INSN_NAME (XINT (in_rtx, i)));
- else
- fprintf (outfile, " %d", XINT (in_rtx, i));
+ fprintf (outfile, " %s", GET_NOTE_INSN_NAME (XINT (in_rtx, i)));
sawclose = 0;
break;
if (GET_CODE (in_rtx) == LABEL_REF)
{
if (subc == NOTE
- && NOTE_LINE_NUMBER (sub) == NOTE_INSN_DELETED_LABEL)
+ && NOTE_KIND (sub) == NOTE_INSN_DELETED_LABEL)
{
if (flag_dump_unnumbered)
fprintf (outfile, " [# deleted]");
goto do_e;
}
- if (flag_dump_unnumbered)
+ if (flag_dump_unnumbered
+ || (flag_dump_unnumbered_links && (i == 1 || i == 2)
+ && (INSN_P (in_rtx) || NOTE_P (in_rtx)
+ || LABEL_P (in_rtx) || BARRIER_P (in_rtx))))
fputs (" #", outfile);
else
fprintf (outfile, " %d", INSN_UID (sub));
sawclose = 0;
break;
- case 'b':
+ case 't':
#ifndef GENERATOR_FILE
- if (XBITMAP (in_rtx, i) == NULL)
- fputs (" {null}", outfile);
+ if (i == 0 && GET_CODE (in_rtx) == DEBUG_IMPLICIT_PTR)
+ print_mem_expr (outfile, DEBUG_IMPLICIT_PTR_DECL (in_rtx));
+ else if (i == 0 && GET_CODE (in_rtx) == DEBUG_PARAMETER_REF)
+ print_mem_expr (outfile, DEBUG_PARAMETER_REF_DECL (in_rtx));
else
- bitmap_print (outfile, XBITMAP (in_rtx, i), " {", "}");
+ dump_addr (outfile, " ", XTREE (in_rtx, i));
#endif
- sawclose = 0;
- break;
-
- case 't':
- fprintf (outfile, " " HOST_PTR_PRINTF, (void *) XTREE (in_rtx, i));
break;
case '*':
break;
default:
- fprintf (stderr,
- "switch format wrong in rtl.print_rtx(). format was: %c.\n",
- format_ptr[-1]);
- abort ();
+ gcc_unreachable ();
}
switch (GET_CODE (in_rtx))
{
#ifndef GENERATOR_FILE
case MEM:
- fprintf (outfile, " [" HOST_WIDE_INT_PRINT_DEC, MEM_ALIAS_SET (in_rtx));
+ if (__builtin_expect (final_insns_dump_p, false))
+ fprintf (outfile, " [");
+ else
+ fprintf (outfile, " [" HOST_WIDE_INT_PRINT_DEC,
+ (HOST_WIDE_INT) MEM_ALIAS_SET (in_rtx));
if (MEM_EXPR (in_rtx))
print_mem_expr (outfile, MEM_EXPR (in_rtx));
+ else
+ fputc (' ', outfile);
- if (MEM_OFFSET (in_rtx))
- fprintf (outfile, "+" HOST_WIDE_INT_PRINT_DEC,
- INTVAL (MEM_OFFSET (in_rtx)));
+ if (MEM_OFFSET_KNOWN_P (in_rtx))
+ fprintf (outfile, "+" HOST_WIDE_INT_PRINT_DEC, MEM_OFFSET (in_rtx));
- if (MEM_SIZE (in_rtx))
- fprintf (outfile, " S" HOST_WIDE_INT_PRINT_DEC,
- INTVAL (MEM_SIZE (in_rtx)));
+ if (MEM_SIZE_KNOWN_P (in_rtx))
+ fprintf (outfile, " S" HOST_WIDE_INT_PRINT_DEC, MEM_SIZE (in_rtx));
if (MEM_ALIGN (in_rtx) != 1)
fprintf (outfile, " A%u", MEM_ALIGN (in_rtx));
+ if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (in_rtx)))
+ fprintf (outfile, " AS%u", MEM_ADDR_SPACE (in_rtx));
+
fputc (']', outfile);
break;
fprintf (outfile, " [%s]", s);
}
break;
+
+ case CONST_WIDE_INT:
+ fprintf (outfile, " ");
+ cwi_output_hex (outfile, in_rtx);
+ break;
#endif
case CODE_LABEL:
break;
}
- if (dump_for_graph
- && (is_insn || NOTE_P (in_rtx)
- || LABEL_P (in_rtx) || BARRIER_P (in_rtx)))
- sawclose = 0;
- else
- {
- fputc (')', outfile);
- sawclose = 1;
- }
+ fputc (')', outfile);
+ sawclose = 1;
}
/* Print an rtx on the current line of FILE. Initially indent IND
characters. */
void
-print_inline_rtx (FILE *outf, rtx x, int ind)
+print_inline_rtx (FILE *outf, const_rtx x, int ind)
{
int oldsaw = sawclose;
int oldindent = indent;
/* Call this function from the debugger to see what X looks like. */
-void
-debug_rtx (rtx x)
+DEBUG_FUNCTION void
+debug_rtx (const_rtx x)
{
outfile = stderr;
sawclose = 0;
fprintf (stderr, "\n");
}
+/* Dump rtx REF. */
+
+DEBUG_FUNCTION void
+debug (const rtx_def &ref)
+{
+ debug_rtx (&ref);
+}
+
+DEBUG_FUNCTION void
+debug (const rtx_def *ptr)
+{
+ if (ptr)
+ debug (*ptr);
+ else
+ fprintf (stderr, "<nil>\n");
+}
+
/* Count of rtx's to print with debug_rtx_list.
This global exists because gdb user defined commands have no arguments. */
-int debug_rtx_count = 0; /* 0 is treated as equivalent to 1 */
+DEBUG_VARIABLE int debug_rtx_count = 0; /* 0 is treated as equivalent to 1 */
/* Call this function to print list from X on.
N is a count of the rtx's to print. Positive values print from the specified
- rtx on. Negative values print a window around the rtx.
- EG: -5 prints 2 rtx's on either side (in addition to the specified rtx). */
+ rtx_insn on. Negative values print a window around the rtx_insn.
+ EG: -5 prints 2 rtx_insn's on either side (in addition to the specified
+ rtx_insn). */
-void
-debug_rtx_list (rtx x, int n)
+DEBUG_FUNCTION void
+debug_rtx_list (const rtx_insn *x, int n)
{
int i,count;
- rtx insn;
+ const rtx_insn *insn;
count = n == 0 ? 1 : n < 0 ? -n : n;
}
}
-/* Call this function to print an rtx list from START to END inclusive. */
+/* Call this function to print an rtx_insn list from START to END
+ inclusive. */
-void
-debug_rtx_range (rtx start, rtx end)
+DEBUG_FUNCTION void
+debug_rtx_range (const rtx_insn *start, const rtx_insn *end)
{
while (1)
{
}
}
-/* Call this function to search an rtx list to find one with insn uid UID,
+/* Call this function to search an rtx_insn list to find one with insn uid UID,
and then call debug_rtx_list to print it, using DEBUG_RTX_COUNT.
The found insn is returned to enable further debugging analysis. */
-rtx
-debug_rtx_find (rtx x, int uid)
+DEBUG_FUNCTION const rtx_insn *
+debug_rtx_find (const rtx_insn *x, int uid)
{
while (x != 0 && INSN_UID (x) != uid)
x = NEXT_INSN (x);
If RTX_FIRST is not an insn, then it alone is printed, with no newline. */
void
-print_rtl (FILE *outf, rtx rtx_first)
+print_rtl (FILE *outf, const_rtx rtx_first)
{
- rtx tmp_rtx;
+ const rtx_insn *tmp_rtx;
outfile = outf;
sawclose = 0;
case CALL_INSN:
case NOTE:
case CODE_LABEL:
+ case JUMP_TABLE_DATA:
case BARRIER:
- for (tmp_rtx = rtx_first; tmp_rtx != 0; tmp_rtx = NEXT_INSN (tmp_rtx))
- if (! flag_dump_unnumbered
- || !NOTE_P (tmp_rtx) || NOTE_LINE_NUMBER (tmp_rtx) < 0)
- {
- fputs (print_rtx_head, outfile);
- print_rtx (tmp_rtx);
- fprintf (outfile, "\n");
- }
+ for (tmp_rtx = as_a <const rtx_insn *> (rtx_first);
+ tmp_rtx != 0;
+ tmp_rtx = NEXT_INSN (tmp_rtx))
+ {
+ fputs (print_rtx_head, outfile);
+ print_rtx (tmp_rtx);
+ fprintf (outfile, "\n");
+ }
break;
default:
/* Return nonzero if we actually printed anything. */
int
-print_rtl_single (FILE *outf, rtx x)
+print_rtl_single (FILE *outf, const_rtx x)
{
+ return print_rtl_single_with_indent (outf, x, 0);
+}
+
+/* Like print_rtl_single, except specify a file and indentation. */
+
+int
+print_rtl_single_with_indent (FILE *outf, const_rtx x, int ind)
+{
+ int old_indent = indent;
+ char *s_indent = (char *) alloca ((size_t) ind + 1);
+ memset ((void *) s_indent, ' ', (size_t) ind);
+ s_indent[ind] = '\0';
+
+ indent = ind;
outfile = outf;
sawclose = 0;
- if (! flag_dump_unnumbered
- || !NOTE_P (x) || NOTE_LINE_NUMBER (x) < 0)
- {
- fputs (print_rtx_head, outfile);
- print_rtx (x);
- putc ('\n', outf);
- return 1;
- }
- return 0;
+ fputs (s_indent, outfile);
+ fputs (print_rtx_head, outfile);
+ print_rtx (x);
+ putc ('\n', outf);
+ indent = old_indent;
+ return 1;
}
if RTX is a CONST_INT then print in decimal format. */
void
-print_simple_rtl (FILE *outf, rtx x)
+print_simple_rtl (FILE *outf, const_rtx x)
{
flag_simple = 1;
print_rtl (outf, x);