Commit 12c3874e by Jan Hubicka Committed by Jan Hubicka

basic-block.h (make_eh_edge, [...]): Declare.


	* basic-block.h (make_eh_edge, break_superblocks): Declare.
	* cfgbuild.c (make_eh_edge):  Make global.
	* cfglayout.c (break_superblocks): Likewise; fix memory leak.
	* except.c (build_post_landing_pads, connect_post_landing_pads,
	dw2_build_landing_pads, sjlj_emit_function_enter,
	sjlj_emit_function_exit, sjlj_emit_dispatch_table,
	sjlj_build_landing_pads): Update CFG.
	(emit_to_new_bb_before): New function.
	(finish_eh_generation): Do not rebuild the CFG.

From-SVN: r78448
parent b29610b3
2004-02-25 Jan Hubicka <jh@suse.cz>
* basic-block.h (make_eh_edge, break_superblocks): Declare.
* cfgbuild.c (make_eh_edge): Make global.
* cfglayout.c (break_superblocks): Likewise; fix memory leak.
* except.c (build_post_landing_pads, connect_post_landing_pads,
dw2_build_landing_pads, sjlj_emit_function_enter,
sjlj_emit_function_exit, sjlj_emit_dispatch_table,
sjlj_build_landing_pads): Update CFG.
(emit_to_new_bb_before): New function.
(finish_eh_generation): Do not rebuild the CFG.
2004-02-25 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> 2004-02-25 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
* config.gcc (hppa*-*-*, parisc*-*-*): Add MASK_BIG_SWITCH to all * config.gcc (hppa*-*-*, parisc*-*-*): Add MASK_BIG_SWITCH to all
......
...@@ -566,6 +566,7 @@ extern bool purge_all_dead_edges (int); ...@@ -566,6 +566,7 @@ extern bool purge_all_dead_edges (int);
extern bool purge_dead_edges (basic_block); extern bool purge_dead_edges (basic_block);
extern void find_sub_basic_blocks (basic_block); extern void find_sub_basic_blocks (basic_block);
extern void find_many_sub_basic_blocks (sbitmap); extern void find_many_sub_basic_blocks (sbitmap);
extern void make_eh_edge (sbitmap *, basic_block, rtx);
extern bool can_fallthru (basic_block, basic_block); extern bool can_fallthru (basic_block, basic_block);
extern void flow_nodes_print (const char *, const sbitmap, FILE *); extern void flow_nodes_print (const char *, const sbitmap, FILE *);
extern void flow_edge_list_print (const char *, const edge *, int, FILE *); extern void flow_edge_list_print (const char *, const edge *, int, FILE *);
...@@ -649,6 +650,7 @@ extern void verify_dominators (enum cdi_direction); ...@@ -649,6 +650,7 @@ extern void verify_dominators (enum cdi_direction);
extern basic_block first_dom_son (enum cdi_direction, basic_block); extern basic_block first_dom_son (enum cdi_direction, basic_block);
extern basic_block next_dom_son (enum cdi_direction, basic_block); extern basic_block next_dom_son (enum cdi_direction, basic_block);
extern bool try_redirect_by_replacing_jump (edge, basic_block, bool); extern bool try_redirect_by_replacing_jump (edge, basic_block, bool);
extern void break_superblocks (void);
#include "cfghooks.h" #include "cfghooks.h"
......
...@@ -53,7 +53,6 @@ static void find_basic_blocks_1 (rtx); ...@@ -53,7 +53,6 @@ static void find_basic_blocks_1 (rtx);
static rtx find_label_refs (rtx, rtx); static rtx find_label_refs (rtx, rtx);
static void make_edges (rtx, basic_block, basic_block, int); static void make_edges (rtx, basic_block, basic_block, int);
static void make_label_edge (sbitmap *, basic_block, rtx, int); static void make_label_edge (sbitmap *, basic_block, rtx, int);
static void make_eh_edge (sbitmap *, basic_block, rtx);
static void find_bb_boundaries (basic_block); static void find_bb_boundaries (basic_block);
static void compute_outgoing_frequencies (basic_block); static void compute_outgoing_frequencies (basic_block);
...@@ -240,7 +239,7 @@ make_label_edge (sbitmap *edge_cache, basic_block src, rtx label, int flags) ...@@ -240,7 +239,7 @@ make_label_edge (sbitmap *edge_cache, basic_block src, rtx label, int flags)
/* Create the edges generated by INSN in REGION. */ /* Create the edges generated by INSN in REGION. */
static void void
make_eh_edge (sbitmap *edge_cache, basic_block src, rtx insn) make_eh_edge (sbitmap *edge_cache, basic_block src, rtx insn)
{ {
int is_call = GET_CODE (insn) == CALL_INSN ? EDGE_ABNORMAL_CALL : 0; int is_call = GET_CODE (insn) == CALL_INSN ? EDGE_ABNORMAL_CALL : 0;
......
...@@ -56,7 +56,6 @@ static void change_scope (rtx, tree, tree); ...@@ -56,7 +56,6 @@ static void change_scope (rtx, tree, tree);
void verify_insn_chain (void); void verify_insn_chain (void);
static void fixup_fallthru_exit_predecessor (void); static void fixup_fallthru_exit_predecessor (void);
static rtx duplicate_insn_chain (rtx, rtx); static rtx duplicate_insn_chain (rtx, rtx);
static void break_superblocks (void);
static tree insn_scope (rtx); static tree insn_scope (rtx);
rtx rtx
...@@ -1144,23 +1143,22 @@ cfg_layout_initialize (void) ...@@ -1144,23 +1143,22 @@ cfg_layout_initialize (void)
} }
/* Splits superblocks. */ /* Splits superblocks. */
static void void
break_superblocks (void) break_superblocks (void)
{ {
sbitmap superblocks; sbitmap superblocks;
int i, need; bool need = false;
basic_block bb;
superblocks = sbitmap_alloc (n_basic_blocks); superblocks = sbitmap_alloc (last_basic_block);
sbitmap_zero (superblocks); sbitmap_zero (superblocks);
need = 0; FOR_EACH_BB (bb)
if (bb->flags & BB_SUPERBLOCK)
for (i = 0; i < n_basic_blocks; i++)
if (BASIC_BLOCK(i)->flags & BB_SUPERBLOCK)
{ {
BASIC_BLOCK(i)->flags &= ~BB_SUPERBLOCK; bb->flags &= ~BB_SUPERBLOCK;
SET_BIT (superblocks, i); SET_BIT (superblocks, bb->index);
need = 1; need = true;
} }
if (need) if (need)
......
...@@ -1629,6 +1629,24 @@ assign_filter_values (void) ...@@ -1629,6 +1629,24 @@ assign_filter_values (void)
htab_delete (ehspec); htab_delete (ehspec);
} }
/* Emit SEQ into basic block just before INSN (that is assumed to be
first instruction of some existing BB and return the newly
produced block. */
static basic_block
emit_to_new_bb_before (rtx seq, rtx insn)
{
rtx last;
basic_block bb;
last = emit_insn_before (seq, insn);
if (GET_CODE (last) == BARRIER)
last = PREV_INSN (last);
bb = create_basic_block (seq, last, BLOCK_FOR_INSN (insn)->prev_bb);
update_bb_for_insn (bb);
bb->flags |= BB_SUPERBLOCK;
return bb;
}
/* Generate the code to actually handle exceptions, which will follow the /* Generate the code to actually handle exceptions, which will follow the
landing pads. */ landing pads. */
...@@ -1702,7 +1720,8 @@ build_post_landing_pads (void) ...@@ -1702,7 +1720,8 @@ build_post_landing_pads (void)
seq = get_insns (); seq = get_insns ();
end_sequence (); end_sequence ();
emit_insn_before (seq, region->u.try.catch->label); emit_to_new_bb_before (seq, region->u.try.catch->label);
break; break;
case ERT_ALLOWED_EXCEPTIONS: case ERT_ALLOWED_EXCEPTIONS:
...@@ -1726,7 +1745,7 @@ build_post_landing_pads (void) ...@@ -1726,7 +1745,7 @@ build_post_landing_pads (void)
seq = get_insns (); seq = get_insns ();
end_sequence (); end_sequence ();
emit_insn_before (seq, region->label); emit_to_new_bb_before (seq, region->label);
break; break;
case ERT_CLEANUP: case ERT_CLEANUP:
...@@ -1758,6 +1777,7 @@ connect_post_landing_pads (void) ...@@ -1758,6 +1777,7 @@ connect_post_landing_pads (void)
struct eh_region *region = cfun->eh->region_array[i]; struct eh_region *region = cfun->eh->region_array[i];
struct eh_region *outer; struct eh_region *outer;
rtx seq; rtx seq;
rtx barrier;
/* Mind we don't process a region more than once. */ /* Mind we don't process a region more than once. */
if (!region || region->region_number != i) if (!region || region->region_number != i)
...@@ -1776,14 +1796,30 @@ connect_post_landing_pads (void) ...@@ -1776,14 +1796,30 @@ connect_post_landing_pads (void)
start_sequence (); start_sequence ();
if (outer) if (outer)
emit_jump (outer->post_landing_pad); {
edge e;
basic_block src, dest;
emit_jump (outer->post_landing_pad);
src = BLOCK_FOR_INSN (region->resume);
dest = BLOCK_FOR_INSN (outer->post_landing_pad);
while (src->succ)
remove_edge (src->succ);
e = make_edge (src, dest, 0);
e->probability = REG_BR_PROB_BASE;
e->count = src->count;
}
else else
emit_library_call (unwind_resume_libfunc, LCT_THROW, emit_library_call (unwind_resume_libfunc, LCT_THROW,
VOIDmode, 1, cfun->eh->exc_ptr, ptr_mode); VOIDmode, 1, cfun->eh->exc_ptr, ptr_mode);
seq = get_insns (); seq = get_insns ();
end_sequence (); end_sequence ();
emit_insn_before (seq, region->resume); barrier = emit_insn_before (seq, region->resume);
/* Avoid duplicate barrier. */
if (GET_CODE (barrier) != BARRIER)
abort ();
delete_insn (barrier);
delete_insn (region->resume); delete_insn (region->resume);
} }
} }
...@@ -1799,7 +1835,9 @@ dw2_build_landing_pads (void) ...@@ -1799,7 +1835,9 @@ dw2_build_landing_pads (void)
{ {
struct eh_region *region = cfun->eh->region_array[i]; struct eh_region *region = cfun->eh->region_array[i];
rtx seq; rtx seq;
basic_block bb;
bool clobbers_hard_regs = false; bool clobbers_hard_regs = false;
edge e;
/* Mind we don't process a region more than once. */ /* Mind we don't process a region more than once. */
if (!region || region->region_number != i) if (!region || region->region_number != i)
...@@ -1859,7 +1897,10 @@ dw2_build_landing_pads (void) ...@@ -1859,7 +1897,10 @@ dw2_build_landing_pads (void)
seq = get_insns (); seq = get_insns ();
end_sequence (); end_sequence ();
emit_insn_before (seq, region->post_landing_pad); bb = emit_to_new_bb_before (seq, region->post_landing_pad);
e = make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
e->count = bb->count;
e->probability = REG_BR_PROB_BASE;
} }
} }
...@@ -2107,9 +2148,21 @@ sjlj_emit_function_enter (rtx dispatch_label) ...@@ -2107,9 +2148,21 @@ sjlj_emit_function_enter (rtx dispatch_label)
for (fn_begin = get_insns (); ; fn_begin = NEXT_INSN (fn_begin)) for (fn_begin = get_insns (); ; fn_begin = NEXT_INSN (fn_begin))
if (GET_CODE (fn_begin) == NOTE if (GET_CODE (fn_begin) == NOTE
&& NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_FUNCTION_BEG) && (NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_FUNCTION_BEG
|| NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_BASIC_BLOCK))
break; break;
emit_insn_after (seq, fn_begin); if (NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_FUNCTION_BEG)
insert_insn_on_edge (seq, ENTRY_BLOCK_PTR->succ);
else
{
rtx last = BB_END (ENTRY_BLOCK_PTR->succ->dest);
for (; ; fn_begin = NEXT_INSN (fn_begin))
if ((GET_CODE (fn_begin) == NOTE
&& NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_FUNCTION_BEG)
|| fn_begin == last)
break;
emit_insn_after (seq, fn_begin);
}
} }
/* Call back from expand_function_end to know where we should put /* Call back from expand_function_end to know where we should put
...@@ -2125,6 +2178,7 @@ static void ...@@ -2125,6 +2178,7 @@ static void
sjlj_emit_function_exit (void) sjlj_emit_function_exit (void)
{ {
rtx seq; rtx seq;
edge e;
start_sequence (); start_sequence ();
...@@ -2138,7 +2192,31 @@ sjlj_emit_function_exit (void) ...@@ -2138,7 +2192,31 @@ sjlj_emit_function_exit (void)
post-dominates all can_throw_internal instructions. This is post-dominates all can_throw_internal instructions. This is
the last possible moment. */ the last possible moment. */
emit_insn_after (seq, cfun->eh->sjlj_exit_after); for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
if (e->flags & EDGE_FALLTHRU)
break;
if (e)
{
rtx insn;
/* Figure out whether the place we are supposed to insert libcall
is inside the last basic block or after it. In the other case
we need to emit to edge. */
if (e->src->next_bb != EXIT_BLOCK_PTR)
abort ();
for (insn = NEXT_INSN (BB_END (e->src)); insn; insn = NEXT_INSN (insn))
if (insn == cfun->eh->sjlj_exit_after)
break;
if (insn)
insert_insn_on_edge (seq, e);
else
{
insn = cfun->eh->sjlj_exit_after;
if (GET_CODE (insn) == CODE_LABEL)
insn = NEXT_INSN (insn);
emit_insn_after (seq, insn);
}
}
} }
static void static void
...@@ -2146,6 +2224,9 @@ sjlj_emit_dispatch_table (rtx dispatch_label, struct sjlj_lp_info *lp_info) ...@@ -2146,6 +2224,9 @@ sjlj_emit_dispatch_table (rtx dispatch_label, struct sjlj_lp_info *lp_info)
{ {
int i, first_reachable; int i, first_reachable;
rtx mem, dispatch, seq, fc; rtx mem, dispatch, seq, fc;
rtx before;
basic_block bb;
edge e;
fc = cfun->eh->sjlj_fc; fc = cfun->eh->sjlj_fc;
...@@ -2200,8 +2281,12 @@ sjlj_emit_dispatch_table (rtx dispatch_label, struct sjlj_lp_info *lp_info) ...@@ -2200,8 +2281,12 @@ sjlj_emit_dispatch_table (rtx dispatch_label, struct sjlj_lp_info *lp_info)
seq = get_insns (); seq = get_insns ();
end_sequence (); end_sequence ();
emit_insn_before (seq, (cfun->eh->region_array[first_reachable] before = cfun->eh->region_array[first_reachable]->post_landing_pad;
->post_landing_pad));
bb = emit_to_new_bb_before (seq, before);
e = make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
e->count = bb->count;
e->probability = REG_BR_PROB_BASE;
} }
static void static void
...@@ -2235,6 +2320,8 @@ sjlj_build_landing_pads (void) ...@@ -2235,6 +2320,8 @@ sjlj_build_landing_pads (void)
void void
finish_eh_generation (void) finish_eh_generation (void)
{ {
basic_block bb;
/* Nothing to do if no regions created. */ /* Nothing to do if no regions created. */
if (cfun->eh->region_tree == NULL) if (cfun->eh->region_tree == NULL)
return; return;
...@@ -2269,8 +2356,25 @@ finish_eh_generation (void) ...@@ -2269,8 +2356,25 @@ finish_eh_generation (void)
/* We've totally changed the CFG. Start over. */ /* We've totally changed the CFG. Start over. */
find_exception_handler_labels (); find_exception_handler_labels ();
rebuild_jump_labels (get_insns ()); break_superblocks ();
find_basic_blocks (get_insns (), max_reg_num (), 0); if (USING_SJLJ_EXCEPTIONS)
commit_edge_insertions ();
FOR_EACH_BB (bb)
{
edge e, next;
bool eh = false;
for (e = bb->succ; e; e = next)
{
next = e->succ_next;
if (e->flags & EDGE_EH)
{
remove_edge (e);
eh = true;
}
}
if (eh)
make_eh_edge (NULL, bb, BB_END (bb));
}
cleanup_cfg (CLEANUP_PRE_LOOP | CLEANUP_NO_INSN_DEL); cleanup_cfg (CLEANUP_PRE_LOOP | CLEANUP_NO_INSN_DEL);
} }
......
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