diff options
author | Bin Cheng <bin.cheng@arm.com> | 2015-06-02 03:33:35 +0000 |
---|---|---|
committer | Bin Cheng <amker@gcc.gnu.org> | 2015-06-02 03:33:35 +0000 |
commit | c70ed622fc3c67f60dd2791f9fbbc77b227ffbda (patch) | |
tree | 1f5e020ab5afc1038a6fcaef4aa52021a0090379 /gcc/tree-ssa-loop-ivopts.c | |
parent | 81371eff9bc7ef26172c925c923fdd28ac3622ce (diff) | |
download | gcc-c70ed622fc3c67f60dd2791f9fbbc77b227ffbda.zip gcc-c70ed622fc3c67f60dd2791f9fbbc77b227ffbda.tar.gz gcc-c70ed622fc3c67f60dd2791f9fbbc77b227ffbda.tar.bz2 |
re PR testsuite/52563 (FAIL: gcc.dg/tree-ssa/scev-[3,4].c scan-tree-dump-times optimized "&a" 1)
PR tree-optimization/52563
PR tree-optimization/62173
* tree-ssa-loop-ivopts.c (struct iv): New field. Reorder fields.
(alloc_iv, set_iv): New parameter.
(determine_biv_step): Delete.
(find_bivs): Inline original determine_biv_step. Pass new
argument to set_iv.
(idx_find_step): Use no_overflow information for conversion.
* tree-scalar-evolution.c (analyze_scalar_evolution_in_loop): Let
resolve_mixers handle folded_casts.
(instantiate_scev_name): Change bool parameter to bool pointer.
(instantiate_scev_poly, instantiate_scev_binary): Ditto.
(instantiate_array_ref, instantiate_scev_not): Ditto.
(instantiate_scev_3, instantiate_scev_2): Ditto.
(instantiate_scev_1, instantiate_scev_r): Ditto.
(instantiate_scev_convert, ): Change parameter. Pass argument
to chrec_convert_aggressive.
(instantiate_scev): Change argument.
(resolve_mixers): New parameter and set it.
(scev_const_prop): New argument.
* tree-scalar-evolution.h (resolve_mixers): New parameter.
* tree-chrec.c (convert_affine_scev): Call chrec_convert instead
of chrec_conert_1.
(chrec_convert): New parameter. Move definition below.
(chrec_convert_aggressive): New parameter and set it. Call
convert_affine_scev.
* tree-chrec.h (chrec_convert): New parameter.
(chrec_convert_aggressive): Ditto.
gcc/testsuite/ChangeLog
PR tree-optimization/52563
PR tree-optimization/62173
* gcc.dg/tree-ssa/scev-3.c: Remove xfail.
* gcc.dg/tree-ssa/scev-4.c: Ditto.
From-SVN: r224009
Diffstat (limited to 'gcc/tree-ssa-loop-ivopts.c')
-rw-r--r-- | gcc/tree-ssa-loop-ivopts.c | 58 |
1 files changed, 27 insertions, 31 deletions
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index 854d7ba..a7f09e7 100644 --- a/gcc/tree-ssa-loop-ivopts.c +++ b/gcc/tree-ssa-loop-ivopts.c @@ -171,9 +171,10 @@ struct iv tree base_object; /* A memory object to that the induction variable points. */ tree step; /* Step of the iv (constant only). */ tree ssa_name; /* The ssa name with the value. */ + unsigned use_id; /* The identifier in the use if it is the case. */ bool biv_p; /* Is it a biv? */ bool have_use_for; /* Do we already have a use for it? */ - unsigned use_id; /* The identifier in the use if it is the case. */ + bool no_overflow; /* True if the iv doesn't overflow. */ }; /* Per-ssa version information (induction variable descriptions, etc.). */ @@ -1005,10 +1006,10 @@ contain_complex_addr_expr (tree expr) } /* Allocates an induction variable with given initial value BASE and step STEP - for loop LOOP. */ + for loop LOOP. NO_OVERFLOW implies the iv doesn't overflow. */ static struct iv * -alloc_iv (tree base, tree step) +alloc_iv (tree base, tree step, bool no_overflow = false) { tree expr = base; struct iv *iv = XCNEW (struct iv); @@ -1035,21 +1036,24 @@ alloc_iv (tree base, tree step) iv->have_use_for = false; iv->use_id = 0; iv->ssa_name = NULL_TREE; + iv->no_overflow = no_overflow; return iv; } -/* Sets STEP and BASE for induction variable IV. */ +/* Sets STEP and BASE for induction variable IV. NO_OVERFLOW implies the IV + doesn't overflow. */ static void -set_iv (struct ivopts_data *data, tree iv, tree base, tree step) +set_iv (struct ivopts_data *data, tree iv, tree base, tree step, + bool no_overflow) { struct version_info *info = name_info (data, iv); gcc_assert (!info->iv); bitmap_set_bit (data->relevant, SSA_NAME_VERSION (iv)); - info->iv = alloc_iv (base, step); + info->iv = alloc_iv (base, step, no_overflow); info->iv->ssa_name = iv; } @@ -1071,31 +1075,12 @@ get_iv (struct ivopts_data *data, tree var) if (!bb || !flow_bb_inside_loop_p (data->current_loop, bb)) - set_iv (data, var, var, build_int_cst (type, 0)); + set_iv (data, var, var, build_int_cst (type, 0), true); } return name_info (data, var)->iv; } -/* Determines the step of a biv defined in PHI. Returns NULL if PHI does - not define a simple affine biv with nonzero step. */ - -static tree -determine_biv_step (gphi *phi) -{ - struct loop *loop = gimple_bb (phi)->loop_father; - tree name = PHI_RESULT (phi); - affine_iv iv; - - if (virtual_operand_p (name)) - return NULL_TREE; - - if (!simple_iv (loop, loop, name, &iv, true)) - return NULL_TREE; - - return integer_zerop (iv.step) ? NULL_TREE : iv.step; -} - /* Return the first non-invariant ssa var found in EXPR. */ static tree @@ -1129,6 +1114,7 @@ static bool find_bivs (struct ivopts_data *data) { gphi *phi; + affine_iv iv; tree step, type, base, stop; bool found = false; struct loop *loop = data->current_loop; @@ -1141,10 +1127,16 @@ find_bivs (struct ivopts_data *data) if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (phi))) continue; - step = determine_biv_step (phi); - if (!step) + if (virtual_operand_p (PHI_RESULT (phi))) continue; + if (!simple_iv (loop, loop, PHI_RESULT (phi), &iv, true)) + continue; + + if (integer_zerop (iv.step)) + continue; + + step = iv.step; base = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop)); /* Stop expanding iv base at the first ssa var referred by iv step. Ideally we should stop at any ssa var, because that's expensive @@ -1167,7 +1159,7 @@ find_bivs (struct ivopts_data *data) step = fold_convert (type, step); } - set_iv (data, PHI_RESULT (phi), base, step); + set_iv (data, PHI_RESULT (phi), base, step, iv.no_overflow); found = true; } @@ -1270,7 +1262,7 @@ find_givs_in_stmt (struct ivopts_data *data, gimple stmt) if (!find_givs_in_stmt_scev (data, stmt, &iv)) return; - set_iv (data, gimple_assign_lhs (stmt), iv.base, iv.step); + set_iv (data, gimple_assign_lhs (stmt), iv.base, iv.step, iv.no_overflow); } /* Finds general ivs in basic block BB. */ @@ -1683,6 +1675,7 @@ idx_find_step (tree base, tree *idx, void *data) { struct ifs_ivopts_data *dta = (struct ifs_ivopts_data *) data; struct iv *iv; + bool use_overflow_semantics = false; tree step, iv_base, iv_step, lbound, off; struct loop *loop = dta->ivopts_data->current_loop; @@ -1742,9 +1735,12 @@ idx_find_step (tree base, tree *idx, void *data) iv_base = iv->base; iv_step = iv->step; + if (iv->no_overflow && nowrap_type_p (TREE_TYPE (iv_step))) + use_overflow_semantics = true; + if (!convert_affine_scev (dta->ivopts_data->current_loop, sizetype, &iv_base, &iv_step, dta->stmt, - false)) + use_overflow_semantics)) { /* The index might wrap. */ return false; |