Commit bec44647 by Kazu Hirata Committed by Kazu Hirata

tree-ssa-forwprop.c (vars, [...]): Remove.

	* tree-ssa-forwprop.c (vars,
	record_single_argument_cond_exprs,
	substitute_single_use_vars): Remove.
	(forward_propagate_into_cond_1, forward_propagate_into_cond):
	New.
	(tree_ssa_forward_propagate_single_use_vars): Call
	forward_propagate_into_cond for each COND_EXPR.

From-SVN: r98072
parent 8450a170
...@@ -4,6 +4,14 @@ ...@@ -4,6 +4,14 @@
* cgraphunit.c (INSNS_PER_CALL): Remove. * cgraphunit.c (INSNS_PER_CALL): Remove.
* tree-ssa-forwprop.c (vars,
record_single_argument_cond_exprs,
substitute_single_use_vars): Remove.
(forward_propagate_into_cond_1, forward_propagate_into_cond):
New.
(tree_ssa_forward_propagate_single_use_vars): Call
forward_propagate_into_cond for each COND_EXPR.
2005-04-12 Richard Henderson <rth@redhat.com> 2005-04-12 Richard Henderson <rth@redhat.com>
* config/i386/i386.c (ix86_prepare_sse_fp_compare_args): Split ... * config/i386/i386.c (ix86_prepare_sse_fp_compare_args): Split ...
......
...@@ -100,7 +100,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -100,7 +100,7 @@ Boston, MA 02111-1307, USA. */
In addition to eliminating the variable and the statement which assigns In addition to eliminating the variable and the statement which assigns
a value to the variable, we may be able to later thread the jump without a value to the variable, we may be able to later thread the jump without
adding insane complexity in the dominator optimizer. adding insane complexity in the dominator optimizer.
Also note these transformations can cascade. We handle this by having Also note these transformations can cascade. We handle this by having
a worklist of COND_EXPR statements to examine. As we make a change to a worklist of COND_EXPR statements to examine. As we make a change to
...@@ -109,293 +109,131 @@ Boston, MA 02111-1307, USA. */ ...@@ -109,293 +109,131 @@ Boston, MA 02111-1307, USA. */
This will (of course) be extended as other needs arise. */ This will (of course) be extended as other needs arise. */
/* Bitmap of variables for which we want immediate uses. This is set /* Forward propagate a single-use variable into COND once. Return a
by record_single_argument_cond_exprs and tested in need_imm_uses_for. */ new condition if successful. Return NULL_TREE otherwise. */
static bitmap vars;
static void tree_ssa_forward_propagate_single_use_vars (void);
static void record_single_argument_cond_exprs (varray_type,
varray_type *,
bitmap);
static void substitute_single_use_vars (varray_type *, varray_type);
/* Find all COND_EXPRs with a condition that is a naked SSA_NAME or
an equality comparison against a constant.
Record the identified COND_EXPRs and the SSA_NAME used in the COND_EXPR
into a virtual array, which is returned to the caller. Also record
into VARS that we will need immediate uses for the identified SSA_NAME.
The more uninteresting COND_EXPRs and associated SSA_NAMEs we can
filter out here, the faster this pass will run since its runtime is
dominated by the time to build immediate uses. */
static void
record_single_argument_cond_exprs (varray_type cond_worklist,
varray_type *vars_worklist,
bitmap vars)
static tree
forward_propagate_into_cond_1 (tree cond, tree *test_var_p)
{ {
/* The first pass over the blocks gathers the set of variables we need tree new_cond = NULL_TREE;
immediate uses for as well as the set of interesting COND_EXPRs. enum tree_code cond_code = TREE_CODE (cond);
tree test_var = NULL_TREE;
A simpler implementation may be appropriate if/when we have a lower tree def;
overhead means of getting immediate use information. */ tree def_rhs;
while (VARRAY_ACTIVE_SIZE (cond_worklist) > 0)
/* If the condition is not a lone variable or an equality test of an
SSA_NAME against an integral constant, then we do not have an
optimizable case.
Note these conditions also ensure the COND_EXPR has no
virtual operands or other side effects. */
if (cond_code != SSA_NAME
&& !((cond_code == EQ_EXPR || cond_code == NE_EXPR)
&& TREE_CODE (TREE_OPERAND (cond, 0)) == SSA_NAME
&& CONSTANT_CLASS_P (TREE_OPERAND (cond, 1))
&& INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (cond, 1)))))
return NULL_TREE;
/* Extract the single variable used in the test into TEST_VAR. */
if (cond_code == SSA_NAME)
test_var = cond;
else
test_var = TREE_OPERAND (cond, 0);
/* Now get the defining statement for TEST_VAR. Skip this case if
it's not defined by some MODIFY_EXPR. */
def = SSA_NAME_DEF_STMT (test_var);
if (TREE_CODE (def) != MODIFY_EXPR)
return NULL_TREE;
def_rhs = TREE_OPERAND (def, 1);
/* If TEST_VAR is set by adding or subtracting a constant
from an SSA_NAME, then it is interesting to us as we
can adjust the constant in the conditional and thus
eliminate the arithmetic operation. */
if (TREE_CODE (def_rhs) == PLUS_EXPR
|| TREE_CODE (def_rhs) == MINUS_EXPR)
{ {
tree last = VARRAY_TOP_TREE (cond_worklist); tree op0 = TREE_OPERAND (def_rhs, 0);
tree op1 = TREE_OPERAND (def_rhs, 1);
VARRAY_POP (cond_worklist);
/* The first operand must be an SSA_NAME and the second
/* See if this block ends in a COND_EXPR. */ operand must be a constant. */
if (last && TREE_CODE (last) == COND_EXPR) if (TREE_CODE (op0) != SSA_NAME
|| !CONSTANT_CLASS_P (op1)
|| !INTEGRAL_TYPE_P (TREE_TYPE (op1)))
return NULL_TREE;
/* Don't propagate if the first operand occurs in
an abnormal PHI. */
if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op0))
return NULL_TREE;
if (has_single_use (test_var))
{ {
tree cond = COND_EXPR_COND (last); tree op0 = TREE_OPERAND (def_rhs, 0);
enum tree_code cond_code = TREE_CODE (cond); tree op1 = TREE_OPERAND (def_rhs, 1);
enum tree_code new_code;
/* If the condition is a lone variable or an equality test of tree t;
an SSA_NAME against an integral constant, then we may have an
optimizable case. /* If the variable was defined via X + C, then we must
subtract C from the constant in the conditional.
Note these conditions also ensure the COND_EXPR has no Otherwise we add C to the constant in the
virtual operands or other side effects. */ conditional. The result must fold into a valid
if (cond_code == SSA_NAME gimple operand to be optimizable. */
|| ((cond_code == EQ_EXPR || cond_code == NE_EXPR) new_code = (TREE_CODE (def_rhs) == PLUS_EXPR
&& TREE_CODE (TREE_OPERAND (cond, 0)) == SSA_NAME ? MINUS_EXPR : PLUS_EXPR);
&& CONSTANT_CLASS_P (TREE_OPERAND (cond, 1)) t = int_const_binop (new_code, TREE_OPERAND (cond, 1), op1, 0);
&& INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (cond, 1))))) if (!is_gimple_val (t))
{ return NULL_TREE;
tree def;
tree test_var; new_cond = build (cond_code, boolean_type_node, op0, t);
/* Extract the single variable used in the test into TEST_VAR. */
if (cond_code == SSA_NAME)
test_var = cond;
else
test_var = TREE_OPERAND (cond, 0);
/* If we have already recorded this SSA_NAME as interesting,
do not do so again. */
if (bitmap_bit_p (vars, SSA_NAME_VERSION (test_var)))
continue;
/* Now get the defining statement for TEST_VAR and see if it
something we are interested in. */
def = SSA_NAME_DEF_STMT (test_var);
if (TREE_CODE (def) == MODIFY_EXPR)
{
tree def_rhs = TREE_OPERAND (def, 1);
/* If TEST_VAR is set by adding or subtracting a constant
from an SSA_NAME, then it is interesting to us as we
can adjust the constant in the conditional and thus
eliminate the arithmetic operation. */
if (TREE_CODE (def_rhs) == PLUS_EXPR
|| TREE_CODE (def_rhs) == MINUS_EXPR)
{
tree op0 = TREE_OPERAND (def_rhs, 0);
tree op1 = TREE_OPERAND (def_rhs, 1);
/* The first operand must be an SSA_NAME and the second
operand must be a constant. */
if (TREE_CODE (op0) != SSA_NAME
|| !CONSTANT_CLASS_P (op1)
|| !INTEGRAL_TYPE_P (TREE_TYPE (op1)))
continue;
/* Don't propagate if the first operand occurs in
an abnormal PHI. */
if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op0))
continue;
}
/* These cases require comparisons of a naked SSA_NAME or
comparison of an SSA_NAME against zero or one. */
else if (TREE_CODE (cond) == SSA_NAME
|| integer_zerop (TREE_OPERAND (cond, 1))
|| integer_onep (TREE_OPERAND (cond, 1)))
{
/* If TEST_VAR is set from a relational operation
between two SSA_NAMEs or a combination of an SSA_NAME
and a constant, then it is interesting. */
if (COMPARISON_CLASS_P (def_rhs))
{
tree op0 = TREE_OPERAND (def_rhs, 0);
tree op1 = TREE_OPERAND (def_rhs, 1);
/* Both operands of DEF_RHS must be SSA_NAMEs or
constants. */
if ((TREE_CODE (op0) != SSA_NAME
&& !is_gimple_min_invariant (op0))
|| (TREE_CODE (op1) != SSA_NAME
&& !is_gimple_min_invariant (op1)))
continue;
/* Don't propagate if the first operand occurs in
an abnormal PHI. */
if (TREE_CODE (op0) == SSA_NAME
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op0))
continue;
/* Don't propagate if the second operand occurs in
an abnormal PHI. */
if (TREE_CODE (op1) == SSA_NAME
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op1))
continue;
}
/* If TEST_VAR is set from a TRUTH_NOT_EXPR, then it
is interesting. */
else if (TREE_CODE (def_rhs) == TRUTH_NOT_EXPR)
{
def_rhs = TREE_OPERAND (def_rhs, 0);
/* DEF_RHS must be an SSA_NAME or constant. */
if (TREE_CODE (def_rhs) != SSA_NAME
&& !is_gimple_min_invariant (def_rhs))
continue;
/* Don't propagate if the operand occurs in
an abnormal PHI. */
if (TREE_CODE (def_rhs) == SSA_NAME
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def_rhs))
continue;
}
/* If TEST_VAR was set from a cast of an integer type
to a boolean type or a cast of a boolean to an
integral, then it is interesting. */
else if (TREE_CODE (def_rhs) == NOP_EXPR
|| TREE_CODE (def_rhs) == CONVERT_EXPR)
{
tree outer_type;
tree inner_type;
outer_type = TREE_TYPE (def_rhs);
inner_type = TREE_TYPE (TREE_OPERAND (def_rhs, 0));
if ((TREE_CODE (outer_type) == BOOLEAN_TYPE
&& INTEGRAL_TYPE_P (inner_type))
|| (TREE_CODE (inner_type) == BOOLEAN_TYPE
&& INTEGRAL_TYPE_P (outer_type)))
;
else
continue;
/* Don't propagate if the operand occurs in
an abnormal PHI. */
if (TREE_CODE (TREE_OPERAND (def_rhs, 0)) == SSA_NAME
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND
(def_rhs, 0)))
continue;
}
else
continue;
}
else
continue;
/* All the tests passed, record TEST_VAR as interesting. */
VARRAY_PUSH_TREE (*vars_worklist, test_var);
bitmap_set_bit (vars, SSA_NAME_VERSION (test_var));
}
}
} }
} }
}
/* Given FORWPROP_DATA containing SSA_NAMEs which are used in COND_EXPRs /* These cases require comparisons of a naked SSA_NAME or
that we may be able to optimize, attempt to rewrite the condition comparison of an SSA_NAME against zero or one. */
in each COND_EXPR to use the RHS of the statement which defines the else if (TREE_CODE (cond) == SSA_NAME
SSA_NAME used in the COND_EXPR. */ || integer_zerop (TREE_OPERAND (cond, 1))
|| integer_onep (TREE_OPERAND (cond, 1)))
static void
substitute_single_use_vars (varray_type *cond_worklist,
varray_type vars_worklist)
{
use_operand_p use_p;
while (VARRAY_ACTIVE_SIZE (vars_worklist) > 0)
{ {
tree test_var = VARRAY_TOP_TREE (vars_worklist); /* If TEST_VAR is set from a relational operation
tree def_stmt = SSA_NAME_DEF_STMT (test_var); between two SSA_NAMEs or a combination of an SSA_NAME
tree def; and a constant, then it is interesting. */
int num_uses, propagated_uses; if (COMPARISON_CLASS_P (def_rhs))
imm_use_iterator imm_iter;
VARRAY_POP (vars_worklist);
propagated_uses = 0;
num_uses = 0;
if (NUM_DEFS (STMT_DEF_OPS (def_stmt)) != 1)
continue;
def = DEF_OP (STMT_DEF_OPS (def_stmt), 0);
/* If TEST_VAR is used more than once and is not a boolean set
via TRUTH_NOT_EXPR with another SSA_NAME as its argument, then
we can not optimize. */
if (has_single_use (def)
|| (TREE_CODE (TREE_TYPE (test_var)) == BOOLEAN_TYPE
&& TREE_CODE (TREE_OPERAND (def_stmt, 1)) == TRUTH_NOT_EXPR
&& (TREE_CODE (TREE_OPERAND (TREE_OPERAND (def_stmt, 1), 0))
== SSA_NAME)))
;
else
continue;
/* Walk over each use and try to forward propagate the RHS of
DEF into the use. */
FOR_EACH_IMM_USE_SAFE (use_p, imm_iter, def)
{ {
tree cond_stmt; tree op0 = TREE_OPERAND (def_rhs, 0);
tree cond; tree op1 = TREE_OPERAND (def_rhs, 1);
enum tree_code cond_code;
tree def_rhs; /* Both operands of DEF_RHS must be SSA_NAMEs or
enum tree_code def_rhs_code; constants. */
tree new_cond; if ((TREE_CODE (op0) != SSA_NAME
&& !is_gimple_min_invariant (op0))
cond_stmt = USE_STMT (use_p); || (TREE_CODE (op1) != SSA_NAME
num_uses++; && !is_gimple_min_invariant (op1)))
return NULL_TREE;
/* For now we can only propagate into COND_EXPRs. */
if (TREE_CODE (cond_stmt) != COND_EXPR) /* Don't propagate if the first operand occurs in
continue; an abnormal PHI. */
if (TREE_CODE (op0) == SSA_NAME
cond = COND_EXPR_COND (cond_stmt); && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op0))
cond_code = TREE_CODE (cond); return NULL_TREE;
def_rhs = TREE_OPERAND (def_stmt, 1);
def_rhs_code = TREE_CODE (def_rhs); /* Don't propagate if the second operand occurs in
an abnormal PHI. */
/* If the definition of the single use variable was from an if (TREE_CODE (op1) == SSA_NAME
arithmetic operation, then we just need to adjust the && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op1))
constant in the COND_EXPR_COND and update the variable tested. */ return NULL_TREE;
if (def_rhs_code == PLUS_EXPR || def_rhs_code == MINUS_EXPR)
{ if (has_single_use (test_var))
tree op0 = TREE_OPERAND (def_rhs, 0);
tree op1 = TREE_OPERAND (def_rhs, 1);
enum tree_code new_code;
tree t;
/* If the variable was defined via X + C, then we must subtract
C from the constant in the conditional. Otherwise we add
C to the constant in the conditional. The result must fold
into a valid gimple operand to be optimizable. */
new_code = def_rhs_code == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR;
t = int_const_binop (new_code, TREE_OPERAND (cond, 1), op1, 0);
if (!is_gimple_val (t))
continue;
new_cond = build (cond_code, boolean_type_node, op0, t);
}
/* If the variable is defined by a conditional expression... */
else if (TREE_CODE_CLASS (def_rhs_code) == tcc_comparison)
{ {
/* TEST_VAR was set from a relational operator. */ /* TEST_VAR was set from a relational operator. */
tree op0 = TREE_OPERAND (def_rhs, 0); tree op0 = TREE_OPERAND (def_rhs, 0);
tree op1 = TREE_OPERAND (def_rhs, 1); tree op1 = TREE_OPERAND (def_rhs, 1);
new_cond = build (def_rhs_code, boolean_type_node, op0, op1); new_cond = build (TREE_CODE (def_rhs),
boolean_type_node, op0, op1);
/* Invert the conditional if necessary. */ /* Invert the conditional if necessary. */
if ((cond_code == EQ_EXPR if ((cond_code == EQ_EXPR
...@@ -405,23 +243,81 @@ substitute_single_use_vars (varray_type *cond_worklist, ...@@ -405,23 +243,81 @@ substitute_single_use_vars (varray_type *cond_worklist,
{ {
new_cond = invert_truthvalue (new_cond); new_cond = invert_truthvalue (new_cond);
/* If we did not get a simple relational expression or /* If we did not get a simple relational
bare SSA_NAME, then we can not optimize this case. */ expression or bare SSA_NAME, then we can
not optimize this case. */
if (!COMPARISON_CLASS_P (new_cond) if (!COMPARISON_CLASS_P (new_cond)
&& TREE_CODE (new_cond) != SSA_NAME) && TREE_CODE (new_cond) != SSA_NAME)
continue; new_cond = NULL_TREE;
} }
} }
}
/* If TEST_VAR is set from a TRUTH_NOT_EXPR, then it
is interesting. */
else if (TREE_CODE (def_rhs) == TRUTH_NOT_EXPR)
{
enum tree_code new_code;
def_rhs = TREE_OPERAND (def_rhs, 0);
/* DEF_RHS must be an SSA_NAME or constant. */
if (TREE_CODE (def_rhs) != SSA_NAME
&& !is_gimple_min_invariant (def_rhs))
return NULL_TREE;
/* Don't propagate if the operand occurs in
an abnormal PHI. */
if (TREE_CODE (def_rhs) == SSA_NAME
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def_rhs))
return NULL_TREE;
if (cond_code == SSA_NAME
|| (cond_code == NE_EXPR
&& integer_zerop (TREE_OPERAND (cond, 1)))
|| (cond_code == EQ_EXPR
&& integer_onep (TREE_OPERAND (cond, 1))))
new_code = EQ_EXPR;
else
new_code = NE_EXPR;
new_cond = build2 (new_code, boolean_type_node, def_rhs,
fold_convert (TREE_TYPE (def_rhs),
integer_zero_node));
}
/* If TEST_VAR was set from a cast of an integer type
to a boolean type or a cast of a boolean to an
integral, then it is interesting. */
else if (TREE_CODE (def_rhs) == NOP_EXPR
|| TREE_CODE (def_rhs) == CONVERT_EXPR)
{
tree outer_type;
tree inner_type;
outer_type = TREE_TYPE (def_rhs);
inner_type = TREE_TYPE (TREE_OPERAND (def_rhs, 0));
if ((TREE_CODE (outer_type) == BOOLEAN_TYPE
&& INTEGRAL_TYPE_P (inner_type))
|| (TREE_CODE (inner_type) == BOOLEAN_TYPE
&& INTEGRAL_TYPE_P (outer_type)))
;
else else
return NULL_TREE;
/* Don't propagate if the operand occurs in
an abnormal PHI. */
if (TREE_CODE (TREE_OPERAND (def_rhs, 0)) == SSA_NAME
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND
(def_rhs, 0)))
return NULL_TREE;
if (has_single_use (test_var))
{ {
bool invert = false;
enum tree_code new_code; enum tree_code new_code;
tree new_arg; tree new_arg;
/* TEST_VAR was set from a TRUTH_NOT_EXPR or a NOP_EXPR. */
if (def_rhs_code == TRUTH_NOT_EXPR)
invert = true;
if (cond_code == SSA_NAME if (cond_code == SSA_NAME
|| (cond_code == NE_EXPR || (cond_code == NE_EXPR
&& integer_zerop (TREE_OPERAND (cond, 1))) && integer_zerop (TREE_OPERAND (cond, 1)))
...@@ -431,38 +327,53 @@ substitute_single_use_vars (varray_type *cond_worklist, ...@@ -431,38 +327,53 @@ substitute_single_use_vars (varray_type *cond_worklist,
else else
new_code = EQ_EXPR; new_code = EQ_EXPR;
if (invert)
new_code = (new_code == EQ_EXPR ? NE_EXPR : EQ_EXPR);
new_arg = TREE_OPERAND (def_rhs, 0); new_arg = TREE_OPERAND (def_rhs, 0);
new_cond = build2 (new_code, boolean_type_node, new_arg, new_cond = build2 (new_code, boolean_type_node, new_arg,
fold_convert (TREE_TYPE (new_arg), fold_convert (TREE_TYPE (new_arg),
integer_zero_node)); integer_zero_node));
} }
}
}
/* Dump details. */ *test_var_p = test_var;
if (dump_file && (dump_flags & TDF_DETAILS)) return new_cond;
{ }
fprintf (dump_file, " Replaced '");
print_generic_expr (dump_file, cond, dump_flags); /* Forward propagate a single-use variable into COND_EXPR as many
fprintf (dump_file, "' with '"); times as possible. */
print_generic_expr (dump_file, new_cond, dump_flags);
fprintf (dump_file, "'\n");
}
/* Replace the condition. */ static void
COND_EXPR_COND (cond_stmt) = new_cond; forward_propagate_into_cond (tree cond_expr)
update_stmt (cond_stmt); {
propagated_uses++; gcc_assert (TREE_CODE (cond_expr) == COND_EXPR);
VARRAY_PUSH_TREE (*cond_worklist, cond_stmt);
while (1)
{
tree test_var = NULL_TREE;
tree cond = COND_EXPR_COND (cond_expr);
tree new_cond = forward_propagate_into_cond_1 (cond, &test_var);
/* Return if unsuccessful. */
if (new_cond == NULL_TREE)
break;
/* Dump details. */
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, " Replaced '");
print_generic_expr (dump_file, cond, dump_flags);
fprintf (dump_file, "' with '");
print_generic_expr (dump_file, new_cond, dump_flags);
fprintf (dump_file, "'\n");
} }
/* If we propagated into all the uses, then we can delete DEF. COND_EXPR_COND (cond_expr) = new_cond;
Unfortunately, we have to find the defining statement in update_stmt (cond_expr);
whatever block it might be in. */
if (num_uses && num_uses == propagated_uses) if (has_zero_uses (test_var))
{ {
block_stmt_iterator bsi = bsi_for_stmt (def_stmt); tree def = SSA_NAME_DEF_STMT (test_var);
block_stmt_iterator bsi = bsi_for_stmt (def);
bsi_remove (&bsi); bsi_remove (&bsi);
} }
} }
...@@ -474,42 +385,13 @@ static void ...@@ -474,42 +385,13 @@ static void
tree_ssa_forward_propagate_single_use_vars (void) tree_ssa_forward_propagate_single_use_vars (void)
{ {
basic_block bb; basic_block bb;
varray_type vars_worklist, cond_worklist;
vars = BITMAP_ALLOC (NULL);
VARRAY_TREE_INIT (vars_worklist, 10, "VARS worklist");
VARRAY_TREE_INIT (cond_worklist, 10, "COND worklist");
/* Prime the COND_EXPR worklist by placing all the COND_EXPRs on the
worklist. */
FOR_EACH_BB (bb) FOR_EACH_BB (bb)
{ {
tree last = last_stmt (bb); tree last = last_stmt (bb);
if (last && TREE_CODE (last) == COND_EXPR) if (last && TREE_CODE (last) == COND_EXPR)
VARRAY_PUSH_TREE (cond_worklist, last); forward_propagate_into_cond (last);
} }
while (VARRAY_ACTIVE_SIZE (cond_worklist) > 0)
{
/* First get a list of all the interesting COND_EXPRs and potential
single use variables which feed those COND_EXPRs. This will drain
COND_WORKLIST and initialize VARS_WORKLIST. */
record_single_argument_cond_exprs (cond_worklist, &vars_worklist, vars);
if (VARRAY_ACTIVE_SIZE (vars_worklist) > 0)
{
/* We've computed immediate uses, so we can/must clear the VARS
bitmap for the next iteration. */
bitmap_clear (vars);
/* And optimize. This will drain VARS_WORKLIST and initialize
COND_WORKLIST for the next iteration. */
substitute_single_use_vars (&cond_worklist, vars_worklist);
}
}
/* All done. Clean up. */
BITMAP_FREE (vars);
} }
......
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