* tree-vrp.c (has_assert_expr, maybe_add_assert_expr): Remove.
From-SVN: r100492
This commit is contained in:
parent
e7d6beb0f8
commit
46c4495f40
|
@ -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.
|
||||
|
|
289
gcc/tree-vrp.c
289
gcc/tree-vrp.c
|
@ -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 *);
|
||||
|
|
Loading…
Reference in New Issue