Commit f645e9a2 by Jan Hubicka Committed by Jan Hubicka

re PR tree-optimization/40585 (tracer duplicates blocks w/o adjusting EH tree)


	PR tree-optimization/40585
	* except.c (expand_resx_expr): When there already is resume
	instruction, produce linked list.
	(build_post_landing_pads): Assert that resume is empty.
	(connect_post_landing_pads): Handle resume lists.
	(dump_eh_tree): Dump resume list.

From-SVN: r149530
parent 06066f92
2009-07-12 Jan Hubicka <jh@suse.cz>
PR tree-optimization/40585
* except.c (expand_resx_expr): When there already is resume
instruction, produce linked list.
(build_post_landing_pads): Assert that resume is empty.
(connect_post_landing_pads): Handle resume lists.
(dump_eh_tree): Dump resume list.
2009-07-12 Ira Rosen <irar@il.ibm.com> 2009-07-12 Ira Rosen <irar@il.ibm.com>
* tree-parloops.c (loop_parallel_p): Call vect_is_simple_reduction * tree-parloops.c (loop_parallel_p): Call vect_is_simple_reduction
......
...@@ -440,12 +440,16 @@ void ...@@ -440,12 +440,16 @@ void
expand_resx_expr (tree exp) expand_resx_expr (tree exp)
{ {
int region_nr = TREE_INT_CST_LOW (TREE_OPERAND (exp, 0)); int region_nr = TREE_INT_CST_LOW (TREE_OPERAND (exp, 0));
rtx insn;
struct eh_region_d *reg = VEC_index (eh_region, struct eh_region_d *reg = VEC_index (eh_region,
cfun->eh->region_array, region_nr); cfun->eh->region_array, region_nr);
gcc_assert (!reg->resume);
do_pending_stack_adjust (); do_pending_stack_adjust ();
reg->resume = emit_jump_insn (gen_rtx_RESX (VOIDmode, region_nr)); insn = emit_jump_insn (gen_rtx_RESX (VOIDmode, region_nr));
if (reg->resume)
reg->resume = gen_rtx_INSN_LIST (VOIDmode, insn, reg->resume);
else
reg->resume = insn;
emit_barrier (); emit_barrier ();
} }
...@@ -2012,6 +2016,7 @@ build_post_landing_pads (void) ...@@ -2012,6 +2016,7 @@ build_post_landing_pads (void)
/* We delay the generation of the _Unwind_Resume until we generate /* We delay the generation of the _Unwind_Resume until we generate
landing pads. We emit a marker here so as to get good control landing pads. We emit a marker here so as to get good control
flow data in the meantime. */ flow data in the meantime. */
gcc_assert (!region->resume);
region->resume region->resume
= emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number)); = emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number));
emit_barrier (); emit_barrier ();
...@@ -2040,6 +2045,7 @@ build_post_landing_pads (void) ...@@ -2040,6 +2045,7 @@ build_post_landing_pads (void)
/* We delay the generation of the _Unwind_Resume until we generate /* We delay the generation of the _Unwind_Resume until we generate
landing pads. We emit a marker here so as to get good control landing pads. We emit a marker here so as to get good control
flow data in the meantime. */ flow data in the meantime. */
gcc_assert (!region->resume);
region->resume region->resume
= emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number)); = emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number));
emit_barrier (); emit_barrier ();
...@@ -2080,6 +2086,7 @@ connect_post_landing_pads (void) ...@@ -2080,6 +2086,7 @@ connect_post_landing_pads (void)
struct eh_region_d *outer; struct eh_region_d *outer;
rtx seq; rtx seq;
rtx barrier; rtx barrier;
rtx resume_list;
region = VEC_index (eh_region, cfun->eh->region_array, i); region = VEC_index (eh_region, cfun->eh->region_array, i);
/* Mind we don't process a region more than once. */ /* Mind we don't process a region more than once. */
...@@ -2088,7 +2095,7 @@ connect_post_landing_pads (void) ...@@ -2088,7 +2095,7 @@ connect_post_landing_pads (void)
/* If there is no RESX, or it has been deleted by flow, there's /* If there is no RESX, or it has been deleted by flow, there's
nothing to fix up. */ nothing to fix up. */
if (! region->resume || INSN_DELETED_P (region->resume)) if (! region->resume)
continue; continue;
/* Search for another landing pad in this function. */ /* Search for another landing pad in this function. */
...@@ -2096,6 +2103,14 @@ connect_post_landing_pads (void) ...@@ -2096,6 +2103,14 @@ connect_post_landing_pads (void)
if (outer->post_landing_pad) if (outer->post_landing_pad)
break; break;
for (resume_list = region->resume; resume_list;
resume_list = (GET_CODE (resume_list) == INSN_LIST
? XEXP (resume_list, 1) : NULL_RTX))
{
rtx resume = (GET_CODE (resume_list) == INSN_LIST
? XEXP (resume_list, 0) : resume_list);
if (INSN_DELETED_P (resume))
continue;
start_sequence (); start_sequence ();
if (outer) if (outer)
...@@ -2104,7 +2119,7 @@ connect_post_landing_pads (void) ...@@ -2104,7 +2119,7 @@ connect_post_landing_pads (void)
basic_block src, dest; basic_block src, dest;
emit_jump (outer->post_landing_pad); emit_jump (outer->post_landing_pad);
src = BLOCK_FOR_INSN (region->resume); src = BLOCK_FOR_INSN (resume);
dest = BLOCK_FOR_INSN (outer->post_landing_pad); dest = BLOCK_FOR_INSN (outer->post_landing_pad);
while (EDGE_COUNT (src->succs) > 0) while (EDGE_COUNT (src->succs) > 0)
remove_edge (EDGE_SUCC (src, 0)); remove_edge (EDGE_SUCC (src, 0));
...@@ -2131,11 +2146,12 @@ connect_post_landing_pads (void) ...@@ -2131,11 +2146,12 @@ connect_post_landing_pads (void)
seq = get_insns (); seq = get_insns ();
end_sequence (); end_sequence ();
barrier = emit_insn_before (seq, region->resume); barrier = emit_insn_before (seq, resume);
/* Avoid duplicate barrier. */ /* Avoid duplicate barrier. */
gcc_assert (BARRIER_P (barrier)); gcc_assert (BARRIER_P (barrier));
delete_insn (barrier); delete_insn (barrier);
delete_insn (region->resume); delete_insn (resume);
}
/* ??? From tree-ssa we can wind up with catch regions whose /* ??? From tree-ssa we can wind up with catch regions whose
label is not instantiated, but whose resx is present. Now label is not instantiated, but whose resx is present. Now
...@@ -4419,6 +4435,15 @@ dump_eh_tree (FILE * out, struct function *fun) ...@@ -4419,6 +4435,15 @@ dump_eh_tree (FILE * out, struct function *fun)
} }
if (i->resume) if (i->resume)
{ {
rtx resume_list = i->resume;
fprintf (out, " resume:");
while (GET_CODE (resume_list) == INSN_LIST)
{
fprintf (out, "%i,", INSN_UID (XEXP (resume_list, 0)));
if (NOTE_P (XEXP (resume_list, 0)))
fprintf (out, " (deleted)");
resume_list = XEXP (resume_list, 1);
}
fprintf (out, " resume:%i", INSN_UID (i->resume)); fprintf (out, " resume:%i", INSN_UID (i->resume));
if (NOTE_P (i->resume)) if (NOTE_P (i->resume))
fprintf (out, " (deleted)"); fprintf (out, " (deleted)");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment