Hi,
This patch refactors codes adding iv candidates in IVO. It renames
functions using straightforward names, it also factors function call to
add_autoinc_candidates from add_candidate to add_iv_candidate_for_use.
Before this patch, we tried to add autoinc candidates for every call to
add_candidate. This has two issues: A) wasting compilation time. B) adding
useless auto-inc candidates for iv's which have ZERO base. These autoinc
candidates are useless because targets generally only support auto-increment
addressing mode with base register pointing to memory object, also because
IVO has its prerequisite conditions on autoinc candidates, these cands are
actually ignored later.
I collected instrumental data, and < 85% candidates are added now when
compiling spec2k on Cortex-a15/thumb.
Also this patch could benefit performance for targets supporting autoinc
addressing mode, because with fewer candidates, IVO algorithm might work
better.
I collected spec2k perf data on Cortex-a15. It shows several cases in
int/fp suites are improved. Overall, both spec2k geo-mean of int/fp are
both improved by ~0.5%. And no regression.
Though I haven't turned on autoinc support in IVO for aarch64, I would
expect this patch will pave the way for that.
So is it OK?
Thanks,
bin
2015-07-08 Bin Cheng <[email protected]>
* tree-ssa-loop-ivopts.c (add_candidate): Remove call to
add_autoinc_candidates.
(add_iv_candidate_for_biv): Rename to add_iv_candidate_for_biv.
(add_iv_candidate_for_biv): Rename from add_iv_candidate_for_biv.
(add_old_ivs_candidates): Rename to add_iv_candidate_for_bivs.
(add_iv_candidate_for_bivs): Rename from add_old_ivs_candidates.
Call new function.
(add_iv_value_candidates): Rename to add_iv_candidate_for_use.
(add_iv_candidate_for_use): Rename from add_iv_value_candidates.
Remove parameter struct iv*. Call add_autoinc_candidates here.
(add_derived_ivs_candidates): Rename to add_iv_candidate_for_uses.
(add_iv_candidate_for_uses): Rename from add_derived_ivs_candidates.
Call new function.
(find_iv_candidates): Call new functions.
Index: gcc/tree-ssa-loop-ivopts.c
===================================================================
--- gcc/tree-ssa-loop-ivopts.c (revision 225531)
+++ gcc/tree-ssa-loop-ivopts.c (working copy)
@@ -2787,7 +2787,8 @@ add_autoinc_candidates (struct ivopts_data *data,
/* Adds a candidate BASE + STEP * i. Important field is set to IMPORTANT and
position to POS. If USE is not NULL, the candidate is set as related to
- it. The candidate computation is scheduled on all available positions. */
+ it. The candidate computation is scheduled before exit condition and at
+ the end of loop. */
static void
add_candidate (struct ivopts_data *data,
@@ -2800,9 +2801,6 @@ add_candidate (struct ivopts_data *data,
if (ip_end_pos (data->current_loop)
&& allow_ip_end_pos_p (data->current_loop))
add_candidate_1 (data, base, step, important, IP_END, use, NULL);
-
- if (use != NULL && use->type == USE_ADDRESS)
- add_autoinc_candidates (data, base, step, important, use);
}
/* Adds standard iv candidates. */
@@ -2831,7 +2829,7 @@ add_standard_iv_candidates (struct ivopts_data *da
/* Adds candidates bases on the old induction variable IV. */
static void
-add_old_iv_candidates (struct ivopts_data *data, struct iv *iv)
+add_iv_candidate_for_biv (struct ivopts_data *data, struct iv *iv)
{
gimple phi;
tree def;
@@ -2871,7 +2869,7 @@ static void
/* Adds candidates based on the old induction variables. */
static void
-add_old_ivs_candidates (struct ivopts_data *data)
+add_iv_candidate_for_bivs (struct ivopts_data *data)
{
unsigned i;
struct iv *iv;
@@ -2881,19 +2879,19 @@ static void
{
iv = ver_info (data, i)->iv;
if (iv && iv->biv_p && !integer_zerop (iv->step))
- add_old_iv_candidates (data, iv);
+ add_iv_candidate_for_biv (data, iv);
}
}
-/* Adds candidates based on the value of the induction variable IV and USE. */
+/* Adds candidates based on the value of USE's iv. */
static void
-add_iv_value_candidates (struct ivopts_data *data,
- struct iv *iv, struct iv_use *use)
+add_iv_candidate_for_use (struct ivopts_data *data, struct iv_use *use)
{
unsigned HOST_WIDE_INT offset;
tree base;
tree basetype;
+ struct iv *iv = use->iv;
add_candidate (data, iv->base, iv->step, false, use);
@@ -2903,21 +2901,25 @@ static void
basetype = TREE_TYPE (iv->base);
if (POINTER_TYPE_P (basetype))
basetype = sizetype;
- add_candidate (data, build_int_cst (basetype, 0),
- iv->step, true, use);
+ add_candidate (data, build_int_cst (basetype, 0), iv->step, true, use);
/* Third, try removing the constant offset. Make sure to even
add a candidate for &a[0] vs. (T *)&a. */
base = strip_offset (iv->base, &offset);
- if (offset
- || base != iv->base)
+ if (offset || base != iv->base)
add_candidate (data, base, iv->step, false, use);
+
+ /* At last, add auto-incremental candidates. Make such variables
+ important since other iv uses with same base object may be based
+ on it. */
+ if (use != NULL && use->type == USE_ADDRESS)
+ add_autoinc_candidates (data, iv->base, iv->step, true, use);
}
/* Adds candidates based on the uses. */
static void
-add_derived_ivs_candidates (struct ivopts_data *data)
+add_iv_candidate_for_uses (struct ivopts_data *data)
{
unsigned i;
@@ -2934,7 +2936,7 @@ static void
case USE_COMPARE:
case USE_ADDRESS:
/* Just add the ivs based on the value of the iv used here. */
- add_iv_value_candidates (data, use->iv, use);
+ add_iv_candidate_for_use (data, use);
break;
default:
@@ -5319,10 +5321,10 @@ find_iv_candidates (struct ivopts_data *data)
add_standard_iv_candidates (data);
/* Add old induction variables. */
- add_old_ivs_candidates (data);
+ add_iv_candidate_for_bivs (data);
/* Add induction variables derived from uses. */
- add_derived_ivs_candidates (data);
+ add_iv_candidate_for_uses (data);
set_autoinc_for_original_candidates (data);