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:
Eric Botcazou 2011-04-07 21:11:51 +00:00 committed by Eric Botcazou
parent df9292840d
commit cf103ca449
7 changed files with 78 additions and 47 deletions

View File

@ -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):

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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,

View File

@ -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)

View File

@ -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 */