aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-loop-ivopts.c
diff options
context:
space:
mode:
authorPaul Brook <paul@codesourcery.com>2006-07-13 18:07:40 +0000
committerPaul Brook <paul@codesourcery.com>2006-07-13 18:07:40 +0000
commita8b20def26f8819020ace682479bdf978f0cd49a (patch)
tree681df20e561672c8cdda690cdbc48d509157afa3 /gcc/tree-ssa-loop-ivopts.c
parent6e53ac993d70b42a4ac831c37ce23ef636c33181 (diff)
Merge from gcc-4_1-branch revision 114100 (gcc-4_1_1-release)
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/csl/sourcerygxx-4_1@115418 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-loop-ivopts.c')
-rw-r--r--gcc/tree-ssa-loop-ivopts.c250
1 files changed, 121 insertions, 129 deletions
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 241dcc94ba6..5eea0c90d91 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -659,6 +659,86 @@ stmt_after_increment (struct loop *loop, struct iv_cand *cand, tree stmt)
}
}
+/* Returns true if EXP is a ssa name that occurs in an abnormal phi node. */
+
+static bool
+abnormal_ssa_name_p (tree exp)
+{
+ if (!exp)
+ return false;
+
+ if (TREE_CODE (exp) != SSA_NAME)
+ return false;
+
+ return SSA_NAME_OCCURS_IN_ABNORMAL_PHI (exp) != 0;
+}
+
+/* Returns false if BASE or INDEX contains a ssa name that occurs in an
+ abnormal phi node. Callback for for_each_index. */
+
+static bool
+idx_contains_abnormal_ssa_name_p (tree base, tree *index,
+ void *data ATTRIBUTE_UNUSED)
+{
+ if (TREE_CODE (base) == ARRAY_REF)
+ {
+ if (abnormal_ssa_name_p (TREE_OPERAND (base, 2)))
+ return false;
+ if (abnormal_ssa_name_p (TREE_OPERAND (base, 3)))
+ return false;
+ }
+
+ return !abnormal_ssa_name_p (*index);
+}
+
+/* Returns true if EXPR contains a ssa name that occurs in an
+ abnormal phi node. */
+
+bool
+contains_abnormal_ssa_name_p (tree expr)
+{
+ enum tree_code code;
+ enum tree_code_class class;
+
+ if (!expr)
+ return false;
+
+ code = TREE_CODE (expr);
+ class = TREE_CODE_CLASS (code);
+
+ if (code == SSA_NAME)
+ return SSA_NAME_OCCURS_IN_ABNORMAL_PHI (expr) != 0;
+
+ if (code == INTEGER_CST
+ || is_gimple_min_invariant (expr))
+ return false;
+
+ if (code == ADDR_EXPR)
+ return !for_each_index (&TREE_OPERAND (expr, 0),
+ idx_contains_abnormal_ssa_name_p,
+ NULL);
+
+ switch (class)
+ {
+ case tcc_binary:
+ case tcc_comparison:
+ if (contains_abnormal_ssa_name_p (TREE_OPERAND (expr, 1)))
+ return true;
+
+ /* Fallthru. */
+ case tcc_unary:
+ if (contains_abnormal_ssa_name_p (TREE_OPERAND (expr, 0)))
+ return true;
+
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ return false;
+}
+
/* Element of the table in that we cache the numbers of iterations obtained
from exits of the loop. */
@@ -667,11 +747,9 @@ struct nfe_cache_elt
/* The edge for that the number of iterations is cached. */
edge exit;
- /* True if the # of iterations was successfully determined. */
- bool valid_p;
-
- /* Description of # of iterations. */
- struct tree_niter_desc niter;
+ /* Number of iterations corresponding to this exit, or NULL if it cannot be
+ determined. */
+ tree niter;
};
/* Hash function for nfe_cache_elt E. */
@@ -694,13 +772,14 @@ nfe_eq (const void *e1, const void *e2)
return elt1->exit == e2;
}
-/* Returns structure describing number of iterations determined from
+/* Returns tree describing number of iterations determined from
EXIT of DATA->current_loop, or NULL if something goes wrong. */
-static struct tree_niter_desc *
+static tree
niter_for_exit (struct ivopts_data *data, edge exit)
{
struct nfe_cache_elt *nfe_desc;
+ struct tree_niter_desc desc;
PTR *slot;
slot = htab_find_slot_with_hash (data->niters, exit,
@@ -711,25 +790,31 @@ niter_for_exit (struct ivopts_data *data, edge exit)
{
nfe_desc = xmalloc (sizeof (struct nfe_cache_elt));
nfe_desc->exit = exit;
- nfe_desc->valid_p = number_of_iterations_exit (data->current_loop,
- exit, &nfe_desc->niter,
- true);
- *slot = nfe_desc;
+
+ /* Try to determine number of iterations. We must know it
+ unconditionally (i.e., without possibility of # of iterations
+ being zero). Also, we cannot safely work with ssa names that
+ appear in phi nodes on abnormal edges, so that we do not create
+ overlapping life ranges for them (PR 27283). */
+ if (number_of_iterations_exit (data->current_loop,
+ exit, &desc, true)
+ && zero_p (desc.may_be_zero)
+ && !contains_abnormal_ssa_name_p (desc.niter))
+ nfe_desc->niter = desc.niter;
+ else
+ nfe_desc->niter = NULL_TREE;
}
else
nfe_desc = *slot;
- if (!nfe_desc->valid_p)
- return NULL;
-
- return &nfe_desc->niter;
+ return nfe_desc->niter;
}
-/* Returns structure describing number of iterations determined from
+/* Returns tree describing number of iterations determined from
single dominating exit of DATA->current_loop, or NULL if something
goes wrong. */
-static struct tree_niter_desc *
+static tree
niter_for_single_dom_exit (struct ivopts_data *data)
{
edge exit = single_dom_exit (data->current_loop);
@@ -893,86 +978,6 @@ determine_biv_step (tree phi)
return (zero_p (iv.step) ? NULL_TREE : iv.step);
}
-/* Returns true if EXP is a ssa name that occurs in an abnormal phi node. */
-
-static bool
-abnormal_ssa_name_p (tree exp)
-{
- if (!exp)
- return false;
-
- if (TREE_CODE (exp) != SSA_NAME)
- return false;
-
- return SSA_NAME_OCCURS_IN_ABNORMAL_PHI (exp) != 0;
-}
-
-/* Returns false if BASE or INDEX contains a ssa name that occurs in an
- abnormal phi node. Callback for for_each_index. */
-
-static bool
-idx_contains_abnormal_ssa_name_p (tree base, tree *index,
- void *data ATTRIBUTE_UNUSED)
-{
- if (TREE_CODE (base) == ARRAY_REF)
- {
- if (abnormal_ssa_name_p (TREE_OPERAND (base, 2)))
- return false;
- if (abnormal_ssa_name_p (TREE_OPERAND (base, 3)))
- return false;
- }
-
- return !abnormal_ssa_name_p (*index);
-}
-
-/* Returns true if EXPR contains a ssa name that occurs in an
- abnormal phi node. */
-
-static bool
-contains_abnormal_ssa_name_p (tree expr)
-{
- enum tree_code code;
- enum tree_code_class class;
-
- if (!expr)
- return false;
-
- code = TREE_CODE (expr);
- class = TREE_CODE_CLASS (code);
-
- if (code == SSA_NAME)
- return SSA_NAME_OCCURS_IN_ABNORMAL_PHI (expr) != 0;
-
- if (code == INTEGER_CST
- || is_gimple_min_invariant (expr))
- return false;
-
- if (code == ADDR_EXPR)
- return !for_each_index (&TREE_OPERAND (expr, 0),
- idx_contains_abnormal_ssa_name_p,
- NULL);
-
- switch (class)
- {
- case tcc_binary:
- case tcc_comparison:
- if (contains_abnormal_ssa_name_p (TREE_OPERAND (expr, 1)))
- return true;
-
- /* Fallthru. */
- case tcc_unary:
- if (contains_abnormal_ssa_name_p (TREE_OPERAND (expr, 0)))
- return true;
-
- break;
-
- default:
- gcc_unreachable ();
- }
-
- return false;
-}
-
/* Finds basic ivs. */
static bool
@@ -1126,20 +1131,13 @@ find_induction_variables (struct ivopts_data *data)
if (dump_file && (dump_flags & TDF_DETAILS))
{
- struct tree_niter_desc *niter;
-
- niter = niter_for_single_dom_exit (data);
+ tree niter = niter_for_single_dom_exit (data);
if (niter)
{
fprintf (dump_file, " number of iterations ");
- print_generic_expr (dump_file, niter->niter, TDF_SLIM);
- fprintf (dump_file, "\n");
-
- fprintf (dump_file, " may be zero if ");
- print_generic_expr (dump_file, niter->may_be_zero, TDF_SLIM);
- fprintf (dump_file, "\n");
- fprintf (dump_file, "\n");
+ print_generic_expr (dump_file, niter, TDF_SLIM);
+ fprintf (dump_file, "\n\n");
};
fprintf (dump_file, "Induction variables:\n\n");
@@ -1529,8 +1527,9 @@ find_interesting_uses_address (struct ivopts_data *data, tree stmt, tree *op_p)
/* Ignore bitfields for now. Not really something terribly complicated
to handle. TODO. */
- if (TREE_CODE (base) == COMPONENT_REF
- && DECL_NONADDRESSABLE_P (TREE_OPERAND (base, 1)))
+ if (TREE_CODE (base) == BIT_FIELD_REF
+ || (TREE_CODE (base) == COMPONENT_REF
+ && DECL_NONADDRESSABLE_P (TREE_OPERAND (base, 1))))
goto fail;
if (STRICT_ALIGNMENT
@@ -2215,12 +2214,8 @@ add_iv_value_candidates (struct ivopts_data *data,
static void
add_iv_outer_candidates (struct ivopts_data *data, struct iv_use *use)
{
- struct tree_niter_desc *niter;
-
/* We must know where we exit the loop and how many times does it roll. */
- niter = niter_for_single_dom_exit (data);
- if (!niter
- || !zero_p (niter->may_be_zero))
+ if (! niter_for_single_dom_exit (data))
return;
add_candidate_1 (data, NULL, NULL, false, IP_NORMAL, use, NULL_TREE);
@@ -4011,7 +4006,6 @@ may_eliminate_iv (struct ivopts_data *data,
{
basic_block ex_bb;
edge exit;
- struct tree_niter_desc *niter;
tree nit, nit_type;
tree wider_type, period, per_type;
struct loop *loop = data->current_loop;
@@ -4034,12 +4028,10 @@ may_eliminate_iv (struct ivopts_data *data,
if (flow_bb_inside_loop_p (loop, exit->dest))
return false;
- niter = niter_for_exit (data, exit);
- if (!niter
- || !zero_p (niter->may_be_zero))
+ nit = niter_for_exit (data, exit);
+ if (!nit)
return false;
- nit = niter->niter;
nit_type = TREE_TYPE (nit);
/* Determine whether we may use the variable to test whether niter iterations
@@ -4122,7 +4114,7 @@ may_replace_final_value (struct ivopts_data *data, struct iv_use *use,
{
struct loop *loop = data->current_loop;
edge exit;
- struct tree_niter_desc *niter;
+ tree nit;
exit = single_dom_exit (loop);
if (!exit)
@@ -4131,12 +4123,11 @@ may_replace_final_value (struct ivopts_data *data, struct iv_use *use,
gcc_assert (dominated_by_p (CDI_DOMINATORS, exit->src,
bb_for_stmt (use->stmt)));
- niter = niter_for_single_dom_exit (data);
- if (!niter
- || !zero_p (niter->may_be_zero))
+ nit = niter_for_single_dom_exit (data);
+ if (!nit)
return false;
- *value = iv_value (use->iv, niter->niter);
+ *value = iv_value (use->iv, nit);
return true;
}
@@ -5693,14 +5684,15 @@ compute_phi_arg_on_exit (edge exit, tree stmts, tree op)
{
for (tsi = tsi_start (stmts); !tsi_end_p (tsi); tsi_next (&tsi))
{
- bsi_insert_after (&bsi, tsi_stmt (tsi), BSI_NEW_STMT);
- protect_loop_closed_ssa_form (exit, bsi_stmt (bsi));
+ tree stmt = tsi_stmt (tsi);
+ bsi_insert_before (&bsi, stmt, BSI_SAME_STMT);
+ protect_loop_closed_ssa_form (exit, stmt);
}
}
else
{
- bsi_insert_after (&bsi, stmts, BSI_NEW_STMT);
- protect_loop_closed_ssa_form (exit, bsi_stmt (bsi));
+ bsi_insert_before (&bsi, stmts, BSI_SAME_STMT);
+ protect_loop_closed_ssa_form (exit, stmts);
}
if (!op)
@@ -5717,7 +5709,7 @@ compute_phi_arg_on_exit (edge exit, tree stmts, tree op)
stmt = build2 (MODIFY_EXPR, TREE_TYPE (op),
def, op);
SSA_NAME_DEF_STMT (def) = stmt;
- bsi_insert_after (&bsi, stmt, BSI_CONTINUE_LINKING);
+ bsi_insert_before (&bsi, stmt, BSI_SAME_STMT);
}
}
}