Commit 45d99234 by Jeff Law Committed by Jeff Law

tree-ssa-threadedge.c: Fix some trailing whitespace problems.

        * tree-ssa-threadedge.c: Fix some trailing whitespace problems.

        * tree-ssa-threadedge.c (thread_through_normal_block): Broken out of ...
        (thread_across_edge): Here.  Call it.

From-SVN: r203217
parent 8a2cb59f
2013-10-04 Jeff Law <law@redhat.com>
* tree-ssa-threadedge.c: Fix some trailing whitespace problems.
* tree-ssa-threadedge.c (thread_through_normal_block): Broken out of ...
(thread_across_edge): Here. Call it.
2013-10-04 Cary Coutant <ccoutant@google.com> 2013-10-04 Cary Coutant <ccoutant@google.com>
* dwarf2out.c (dw_sra_loc_expr): Release addr_table entries when * dwarf2out.c (dw_sra_loc_expr): Release addr_table entries when
......
...@@ -771,7 +771,7 @@ thread_around_empty_blocks (edge taken_edge, ...@@ -771,7 +771,7 @@ thread_around_empty_blocks (edge taken_edge,
gsi = gsi_start_nondebug_bb (bb); gsi = gsi_start_nondebug_bb (bb);
/* If the block has no statements, but does have a single successor, then /* If the block has no statements, but does have a single successor, then
it's just a forwarding block and we can thread through it trivially. it's just a forwarding block and we can thread through it trivially.
However, note that just threading through empty blocks with single However, note that just threading through empty blocks with single
successors is not inherently profitable. For the jump thread to successors is not inherently profitable. For the jump thread to
...@@ -779,7 +779,7 @@ thread_around_empty_blocks (edge taken_edge, ...@@ -779,7 +779,7 @@ thread_around_empty_blocks (edge taken_edge,
By taking the return value from the recursive call, we get the By taking the return value from the recursive call, we get the
desired effect of returning TRUE when we found a profitable jump desired effect of returning TRUE when we found a profitable jump
threading opportunity and FALSE otherwise. threading opportunity and FALSE otherwise.
This is particularly important when this routine is called after This is particularly important when this routine is called after
processing a joiner block. Returning TRUE too aggressively in processing a joiner block. Returning TRUE too aggressively in
...@@ -844,13 +844,16 @@ thread_around_empty_blocks (edge taken_edge, ...@@ -844,13 +844,16 @@ thread_around_empty_blocks (edge taken_edge,
path); path);
return true; return true;
} }
return false; return false;
} }
/* We are exiting E->src, see if E->dest ends with a conditional /* We are exiting E->src, see if E->dest ends with a conditional
jump which has a known value when reached via E. jump which has a known value when reached via E.
E->dest can have arbitrary side effects which, if threading is
successful, will be maintained.
Special care is necessary if E is a back edge in the CFG as we Special care is necessary if E is a back edge in the CFG as we
may have already recorded equivalences for E->dest into our may have already recorded equivalences for E->dest into our
various tables, including the result of the conditional at various tables, including the result of the conditional at
...@@ -858,11 +861,6 @@ thread_around_empty_blocks (edge taken_edge, ...@@ -858,11 +861,6 @@ thread_around_empty_blocks (edge taken_edge,
limited in that case to avoid short-circuiting the loop limited in that case to avoid short-circuiting the loop
incorrectly. incorrectly.
Note it is quite common for the first block inside a loop to
end with a conditional which is either always true or always
false when reached via the loop backedge. Thus we do not want
to blindly disable threading across a loop backedge.
DUMMY_COND is a shared cond_expr used by condition simplification as scratch, DUMMY_COND is a shared cond_expr used by condition simplification as scratch,
to avoid allocating memory. to avoid allocating memory.
...@@ -873,17 +871,19 @@ thread_around_empty_blocks (edge taken_edge, ...@@ -873,17 +871,19 @@ thread_around_empty_blocks (edge taken_edge,
STACK is used to undo temporary equivalences created during the walk of STACK is used to undo temporary equivalences created during the walk of
E->dest. E->dest.
SIMPLIFY is a pass-specific function used to simplify statements. */ SIMPLIFY is a pass-specific function used to simplify statements.
void Our caller is responsible for restoring the state of the expression
thread_across_edge (gimple dummy_cond, and const_and_copies stacks. */
edge e,
bool handle_dominating_asserts,
vec<tree> *stack,
tree (*simplify) (gimple, gimple))
{
gimple stmt;
static bool
thread_through_normal_block (edge e,
gimple dummy_cond,
bool handle_dominating_asserts,
vec<tree> *stack,
tree (*simplify) (gimple, gimple),
vec<jump_thread_edge *> *path)
{
/* If E is a backedge, then we want to verify that the COND_EXPR, /* If E is a backedge, then we want to verify that the COND_EXPR,
SWITCH_EXPR or GOTO_EXPR at the end of e->dest is not affected SWITCH_EXPR or GOTO_EXPR at the end of e->dest is not affected
by any statements in e->dest. If it is affected, then it is not by any statements in e->dest. If it is affected, then it is not
...@@ -891,20 +891,19 @@ thread_across_edge (gimple dummy_cond, ...@@ -891,20 +891,19 @@ thread_across_edge (gimple dummy_cond,
if (e->flags & EDGE_DFS_BACK) if (e->flags & EDGE_DFS_BACK)
{ {
if (cond_arg_set_in_bb (e, e->dest)) if (cond_arg_set_in_bb (e, e->dest))
goto fail; return false;
} }
stmt_count = 0;
/* PHIs create temporary equivalences. */ /* PHIs create temporary equivalences. */
if (!record_temporary_equivalences_from_phis (e, stack)) if (!record_temporary_equivalences_from_phis (e, stack))
goto fail; return false;
/* Now walk each statement recording any context sensitive /* Now walk each statement recording any context sensitive
temporary equivalences we can detect. */ temporary equivalences we can detect. */
stmt = record_temporary_equivalences_from_stmts_at_dest (e, stack, simplify); gimple stmt
= record_temporary_equivalences_from_stmts_at_dest (e, stack, simplify);
if (!stmt) if (!stmt)
goto fail; return false;
/* If we stopped at a COND_EXPR or SWITCH_EXPR, see if we know which arm /* If we stopped at a COND_EXPR or SWITCH_EXPR, see if we know which arm
will be taken. */ will be taken. */
...@@ -927,9 +926,8 @@ thread_across_edge (gimple dummy_cond, ...@@ -927,9 +926,8 @@ thread_across_edge (gimple dummy_cond,
/* DEST could be NULL for a computed jump to an absolute /* DEST could be NULL for a computed jump to an absolute
address. */ address. */
if (dest == NULL || dest == e->dest) if (dest == NULL || dest == e->dest)
goto fail; return false;
vec<jump_thread_edge *> *path = new vec<jump_thread_edge *> ();
jump_thread_edge *x jump_thread_edge *x
= new jump_thread_edge (e, EDGE_START_JUMP_THREAD); = new jump_thread_edge (e, EDGE_START_JUMP_THREAD);
path->safe_push (x); path->safe_push (x);
...@@ -956,14 +954,65 @@ thread_across_edge (gimple dummy_cond, ...@@ -956,14 +954,65 @@ thread_across_edge (gimple dummy_cond,
path); path);
BITMAP_FREE (visited); BITMAP_FREE (visited);
} }
return true;
remove_temporary_equivalences (stack);
propagate_threaded_block_debug_into (path->last ()->e->dest,
e->dest);
register_jump_thread (path);
return;
} }
} }
return false;
}
/* We are exiting E->src, see if E->dest ends with a conditional
jump which has a known value when reached via E.
Special care is necessary if E is a back edge in the CFG as we
may have already recorded equivalences for E->dest into our
various tables, including the result of the conditional at
the end of E->dest. Threading opportunities are severely
limited in that case to avoid short-circuiting the loop
incorrectly.
Note it is quite common for the first block inside a loop to
end with a conditional which is either always true or always
false when reached via the loop backedge. Thus we do not want
to blindly disable threading across a loop backedge.
DUMMY_COND is a shared cond_expr used by condition simplification as scratch,
to avoid allocating memory.
HANDLE_DOMINATING_ASSERTS is true if we should try to replace operands of
the simplified condition with left-hand sides of ASSERT_EXPRs they are
used in.
STACK is used to undo temporary equivalences created during the walk of
E->dest.
SIMPLIFY is a pass-specific function used to simplify statements. */
void
thread_across_edge (gimple dummy_cond,
edge e,
bool handle_dominating_asserts,
vec<tree> *stack,
tree (*simplify) (gimple, gimple))
{
stmt_count = 0;
vec<jump_thread_edge *> *path = new vec<jump_thread_edge *> ();
if (thread_through_normal_block (e, dummy_cond, handle_dominating_asserts,
stack, simplify, path))
{
propagate_threaded_block_debug_into (path->last ()->e->dest,
e->dest);
remove_temporary_equivalences (stack);
register_jump_thread (path);
return;
}
else
{
/* There should be no edges on the path, so no need to walk through
the vector entries. */
gcc_assert (path->length () == 0);
path->release ();
}
/* We were unable to determine what out edge from E->dest is taken. However, /* We were unable to determine what out edge from E->dest is taken. However,
we might still be able to thread through successors of E->dest. This we might still be able to thread through successors of E->dest. This
...@@ -1026,6 +1075,5 @@ thread_across_edge (gimple dummy_cond, ...@@ -1026,6 +1075,5 @@ thread_across_edge (gimple dummy_cond,
BITMAP_FREE (visited); BITMAP_FREE (visited);
} }
fail:
remove_temporary_equivalences (stack); remove_temporary_equivalences (stack);
} }
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