Commit 8926e325 by Tom de Vries Committed by Tom de Vries

Add gimple_find_sub_bbs

2015-04-17  Tom de Vries  <tom@codesourcery.com>
	    Michael Matz  <matz@suse.de>

	* tree-cfg.c (make_blocks_1): Factor out of ...
	(make_blocks): ... here.
	(make_edges_bb): Factor out of ...
	(make_edges): ... here.
	(gimple_find_sub_bbs): New function.
	* tree-cfg.h (gimple_find_sub_bbs): Declare.

Co-Authored-By: Michael Matz <matz@suse.de>

From-SVN: r222170
parent cef3bed6
2015-04-17 Tom de Vries <tom@codesourcery.com> 2015-04-17 Tom de Vries <tom@codesourcery.com>
Michael Matz <matz@suse.de>
* tree-cfg.c (make_blocks_1): Factor out of ...
(make_blocks): ... here.
(make_edges_bb): Factor out of ...
(make_edges): ... here.
(gimple_find_sub_bbs): New function.
* tree-cfg.h (gimple_find_sub_bbs): Declare.
2015-04-17 Tom de Vries <tom@codesourcery.com>
* tree.c (free_lang_data): Disable lang_hooks.gimplify_expr. * tree.c (free_lang_data): Disable lang_hooks.gimplify_expr.
......
...@@ -513,16 +513,15 @@ gimple_call_initialize_ctrl_altering (gimple stmt) ...@@ -513,16 +513,15 @@ gimple_call_initialize_ctrl_altering (gimple stmt)
} }
/* Build a flowgraph for the sequence of stmts SEQ. */ /* Insert SEQ after BB and build a flowgraph. */
static void static basic_block
make_blocks (gimple_seq seq) make_blocks_1 (gimple_seq seq, basic_block bb)
{ {
gimple_stmt_iterator i = gsi_start (seq); gimple_stmt_iterator i = gsi_start (seq);
gimple stmt = NULL; gimple stmt = NULL;
bool start_new_block = true; bool start_new_block = true;
bool first_stmt_of_seq = true; bool first_stmt_of_seq = true;
basic_block bb = ENTRY_BLOCK_PTR_FOR_FN (cfun);
while (!gsi_end_p (i)) while (!gsi_end_p (i))
{ {
...@@ -579,8 +578,16 @@ make_blocks (gimple_seq seq) ...@@ -579,8 +578,16 @@ make_blocks (gimple_seq seq)
gsi_next (&i); gsi_next (&i);
first_stmt_of_seq = false; first_stmt_of_seq = false;
} }
return bb;
} }
/* Build a flowgraph for the sequence of stmts SEQ. */
static void
make_blocks (gimple_seq seq)
{
make_blocks_1 (seq, ENTRY_BLOCK_PTR_FOR_FN (cfun));
}
/* Create and return a new empty basic block after bb AFTER. */ /* Create and return a new empty basic block after bb AFTER. */
...@@ -807,41 +814,26 @@ handle_abnormal_edges (basic_block *dispatcher_bbs, ...@@ -807,41 +814,26 @@ handle_abnormal_edges (basic_block *dispatcher_bbs,
make_edge (*dispatcher, for_bb, EDGE_ABNORMAL); make_edge (*dispatcher, for_bb, EDGE_ABNORMAL);
} }
/* Join all the blocks in the flowgraph. */ /* Creates outgoing edges for BB. Returns 1 when it ends with an
computed goto, returns 2 when it ends with a statement that
might return to this function via an nonlocal goto, otherwise
return 0. Updates *PCUR_REGION with the OMP region this BB is in. */
static void static int
make_edges (void) make_edges_bb (basic_block bb, struct omp_region **pcur_region, int *pomp_index)
{ {
basic_block bb;
struct omp_region *cur_region = NULL;
auto_vec<basic_block> ab_edge_goto;
auto_vec<basic_block> ab_edge_call;
int *bb_to_omp_idx = NULL;
int cur_omp_region_idx = 0;
/* Create an edge from entry to the first block with executable
statements in it. */
make_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun),
BASIC_BLOCK_FOR_FN (cfun, NUM_FIXED_BLOCKS),
EDGE_FALLTHRU);
/* Traverse the basic block array placing edges. */
FOR_EACH_BB_FN (bb, cfun)
{
gimple last = last_stmt (bb); gimple last = last_stmt (bb);
bool fallthru; bool fallthru = false;
int ret = 0;
if (bb_to_omp_idx) if (!last)
bb_to_omp_idx[bb->index] = cur_omp_region_idx; return ret;
if (last) switch (gimple_code (last))
{
enum gimple_code code = gimple_code (last);
switch (code)
{ {
case GIMPLE_GOTO: case GIMPLE_GOTO:
if (make_goto_expr_edges (bb)) if (make_goto_expr_edges (bb))
ab_edge_goto.safe_push (bb); ret = 1;
fallthru = false; fallthru = false;
break; break;
case GIMPLE_RETURN: case GIMPLE_RETURN:
...@@ -872,7 +864,7 @@ make_edges (void) ...@@ -872,7 +864,7 @@ make_edges (void)
make edges from this call site to all the nonlocal goto make edges from this call site to all the nonlocal goto
handlers. */ handlers. */
if (stmt_can_make_abnormal_goto (last)) if (stmt_can_make_abnormal_goto (last))
ab_edge_call.safe_push (bb); ret = 2;
/* If this statement has reachable exception handlers, then /* If this statement has reachable exception handlers, then
create abnormal edges to them. */ create abnormal edges to them. */
...@@ -903,10 +895,7 @@ make_edges (void) ...@@ -903,10 +895,7 @@ make_edges (void)
break; break;
CASE_GIMPLE_OMP: CASE_GIMPLE_OMP:
fallthru = make_gimple_omp_edges (bb, &cur_region, fallthru = make_gimple_omp_edges (bb, pcur_region, pomp_index);
&cur_omp_region_idx);
if (cur_region && bb_to_omp_idx == NULL)
bb_to_omp_idx = XCNEWVEC (int, n_basic_blocks_for_fn (cfun));
break; break;
case GIMPLE_TRANSACTION: case GIMPLE_TRANSACTION:
...@@ -922,13 +911,49 @@ make_edges (void) ...@@ -922,13 +911,49 @@ make_edges (void)
default: default:
gcc_assert (!stmt_ends_bb_p (last)); gcc_assert (!stmt_ends_bb_p (last));
fallthru = true; fallthru = true;
break;
} }
}
else
fallthru = true;
if (fallthru) if (fallthru)
make_edge (bb, bb->next_bb, EDGE_FALLTHRU); make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
return ret;
}
/* Join all the blocks in the flowgraph. */
static void
make_edges (void)
{
basic_block bb;
struct omp_region *cur_region = NULL;
auto_vec<basic_block> ab_edge_goto;
auto_vec<basic_block> ab_edge_call;
int *bb_to_omp_idx = NULL;
int cur_omp_region_idx = 0;
/* Create an edge from entry to the first block with executable
statements in it. */
make_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun),
BASIC_BLOCK_FOR_FN (cfun, NUM_FIXED_BLOCKS),
EDGE_FALLTHRU);
/* Traverse the basic block array placing edges. */
FOR_EACH_BB_FN (bb, cfun)
{
int mer;
if (bb_to_omp_idx)
bb_to_omp_idx[bb->index] = cur_omp_region_idx;
mer = make_edges_bb (bb, &cur_region, &cur_omp_region_idx);
if (mer == 1)
ab_edge_goto.safe_push (bb);
else if (mer == 2)
ab_edge_call.safe_push (bb);
if (cur_region && bb_to_omp_idx == NULL)
bb_to_omp_idx = XCNEWVEC (int, n_basic_blocks_for_fn (cfun));
} }
/* Computed gotos are hell to deal with, especially if there are /* Computed gotos are hell to deal with, especially if there are
...@@ -1008,6 +1033,43 @@ make_edges (void) ...@@ -1008,6 +1033,43 @@ make_edges (void)
fold_cond_expr_cond (); fold_cond_expr_cond ();
} }
/* Add SEQ after GSI. Start new bb after GSI, and created further bbs as
needed. Returns true if new bbs were created.
Note: This is transitional code, and should not be used for new code. We
should be able to get rid of this by rewriting all target va-arg
gimplification hooks to use an interface gimple_build_cond_value as described
in https://gcc.gnu.org/ml/gcc-patches/2015-02/msg01194.html. */
bool
gimple_find_sub_bbs (gimple_seq seq, gimple_stmt_iterator *gsi)
{
gimple stmt = gsi_stmt (*gsi);
basic_block bb = gimple_bb (stmt);
basic_block lastbb, afterbb;
int old_num_bbs = n_basic_blocks_for_fn (cfun);
edge e;
lastbb = make_blocks_1 (seq, bb);
if (old_num_bbs == n_basic_blocks_for_fn (cfun))
return false;
e = split_block (bb, stmt);
/* Move e->dest to come after the new basic blocks. */
afterbb = e->dest;
unlink_block (afterbb);
link_block (afterbb, lastbb);
redirect_edge_succ (e, bb->next_bb);
bb = bb->next_bb;
while (bb != afterbb)
{
struct omp_region *cur_region = NULL;
int cur_omp_region_idx = 0;
int mer = make_edges_bb (bb, &cur_region, &cur_omp_region_idx);
gcc_assert (!mer && !cur_region);
add_bb_to_loop (bb, afterbb->loop_father);
bb = bb->next_bb;
}
return true;
}
/* Find the next available discriminator value for LOCUS. The /* Find the next available discriminator value for LOCUS. The
discriminator distinguishes among several basic blocks that discriminator distinguishes among several basic blocks that
share a common locus, allowing for more accurate sample-based share a common locus, allowing for more accurate sample-based
......
...@@ -103,5 +103,6 @@ extern void extract_true_false_edges_from_block (basic_block, edge *, edge *); ...@@ -103,5 +103,6 @@ extern void extract_true_false_edges_from_block (basic_block, edge *, edge *);
extern unsigned int execute_fixup_cfg (void); extern unsigned int execute_fixup_cfg (void);
extern unsigned int split_critical_edges (void); extern unsigned int split_critical_edges (void);
extern basic_block insert_cond_bb (basic_block, gimple, gimple); extern basic_block insert_cond_bb (basic_block, gimple, gimple);
extern bool gimple_find_sub_bbs (gimple_seq, gimple_stmt_iterator *);
#endif /* _TREE_CFG_H */ #endif /* _TREE_CFG_H */
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