mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-05 01:59:39 +08:00
Makefile.in (final.o): Depend on BASIC_BLOCK_H.
* Makefile.in (final.o): Depend on BASIC_BLOCK_H. * final.c (final_end_function): Use app_disable. Rearrange note handling into a switch. Emit deleted labels. (output_asm_label): Generate label strings for deleted labels. * flow.c (tail_recursion_label_list): New. (find_basic_blocks_1): Set label_value_list directly. Collect list of tail recursion labels from call_placeholders. Don't add deleted labels to the label value list. (cleanup_cfg): Use free_EXPR_LIST_list. (flow_delete_insn_chain): Turn non-removable labels into notes. (flow_delete_block): Don't disable deleting the block because of a non-removable label. (tail_recursion_label_p): New. (merge_blocks_move_predecessor_nojumps): Don't disable the merge because of a label. (merge_blocks_move_successor_nojumps): Likewise. Also move a jump table. (merge_blocks): Disable a merge because of tail recursion labels. * ifcvt.c (merge_if_block): Don't disable a merge because of a label. Use a more accurate measure of not merging the join block. (find_if_block): Don't disable conversion because of a label. (find_if_case_1, find_if_case_2): Likewise. * jump.c (duplicate_loop_exit_test): Preserve the kind of list element when copying. (squeeze_notes): Also leave EH notes. (mark_jump_label): Ignore deleted labels. Use an INSN_LIST for REG_LABEL notes. (delete_insn): Preserve LABEL_NAME in NOTE_SOURCE_FILE when deleting a label. * print-rtl.c (print_rtx): Print NOTE_SOURCE_FILE for NOTE_INSN_DELETED_LABEL. Print `[# deleted]' for a label_ref referring to a deleted label. Convert tail handling to a switch. * rtl.def (CODE_LABEL): Rearrange elements to be compatible with NOTE for NOTE_INSN_DELETED_LABEL. (NOTE): Fix commentary. * rtl.h (REG_LABEL): Update commentary wrt INSN_LIST. (REG_CC_SETTER, REG_CC_USER, REG_LIBCALL): Likewise. (CODE_LABEL_NUMBER, LABEL_NAME): Update index. (LABEL_NUSES, LABEL_REFS): Likewise. * unroll.c (copy_loop_body): Don't copy NOTE_INSN_DELETED_LABEL. From-SVN: r33876
This commit is contained in:
parent
fb0f12c932
commit
be1bb65263
@ -1,3 +1,46 @@
|
||||
2000-05-12 Richard Henderson <rth@cygnus.com>
|
||||
|
||||
* Makefile.in (final.o): Depend on BASIC_BLOCK_H.
|
||||
* final.c (final_end_function): Use app_disable. Rearrange note
|
||||
handling into a switch. Emit deleted labels.
|
||||
(output_asm_label): Generate label strings for deleted labels.
|
||||
* flow.c (tail_recursion_label_list): New.
|
||||
(find_basic_blocks_1): Set label_value_list directly. Collect list
|
||||
of tail recursion labels from call_placeholders. Don't add deleted
|
||||
labels to the label value list.
|
||||
(cleanup_cfg): Use free_EXPR_LIST_list.
|
||||
(flow_delete_insn_chain): Turn non-removable labels into notes.
|
||||
(flow_delete_block): Don't disable deleting the block because of
|
||||
a non-removable label.
|
||||
(tail_recursion_label_p): New.
|
||||
(merge_blocks_move_predecessor_nojumps): Don't disable the merge
|
||||
because of a label.
|
||||
(merge_blocks_move_successor_nojumps): Likewise. Also move a
|
||||
jump table.
|
||||
(merge_blocks): Disable a merge because of tail recursion labels.
|
||||
* ifcvt.c (merge_if_block): Don't disable a merge because of a label.
|
||||
Use a more accurate measure of not merging the join block.
|
||||
(find_if_block): Don't disable conversion because of a label.
|
||||
(find_if_case_1, find_if_case_2): Likewise.
|
||||
* jump.c (duplicate_loop_exit_test): Preserve the kind of list
|
||||
element when copying.
|
||||
(squeeze_notes): Also leave EH notes.
|
||||
(mark_jump_label): Ignore deleted labels. Use an INSN_LIST for
|
||||
REG_LABEL notes.
|
||||
(delete_insn): Preserve LABEL_NAME in NOTE_SOURCE_FILE when
|
||||
deleting a label.
|
||||
* print-rtl.c (print_rtx): Print NOTE_SOURCE_FILE for
|
||||
NOTE_INSN_DELETED_LABEL. Print `[# deleted]' for a label_ref
|
||||
referring to a deleted label. Convert tail handling to a switch.
|
||||
* rtl.def (CODE_LABEL): Rearrange elements to be compatible with NOTE
|
||||
for NOTE_INSN_DELETED_LABEL.
|
||||
(NOTE): Fix commentary.
|
||||
* rtl.h (REG_LABEL): Update commentary wrt INSN_LIST.
|
||||
(REG_CC_SETTER, REG_CC_USER, REG_LIBCALL): Likewise.
|
||||
(CODE_LABEL_NUMBER, LABEL_NAME): Update index.
|
||||
(LABEL_NUSES, LABEL_REFS): Likewise.
|
||||
* unroll.c (copy_loop_body): Don't copy NOTE_INSN_DELETED_LABEL.
|
||||
|
||||
2000-05-12 Zack Weinberg <zack@wolery.cumb.org>
|
||||
|
||||
* fixinc/fixfixes.c (IO_use_fix, IO_defn_fix, CTRL_use_fix,
|
||||
|
@ -1374,7 +1374,7 @@ final.o : final.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h intl.h \
|
||||
$(REGS_H) $(RECOG_H) conditions.h insn-config.h insn-attr.h function.h \
|
||||
real.h output.h hard-reg-set.h insn-flags.h insn-codes.h gstab.h except.h \
|
||||
xcoffout.h defaults.h toplev.h reload.h dwarfout.h dwarf2out.h sdbout.h \
|
||||
dbxout.h
|
||||
dbxout.h $(BASIC_BLOCK_H)
|
||||
recog.o : recog.c $(CONFIG_H) system.h $(RTL_H) function.h $(BASIC_BLOCK_H) \
|
||||
$(REGS_H) $(RECOG_H) hard-reg-set.h flags.h insn-config.h insn-attr.h \
|
||||
insn-flags.h insn-codes.h real.h toplev.h output.h resource.h
|
||||
|
346
gcc/final.c
346
gcc/final.c
@ -68,6 +68,7 @@ Boston, MA 02111-1307, USA. */
|
||||
#include "toplev.h"
|
||||
#include "reload.h"
|
||||
#include "intl.h"
|
||||
#include "basic-block.h"
|
||||
|
||||
/* Get N_SLINE and N_SOL from stab.h if we can expect the file to exist. */
|
||||
#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
|
||||
@ -1782,11 +1783,7 @@ final_end_function (first, file, optimize)
|
||||
FILE *file;
|
||||
int optimize ATTRIBUTE_UNUSED;
|
||||
{
|
||||
if (app_on)
|
||||
{
|
||||
fputs (ASM_APP_OFF, file);
|
||||
app_on = 0;
|
||||
}
|
||||
app_disable ();
|
||||
|
||||
#ifdef SDB_DEBUGGING_INFO
|
||||
if (write_symbols == SDB_DEBUG)
|
||||
@ -2082,218 +2079,243 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
|
||||
if (prescan > 0)
|
||||
break;
|
||||
|
||||
/* Align the beginning of a loop, for higher speed
|
||||
on certain machines. */
|
||||
|
||||
if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
|
||||
break; /* This used to depend on optimize, but that was bogus. */
|
||||
if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)
|
||||
break;
|
||||
|
||||
if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG
|
||||
&& ! exceptions_via_longjmp)
|
||||
switch (NOTE_LINE_NUMBER (insn))
|
||||
{
|
||||
ASM_OUTPUT_INTERNAL_LABEL (file, "LEHB", NOTE_EH_HANDLER (insn));
|
||||
if (! flag_new_exceptions)
|
||||
add_eh_table_entry (NOTE_EH_HANDLER (insn));
|
||||
case NOTE_INSN_DELETED:
|
||||
case NOTE_INSN_LOOP_BEG:
|
||||
case NOTE_INSN_LOOP_END:
|
||||
case NOTE_INSN_LOOP_CONT:
|
||||
case NOTE_INSN_LOOP_VTOP:
|
||||
case NOTE_INSN_FUNCTION_END:
|
||||
case NOTE_INSN_SETJMP:
|
||||
case NOTE_INSN_REPEATED_LINE_NUMBER:
|
||||
case NOTE_INSN_RANGE_BEG:
|
||||
case NOTE_INSN_RANGE_END:
|
||||
case NOTE_INSN_LIVE:
|
||||
case NOTE_INSN_EXPECTED_VALUE:
|
||||
break;
|
||||
|
||||
case NOTE_INSN_BASIC_BLOCK:
|
||||
if (flag_debug_asm)
|
||||
fprintf (asm_out_file, "\t%s basic block %d\n",
|
||||
ASM_COMMENT_START, NOTE_BASIC_BLOCK (insn)->index);
|
||||
break;
|
||||
|
||||
case NOTE_INSN_EH_REGION_BEG:
|
||||
if (! exceptions_via_longjmp)
|
||||
{
|
||||
ASM_OUTPUT_INTERNAL_LABEL (file, "LEHB", NOTE_EH_HANDLER (insn));
|
||||
if (! flag_new_exceptions)
|
||||
add_eh_table_entry (NOTE_EH_HANDLER (insn));
|
||||
#ifdef ASM_OUTPUT_EH_REGION_BEG
|
||||
ASM_OUTPUT_EH_REGION_BEG (file, NOTE_EH_HANDLER (insn));
|
||||
ASM_OUTPUT_EH_REGION_BEG (file, NOTE_EH_HANDLER (insn));
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END
|
||||
&& ! exceptions_via_longjmp)
|
||||
{
|
||||
ASM_OUTPUT_INTERNAL_LABEL (file, "LEHE", NOTE_EH_HANDLER (insn));
|
||||
if (flag_new_exceptions)
|
||||
add_eh_table_entry (NOTE_EH_HANDLER (insn));
|
||||
case NOTE_INSN_EH_REGION_END:
|
||||
if (! exceptions_via_longjmp)
|
||||
{
|
||||
ASM_OUTPUT_INTERNAL_LABEL (file, "LEHE", NOTE_EH_HANDLER (insn));
|
||||
if (flag_new_exceptions)
|
||||
add_eh_table_entry (NOTE_EH_HANDLER (insn));
|
||||
#ifdef ASM_OUTPUT_EH_REGION_END
|
||||
ASM_OUTPUT_EH_REGION_END (file, NOTE_EH_HANDLER (insn));
|
||||
ASM_OUTPUT_EH_REGION_END (file, NOTE_EH_HANDLER (insn));
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_PROLOGUE_END)
|
||||
{
|
||||
case NOTE_INSN_PROLOGUE_END:
|
||||
#ifdef FUNCTION_END_PROLOGUE
|
||||
FUNCTION_END_PROLOGUE (file);
|
||||
#endif
|
||||
profile_after_prologue (file);
|
||||
break;
|
||||
}
|
||||
|
||||
case NOTE_INSN_EPILOGUE_BEG:
|
||||
#ifdef FUNCTION_BEGIN_EPILOGUE
|
||||
if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EPILOGUE_BEG)
|
||||
{
|
||||
FUNCTION_BEGIN_EPILOGUE (file);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
if (write_symbols == NO_DEBUG)
|
||||
break;
|
||||
if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG)
|
||||
{
|
||||
case NOTE_INSN_FUNCTION_BEG:
|
||||
if (write_symbols == NO_DEBUG)
|
||||
break;
|
||||
#if defined(SDB_DEBUGGING_INFO) && defined(MIPS_DEBUGGING_INFO)
|
||||
/* MIPS stabs require the parameter descriptions to be after the
|
||||
function entry point rather than before. */
|
||||
if (write_symbols == SDB_DEBUG)
|
||||
sdbout_begin_function (last_linenum);
|
||||
{
|
||||
app_disable ();
|
||||
sdbout_begin_function (last_linenum);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef DWARF_DEBUGGING_INFO
|
||||
/* This outputs a marker where the function body starts, so it
|
||||
must be after the prologue. */
|
||||
if (write_symbols == DWARF_DEBUG)
|
||||
dwarfout_begin_function ();
|
||||
{
|
||||
app_disable ();
|
||||
dwarfout_begin_function ();
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED)
|
||||
break; /* An insn that was "deleted" */
|
||||
if (app_on)
|
||||
{
|
||||
fputs (ASM_APP_OFF, file);
|
||||
app_on = 0;
|
||||
}
|
||||
if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG
|
||||
&& (debug_info_level == DINFO_LEVEL_NORMAL
|
||||
|
||||
case NOTE_INSN_BLOCK_BEG:
|
||||
if (debug_info_level == DINFO_LEVEL_NORMAL
|
||||
|| debug_info_level == DINFO_LEVEL_VERBOSE
|
||||
|| write_symbols == DWARF_DEBUG
|
||||
|| write_symbols == DWARF2_DEBUG))
|
||||
{
|
||||
int n = BLOCK_NUMBER (NOTE_BLOCK (insn));
|
||||
|| write_symbols == DWARF2_DEBUG)
|
||||
{
|
||||
int n = BLOCK_NUMBER (NOTE_BLOCK (insn));
|
||||
|
||||
++block_depth;
|
||||
high_block_linenum = last_linenum;
|
||||
app_disable ();
|
||||
++block_depth;
|
||||
high_block_linenum = last_linenum;
|
||||
|
||||
/* Output debugging info about the symbol-block beginning. */
|
||||
/* Output debugging info about the symbol-block beginning. */
|
||||
#ifdef SDB_DEBUGGING_INFO
|
||||
if (write_symbols == SDB_DEBUG)
|
||||
sdbout_begin_block (file, last_linenum, n);
|
||||
if (write_symbols == SDB_DEBUG)
|
||||
sdbout_begin_block (file, last_linenum, n);
|
||||
#endif
|
||||
#ifdef XCOFF_DEBUGGING_INFO
|
||||
if (write_symbols == XCOFF_DEBUG)
|
||||
xcoffout_begin_block (file, last_linenum, n);
|
||||
if (write_symbols == XCOFF_DEBUG)
|
||||
xcoffout_begin_block (file, last_linenum, n);
|
||||
#endif
|
||||
#ifdef DBX_DEBUGGING_INFO
|
||||
if (write_symbols == DBX_DEBUG)
|
||||
ASM_OUTPUT_INTERNAL_LABEL (file, "LBB", n);
|
||||
if (write_symbols == DBX_DEBUG)
|
||||
ASM_OUTPUT_INTERNAL_LABEL (file, "LBB", n);
|
||||
#endif
|
||||
#ifdef DWARF_DEBUGGING_INFO
|
||||
if (write_symbols == DWARF_DEBUG)
|
||||
dwarfout_begin_block (n);
|
||||
if (write_symbols == DWARF_DEBUG)
|
||||
dwarfout_begin_block (n);
|
||||
#endif
|
||||
#ifdef DWARF2_DEBUGGING_INFO
|
||||
if (write_symbols == DWARF2_DEBUG)
|
||||
dwarf2out_begin_block (n);
|
||||
if (write_symbols == DWARF2_DEBUG)
|
||||
dwarf2out_begin_block (n);
|
||||
#endif
|
||||
|
||||
/* Mark this block as output. */
|
||||
TREE_ASM_WRITTEN (NOTE_BLOCK (insn)) = 1;
|
||||
}
|
||||
else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END
|
||||
&& (debug_info_level == DINFO_LEVEL_NORMAL
|
||||
|| debug_info_level == DINFO_LEVEL_VERBOSE
|
||||
|| write_symbols == DWARF_DEBUG
|
||||
|| write_symbols == DWARF2_DEBUG))
|
||||
{
|
||||
int n = BLOCK_NUMBER (NOTE_BLOCK (insn));
|
||||
/* Mark this block as output. */
|
||||
TREE_ASM_WRITTEN (NOTE_BLOCK (insn)) = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
/* End of a symbol-block. */
|
||||
case NOTE_INSN_BLOCK_END:
|
||||
if (debug_info_level == DINFO_LEVEL_NORMAL
|
||||
|| debug_info_level == DINFO_LEVEL_VERBOSE
|
||||
|| write_symbols == DWARF_DEBUG
|
||||
|| write_symbols == DWARF2_DEBUG)
|
||||
{
|
||||
int n = BLOCK_NUMBER (NOTE_BLOCK (insn));
|
||||
|
||||
--block_depth;
|
||||
if (block_depth < 0)
|
||||
app_disable ();
|
||||
|
||||
/* End of a symbol-block. */
|
||||
--block_depth;
|
||||
if (block_depth < 0)
|
||||
abort ();
|
||||
|
||||
#ifdef XCOFF_DEBUGGING_INFO
|
||||
if (write_symbols == XCOFF_DEBUG)
|
||||
xcoffout_end_block (file, high_block_linenum, n);
|
||||
#endif
|
||||
#ifdef DBX_DEBUGGING_INFO
|
||||
if (write_symbols == DBX_DEBUG)
|
||||
ASM_OUTPUT_INTERNAL_LABEL (file, "LBE", n);
|
||||
#endif
|
||||
#ifdef SDB_DEBUGGING_INFO
|
||||
if (write_symbols == SDB_DEBUG)
|
||||
sdbout_end_block (file, high_block_linenum, n);
|
||||
#endif
|
||||
#ifdef DWARF_DEBUGGING_INFO
|
||||
if (write_symbols == DWARF_DEBUG)
|
||||
dwarfout_end_block (n);
|
||||
#endif
|
||||
#ifdef DWARF2_DEBUGGING_INFO
|
||||
if (write_symbols == DWARF2_DEBUG)
|
||||
dwarf2out_end_block (n);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case NOTE_INSN_DELETED_LABEL:
|
||||
/* Emit the label. We may have deleted the CODE_LABEL because
|
||||
the label could be proved to be unreachable, though still
|
||||
referenced (in the form of having its address taken. */
|
||||
/* ??? Figure out how not to do this unconditionally. This
|
||||
interferes with bundling on LIW targets. */
|
||||
ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (insn));
|
||||
|
||||
if (debug_info_level == DINFO_LEVEL_NORMAL
|
||||
|| debug_info_level == DINFO_LEVEL_VERBOSE)
|
||||
{
|
||||
#ifdef DWARF_DEBUGGING_INFO
|
||||
if (write_symbols == DWARF_DEBUG)
|
||||
dwarfout_label (insn);
|
||||
#endif
|
||||
#ifdef DWARF2_DEBUGGING_INFO
|
||||
if (write_symbols == DWARF2_DEBUG)
|
||||
dwarf2out_label (insn);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (NOTE_LINE_NUMBER (insn) <= 0)
|
||||
abort ();
|
||||
|
||||
#ifdef XCOFF_DEBUGGING_INFO
|
||||
if (write_symbols == XCOFF_DEBUG)
|
||||
xcoffout_end_block (file, high_block_linenum, n);
|
||||
#endif
|
||||
#ifdef DBX_DEBUGGING_INFO
|
||||
if (write_symbols == DBX_DEBUG)
|
||||
ASM_OUTPUT_INTERNAL_LABEL (file, "LBE", n);
|
||||
#endif
|
||||
#ifdef SDB_DEBUGGING_INFO
|
||||
if (write_symbols == SDB_DEBUG)
|
||||
sdbout_end_block (file, high_block_linenum, n);
|
||||
#endif
|
||||
#ifdef DWARF_DEBUGGING_INFO
|
||||
if (write_symbols == DWARF_DEBUG)
|
||||
dwarfout_end_block (n);
|
||||
#endif
|
||||
#ifdef DWARF2_DEBUGGING_INFO
|
||||
if (write_symbols == DWARF2_DEBUG)
|
||||
dwarf2out_end_block (n);
|
||||
#endif
|
||||
}
|
||||
else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL
|
||||
&& (debug_info_level == DINFO_LEVEL_NORMAL
|
||||
|| debug_info_level == DINFO_LEVEL_VERBOSE))
|
||||
{
|
||||
#ifdef DWARF_DEBUGGING_INFO
|
||||
if (write_symbols == DWARF_DEBUG)
|
||||
dwarfout_label (insn);
|
||||
#endif
|
||||
#ifdef DWARF2_DEBUGGING_INFO
|
||||
if (write_symbols == DWARF2_DEBUG)
|
||||
dwarf2out_label (insn);
|
||||
#endif
|
||||
}
|
||||
else if (NOTE_LINE_NUMBER (insn) > 0)
|
||||
/* This note is a line-number. */
|
||||
{
|
||||
register rtx note;
|
||||
/* This note is a line-number. */
|
||||
{
|
||||
register rtx note;
|
||||
int note_after = 0;
|
||||
|
||||
#if 0 /* This is what we used to do. */
|
||||
output_source_line (file, insn);
|
||||
#endif
|
||||
int note_after = 0;
|
||||
|
||||
/* If there is anything real after this note,
|
||||
output it. If another line note follows, omit this one. */
|
||||
for (note = NEXT_INSN (insn); note; note = NEXT_INSN (note))
|
||||
{
|
||||
if (GET_CODE (note) != NOTE && GET_CODE (note) != CODE_LABEL)
|
||||
break;
|
||||
/* These types of notes can be significant
|
||||
so make sure the preceding line number stays. */
|
||||
else if (GET_CODE (note) == NOTE
|
||||
&& (NOTE_LINE_NUMBER (note) == NOTE_INSN_BLOCK_BEG
|
||||
|| NOTE_LINE_NUMBER (note) == NOTE_INSN_BLOCK_END
|
||||
|| NOTE_LINE_NUMBER (note) == NOTE_INSN_FUNCTION_BEG))
|
||||
break;
|
||||
else if (GET_CODE (note) == NOTE && NOTE_LINE_NUMBER (note) > 0)
|
||||
{
|
||||
/* Another line note follows; we can delete this note
|
||||
if no intervening line numbers have notes elsewhere. */
|
||||
int num;
|
||||
for (num = NOTE_LINE_NUMBER (insn) + 1;
|
||||
num < NOTE_LINE_NUMBER (note);
|
||||
num++)
|
||||
if (line_note_exists[num])
|
||||
break;
|
||||
|
||||
if (num >= NOTE_LINE_NUMBER (note))
|
||||
note_after = 1;
|
||||
/* If there is anything real after this note, output it.
|
||||
If another line note follows, omit this one. */
|
||||
for (note = NEXT_INSN (insn); note; note = NEXT_INSN (note))
|
||||
{
|
||||
if (GET_CODE (note) != NOTE && GET_CODE (note) != CODE_LABEL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Output this line note
|
||||
if it is the first or the last line note in a row. */
|
||||
if (!note_after)
|
||||
output_source_line (file, insn);
|
||||
/* These types of notes can be significant
|
||||
so make sure the preceding line number stays. */
|
||||
else if (GET_CODE (note) == NOTE
|
||||
&& (NOTE_LINE_NUMBER (note) == NOTE_INSN_BLOCK_BEG
|
||||
|| NOTE_LINE_NUMBER (note) == NOTE_INSN_BLOCK_END
|
||||
|| NOTE_LINE_NUMBER (note) == NOTE_INSN_FUNCTION_BEG))
|
||||
break;
|
||||
else if (GET_CODE (note) == NOTE && NOTE_LINE_NUMBER (note) > 0)
|
||||
{
|
||||
/* Another line note follows; we can delete this note
|
||||
if no intervening line numbers have notes elsewhere. */
|
||||
int num;
|
||||
for (num = NOTE_LINE_NUMBER (insn) + 1;
|
||||
num < NOTE_LINE_NUMBER (note);
|
||||
num++)
|
||||
if (line_note_exists[num])
|
||||
break;
|
||||
|
||||
if (num >= NOTE_LINE_NUMBER (note))
|
||||
note_after = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Output this line note if it is the first or the last line
|
||||
note in a row. */
|
||||
if (!note_after)
|
||||
output_source_line (file, insn);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case BARRIER:
|
||||
#if defined (DWARF2_UNWIND_INFO)
|
||||
/* If we push arguments, we need to check all insns for stack
|
||||
adjustments. */
|
||||
if (!ACCUMULATE_OUTGOING_ARGS && dwarf2out_do_frame ())
|
||||
dwarf2out_frame_debug (insn);
|
||||
/* If we push arguments, we need to check all insns for stack
|
||||
adjustments. */
|
||||
if (!ACCUMULATE_OUTGOING_ARGS && dwarf2out_do_frame ())
|
||||
dwarf2out_frame_debug (insn);
|
||||
#endif
|
||||
break;
|
||||
|
||||
@ -3544,8 +3566,10 @@ output_asm_label (x)
|
||||
char buf[256];
|
||||
|
||||
if (GET_CODE (x) == LABEL_REF)
|
||||
ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
|
||||
else if (GET_CODE (x) == CODE_LABEL)
|
||||
x = XEXP (x, 0);
|
||||
if (GET_CODE (x) == CODE_LABEL
|
||||
|| (GET_CODE (x) == NOTE
|
||||
&& NOTE_LINE_NUMBER (x) == NOTE_INSN_DELETED_LABEL))
|
||||
ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
|
||||
else
|
||||
output_operand_lossage ("`%l' operand isn't a label");
|
||||
|
127
gcc/flow.c
127
gcc/flow.c
@ -253,6 +253,7 @@ varray_type basic_block_for_insn;
|
||||
bit of surgery to be able to use or co-opt the routines in jump. */
|
||||
|
||||
static rtx label_value_list;
|
||||
static rtx tail_recursion_label_list;
|
||||
|
||||
/* Holds information for tracking conditional register life information. */
|
||||
struct reg_cond_life_info
|
||||
@ -307,7 +308,7 @@ struct propagate_block_info
|
||||
|
||||
/* Forward declarations */
|
||||
static int count_basic_blocks PARAMS ((rtx));
|
||||
static rtx find_basic_blocks_1 PARAMS ((rtx));
|
||||
static void find_basic_blocks_1 PARAMS ((rtx));
|
||||
static void clear_edges PARAMS ((void));
|
||||
static void make_edges PARAMS ((rtx));
|
||||
static void make_label_edge PARAMS ((sbitmap *, basic_block,
|
||||
@ -325,6 +326,7 @@ static void delete_eh_regions PARAMS ((void));
|
||||
static int can_delete_note_p PARAMS ((rtx));
|
||||
static void expunge_block PARAMS ((basic_block));
|
||||
static int can_delete_label_p PARAMS ((rtx));
|
||||
static int tail_recursion_label_p PARAMS ((rtx));
|
||||
static int merge_blocks_move_predecessor_nojumps PARAMS ((basic_block,
|
||||
basic_block));
|
||||
static int merge_blocks_move_successor_nojumps PARAMS ((basic_block,
|
||||
@ -437,7 +439,7 @@ find_basic_blocks (f, nregs, file)
|
||||
|
||||
VARRAY_BB_INIT (basic_block_info, n_basic_blocks, "basic_block_info");
|
||||
|
||||
label_value_list = find_basic_blocks_1 (f);
|
||||
find_basic_blocks_1 (f);
|
||||
|
||||
/* Record the block to which an insn belongs. */
|
||||
/* ??? This should be done another way, by which (perhaps) a label is
|
||||
@ -535,7 +537,7 @@ count_basic_blocks (f)
|
||||
Collect and return a list of labels whose addresses are taken. This
|
||||
will be used in make_edges for use with computed gotos. */
|
||||
|
||||
static rtx
|
||||
static void
|
||||
find_basic_blocks_1 (f)
|
||||
rtx f;
|
||||
{
|
||||
@ -543,7 +545,8 @@ find_basic_blocks_1 (f)
|
||||
int i = 0;
|
||||
rtx bb_note = NULL_RTX;
|
||||
rtx eh_list = NULL_RTX;
|
||||
rtx label_value_list = NULL_RTX;
|
||||
rtx lvl = NULL_RTX;
|
||||
rtx trll = NULL_RTX;
|
||||
rtx head = NULL_RTX;
|
||||
rtx end = NULL_RTX;
|
||||
|
||||
@ -667,6 +670,12 @@ find_basic_blocks_1 (f)
|
||||
int region = (note ? INTVAL (XEXP (note, 0)) : 1);
|
||||
int call_has_abnormal_edge = 0;
|
||||
|
||||
/* If this is a call placeholder, record its tail recursion
|
||||
label, if any. */
|
||||
if (GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER
|
||||
&& XEXP (PATTERN (insn), 3) != NULL_RTX)
|
||||
trll = alloc_EXPR_LIST (0, XEXP (PATTERN (insn), 3), trll);
|
||||
|
||||
/* If there is an EH region or rethrow, we have an edge. */
|
||||
if ((eh_list && region > 0)
|
||||
|| find_reg_note (insn, REG_EH_RETHROW, NULL_RTX))
|
||||
@ -724,15 +733,16 @@ find_basic_blocks_1 (f)
|
||||
rtx lab = XEXP (note, 0), next;
|
||||
|
||||
if (lab == eh_return_stub_label)
|
||||
;
|
||||
;
|
||||
else if ((next = next_nonnote_insn (lab)) != NULL
|
||||
&& GET_CODE (next) == JUMP_INSN
|
||||
&& (GET_CODE (PATTERN (next)) == ADDR_VEC
|
||||
|| GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
|
||||
;
|
||||
else if (GET_CODE (lab) == NOTE)
|
||||
;
|
||||
else
|
||||
label_value_list
|
||||
= alloc_EXPR_LIST (0, XEXP (note, 0), label_value_list);
|
||||
lvl = alloc_EXPR_LIST (0, XEXP (note, 0), lvl);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -745,7 +755,8 @@ find_basic_blocks_1 (f)
|
||||
if (i != n_basic_blocks)
|
||||
abort ();
|
||||
|
||||
return label_value_list;
|
||||
label_value_list = lvl;
|
||||
tail_recursion_label_list = trll;
|
||||
}
|
||||
|
||||
/* Tidy the CFG by deleting unreachable code and whatnot. */
|
||||
@ -761,7 +772,8 @@ cleanup_cfg (f)
|
||||
mark_critical_edges ();
|
||||
|
||||
/* Kill the data we won't maintain. */
|
||||
label_value_list = NULL_RTX;
|
||||
free_EXPR_LIST_list (&label_value_list);
|
||||
free_EXPR_LIST_list (&tail_recursion_label_list);
|
||||
}
|
||||
|
||||
/* Create a new basic block consisting of the instructions between
|
||||
@ -1853,8 +1865,14 @@ flow_delete_insn_chain (start, finish)
|
||||
next = NEXT_INSN (start);
|
||||
if (GET_CODE (start) == NOTE && !can_delete_note_p (start))
|
||||
;
|
||||
else if (GET_CODE (start) == CODE_LABEL && !can_delete_label_p (start))
|
||||
;
|
||||
else if (GET_CODE (start) == CODE_LABEL
|
||||
&& ! can_delete_label_p (start))
|
||||
{
|
||||
const char *name = LABEL_NAME (start);
|
||||
PUT_CODE (start, NOTE);
|
||||
NOTE_LINE_NUMBER (start) = NOTE_INSN_DELETED_LABEL;
|
||||
NOTE_SOURCE_FILE (start) = name;
|
||||
}
|
||||
else
|
||||
next = flow_delete_insn (start);
|
||||
|
||||
@ -1910,20 +1928,6 @@ flow_delete_block (b)
|
||||
}
|
||||
prev = &XEXP (x, 1);
|
||||
}
|
||||
|
||||
/* This label may be referenced by code solely for its value, or
|
||||
referenced by static data, or something. We have determined
|
||||
that it is not reachable, but cannot delete the label itself.
|
||||
Save code space and continue to delete the balance of the block,
|
||||
along with properly updating the cfg. */
|
||||
if (!can_delete_label_p (insn))
|
||||
{
|
||||
/* If we've only got one of these, skip the whole deleting
|
||||
insns thing. */
|
||||
if (insn == b->end)
|
||||
goto no_delete_insns;
|
||||
insn = NEXT_INSN (insn);
|
||||
}
|
||||
}
|
||||
|
||||
/* Include any jump table following the basic block. */
|
||||
@ -1944,8 +1948,6 @@ flow_delete_block (b)
|
||||
/* Selectively delete the entire chain. */
|
||||
flow_delete_insn_chain (insn, end);
|
||||
|
||||
no_delete_insns:
|
||||
|
||||
/* Remove the edges into and out of this block. Note that there may
|
||||
indeed be edges in, if we are removing an unreachable loop. */
|
||||
{
|
||||
@ -2063,6 +2065,19 @@ can_delete_label_p (label)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
tail_recursion_label_p (label)
|
||||
rtx label;
|
||||
{
|
||||
rtx x;
|
||||
|
||||
for (x = tail_recursion_label_list; x ; x = XEXP (x, 1))
|
||||
if (label == XEXP (x, 0))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Blocks A and B are to be merged into a single block A. The insns
|
||||
are already contiguous, hence `nomove'. */
|
||||
|
||||
@ -2180,19 +2195,10 @@ merge_blocks_move_predecessor_nojumps (a, b)
|
||||
start = a->head;
|
||||
end = a->end;
|
||||
|
||||
/* We want to delete the BARRIER after the end of the insns we are
|
||||
going to move. If we don't find a BARRIER, then do nothing. This
|
||||
can happen in some cases if we have labels we can not delete.
|
||||
|
||||
Similarly, do nothing if we can not delete the label at the start
|
||||
of the target block. */
|
||||
barrier = next_nonnote_insn (end);
|
||||
if (GET_CODE (barrier) != BARRIER
|
||||
|| (GET_CODE (b->head) == CODE_LABEL
|
||||
&& ! can_delete_label_p (b->head)))
|
||||
return 0;
|
||||
else
|
||||
flow_delete_insn (barrier);
|
||||
if (GET_CODE (barrier) != BARRIER)
|
||||
abort ();
|
||||
flow_delete_insn (barrier);
|
||||
|
||||
/* Move block and loop notes out of the chain so that we do not
|
||||
disturb their order.
|
||||
@ -2240,20 +2246,23 @@ merge_blocks_move_successor_nojumps (a, b)
|
||||
|
||||
start = b->head;
|
||||
end = b->end;
|
||||
barrier = NEXT_INSN (end);
|
||||
|
||||
/* We want to delete the BARRIER after the end of the insns we are
|
||||
going to move. If we don't find a BARRIER, then do nothing. This
|
||||
can happen in some cases if we have labels we can not delete.
|
||||
/* Recognize a jump table following block B. */
|
||||
if (GET_CODE (barrier) == CODE_LABEL
|
||||
&& NEXT_INSN (barrier)
|
||||
&& GET_CODE (NEXT_INSN (barrier)) == JUMP_INSN
|
||||
&& (GET_CODE (PATTERN (NEXT_INSN (barrier))) == ADDR_VEC
|
||||
|| GET_CODE (PATTERN (NEXT_INSN (barrier))) == ADDR_DIFF_VEC))
|
||||
{
|
||||
end = NEXT_INSN (barrier);
|
||||
barrier = NEXT_INSN (end);
|
||||
}
|
||||
|
||||
Similarly, do nothing if we can not delete the label at the start
|
||||
of the target block. */
|
||||
barrier = next_nonnote_insn (end);
|
||||
if (GET_CODE (barrier) != BARRIER
|
||||
|| (GET_CODE (b->head) == CODE_LABEL
|
||||
&& ! can_delete_label_p (b->head)))
|
||||
return 0;
|
||||
else
|
||||
flow_delete_insn (barrier);
|
||||
/* There had better have been a barrier there. Delete it. */
|
||||
if (GET_CODE (barrier) != BARRIER)
|
||||
abort ();
|
||||
flow_delete_insn (barrier);
|
||||
|
||||
/* Move block and loop notes out of the chain so that we do not
|
||||
disturb their order.
|
||||
@ -2287,17 +2296,17 @@ merge_blocks (e, b, c)
|
||||
edge e;
|
||||
basic_block b, c;
|
||||
{
|
||||
/* If C has a tail recursion label, do not merge. There is no
|
||||
edge recorded from the call_placeholder back to this label, as
|
||||
that would make optimize_sibling_and_tail_recursive_calls more
|
||||
complex for no gain. */
|
||||
if (GET_CODE (c->head) == CODE_LABEL
|
||||
&& tail_recursion_label_p (c->head))
|
||||
return 0;
|
||||
|
||||
/* If B has a fallthru edge to C, no need to move anything. */
|
||||
if (e->flags & EDGE_FALLTHRU)
|
||||
{
|
||||
/* If a label still appears somewhere and we cannot delete the label,
|
||||
then we cannot merge the blocks. The edge was tidied already. */
|
||||
|
||||
rtx insn, stop = NEXT_INSN (c->head);
|
||||
for (insn = NEXT_INSN (b->end); insn != stop; insn = NEXT_INSN (insn))
|
||||
if (GET_CODE (insn) == CODE_LABEL && !can_delete_label_p (insn))
|
||||
return 0;
|
||||
|
||||
merge_blocks_nomove (b, c);
|
||||
|
||||
if (rtl_dump_file)
|
||||
|
59
gcc/ifcvt.c
59
gcc/ifcvt.c
@ -1275,37 +1275,8 @@ merge_if_block (test_bb, then_bb, else_bb, join_bb)
|
||||
get their addresses taken. */
|
||||
if (else_bb)
|
||||
{
|
||||
if (LABEL_NUSES (else_bb->head) == 0
|
||||
&& ! LABEL_PRESERVE_P (else_bb->head)
|
||||
&& ! LABEL_NAME (else_bb->head))
|
||||
{
|
||||
/* We can merge the ELSE. */
|
||||
merge_blocks_nomove (combo_bb, else_bb);
|
||||
num_removed_blocks++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We cannot merge the ELSE. */
|
||||
|
||||
/* Properly rewire the edge out of the now combined
|
||||
TEST-THEN block to point here. */
|
||||
remove_edge (combo_bb->succ);
|
||||
if (combo_bb->succ || else_bb->pred)
|
||||
abort ();
|
||||
make_edge (NULL, combo_bb, else_bb, EDGE_FALLTHRU);
|
||||
|
||||
/* Remove the jump and cruft from the end of the TEST-THEN block. */
|
||||
tidy_fallthru_edge (combo_bb->succ, combo_bb, else_bb);
|
||||
|
||||
/* Make sure we update life info properly. */
|
||||
SET_UPDATE_LIFE(combo_bb);
|
||||
if (else_bb->global_live_at_end)
|
||||
COPY_REG_SET (else_bb->global_live_at_start,
|
||||
else_bb->global_live_at_end);
|
||||
|
||||
/* The ELSE is the new combo block. */
|
||||
combo_bb = else_bb;
|
||||
}
|
||||
merge_blocks_nomove (combo_bb, else_bb);
|
||||
num_removed_blocks++;
|
||||
}
|
||||
|
||||
/* If there was no join block reported, that means it was not adjacent
|
||||
@ -1325,12 +1296,11 @@ merge_if_block (test_bb, then_bb, else_bb, join_bb)
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* The JOIN block had a label. It may have had quite a number
|
||||
of other predecessors too, but probably not. See if we can
|
||||
merge this with the others. */
|
||||
else if (LABEL_NUSES (join_bb->head) == 0
|
||||
&& ! LABEL_PRESERVE_P (join_bb->head)
|
||||
&& ! LABEL_NAME (join_bb->head))
|
||||
/* The JOIN block may have had quite a number of other predecessors too.
|
||||
Since we've already merged the TEST, THEN and ELSE blocks, we should
|
||||
have only one remaining edge from our if-then-else diamond. If there
|
||||
is more than one remaining edge, it must come from elsewhere. */
|
||||
else if (join_bb->pred->pred_next == NULL)
|
||||
{
|
||||
/* We can merge the JOIN. */
|
||||
if (combo_bb->global_live_at_end)
|
||||
@ -1438,11 +1408,6 @@ find_if_block (test_bb, then_edge, else_edge)
|
||||
|| (then_succ->flags & EDGE_COMPLEX))
|
||||
return FALSE;
|
||||
|
||||
/* The THEN block may not start with a label, as might happen with an
|
||||
unused user label that has had its address taken. */
|
||||
if (GET_CODE (then_bb->head) == CODE_LABEL)
|
||||
return FALSE;
|
||||
|
||||
/* If the THEN block's successor is the other edge out of the TEST block,
|
||||
then we have an IF-THEN combo without an ELSE. */
|
||||
if (then_succ->dest == else_bb)
|
||||
@ -1600,10 +1565,6 @@ find_if_case_1 (test_bb, then_edge, else_edge)
|
||||
if (then_bb->pred->pred_next != NULL)
|
||||
return FALSE;
|
||||
|
||||
/* THEN has no label. */
|
||||
if (GET_CODE (then_bb->head) == CODE_LABEL)
|
||||
return FALSE;
|
||||
|
||||
/* ELSE follows THEN. (??? could be moved) */
|
||||
if (else_bb->index != then_bb->index + 1)
|
||||
return FALSE;
|
||||
@ -1674,12 +1635,6 @@ find_if_case_2 (test_bb, then_edge, else_edge)
|
||||
if (else_bb->pred->pred_next != NULL)
|
||||
return FALSE;
|
||||
|
||||
/* ELSE has a label we can delete. */
|
||||
if (LABEL_NUSES (else_bb->head) > 1
|
||||
|| LABEL_PRESERVE_P (else_bb->head)
|
||||
|| LABEL_NAME (else_bb->head))
|
||||
return FALSE;
|
||||
|
||||
/* ELSE is predicted or SUCC(ELSE) postdominates THEN. */
|
||||
note = find_reg_note (test_bb->end, REG_BR_PROB, NULL_RTX);
|
||||
if (note && INTVAL (XEXP (note, 0)) >= REG_BR_PROB_BASE / 2)
|
||||
|
36
gcc/jump.c
36
gcc/jump.c
@ -1262,10 +1262,19 @@ duplicate_loop_exit_test (loop_start)
|
||||
make them. */
|
||||
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
|
||||
if (REG_NOTE_KIND (link) != REG_LABEL)
|
||||
REG_NOTES (copy)
|
||||
= copy_insn_1 (gen_rtx_EXPR_LIST (REG_NOTE_KIND (link),
|
||||
XEXP (link, 0),
|
||||
REG_NOTES (copy)));
|
||||
{
|
||||
if (GET_CODE (link) == EXPR_LIST)
|
||||
REG_NOTES (copy)
|
||||
= copy_insn_1 (gen_rtx_EXPR_LIST (REG_NOTE_KIND (link),
|
||||
XEXP (link, 0),
|
||||
REG_NOTES (copy)));
|
||||
else
|
||||
REG_NOTES (copy)
|
||||
= copy_insn_1 (gen_rtx_INSN_LIST (REG_NOTE_KIND (link),
|
||||
XEXP (link, 0),
|
||||
REG_NOTES (copy)));
|
||||
}
|
||||
|
||||
if (reg_map && REG_NOTES (copy))
|
||||
replace_regs (REG_NOTES (copy), reg_map, max_reg, 1);
|
||||
break;
|
||||
@ -1345,8 +1354,8 @@ duplicate_loop_exit_test (loop_start)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Move all block-beg, block-end, loop-beg, loop-cont, loop-vtop, and
|
||||
loop-end notes between START and END out before START. Assume that
|
||||
/* Move all block-beg, block-end, loop-beg, loop-cont, loop-vtop, loop-end,
|
||||
eh-beg, eh-end notes between START and END out before START. Assume that
|
||||
END is not such a note. START may be such a note. Returns the value
|
||||
of the new starting insn, which may be different if the original start
|
||||
was such a note. */
|
||||
@ -1367,7 +1376,9 @@ squeeze_notes (start, end)
|
||||
|| NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG
|
||||
|| NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END
|
||||
|| NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_CONT
|
||||
|| NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_VTOP))
|
||||
|| NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_VTOP
|
||||
|| NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG
|
||||
|| NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END))
|
||||
{
|
||||
if (insn == start)
|
||||
start = next;
|
||||
@ -2389,6 +2400,12 @@ mark_jump_label (x, insn, cross_jump, in_mem)
|
||||
rtx note;
|
||||
rtx next;
|
||||
|
||||
/* Ignore remaining references to unreachable labels that
|
||||
have been deleted. */
|
||||
if (GET_CODE (label) == NOTE
|
||||
&& NOTE_LINE_NUMBER (label) == NOTE_INSN_DELETED_LABEL)
|
||||
break;
|
||||
|
||||
if (GET_CODE (label) != CODE_LABEL)
|
||||
abort ();
|
||||
|
||||
@ -2449,7 +2466,7 @@ mark_jump_label (x, insn, cross_jump, in_mem)
|
||||
is no longer valid because of the more accurate cfg
|
||||
we build in find_basic_blocks -- it no longer pessimizes
|
||||
code when it finds a REG_LABEL note. */
|
||||
REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_LABEL, label,
|
||||
REG_NOTES (insn) = gen_rtx_INSN_LIST (REG_LABEL, label,
|
||||
REG_NOTES (insn));
|
||||
}
|
||||
}
|
||||
@ -2755,9 +2772,10 @@ delete_insn (insn)
|
||||
dont_really_delete = 1;
|
||||
else if (! dont_really_delete)
|
||||
{
|
||||
const char *name = LABEL_NAME (insn);
|
||||
PUT_CODE (insn, NOTE);
|
||||
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED_LABEL;
|
||||
NOTE_SOURCE_FILE (insn) = 0;
|
||||
NOTE_SOURCE_FILE (insn) = name;
|
||||
dont_really_delete = 1;
|
||||
}
|
||||
}
|
||||
|
@ -210,6 +210,13 @@ print_rtx (in_rtx)
|
||||
indent -= 2;
|
||||
break;
|
||||
|
||||
case NOTE_INSN_DELETED_LABEL:
|
||||
if (NOTE_SOURCE_FILE (in_rtx))
|
||||
fprintf (outfile, " (\"%s\")", NOTE_SOURCE_FILE (in_rtx));
|
||||
else
|
||||
fprintf (outfile, " \"\"");
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
const char * const str = X0STR (in_rtx, i);
|
||||
@ -334,11 +341,25 @@ print_rtx (in_rtx)
|
||||
rtx sub = XEXP (in_rtx, i);
|
||||
enum rtx_code subc = GET_CODE (sub);
|
||||
|
||||
if (GET_CODE (in_rtx) == LABEL_REF && subc != CODE_LABEL)
|
||||
goto do_e;
|
||||
if (GET_CODE (in_rtx) == LABEL_REF)
|
||||
{
|
||||
if (subc == NOTE
|
||||
&& NOTE_LINE_NUMBER (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)
|
||||
fputc ('#', outfile);
|
||||
fputs (" #", outfile);
|
||||
else
|
||||
fprintf (outfile, " %d", INSN_UID (sub));
|
||||
}
|
||||
@ -372,34 +393,43 @@ print_rtx (in_rtx)
|
||||
abort ();
|
||||
}
|
||||
|
||||
if (GET_CODE (in_rtx) == MEM)
|
||||
fprintf (outfile, " %d", MEM_ALIAS_SET (in_rtx));
|
||||
switch (GET_CODE (in_rtx))
|
||||
{
|
||||
case MEM:
|
||||
fprintf (outfile, " %d", MEM_ALIAS_SET (in_rtx));
|
||||
break;
|
||||
|
||||
#if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT && MAX_LONG_DOUBLE_TYPE_SIZE == 64
|
||||
if (GET_CODE (in_rtx) == CONST_DOUBLE && FLOAT_MODE_P (GET_MODE (in_rtx)))
|
||||
{
|
||||
double val;
|
||||
REAL_VALUE_FROM_CONST_DOUBLE (val, in_rtx);
|
||||
fprintf (outfile, " [%.16g]", val);
|
||||
}
|
||||
case CONST_DOUBLE:
|
||||
if (FLOAT_MODE_P (GET_MODE (in_rtx)))
|
||||
{
|
||||
double val;
|
||||
REAL_VALUE_FROM_CONST_DOUBLE (val, in_rtx);
|
||||
fprintf (outfile, " [%.16g]", val);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
if (GET_CODE (in_rtx) == CODE_LABEL)
|
||||
{
|
||||
case CODE_LABEL:
|
||||
fprintf (outfile, " [%d uses]", LABEL_NUSES (in_rtx));
|
||||
if (LABEL_ALTERNATE_NAME (in_rtx))
|
||||
fprintf (outfile, " [alternate name: %s]",
|
||||
LABEL_ALTERNATE_NAME (in_rtx));
|
||||
break;
|
||||
|
||||
case CALL_PLACEHOLDER:
|
||||
for (tem = XEXP (in_rtx, 0); tem != 0; tem = NEXT_INSN (tem))
|
||||
if (GET_CODE (tem) == CALL_INSN)
|
||||
{
|
||||
fprintf (outfile, " ");
|
||||
print_rtx (tem);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (GET_CODE (in_rtx) == CALL_PLACEHOLDER)
|
||||
for (tem = XEXP (in_rtx, 0); tem != 0; tem = NEXT_INSN (tem))
|
||||
if (GET_CODE (tem) == CALL_INSN)
|
||||
{
|
||||
fprintf (outfile, " ");
|
||||
print_rtx (tem);
|
||||
break;
|
||||
}
|
||||
|
||||
if (dump_for_graph
|
||||
&& (is_insn || GET_CODE (in_rtx) == NOTE
|
||||
|
19
gcc/rtl.def
19
gcc/rtl.def
@ -413,21 +413,16 @@ DEF_RTL_EXPR(BARRIER, "barrier", "iuu", 'x')
|
||||
|
||||
/* Holds a label that is followed by instructions.
|
||||
Operand:
|
||||
3: is a number that is unique in the entire compilation.
|
||||
4: is the user-given name of the label, if any.
|
||||
5: is used in jump.c for the use-count of the label.
|
||||
6: is used in flow.c to point to the chain of label_ref's to this label.
|
||||
3: is used in jump.c for the use-count of the label.
|
||||
4: is used in flow.c to point to the chain of label_ref's to this label.
|
||||
5: is a number that is unique in the entire compilation.
|
||||
6: is the user-given name of the label, if any.
|
||||
7: is the alternate label name. */
|
||||
DEF_RTL_EXPR(CODE_LABEL, "code_label", "iuuis00s", 'x')
|
||||
DEF_RTL_EXPR(CODE_LABEL, "code_label", "iuu00iss", 'x')
|
||||
|
||||
/* Say where in the code a source line starts, for symbol table's sake.
|
||||
Contains a filename and a line number. Line numbers <= 0 are special:
|
||||
0 is used in a dummy placed at the front of every function
|
||||
just so there will never be a need to delete the first insn;
|
||||
-1 indicates a dummy; insns to be deleted by flow analysis and combining
|
||||
are really changed to NOTEs with a number of -1.
|
||||
-2 means beginning of a name binding contour; output N_LBRAC.
|
||||
-3 means end of a contour; output N_RBRAC. */
|
||||
Contains a filename and a line number. Line numbers <= 0 are special;
|
||||
See enum note_insn in rtl.h. */
|
||||
DEF_RTL_EXPR(NOTE, "note", "iuu0n", 'x')
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
|
21
gcc/rtl.h
21
gcc/rtl.h
@ -417,7 +417,7 @@ enum reg_note
|
||||
appear on an insn which copies a register parameter to a pseudo-register,
|
||||
if there is a memory address which could be used to hold that
|
||||
pseudo-register throughout the function. */
|
||||
REG_EQUIV,
|
||||
REG_EQUIV,
|
||||
|
||||
/* Like REG_EQUIV except that the destination is only momentarily equal
|
||||
to the specified rtx. Therefore, it cannot be used for substitution;
|
||||
@ -437,7 +437,8 @@ enum reg_note
|
||||
REG_RETVAL,
|
||||
|
||||
/* The inverse of REG_RETVAL: it goes on the first insn of the library call
|
||||
and points at the one that has the REG_RETVAL. */
|
||||
and points at the one that has the REG_RETVAL. This note is also an
|
||||
INSN_LIST. */
|
||||
REG_LIBCALL,
|
||||
|
||||
/* The register is always nonnegative during the containing loop. This is
|
||||
@ -459,11 +460,13 @@ enum reg_note
|
||||
we permit putting a cc0-setting insn in the delay slot of a branch as
|
||||
long as only one copy of the insn exists. In that case, these notes
|
||||
point from one to the other to allow code generation to determine what
|
||||
any require information and to properly update CC_STATUS. */
|
||||
any require information and to properly update CC_STATUS. These notes
|
||||
are INSN_LISTs. */
|
||||
REG_CC_SETTER, REG_CC_USER,
|
||||
|
||||
/* Points to a CODE_LABEL. Used by non-JUMP_INSNs to say that the
|
||||
CODE_LABEL contained in the REG_LABEL note is used by the insn. */
|
||||
CODE_LABEL contained in the REG_LABEL note is used by the insn.
|
||||
This note is an INSN_LIST. */
|
||||
REG_LABEL,
|
||||
|
||||
/* REG_DEP_ANTI and REG_DEP_OUTPUT are used in LOG_LINKS to represent
|
||||
@ -544,7 +547,7 @@ extern const char * const reg_note_name[];
|
||||
/* The label-number of a code-label. The assembler label
|
||||
is made from `L' and the label-number printed in decimal.
|
||||
Label numbers are unique in a compilation. */
|
||||
#define CODE_LABEL_NUMBER(INSN) XINT(INSN, 3)
|
||||
#define CODE_LABEL_NUMBER(INSN) XINT(INSN, 5)
|
||||
|
||||
#define LINE_NUMBER NOTE
|
||||
|
||||
@ -664,11 +667,11 @@ extern const char * const note_insn_name[NOTE_INSN_MAX - NOTE_INSN_BIAS];
|
||||
|
||||
/* The name of a label, in case it corresponds to an explicit label
|
||||
in the input source code. */
|
||||
#define LABEL_NAME(RTX) XCSTR(RTX, 4, CODE_LABEL)
|
||||
#define LABEL_NAME(RTX) XCSTR(RTX, 6, CODE_LABEL)
|
||||
|
||||
/* In jump.c, each label contains a count of the number
|
||||
of LABEL_REFs that point at it, so unused labels can be deleted. */
|
||||
#define LABEL_NUSES(RTX) XCINT(RTX, 5, CODE_LABEL)
|
||||
#define LABEL_NUSES(RTX) XCINT(RTX, 3, CODE_LABEL)
|
||||
|
||||
/* Associate a name with a CODE_LABEL. */
|
||||
#define LABEL_ALTERNATE_NAME(RTX) XCSTR(RTX, 7, CODE_LABEL)
|
||||
@ -687,8 +690,8 @@ extern const char * const note_insn_name[NOTE_INSN_MAX - NOTE_INSN_BIAS];
|
||||
/* Once basic blocks are found in flow.c,
|
||||
each CODE_LABEL starts a chain that goes through
|
||||
all the LABEL_REFs that jump to that label.
|
||||
The chain eventually winds up at the CODE_LABEL; it is circular. */
|
||||
#define LABEL_REFS(LABEL) XCEXP(LABEL, 6, CODE_LABEL)
|
||||
The chain eventually winds up at the CODE_LABEL: it is circular. */
|
||||
#define LABEL_REFS(LABEL) XCEXP(LABEL, 4, CODE_LABEL)
|
||||
|
||||
/* This is the field in the LABEL_REF through which the circular chain
|
||||
of references to a particular label is linked.
|
||||
|
@ -2207,6 +2207,7 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration,
|
||||
this new block. */
|
||||
|
||||
if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED
|
||||
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED_LABEL
|
||||
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK
|
||||
&& ((NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_VTOP
|
||||
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_CONT)
|
||||
|
Loading…
Reference in New Issue
Block a user