123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868 |
- /* Print RTL for GCC.
- 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 3, or (at your option) any later
- version.
- GCC is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- for more details.
- You should have received a copy of the GNU General Public License
- 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. */
- #ifdef GENERATOR_FILE
- #include "bconfig.h"
- #else
- #include "config.h"
- #endif
- #include "system.h"
- #include "coretypes.h"
- #include "tm.h"
- #include "rtl.h"
- /* These headers all define things which are not available in
- generator programs. */
- #ifndef GENERATOR_FILE
- #include "hash-set.h"
- #include "machmode.h"
- #include "vec.h"
- #include "double-int.h"
- #include "input.h"
- #include "alias.h"
- #include "symtab.h"
- #include "wide-int.h"
- #include "inchash.h"
- #include "tree.h"
- #include "print-tree.h"
- #include "flags.h"
- #include "hard-reg-set.h"
- #include "predict.h"
- #include "input.h"
- #include "function.h"
- #include "basic-block.h"
- #include "diagnostic.h"
- #include "tree-pretty-print.h"
- #include "cselib.h"
- #include "dumpfile.h" /* for dump_flags */
- #include "dwarf2out.h"
- #endif
- static FILE *outfile;
- static int sawclose = 0;
- static int indent;
- 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 = "";
- #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;
- #ifndef GENERATOR_FILE
- void
- print_mem_expr (FILE *outfile, const_tree 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 (const_rtx in_rtx)
- {
- int i = 0;
- int j;
- const char *format_ptr;
- int is_insn;
- if (sawclose)
- {
- if (flag_simple)
- fputc (' ', outfile);
- else
- fprintf (outfile, "\n%s%*s", print_rtx_head, indent * 2, "");
- sawclose = 0;
- }
- if (in_rtx == 0)
- {
- fputs ("(nil)", outfile);
- sawclose = 1;
- return;
- }
- else if (GET_CODE (in_rtx) > NUM_RTX_CODE)
- {
- 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);
- /* 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)
- {
- if (RTX_FLAG (in_rtx, in_struct))
- fputs ("/s", outfile);
- if (RTX_FLAG (in_rtx, volatil))
- fputs ("/v", 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, jump))
- fputs ("/j", outfile);
- if (RTX_FLAG (in_rtx, call))
- fputs ("/c", 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)));
- /* 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 (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;
- for (; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++)
- switch (*format_ptr++)
- {
- const char *str;
- case 'T':
- str = XTMPL (in_rtx, i);
- goto string;
- case 'S':
- case 's':
- str = XSTR (in_rtx, i);
- string:
- if (str == 0)
- fputs (" \"\"", outfile);
- else
- fprintf (outfile, " (\"%s\")", str);
- sawclose = 1;
- break;
- /* 0 indicates a field for internal use that should not be printed.
- An exception is the third field of a NOTE, where it indicates
- that the field has several different valid contents. */
- case '0':
- #ifndef GENERATOR_FILE
- if (i == 1 && GET_CODE (in_rtx) == SYMBOL_REF)
- {
- int flags = SYMBOL_REF_FLAGS (in_rtx);
- if (flags)
- fprintf (outfile, " [flags %#x]", flags);
- tree decl = SYMBOL_REF_DECL (in_rtx);
- if (decl)
- print_node_brief (outfile, "", decl, dump_flags);
- }
- else if (i == 3 && NOTE_P (in_rtx))
- {
- switch (NOTE_KIND (in_rtx))
- {
- case NOTE_INSN_EH_REGION_BEG:
- case NOTE_INSN_EH_REGION_END:
- if (flag_dump_unnumbered)
- fprintf (outfile, " #");
- else
- fprintf (outfile, " %d", NOTE_EH_HANDLER (in_rtx));
- sawclose = 1;
- break;
- case NOTE_INSN_BLOCK_BEG:
- case NOTE_INSN_BLOCK_END:
- dump_addr (outfile, " ", NOTE_BLOCK (in_rtx));
- sawclose = 1;
- break;
- case NOTE_INSN_BASIC_BLOCK:
- {
- basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
- if (bb != 0)
- fprintf (outfile, " [bb %d]", bb->index);
- break;
- }
- case NOTE_INSN_DELETED_LABEL:
- case NOTE_INSN_DELETED_DEBUG_LABEL:
- {
- const char *label = NOTE_DELETED_LABEL_NAME (in_rtx);
- if (label)
- fprintf (outfile, " (\"%s\")", label);
- else
- fprintf (outfile, " \"\"");
- }
- break;
- case NOTE_INSN_SWITCH_TEXT_SECTIONS:
- {
- basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
- if (bb != 0)
- fprintf (outfile, " [bb %d]", bb->index);
- break;
- }
- case NOTE_INSN_VAR_LOCATION:
- case NOTE_INSN_CALL_ARG_LOCATION:
- fputc (' ', outfile);
- print_rtx (NOTE_VAR_LOCATION (in_rtx));
- break;
- case NOTE_INSN_CFI:
- fputc ('\n', outfile);
- output_cfi_directive (outfile, NOTE_CFI (in_rtx));
- fputc ('\t', outfile);
- 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, " ");
- 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;
- case 'E':
- case 'V':
- indent += 2;
- if (sawclose)
- {
- fprintf (outfile, "\n%s%*s",
- print_rtx_head, indent * 2, "");
- sawclose = 0;
- }
- fputs (" [", outfile);
- if (NULL != XVEC (in_rtx, i))
- {
- indent += 2;
- if (XVECLEN (in_rtx, i))
- sawclose = 1;
- for (j = 0; j < XVECLEN (in_rtx, i); j++)
- print_rtx (XVECEXP (in_rtx, i, j));
- indent -= 2;
- }
- if (sawclose)
- fprintf (outfile, "\n%s%*s", print_rtx_head, indent * 2, "");
- fputs ("]", outfile);
- sawclose = 1;
- indent -= 2;
- break;
- case 'w':
- if (! flag_simple)
- fprintf (outfile, " ");
- fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, XWINT (in_rtx, i));
- if (! flag_simple)
- fprintf (outfile, " [" HOST_WIDE_INT_PRINT_HEX "]",
- (unsigned HOST_WIDE_INT) XWINT (in_rtx, i));
- break;
- case 'i':
- if (i == 4 && INSN_P (in_rtx))
- {
- #ifndef GENERATOR_FILE
- 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_HAS_LOCATION (in_insn))
- {
- expanded_location xloc = insn_location (in_insn);
- fprintf (outfile, " %s:%i", xloc.file, xloc.line);
- }
- #endif
- }
- 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_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) && (unsigned) value < FIRST_PSEUDO_REGISTER)
- fprintf (outfile, " %d %s", value, reg_names[value]);
- else if (REG_P (in_rtx)
- && (unsigned) 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 if (value == VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM)
- fprintf (outfile, " %d virtual-preferred-stack-boundary",
- 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)))
- 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);
- }
- if (REG_P (in_rtx) && REGNO (in_rtx) != ORIGINAL_REGNO (in_rtx))
- fprintf (outfile, " [%d]", ORIGINAL_REGNO (in_rtx));
- #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)
- fprintf (outfile, " {%s}", name);
- sawclose = 0;
- }
- break;
- /* Print NOTE_INSN names rather than integer codes. */
- case 'n':
- fprintf (outfile, " %s", GET_NOTE_INSN_NAME (XINT (in_rtx, i)));
- sawclose = 0;
- break;
- case 'u':
- if (XEXP (in_rtx, i) != NULL)
- {
- rtx sub = XEXP (in_rtx, i);
- enum rtx_code subc = GET_CODE (sub);
- if (GET_CODE (in_rtx) == LABEL_REF)
- {
- if (subc == NOTE
- && NOTE_KIND (sub) == NOTE_INSN_DELETED_LABEL)
- {
- if (flag_dump_unnumbered)
- fprintf (outfile, " [# deleted]");
- else
- fprintf (outfile, " [%d deleted]", INSN_UID (sub));
- sawclose = 0;
- break;
- }
- if (subc != CODE_LABEL)
- goto do_e;
- }
- 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));
- }
- else
- fputs (" 0", outfile);
- sawclose = 0;
- break;
- case 't':
- #ifndef GENERATOR_FILE
- 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
- dump_addr (outfile, " ", XTREE (in_rtx, i));
- #endif
- break;
- case '*':
- fputs (" Unknown", outfile);
- sawclose = 0;
- break;
- case 'B':
- #ifndef GENERATOR_FILE
- if (XBBDEF (in_rtx, i))
- fprintf (outfile, " %i", XBBDEF (in_rtx, i)->index);
- #endif
- break;
- default:
- gcc_unreachable ();
- }
- switch (GET_CODE (in_rtx))
- {
- #ifndef GENERATOR_FILE
- case MEM:
- 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_KNOWN_P (in_rtx))
- fprintf (outfile, "+" HOST_WIDE_INT_PRINT_DEC, MEM_OFFSET (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;
- case CONST_DOUBLE:
- if (FLOAT_MODE_P (GET_MODE (in_rtx)))
- {
- char s[60];
- real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (in_rtx),
- sizeof (s), 0, 1);
- fprintf (outfile, " %s", s);
- real_to_hexadecimal (s, CONST_DOUBLE_REAL_VALUE (in_rtx),
- sizeof (s), 0, 1);
- fprintf (outfile, " [%s]", s);
- }
- break;
- case CONST_WIDE_INT:
- fprintf (outfile, " ");
- cwi_output_hex (outfile, in_rtx);
- break;
- #endif
- case CODE_LABEL:
- fprintf (outfile, " [%d uses]", LABEL_NUSES (in_rtx));
- switch (LABEL_KIND (in_rtx))
- {
- case LABEL_NORMAL: break;
- case LABEL_STATIC_ENTRY: fputs (" [entry]", outfile); break;
- case LABEL_GLOBAL_ENTRY: fputs (" [global entry]", outfile); break;
- case LABEL_WEAK_ENTRY: fputs (" [weak entry]", outfile); break;
- default: gcc_unreachable ();
- }
- break;
- default:
- break;
- }
- fputc (')', outfile);
- sawclose = 1;
- }
- /* Print an rtx on the current line of FILE. Initially indent IND
- characters. */
- void
- print_inline_rtx (FILE *outf, const_rtx x, int ind)
- {
- int oldsaw = sawclose;
- int oldindent = indent;
- sawclose = 0;
- indent = ind;
- outfile = outf;
- print_rtx (x);
- sawclose = oldsaw;
- indent = oldindent;
- }
- /* Call this function from the debugger to see what X looks like. */
- DEBUG_FUNCTION void
- debug_rtx (const_rtx x)
- {
- outfile = stderr;
- sawclose = 0;
- print_rtx (x);
- 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. */
- 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_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). */
- DEBUG_FUNCTION void
- debug_rtx_list (const rtx_insn *x, int n)
- {
- int i,count;
- const rtx_insn *insn;
- count = n == 0 ? 1 : n < 0 ? -n : n;
- /* If we are printing a window, back up to the start. */
- if (n < 0)
- for (i = count / 2; i > 0; i--)
- {
- if (PREV_INSN (x) == 0)
- break;
- x = PREV_INSN (x);
- }
- for (i = count, insn = x; i > 0 && insn != 0; i--, insn = NEXT_INSN (insn))
- {
- debug_rtx (insn);
- fprintf (stderr, "\n");
- }
- }
- /* Call this function to print an rtx_insn list from START to END
- inclusive. */
- DEBUG_FUNCTION void
- debug_rtx_range (const rtx_insn *start, const rtx_insn *end)
- {
- while (1)
- {
- debug_rtx (start);
- fprintf (stderr, "\n");
- if (!start || start == end)
- break;
- start = NEXT_INSN (start);
- }
- }
- /* 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. */
- DEBUG_FUNCTION const_rtx
- debug_rtx_find (const rtx_insn *x, int uid)
- {
- while (x != 0 && INSN_UID (x) != uid)
- x = NEXT_INSN (x);
- if (x != 0)
- {
- debug_rtx_list (x, debug_rtx_count);
- return x;
- }
- else
- {
- fprintf (stderr, "insn uid %d not found\n", uid);
- return 0;
- }
- }
- /* External entry point for printing a chain of insns
- starting with RTX_FIRST onto file OUTF.
- A blank line separates insns.
- If RTX_FIRST is not an insn, then it alone is printed, with no newline. */
- void
- print_rtl (FILE *outf, const_rtx rtx_first)
- {
- const rtx_insn *tmp_rtx;
- outfile = outf;
- sawclose = 0;
- if (rtx_first == 0)
- {
- fputs (print_rtx_head, outf);
- fputs ("(nil)\n", outf);
- }
- else
- switch (GET_CODE (rtx_first))
- {
- case INSN:
- case JUMP_INSN:
- case CALL_INSN:
- case NOTE:
- case CODE_LABEL:
- case JUMP_TABLE_DATA:
- case BARRIER:
- 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:
- fputs (print_rtx_head, outfile);
- print_rtx (rtx_first);
- }
- }
- /* Like print_rtx, except specify a file. */
- /* Return nonzero if we actually printed anything. */
- int
- 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;
- fputs (s_indent, outfile);
- fputs (print_rtx_head, outfile);
- print_rtx (x);
- putc ('\n', outf);
- indent = old_indent;
- return 1;
- }
- /* Like print_rtl except without all the detail; for example,
- if RTX is a CONST_INT then print in decimal format. */
- void
- print_simple_rtl (FILE *outf, const_rtx x)
- {
- flag_simple = 1;
- print_rtl (outf, x);
- flag_simple = 0;
- }
|