basic-block.h (force_nonfallthru): Move to...
* basic-block.h (force_nonfallthru): Move to... * cfghooks.h (struct cfg_hooks): Add force_nonfallthru hook. (force_nonfallthru): ...here. * cfghooks.c (force_nonfallthru): New function. * cfgrtl.c (force_nonfallthru): Rename into... (rtl_force_nonfallthru): ...this. (commit_one_edge_insertion): Do not set AUX field. (commit_edge_insertions): Do not discover new basic blocks. (rtl_cfg_hooks): Add rtl_force_nonfallthru. (cfg_layout_rtl_cfg_hooks): Likewise. * function.c (thread_prologue_and_epilogue_insns): Remove bogus ATTRIBUTE_UNUSED. Discover new basic blocks in the prologue insns. * tree-cfg.c (gimple_cfg_hooks): Add NULL for force_nonfallthru. From-SVN: r172128
This commit is contained in:
parent
df9292840d
commit
cf103ca449
@ -1,3 +1,19 @@
|
||||
2011-04-07 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* basic-block.h (force_nonfallthru): Move to...
|
||||
* cfghooks.h (struct cfg_hooks): Add force_nonfallthru hook.
|
||||
(force_nonfallthru): ...here.
|
||||
* cfghooks.c (force_nonfallthru): New function.
|
||||
* cfgrtl.c (force_nonfallthru): Rename into...
|
||||
(rtl_force_nonfallthru): ...this.
|
||||
(commit_one_edge_insertion): Do not set AUX field.
|
||||
(commit_edge_insertions): Do not discover new basic blocks.
|
||||
(rtl_cfg_hooks): Add rtl_force_nonfallthru.
|
||||
(cfg_layout_rtl_cfg_hooks): Likewise.
|
||||
* function.c (thread_prologue_and_epilogue_insns): Remove bogus
|
||||
ATTRIBUTE_UNUSED. Discover new basic blocks in the prologue insns.
|
||||
* tree-cfg.c (gimple_cfg_hooks): Add NULL for force_nonfallthru.
|
||||
|
||||
2011-04-07 Anatoly Sokolov <aesok@post.ru>
|
||||
|
||||
* config/mips/mips.h (REG_MODE_OK_FOR_BASE_P, REG_OK_FOR_INDEX_P):
|
||||
|
@ -794,7 +794,6 @@ extern void flow_nodes_print (const char *, const_sbitmap, FILE *);
|
||||
extern void flow_edge_list_print (const char *, const edge *, int, FILE *);
|
||||
|
||||
/* In cfgrtl.c */
|
||||
extern basic_block force_nonfallthru (edge);
|
||||
extern rtx block_label (basic_block);
|
||||
extern bool purge_all_dead_edges (void);
|
||||
extern bool purge_dead_edges (basic_block);
|
||||
|
@ -398,8 +398,7 @@ redirect_edge_and_branch_force (edge e, basic_block dest)
|
||||
rescan_loop_exit (e, false, true);
|
||||
|
||||
ret = cfg_hooks->redirect_edge_and_branch_force (e, dest);
|
||||
if (ret != NULL
|
||||
&& dom_info_available_p (CDI_DOMINATORS))
|
||||
if (ret != NULL && dom_info_available_p (CDI_DOMINATORS))
|
||||
set_immediate_dominator (CDI_DOMINATORS, ret, src);
|
||||
|
||||
if (current_loops != NULL)
|
||||
@ -820,6 +819,8 @@ make_forwarder_block (basic_block bb, bool (*redirect_edge_p) (edge),
|
||||
return fallthru;
|
||||
}
|
||||
|
||||
/* Try to make the edge fallthru. */
|
||||
|
||||
void
|
||||
tidy_fallthru_edge (edge e)
|
||||
{
|
||||
@ -874,6 +875,42 @@ tidy_fallthru_edges (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Edge E is assumed to be fallthru edge. Emit needed jump instruction
|
||||
(and possibly create new basic block) to make edge non-fallthru.
|
||||
Return newly created BB or NULL if none. */
|
||||
|
||||
basic_block
|
||||
force_nonfallthru (edge e)
|
||||
{
|
||||
basic_block ret, src = e->src, dest = e->dest;
|
||||
struct loop *loop;
|
||||
|
||||
if (!cfg_hooks->force_nonfallthru)
|
||||
internal_error ("%s does not support force_nonfallthru",
|
||||
cfg_hooks->name);
|
||||
|
||||
if (current_loops != NULL)
|
||||
rescan_loop_exit (e, false, true);
|
||||
|
||||
ret = cfg_hooks->force_nonfallthru (e);
|
||||
if (ret != NULL && dom_info_available_p (CDI_DOMINATORS))
|
||||
set_immediate_dominator (CDI_DOMINATORS, ret, src);
|
||||
|
||||
if (current_loops != NULL)
|
||||
{
|
||||
if (ret != NULL)
|
||||
{
|
||||
loop = find_common_loop (single_pred (ret)->loop_father,
|
||||
single_succ (ret)->loop_father);
|
||||
add_bb_to_loop (ret, loop);
|
||||
}
|
||||
else if (find_edge (src, dest) == e)
|
||||
rescan_loop_exit (e, true, false);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Returns true if we can duplicate basic block BB. */
|
||||
|
||||
bool
|
||||
|
@ -85,9 +85,12 @@ struct cfg_hooks
|
||||
basic_block (*split_edge) (edge);
|
||||
void (*make_forwarder_block) (edge);
|
||||
|
||||
/* Tries to make the edge fallthru. */
|
||||
/* Try to make the edge fallthru. */
|
||||
void (*tidy_fallthru_edge) (edge);
|
||||
|
||||
/* Make the edge non-fallthru. */
|
||||
basic_block (*force_nonfallthru) (edge);
|
||||
|
||||
/* Say whether a block ends with a call, possibly followed by some
|
||||
other code that must stay with the call. */
|
||||
bool (*block_ends_with_call_p) (basic_block);
|
||||
@ -156,6 +159,7 @@ extern bool can_merge_blocks_p (basic_block, basic_block);
|
||||
extern void merge_blocks (basic_block, basic_block);
|
||||
extern edge make_forwarder_block (basic_block, bool (*)(edge),
|
||||
void (*) (basic_block));
|
||||
extern basic_block force_nonfallthru (edge);
|
||||
extern void tidy_fallthru_edge (edge);
|
||||
extern void tidy_fallthru_edges (void);
|
||||
extern void predict_edge (edge e, enum br_predictor predictor, int probability);
|
||||
|
43
gcc/cfgrtl.c
43
gcc/cfgrtl.c
@ -1279,8 +1279,8 @@ force_nonfallthru_and_redirect (edge e, basic_block target)
|
||||
(and possibly create new basic block) to make edge non-fallthru.
|
||||
Return newly created BB or NULL if none. */
|
||||
|
||||
basic_block
|
||||
force_nonfallthru (edge e)
|
||||
static basic_block
|
||||
rtl_force_nonfallthru (edge e)
|
||||
{
|
||||
return force_nonfallthru_and_redirect (e, e->dest);
|
||||
}
|
||||
@ -1566,10 +1566,6 @@ commit_one_edge_insertion (edge e)
|
||||
}
|
||||
else
|
||||
gcc_assert (!JUMP_P (last));
|
||||
|
||||
/* Mark the basic block for find_many_sub_basic_blocks. */
|
||||
if (current_ir_type () != IR_RTL_CFGLAYOUT)
|
||||
bb->aux = &bb->aux;
|
||||
}
|
||||
|
||||
/* Update the CFG for all queued instructions. */
|
||||
@ -1578,8 +1574,6 @@ void
|
||||
commit_edge_insertions (void)
|
||||
{
|
||||
basic_block bb;
|
||||
sbitmap blocks;
|
||||
bool changed = false;
|
||||
|
||||
#ifdef ENABLE_CHECKING
|
||||
verify_flow_info ();
|
||||
@ -1592,35 +1586,8 @@ commit_edge_insertions (void)
|
||||
|
||||
FOR_EACH_EDGE (e, ei, bb->succs)
|
||||
if (e->insns.r)
|
||||
{
|
||||
changed = true;
|
||||
commit_one_edge_insertion (e);
|
||||
}
|
||||
commit_one_edge_insertion (e);
|
||||
}
|
||||
|
||||
if (!changed)
|
||||
return;
|
||||
|
||||
/* In the old rtl CFG API, it was OK to insert control flow on an
|
||||
edge, apparently? In cfglayout mode, this will *not* work, and
|
||||
the caller is responsible for making sure that control flow is
|
||||
valid at all times. */
|
||||
if (current_ir_type () == IR_RTL_CFGLAYOUT)
|
||||
return;
|
||||
|
||||
blocks = sbitmap_alloc (last_basic_block);
|
||||
sbitmap_zero (blocks);
|
||||
FOR_EACH_BB (bb)
|
||||
if (bb->aux)
|
||||
{
|
||||
SET_BIT (blocks, bb->index);
|
||||
/* Check for forgotten bb->aux values before commit_edge_insertions
|
||||
call. */
|
||||
gcc_assert (bb->aux == &bb->aux);
|
||||
bb->aux = NULL;
|
||||
}
|
||||
find_many_sub_basic_blocks (blocks);
|
||||
sbitmap_free (blocks);
|
||||
}
|
||||
|
||||
|
||||
@ -3233,6 +3200,7 @@ struct cfg_hooks rtl_cfg_hooks = {
|
||||
rtl_split_edge,
|
||||
rtl_make_forwarder_block,
|
||||
rtl_tidy_fallthru_edge,
|
||||
rtl_force_nonfallthru,
|
||||
rtl_block_ends_with_call_p,
|
||||
rtl_block_ends_with_condjump_p,
|
||||
rtl_flow_call_edges_add,
|
||||
@ -3276,7 +3244,8 @@ struct cfg_hooks cfg_layout_rtl_cfg_hooks = {
|
||||
cfg_layout_duplicate_bb,
|
||||
cfg_layout_split_edge,
|
||||
rtl_make_forwarder_block,
|
||||
NULL,
|
||||
NULL, /* tidy_fallthru_edge */
|
||||
rtl_force_nonfallthru,
|
||||
rtl_block_ends_with_call_p,
|
||||
rtl_block_ends_with_condjump_p,
|
||||
rtl_flow_call_edges_add,
|
||||
|
@ -5295,8 +5295,7 @@ thread_prologue_and_epilogue_insns (void)
|
||||
{
|
||||
bool inserted;
|
||||
rtx seq ATTRIBUTE_UNUSED, epilogue_end ATTRIBUTE_UNUSED;
|
||||
edge entry_edge ATTRIBUTE_UNUSED;
|
||||
edge e;
|
||||
edge entry_edge, e;
|
||||
edge_iterator ei;
|
||||
|
||||
rtl_profile_for_bb (ENTRY_BLOCK_PTR);
|
||||
@ -5328,10 +5327,6 @@ thread_prologue_and_epilogue_insns (void)
|
||||
record_insns (seq, NULL, &prologue_insn_hash);
|
||||
set_insn_locators (seq, prologue_locator);
|
||||
|
||||
/* This relies on the fact that committing the edge insertion
|
||||
will look for basic blocks within the inserted instructions,
|
||||
which in turn relies on the fact that we are not in CFG
|
||||
layout mode here. */
|
||||
insert_insn_on_edge (seq, entry_edge);
|
||||
inserted = true;
|
||||
#endif
|
||||
@ -5566,13 +5561,23 @@ thread_prologue_and_epilogue_insns (void)
|
||||
cur_bb->aux = cur_bb->next_bb;
|
||||
cfg_layout_finalize ();
|
||||
}
|
||||
|
||||
epilogue_done:
|
||||
default_rtl_profile ();
|
||||
|
||||
if (inserted)
|
||||
{
|
||||
sbitmap blocks;
|
||||
|
||||
commit_edge_insertions ();
|
||||
|
||||
/* Look for basic blocks within the prologue insns. */
|
||||
blocks = sbitmap_alloc (last_basic_block);
|
||||
sbitmap_zero (blocks);
|
||||
SET_BIT (blocks, entry_edge->dest->index);
|
||||
find_many_sub_basic_blocks (blocks);
|
||||
sbitmap_free (blocks);
|
||||
|
||||
/* The epilogue insns we inserted may cause the exit edge to no longer
|
||||
be fallthru. */
|
||||
FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
|
||||
|
@ -7135,6 +7135,7 @@ struct cfg_hooks gimple_cfg_hooks = {
|
||||
gimple_split_edge, /* split_edge */
|
||||
gimple_make_forwarder_block, /* make_forward_block */
|
||||
NULL, /* tidy_fallthru_edge */
|
||||
NULL, /* force_nonfallthru */
|
||||
gimple_block_ends_with_call_p,/* block_ends_with_call_p */
|
||||
gimple_block_ends_with_condjump_p, /* block_ends_with_condjump_p */
|
||||
gimple_flow_call_edges_add, /* flow_call_edges_add */
|
||||
|
Loading…
x
Reference in New Issue
Block a user