* tree-vrp.c (has_assert_expr, maybe_add_assert_expr): Remove.

From-SVN: r100492
This commit is contained in:
Diego Novillo 2005-06-02 12:35:25 +00:00 committed by Diego Novillo
parent e7d6beb0f8
commit 46c4495f40
2 changed files with 4 additions and 289 deletions

View File

@ -1,3 +1,7 @@
2005-06-02 Diego Novillo <dnovillo@redhat.com>
* tree-vrp.c (has_assert_expr, maybe_add_assert_expr): Remove.
2005-06-02 Jan Hubicka <jh@suse.cz>
* cgraph.c (dump_cgraph_node): Print new flags.

View File

@ -1907,295 +1907,6 @@ infer_value_range (tree stmt, tree op, enum tree_code *comp_code_p, tree *val_p)
}
#if 0
/* Return true if OP is the result of an ASSERT_EXPR that tests the
same condition as COND. */
static bool
has_assert_expr (tree op, tree cond)
{
tree def_stmt = SSA_NAME_DEF_STMT (op);
tree assert_expr, other_cond, other_op;
/* If OP was not generated by an ASSERT_EXPR, return false. */
if (TREE_CODE (def_stmt) != MODIFY_EXPR
|| TREE_CODE (TREE_OPERAND (def_stmt, 1)) != ASSERT_EXPR)
return false;
assert_expr = TREE_OPERAND (def_stmt, 1);
other_cond = ASSERT_EXPR_COND (assert_expr);
other_op = ASSERT_EXPR_VAR (assert_expr);
if (TREE_CODE (cond) == TREE_CODE (other_cond))
{
tree t1, t2;
/* If COND is not a comparison predicate, something is wrong. */
gcc_assert (COMPARISON_CLASS_P (cond));
/* Note that we only need to compare against one of the operands
of OTHER_COND.
Suppose that we are about to insert the assertion ASSERT_EXPR
<x_4, x_4 != 0> and the defining statement for x_4 is x_4 =
ASSERT_EXPR <x_3, x_3 != 0>.
In this case, we don't really want to insert a new
ASSERT_EXPR for x_4 because that would be redundant. We
already know that x_4 is not 0. So, when comparing the
conditionals 'x_3 != 0' and 'x_4 != 0', we don't want to
compare x_3 and x_4, we just want to compare the predicate's
code (!=) and the other operand (0). */
if (TREE_OPERAND (cond, 0) == op)
t1 = TREE_OPERAND (cond, 1);
else
t1 = TREE_OPERAND (cond, 0);
if (TREE_OPERAND (other_cond, 0) == other_op)
t2 = TREE_OPERAND (other_cond, 1);
else
t2 = TREE_OPERAND (other_cond, 0);
return (t1 == t2 || operand_equal_p (t1, t2, 0));
}
return false;
}
/* Traverse all the statements in block BB looking for used variables.
Variables used in BB are added to bitmap FOUND. The algorithm
works in three main parts:
1- For every statement S in BB, all the variables used by S are
added to bitmap FOUND.
2- If statement S uses an operand N in a way that exposes a known
value range for N, then if N was not already generated by an
ASSERT_EXPR, create a new ASSERT_EXPR for N. For instance, if N
is a pointer and the statement dereferences it, we can assume
that N is not NULL.
3- COND_EXPRs are a special case of #2. We can derive range
information from the predicate but need to insert different
ASSERT_EXPRs for each of the sub-graphs rooted at the
conditional block. If the last statement of BB is a conditional
expression of the form 'X op Y', then
a) Remove X and Y from the set FOUND.
b) If the conditional dominates its THEN_CLAUSE sub-graph,
recurse into it. On return, if X and/or Y are marked in
FOUND, then an ASSERT_EXPR is added for the corresponding
variable.
c) Repeat step (b) on the ELSE_CLAUSE.
d) Mark X and Y in FOUND.
4- If BB does not end in a conditional expression, then we recurse
into BB's dominator children.
At the end of the recursive traversal, ASSERT_EXPRs will have been
added to the edges of COND_EXPR blocks that have sub-graphs using
one or both predicate operands. For instance,
if (a == 9)
b = a;
else
b = c + 1;
In this case, an assertion on the THEN clause is useful to
determine that 'a' is always 9 on that edge. However, an assertion
on the ELSE clause would be unnecessary.
On exit from this function, all the names created by the newly
inserted ASSERT_EXPRs need to be added to the SSA web by rewriting
the SSA names that they replace.
TODO. Handle SWITCH_EXPR. */
static bool
maybe_add_assert_expr (basic_block bb)
{
block_stmt_iterator si;
tree last;
bool added;
/* Step 1. Mark all the SSA names used in BB in bitmap FOUND. */
added = false;
last = NULL_TREE;
for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
{
tree stmt, op;
ssa_op_iter i;
stmt = bsi_stmt (si);
/* Mark all the SSA names used by STMT in bitmap FOUND. If STMT
is inside the sub-graph of a conditional block, when we
return from this recursive walk, our parent will use the
FOUND bitset to determine if one of the operands it was
looking for was present in the sub-graph. */
FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_USE)
{
tree cond;
/* If OP is used only once, namely in this STMT, don't
bother inserting an ASSERT_EXPR for it. Such an
ASSERT_EXPR would do nothing but increase compile time.
Experiments show that with this simple check, we can save
more than 20% of ASSERT_EXPRs. */
if (has_single_use (op))
continue;
SET_BIT (found, SSA_NAME_VERSION (op));
cond = infer_value_range (stmt, op);
if (!cond)
continue;
/* Step 2. If OP is used in such a way that we can infer a
value range for it, create a new ASSERT_EXPR for OP
(unless OP already has an ASSERT_EXPR). */
gcc_assert (!is_ctrl_stmt (stmt));
if (has_assert_expr (op, cond))
continue;
if (!stmt_ends_bb_p (stmt))
{
/* If STMT does not end the block, we can insert the new
assertion right after it. */
tree t = build_assert_expr_for (cond, op);
bsi_insert_after (&si, t, BSI_NEW_STMT);
added = true;
}
else
{
/* STMT must be the last statement in BB. We can only
insert new assertions on the non-abnormal edge out of
BB. Note that since STMT is not control flow, there
may only be one non-abnormal edge out of BB. */
edge_iterator ei;
edge e;
FOR_EACH_EDGE (e, ei, bb->succs)
if (!(e->flags & EDGE_ABNORMAL))
{
tree t = build_assert_expr_for (cond, op);
bsi_insert_on_edge (e, t);
added = true;
break;
}
}
}
/* Remember the last statement of the block. */
last = stmt;
}
/* Step 3. If BB's last statement is a conditional expression
involving integer operands, recurse into each of the sub-graphs
rooted at BB to determine if we need to add ASSERT_EXPRs.
Notice that we only care about the first operand of the
conditional. Adding assertions for both operands may actually
hinder VRP. FIXME, add example. */
if (last
&& TREE_CODE (last) == COND_EXPR
&& !fp_predicate (COND_EXPR_COND (last))
&& !ZERO_SSA_OPERANDS (last, SSA_OP_USE))
{
edge e;
edge_iterator ei;
tree op, cond;
basic_block son;
ssa_op_iter iter;
cond = COND_EXPR_COND (last);
/* Get just the first use operand. */
FOR_EACH_SSA_TREE_OPERAND (op, last, iter, SSA_OP_USE)
break;
gcc_assert (op != NULL);
/* Do not attempt to infer anything in names that flow through
abnormal edges. */
if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
return false;
/* Remove the COND_EXPR operand from the FOUND bitmap.
Otherwise, when we finish traversing each of the sub-graphs,
we won't know whether the variables were found in the
sub-graphs or if they had been found in a block upstream from
BB. */
RESET_BIT (found, SSA_NAME_VERSION (op));
/* Look for uses of the operands in each of the sub-graphs
rooted at BB. We need to check each of the outgoing edges
separately, so that we know what kind of ASSERT_EXPR to
insert. */
FOR_EACH_EDGE (e, ei, bb->succs)
{
/* If BB strictly dominates the sub-graph at E->DEST,
recurse into it. */
if (e->dest != bb
&& dominated_by_p (CDI_DOMINATORS, e->dest, bb))
added |= maybe_add_assert_expr (e->dest);
/* Once we traversed the sub-graph, check if any block inside
used either of the predicate's operands. If so, add the
appropriate ASSERT_EXPR. */
if (TEST_BIT (found, SSA_NAME_VERSION (op)))
{
/* We found a use of OP in the sub-graph rooted at
E->DEST. Add an ASSERT_EXPR according to whether
E goes to THEN_CLAUSE or ELSE_CLAUSE. */
tree c, t;
if (e->flags & EDGE_TRUE_VALUE)
c = unshare_expr (cond);
else if (e->flags & EDGE_FALSE_VALUE)
c = invert_truthvalue (cond);
else
gcc_unreachable ();
t = build_assert_expr_for (c, op);
bsi_insert_on_edge (e, t);
added = true;
}
}
/* Finally, mark all the COND_EXPR operands as found. */
SET_BIT (found, SSA_NAME_VERSION (op));
/* Recurse into the dominator children of BB that are not BB's
immediate successors. Note that we have already visited BB's
other dominator children above. */
for (son = first_dom_son (CDI_DOMINATORS, bb);
son;
son = next_dom_son (CDI_DOMINATORS, son))
{
if (find_edge (bb, son) == NULL)
added |= maybe_add_assert_expr (son);
}
}
else
{
/* Step 4. Recurse into the dominator children of BB. */
basic_block son;
for (son = first_dom_son (CDI_DOMINATORS, bb);
son;
son = next_dom_son (CDI_DOMINATORS, son))
added |= maybe_add_assert_expr (son);
}
return added;
}
#endif
void dump_asserts_for (FILE *, tree);
void debug_asserts_for (tree);
void dump_all_asserts (FILE *);