diff options
author | Paul Brook <paul@codesourcery.com> | 2006-07-13 18:07:40 +0000 |
---|---|---|
committer | Paul Brook <paul@codesourcery.com> | 2006-07-13 18:07:40 +0000 |
commit | a8b20def26f8819020ace682479bdf978f0cd49a (patch) | |
tree | 681df20e561672c8cdda690cdbc48d509157afa3 /gcc/tree-ssa-loop-ivopts.c | |
parent | 6e53ac993d70b42a4ac831c37ce23ef636c33181 (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.c | 250 |
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); } } } |