re PR tree-optimization/50693 (Loop optimization restricted by GOTOs)
PR tree-optimization/50693 * tree-cfg.c (gimple_can_merge_blocks_p): Allow merging with non-forced user labels. (gimple_merge_blocks): Turn non-forced user labels into debug bind stmt with the label as first operand and reset value. (gimple_duplicate_bb): Don't duplicate label debug stmts. * dwarf2out.c (gen_label_die): Handle NOTE_INSN_DELETED_DEBUG_LABEL. * final.c (final_scan_insn): Likewise. (rest_of_clean_state): Don't dump NOTE_INSN_DELETED_DEBUG_LABEL. * var-tracking.c (debug_label_num): New variable. (delete_debug_insns): Don't delete DEBUG_INSNs for LABEL_DECLs, instead turn them into NOTE_INSN_DELETED_DEBUG_LABEL notes. * cfglayout.c (skip_insns_after_block, duplicate_insn_chain): Handle NOTE_INSN_DELETED_DEBUG_LABEL. (duplicate_insn_chain): Don't duplicate LABEL_DECL DEBUG_INSNs. * insn-notes.def (DELETED_DEBUG_LABEL): New note kind. * print-rtl.c (print_rtx): Handle NOTE_INSN_DELETED_DEBUG_LABEL. * gengtype.c (adjust_field_rtx_def): Likewise. * config/i386/i386.c (ix86_output_function_epilogue): For MachO clear CODE_LABEL_NUMBER of NOTE_INSN_DELETED_DEBUG_LABEL if their are at the end of function and nop hasn't been emitted. * config/rs6000/rs6000.c (rs6000_output_function_epilogue): Likewise. From-SVN: r181014
This commit is contained in:
parent
eed33268ff
commit
5619e52cfb
@ -1,3 +1,28 @@
|
||||
2011-11-05 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/50693
|
||||
* tree-cfg.c (gimple_can_merge_blocks_p): Allow merging with
|
||||
non-forced user labels.
|
||||
(gimple_merge_blocks): Turn non-forced user labels into
|
||||
debug bind stmt with the label as first operand and reset value.
|
||||
(gimple_duplicate_bb): Don't duplicate label debug stmts.
|
||||
* dwarf2out.c (gen_label_die): Handle NOTE_INSN_DELETED_DEBUG_LABEL.
|
||||
* final.c (final_scan_insn): Likewise.
|
||||
(rest_of_clean_state): Don't dump NOTE_INSN_DELETED_DEBUG_LABEL.
|
||||
* var-tracking.c (debug_label_num): New variable.
|
||||
(delete_debug_insns): Don't delete DEBUG_INSNs for LABEL_DECLs,
|
||||
instead turn them into NOTE_INSN_DELETED_DEBUG_LABEL notes.
|
||||
* cfglayout.c (skip_insns_after_block, duplicate_insn_chain): Handle
|
||||
NOTE_INSN_DELETED_DEBUG_LABEL.
|
||||
(duplicate_insn_chain): Don't duplicate LABEL_DECL DEBUG_INSNs.
|
||||
* insn-notes.def (DELETED_DEBUG_LABEL): New note kind.
|
||||
* print-rtl.c (print_rtx): Handle NOTE_INSN_DELETED_DEBUG_LABEL.
|
||||
* gengtype.c (adjust_field_rtx_def): Likewise.
|
||||
* config/i386/i386.c (ix86_output_function_epilogue): For MachO
|
||||
clear CODE_LABEL_NUMBER of NOTE_INSN_DELETED_DEBUG_LABEL
|
||||
if their are at the end of function and nop hasn't been emitted.
|
||||
* config/rs6000/rs6000.c (rs6000_output_function_epilogue): Likewise.
|
||||
|
||||
2011-11-05 Georg-Johann Lay <avr@gjlay.de>
|
||||
|
||||
PR rtl-optimization/50448
|
||||
|
@ -149,6 +149,7 @@ skip_insns_after_block (basic_block bb)
|
||||
break;
|
||||
case NOTE_INSN_DELETED:
|
||||
case NOTE_INSN_DELETED_LABEL:
|
||||
case NOTE_INSN_DELETED_DEBUG_LABEL:
|
||||
continue;
|
||||
default:
|
||||
reorder_insns (insn, insn, last_insn);
|
||||
@ -1174,6 +1175,10 @@ duplicate_insn_chain (rtx from, rtx to)
|
||||
switch (GET_CODE (insn))
|
||||
{
|
||||
case DEBUG_INSN:
|
||||
/* Don't duplicate label debug insns. */
|
||||
if (TREE_CODE (INSN_VAR_LOCATION_DECL (insn)) == LABEL_DECL)
|
||||
break;
|
||||
/* FALLTHRU */
|
||||
case INSN:
|
||||
case CALL_INSN:
|
||||
case JUMP_INSN:
|
||||
@ -1219,6 +1224,7 @@ duplicate_insn_chain (rtx from, rtx to)
|
||||
|
||||
case NOTE_INSN_DELETED:
|
||||
case NOTE_INSN_DELETED_LABEL:
|
||||
case NOTE_INSN_DELETED_DEBUG_LABEL:
|
||||
/* No problem to strip these. */
|
||||
case NOTE_INSN_FUNCTION_BEG:
|
||||
/* There is always just single entry to function. */
|
||||
|
@ -10879,15 +10879,28 @@ ix86_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
|
||||
it looks like we might want one, insert a NOP. */
|
||||
{
|
||||
rtx insn = get_last_insn ();
|
||||
rtx deleted_debug_label = NULL_RTX;
|
||||
while (insn
|
||||
&& NOTE_P (insn)
|
||||
&& NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
|
||||
insn = PREV_INSN (insn);
|
||||
{
|
||||
/* Don't insert a nop for NOTE_INSN_DELETED_DEBUG_LABEL
|
||||
notes only, instead set their CODE_LABEL_NUMBER to -1,
|
||||
otherwise there would be code generation differences
|
||||
in between -g and -g0. */
|
||||
if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_DELETED_DEBUG_LABEL)
|
||||
deleted_debug_label = insn;
|
||||
insn = PREV_INSN (insn);
|
||||
}
|
||||
if (insn
|
||||
&& (LABEL_P (insn)
|
||||
|| (NOTE_P (insn)
|
||||
&& NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
|
||||
fputs ("\tnop\n", file);
|
||||
else if (deleted_debug_label)
|
||||
for (insn = deleted_debug_label; insn; insn = NEXT_INSN (insn))
|
||||
if (NOTE_KIND (insn) == NOTE_INSN_DELETED_DEBUG_LABEL)
|
||||
CODE_LABEL_NUMBER (insn) = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -21461,15 +21461,28 @@ rs6000_output_function_epilogue (FILE *file,
|
||||
it looks like we might want one, insert a NOP. */
|
||||
{
|
||||
rtx insn = get_last_insn ();
|
||||
rtx deleted_debug_label = NULL_RTX;
|
||||
while (insn
|
||||
&& NOTE_P (insn)
|
||||
&& NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
|
||||
insn = PREV_INSN (insn);
|
||||
{
|
||||
/* Don't insert a nop for NOTE_INSN_DELETED_DEBUG_LABEL
|
||||
notes only, instead set their CODE_LABEL_NUMBER to -1,
|
||||
otherwise there would be code generation differences
|
||||
in between -g and -g0. */
|
||||
if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_DELETED_DEBUG_LABEL)
|
||||
deleted_debug_label = insn;
|
||||
insn = PREV_INSN (insn);
|
||||
}
|
||||
if (insn
|
||||
&& (LABEL_P (insn)
|
||||
|| (NOTE_P (insn)
|
||||
&& NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
|
||||
fputs ("\tnop\n", file);
|
||||
else if (deleted_debug_label)
|
||||
for (insn = deleted_debug_label; insn; insn = NEXT_INSN (insn))
|
||||
if (NOTE_KIND (insn) == NOTE_INSN_DELETED_DEBUG_LABEL)
|
||||
CODE_LABEL_NUMBER (insn) = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -18020,6 +18020,14 @@ gen_label_die (tree decl, dw_die_ref context_die)
|
||||
ASM_GENERATE_INTERNAL_LABEL (label, "L", CODE_LABEL_NUMBER (insn));
|
||||
add_AT_lbl_id (lbl_die, DW_AT_low_pc, label);
|
||||
}
|
||||
else if (insn
|
||||
&& NOTE_P (insn)
|
||||
&& NOTE_KIND (insn) == NOTE_INSN_DELETED_DEBUG_LABEL
|
||||
&& CODE_LABEL_NUMBER (insn) != -1)
|
||||
{
|
||||
ASM_GENERATE_INTERNAL_LABEL (label, "LDL", CODE_LABEL_NUMBER (insn));
|
||||
add_AT_lbl_id (lbl_die, DW_AT_low_pc, label);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2080,6 +2080,12 @@ final_scan_insn (rtx insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
|
||||
ASM_OUTPUT_DEBUG_LABEL (file, "L", CODE_LABEL_NUMBER (insn));
|
||||
break;
|
||||
|
||||
case NOTE_INSN_DELETED_DEBUG_LABEL:
|
||||
/* Similarly, but need to use different namespace for it. */
|
||||
if (CODE_LABEL_NUMBER (insn) != -1)
|
||||
ASM_OUTPUT_DEBUG_LABEL (file, "LDL", CODE_LABEL_NUMBER (insn));
|
||||
break;
|
||||
|
||||
case NOTE_INSN_VAR_LOCATION:
|
||||
case NOTE_INSN_CALL_ARG_LOCATION:
|
||||
if (!DECL_IGNORED_P (current_function_decl))
|
||||
@ -4369,7 +4375,8 @@ rest_of_clean_state (void)
|
||||
(NOTE_KIND (insn) != NOTE_INSN_VAR_LOCATION
|
||||
&& NOTE_KIND (insn) != NOTE_INSN_CALL_ARG_LOCATION
|
||||
&& NOTE_KIND (insn) != NOTE_INSN_BLOCK_BEG
|
||||
&& NOTE_KIND (insn) != NOTE_INSN_BLOCK_END)))
|
||||
&& NOTE_KIND (insn) != NOTE_INSN_BLOCK_END
|
||||
&& NOTE_KIND (insn) != NOTE_INSN_DELETED_DEBUG_LABEL)))
|
||||
print_rtl_single (final_output, insn);
|
||||
}
|
||||
|
||||
|
@ -1015,6 +1015,7 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
|
||||
{
|
||||
case NOTE_INSN_MAX:
|
||||
case NOTE_INSN_DELETED_LABEL:
|
||||
case NOTE_INSN_DELETED_DEBUG_LABEL:
|
||||
note_flds = create_field (note_flds, &string_type, "rt_str");
|
||||
break;
|
||||
|
||||
|
@ -36,6 +36,10 @@ INSN_NOTE (DELETED)
|
||||
|
||||
/* Generated in place of user-declared labels when they are deleted. */
|
||||
INSN_NOTE (DELETED_LABEL)
|
||||
/* Similarly, but for labels that have been present in debug stmts
|
||||
earlier and thus will only appear with -g. These must use different
|
||||
label namespace. */
|
||||
INSN_NOTE (DELETED_DEBUG_LABEL)
|
||||
|
||||
/* These are used to mark the beginning and end of a lexical block.
|
||||
See NOTE_BLOCK and reorder_blocks. */
|
||||
|
@ -283,6 +283,7 @@ print_rtx (const_rtx in_rtx)
|
||||
}
|
||||
|
||||
case NOTE_INSN_DELETED_LABEL:
|
||||
case NOTE_INSN_DELETED_DEBUG_LABEL:
|
||||
{
|
||||
const char *label = NOTE_DELETED_LABEL_NAME (in_rtx);
|
||||
if (label)
|
||||
@ -442,7 +443,8 @@ print_rtx (const_rtx 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)
|
||||
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
|
||||
|
@ -1454,8 +1454,8 @@ gimple_can_merge_blocks_p (basic_block a, basic_block b)
|
||||
break;
|
||||
lab = gimple_label_label (stmt);
|
||||
|
||||
/* Do not remove user labels. */
|
||||
if (!DECL_ARTIFICIAL (lab))
|
||||
/* Do not remove user forced labels. */
|
||||
if (!DECL_ARTIFICIAL (lab) && FORCED_LABEL (lab))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1701,6 +1701,15 @@ gimple_merge_blocks (basic_block a, basic_block b)
|
||||
gimple_stmt_iterator dest_gsi = gsi_start_bb (a);
|
||||
gsi_insert_before (&dest_gsi, stmt, GSI_NEW_STMT);
|
||||
}
|
||||
/* Other user labels keep around in a form of a debug stmt. */
|
||||
else if (!DECL_ARTIFICIAL (label) && MAY_HAVE_DEBUG_STMTS)
|
||||
{
|
||||
gimple dbg = gimple_build_debug_bind (label,
|
||||
integer_zero_node,
|
||||
stmt);
|
||||
gimple_debug_bind_reset_value (dbg);
|
||||
gsi_insert_before (&gsi, dbg, GSI_SAME_STMT);
|
||||
}
|
||||
|
||||
lp_nr = EH_LANDING_PAD_NR (label);
|
||||
if (lp_nr)
|
||||
@ -5207,6 +5216,12 @@ gimple_duplicate_bb (basic_block bb)
|
||||
if (gimple_code (stmt) == GIMPLE_LABEL)
|
||||
continue;
|
||||
|
||||
/* Don't duplicate label debug stmts. */
|
||||
if (gimple_debug_bind_p (stmt)
|
||||
&& TREE_CODE (gimple_debug_bind_get_var (stmt))
|
||||
== LABEL_DECL)
|
||||
continue;
|
||||
|
||||
/* Create a new copy of STMT and duplicate STMT's virtual
|
||||
operands. */
|
||||
copy = gimple_copy (stmt);
|
||||
|
@ -9517,6 +9517,12 @@ vt_initialize (void)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* This is *not* reset after each function. It gives each
|
||||
NOTE_INSN_DELETED_DEBUG_LABEL in the entire compilation
|
||||
a unique label number. */
|
||||
|
||||
static int debug_label_num = 1;
|
||||
|
||||
/* Get rid of all debug insns from the insn stream. */
|
||||
|
||||
static void
|
||||
@ -9532,7 +9538,22 @@ delete_debug_insns (void)
|
||||
{
|
||||
FOR_BB_INSNS_SAFE (bb, insn, next)
|
||||
if (DEBUG_INSN_P (insn))
|
||||
delete_insn (insn);
|
||||
{
|
||||
tree decl = INSN_VAR_LOCATION_DECL (insn);
|
||||
if (TREE_CODE (decl) == LABEL_DECL
|
||||
&& DECL_NAME (decl)
|
||||
&& !DECL_RTL_SET_P (decl))
|
||||
{
|
||||
PUT_CODE (insn, NOTE);
|
||||
NOTE_KIND (insn) = NOTE_INSN_DELETED_DEBUG_LABEL;
|
||||
NOTE_DELETED_LABEL_NAME (insn)
|
||||
= IDENTIFIER_POINTER (DECL_NAME (decl));
|
||||
SET_DECL_RTL (decl, insn);
|
||||
CODE_LABEL_NUMBER (insn) = debug_label_num++;
|
||||
}
|
||||
else
|
||||
delete_insn (insn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user