cfgloop.h: Include vec-prim.h.
* cfgloop.h: Include vec-prim.h. (enum li_flags): Remove LI_ONLY_OLD. (loop_iterator): Changed. (fel_next, fel_init): Iterate over loop tree. (FOR_EACH_LOOP_BREAK): New macro. * loop-unswitch.c (unswitch_loops): Do not pass LI_ONLY_OLD to FOR_EACH_LOOP. * tree-ssa-loop-unswitch.c (tree_ssa_unswitch_loops): Ditto. * modulo-sched.c (sms_schedule): Ditto. * tree-vectorizer.c (vectorize_loops): Ditto. * doc/loop.texi: Update information on loop numbering and behavior of FOR_EACH_LOOP wrto new loops. * tree-scalar-evolution.c (compute_overall_effect_of_inner_loop, add_to_evolution_1): Test nestedness of loops instead of comparing their numbers. * tree-chrec.c (chrec_fold_plus_poly_poly, chrec_fold_multiply_poly_poly, chrec_evaluate, hide_evolution_in_other_loops_than_loop, chrec_component_in_loop_num, reset_evolution_in_loop): Ditto. * Makefile.in (CFGLOOP_H): Add vecprim.h dependency. From-SVN: r121422
This commit is contained in:
parent
e7917d06e8
commit
677cc14d2d
|
@ -1,3 +1,26 @@
|
||||||
|
2007-01-31 Zdenek Dvorak <dvorakz@suse.cz>
|
||||||
|
|
||||||
|
* cfgloop.h: Include vec-prim.h.
|
||||||
|
(enum li_flags): Remove LI_ONLY_OLD.
|
||||||
|
(loop_iterator): Changed.
|
||||||
|
(fel_next, fel_init): Iterate over loop tree.
|
||||||
|
(FOR_EACH_LOOP_BREAK): New macro.
|
||||||
|
* loop-unswitch.c (unswitch_loops): Do not pass LI_ONLY_OLD to
|
||||||
|
FOR_EACH_LOOP.
|
||||||
|
* tree-ssa-loop-unswitch.c (tree_ssa_unswitch_loops): Ditto.
|
||||||
|
* modulo-sched.c (sms_schedule): Ditto.
|
||||||
|
* tree-vectorizer.c (vectorize_loops): Ditto.
|
||||||
|
* doc/loop.texi: Update information on loop numbering and behavior of
|
||||||
|
FOR_EACH_LOOP wrto new loops.
|
||||||
|
* tree-scalar-evolution.c (compute_overall_effect_of_inner_loop,
|
||||||
|
add_to_evolution_1): Test nestedness of loops instead of comparing
|
||||||
|
their numbers.
|
||||||
|
* tree-chrec.c (chrec_fold_plus_poly_poly,
|
||||||
|
chrec_fold_multiply_poly_poly, chrec_evaluate,
|
||||||
|
hide_evolution_in_other_loops_than_loop, chrec_component_in_loop_num,
|
||||||
|
reset_evolution_in_loop): Ditto.
|
||||||
|
* Makefile.in (CFGLOOP_H): Add vecprim.h dependency.
|
||||||
|
|
||||||
2007-01-31 Dirk Mueller <dmueller@suse.de>
|
2007-01-31 Dirk Mueller <dmueller@suse.de>
|
||||||
|
|
||||||
* c-common.c (warn_about_parentheses): Separate warning about
|
* c-common.c (warn_about_parentheses): Separate warning about
|
||||||
|
|
|
@ -749,7 +749,7 @@ RESOURCE_H = resource.h hard-reg-set.h
|
||||||
SCHED_INT_H = sched-int.h $(INSN_ATTR_H) $(BASIC_BLOCK_H) $(RTL_H)
|
SCHED_INT_H = sched-int.h $(INSN_ATTR_H) $(BASIC_BLOCK_H) $(RTL_H)
|
||||||
INTEGRATE_H = integrate.h $(VARRAY_H)
|
INTEGRATE_H = integrate.h $(VARRAY_H)
|
||||||
CFGLAYOUT_H = cfglayout.h $(BASIC_BLOCK_H)
|
CFGLAYOUT_H = cfglayout.h $(BASIC_BLOCK_H)
|
||||||
CFGLOOP_H = cfgloop.h $(BASIC_BLOCK_H) $(RTL_H)
|
CFGLOOP_H = cfgloop.h $(BASIC_BLOCK_H) $(RTL_H) vecprim.h
|
||||||
IPA_UTILS_H = ipa-utils.h $(TREE_H) $(CGRAPH_H)
|
IPA_UTILS_H = ipa-utils.h $(TREE_H) $(CGRAPH_H)
|
||||||
IPA_REFERENCE_H = ipa-reference.h bitmap.h $(TREE_H)
|
IPA_REFERENCE_H = ipa-reference.h bitmap.h $(TREE_H)
|
||||||
IPA_TYPE_ESCAPE_H = ipa-type-escape.h $(TREE_H)
|
IPA_TYPE_ESCAPE_H = ipa-type-escape.h $(TREE_H)
|
||||||
|
|
120
gcc/cfgloop.h
120
gcc/cfgloop.h
|
@ -25,6 +25,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
#include "basic-block.h"
|
#include "basic-block.h"
|
||||||
/* For rtx_code. */
|
/* For rtx_code. */
|
||||||
#include "rtl.h"
|
#include "rtl.h"
|
||||||
|
#include "vecprim.h"
|
||||||
|
|
||||||
/* Structure to hold decision about unrolling/peeling. */
|
/* Structure to hold decision about unrolling/peeling. */
|
||||||
enum lpt_dec
|
enum lpt_dec
|
||||||
|
@ -428,81 +429,124 @@ enum li_flags
|
||||||
LI_INCLUDE_ROOT = 1, /* Include the fake root of the loop tree. */
|
LI_INCLUDE_ROOT = 1, /* Include the fake root of the loop tree. */
|
||||||
LI_FROM_INNERMOST = 2, /* Iterate over the loops in the reverse order,
|
LI_FROM_INNERMOST = 2, /* Iterate over the loops in the reverse order,
|
||||||
starting from innermost ones. */
|
starting from innermost ones. */
|
||||||
LI_ONLY_INNERMOST = 4,/* Iterate only over innermost loops. */
|
LI_ONLY_INNERMOST = 4 /* Iterate only over innermost loops. */
|
||||||
LI_ONLY_OLD = 8 /* Do not traverse the loops created during the
|
|
||||||
traversal (this is the default behavior with
|
|
||||||
LI_FROM_INNERMOST). */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The iterator for loops. */
|
/* The iterator for loops. */
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int idx; /* Index of the actual loop. */
|
/* The list of loops to visit. */
|
||||||
int end; /* Only loops before end should be traversed. */
|
VEC(int,heap) *to_visit;
|
||||||
|
|
||||||
|
/* The index of the actual loop. */
|
||||||
|
unsigned idx;
|
||||||
} loop_iterator;
|
} loop_iterator;
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
fel_next (loop_iterator *li, loop_p *loop, unsigned flags)
|
fel_next (loop_iterator *li, loop_p *loop)
|
||||||
{
|
{
|
||||||
if (flags & LI_FROM_INNERMOST)
|
int anum;
|
||||||
|
|
||||||
|
while (VEC_iterate (int, li->to_visit, li->idx, anum))
|
||||||
{
|
{
|
||||||
li->idx--;
|
|
||||||
for (; li->idx > li->end; li->idx--)
|
|
||||||
{
|
|
||||||
*loop = VEC_index (loop_p, current_loops->larray, li->idx);
|
|
||||||
if (*loop
|
|
||||||
&& (!(flags & LI_ONLY_INNERMOST)
|
|
||||||
|| (*loop)->inner == NULL))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!(flags & LI_ONLY_OLD))
|
|
||||||
li->end = number_of_loops ();
|
|
||||||
li->idx++;
|
li->idx++;
|
||||||
for (; li->idx < li->end; li->idx++)
|
*loop = get_loop (anum);
|
||||||
{
|
if (*loop)
|
||||||
*loop = VEC_index (loop_p, current_loops->larray, li->idx);
|
|
||||||
if (*loop
|
|
||||||
&& (!(flags & LI_ONLY_INNERMOST)
|
|
||||||
|| (*loop)->inner == NULL))
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
VEC_free (int, heap, li->to_visit);
|
||||||
*loop = NULL;
|
*loop = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
fel_init (loop_iterator *li, loop_p *loop, unsigned flags)
|
fel_init (loop_iterator *li, loop_p *loop, unsigned flags)
|
||||||
{
|
{
|
||||||
|
struct loop *aloop;
|
||||||
|
unsigned i;
|
||||||
|
int mn;
|
||||||
|
|
||||||
|
li->idx = 0;
|
||||||
if (!current_loops)
|
if (!current_loops)
|
||||||
{
|
{
|
||||||
li->idx = 0;
|
li->to_visit = NULL;
|
||||||
li->end = 0;
|
|
||||||
*loop = NULL;
|
*loop = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & LI_FROM_INNERMOST)
|
li->to_visit = VEC_alloc (int, heap, number_of_loops ());
|
||||||
|
mn = (flags & LI_INCLUDE_ROOT) ? 0 : 1;
|
||||||
|
|
||||||
|
if (flags & LI_ONLY_INNERMOST)
|
||||||
{
|
{
|
||||||
li->idx = number_of_loops ();
|
for (i = 0; VEC_iterate (loop_p, current_loops->larray, i, aloop); i++)
|
||||||
li->end = (flags & LI_INCLUDE_ROOT) ? -1 : 0;
|
if (aloop != NULL
|
||||||
|
&& aloop->inner == NULL
|
||||||
|
&& aloop->num >= mn)
|
||||||
|
VEC_quick_push (int, li->to_visit, aloop->num);
|
||||||
|
}
|
||||||
|
else if (flags & LI_FROM_INNERMOST)
|
||||||
|
{
|
||||||
|
/* Push the loops to LI->TO_VISIT in postorder. */
|
||||||
|
for (aloop = current_loops->tree_root;
|
||||||
|
aloop->inner != NULL;
|
||||||
|
aloop = aloop->inner)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (aloop->num >= mn)
|
||||||
|
VEC_quick_push (int, li->to_visit, aloop->num);
|
||||||
|
|
||||||
|
if (aloop->next)
|
||||||
|
{
|
||||||
|
for (aloop = aloop->next;
|
||||||
|
aloop->inner != NULL;
|
||||||
|
aloop = aloop->inner)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (!aloop->outer)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
aloop = aloop->outer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
li->idx = (flags & LI_INCLUDE_ROOT) ? -1 : 0;
|
/* Push the loops to LI->TO_VISIT in preorder. */
|
||||||
li->end = number_of_loops ();
|
aloop = current_loops->tree_root;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (aloop->num >= mn)
|
||||||
|
VEC_quick_push (int, li->to_visit, aloop->num);
|
||||||
|
|
||||||
|
if (aloop->inner != NULL)
|
||||||
|
aloop = aloop->inner;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (aloop != NULL && aloop->next == NULL)
|
||||||
|
aloop = aloop->outer;
|
||||||
|
if (aloop == NULL)
|
||||||
|
break;
|
||||||
|
aloop = aloop->next;
|
||||||
}
|
}
|
||||||
fel_next (li, loop, flags);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fel_next (li, loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FOR_EACH_LOOP(LI, LOOP, FLAGS) \
|
#define FOR_EACH_LOOP(LI, LOOP, FLAGS) \
|
||||||
for (fel_init (&(LI), &(LOOP), FLAGS); \
|
for (fel_init (&(LI), &(LOOP), FLAGS); \
|
||||||
(LOOP); \
|
(LOOP); \
|
||||||
fel_next (&(LI), &(LOOP), FLAGS))
|
fel_next (&(LI), &(LOOP)))
|
||||||
|
|
||||||
|
#define FOR_EACH_LOOP_BREAK(LI) \
|
||||||
|
{ \
|
||||||
|
VEC_free (int, heap, (LI)->to_visit); \
|
||||||
|
break; \
|
||||||
|
}
|
||||||
|
|
||||||
/* The properties of the target. */
|
/* The properties of the target. */
|
||||||
|
|
||||||
|
|
|
@ -64,17 +64,24 @@ function. Each of the loops is represented in a @code{struct loop}
|
||||||
structure. Each loop is assigned an index (@code{num} field of the
|
structure. Each loop is assigned an index (@code{num} field of the
|
||||||
@code{struct loop} structure), and the pointer to the loop is stored in
|
@code{struct loop} structure), and the pointer to the loop is stored in
|
||||||
the corresponding field of the @code{larray} vector in the loops
|
the corresponding field of the @code{larray} vector in the loops
|
||||||
structure. Index of a sub-loop is always greater than the index of its
|
structure. The indices do not have to be continuous, there may be
|
||||||
super-loop. The indices do not have to be continuous, there may be
|
|
||||||
empty (@code{NULL}) entries in the @code{larray} created by deleting
|
empty (@code{NULL}) entries in the @code{larray} created by deleting
|
||||||
loops. The index of a loop never changes.
|
loops. Also, there is no guarantee on the relative order of a loop
|
||||||
|
and its subloops in the numbering. The index of a loop never changes.
|
||||||
|
|
||||||
The entries of the @code{larray} field should not be accessed directly.
|
The entries of the @code{larray} field should not be accessed directly.
|
||||||
The function @code{get_loop} returns the loop description for a loop with
|
The function @code{get_loop} returns the loop description for a loop with
|
||||||
the given index. @code{number_of_loops} function returns number of
|
the given index. @code{number_of_loops} function returns number of
|
||||||
loops in the function. To traverse all loops, use @code{FOR_EACH_LOOP}
|
loops in the function. To traverse all loops, use @code{FOR_EACH_LOOP}
|
||||||
macro. The @code{flags} argument of the macro is used to determine
|
macro. The @code{flags} argument of the macro is used to determine
|
||||||
the direction of traversal and the set of loops visited.
|
the direction of traversal and the set of loops visited. Each loop is
|
||||||
|
guaranteed to be visited exactly once, regardless of the changes to the
|
||||||
|
loop tree, and the loops may be removed during the traversal. The newly
|
||||||
|
created loops are never traversed, if they need to be visited, this
|
||||||
|
must be done separately after their creation. The @code{FOR_EACH_LOOP}
|
||||||
|
macro allocates temporary variables. If the @code{FOR_EACH_LOOP} loop
|
||||||
|
were ended using break or goto, they would not be released;
|
||||||
|
@code{FOR_EACH_LOOP_BREAK} macro must be used instead.
|
||||||
|
|
||||||
Each basic block contains the reference to the innermost loop it belongs
|
Each basic block contains the reference to the innermost loop it belongs
|
||||||
to (@code{loop_father}). For this reason, it is only possible to have
|
to (@code{loop_father}). For this reason, it is only possible to have
|
||||||
|
|
|
@ -143,7 +143,7 @@ unswitch_loops (void)
|
||||||
|
|
||||||
/* Go through inner loops (only original ones). */
|
/* Go through inner loops (only original ones). */
|
||||||
|
|
||||||
FOR_EACH_LOOP (li, loop, LI_ONLY_OLD | LI_ONLY_INNERMOST)
|
FOR_EACH_LOOP (li, loop, LI_ONLY_INNERMOST)
|
||||||
{
|
{
|
||||||
unswitch_single_loop (loop, NULL_RTX, 0);
|
unswitch_single_loop (loop, NULL_RTX, 0);
|
||||||
#ifdef ENABLE_CHECKING
|
#ifdef ENABLE_CHECKING
|
||||||
|
|
|
@ -1028,7 +1028,7 @@ sms_schedule (void)
|
||||||
df = NULL;
|
df = NULL;
|
||||||
|
|
||||||
/* We don't want to perform SMS on new loops - created by versioning. */
|
/* We don't want to perform SMS on new loops - created by versioning. */
|
||||||
FOR_EACH_LOOP (li, loop, LI_ONLY_OLD)
|
FOR_EACH_LOOP (li, loop, 0)
|
||||||
{
|
{
|
||||||
rtx head, tail;
|
rtx head, tail;
|
||||||
rtx count_reg, count_init;
|
rtx count_reg, count_init;
|
||||||
|
|
|
@ -99,6 +99,8 @@ chrec_fold_plus_poly_poly (enum tree_code code,
|
||||||
tree poly1)
|
tree poly1)
|
||||||
{
|
{
|
||||||
tree left, right;
|
tree left, right;
|
||||||
|
struct loop *loop0 = get_chrec_loop (poly0);
|
||||||
|
struct loop *loop1 = get_chrec_loop (poly1);
|
||||||
|
|
||||||
gcc_assert (poly0);
|
gcc_assert (poly0);
|
||||||
gcc_assert (poly1);
|
gcc_assert (poly1);
|
||||||
|
@ -111,7 +113,7 @@ chrec_fold_plus_poly_poly (enum tree_code code,
|
||||||
{a, +, b}_1 + {c, +, d}_2 -> {{a, +, b}_1 + c, +, d}_2,
|
{a, +, b}_1 + {c, +, d}_2 -> {{a, +, b}_1 + c, +, d}_2,
|
||||||
{a, +, b}_2 + {c, +, d}_1 -> {{c, +, d}_1 + a, +, b}_2,
|
{a, +, b}_2 + {c, +, d}_1 -> {{c, +, d}_1 + a, +, b}_2,
|
||||||
{a, +, b}_x + {c, +, d}_x -> {a+c, +, b+d}_x. */
|
{a, +, b}_x + {c, +, d}_x -> {a+c, +, b+d}_x. */
|
||||||
if (CHREC_VARIABLE (poly0) < CHREC_VARIABLE (poly1))
|
if (flow_loop_nested_p (loop0, loop1))
|
||||||
{
|
{
|
||||||
if (code == PLUS_EXPR)
|
if (code == PLUS_EXPR)
|
||||||
return build_polynomial_chrec
|
return build_polynomial_chrec
|
||||||
|
@ -128,7 +130,7 @@ chrec_fold_plus_poly_poly (enum tree_code code,
|
||||||
: build_int_cst_type (type, -1)));
|
: build_int_cst_type (type, -1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CHREC_VARIABLE (poly0) > CHREC_VARIABLE (poly1))
|
if (flow_loop_nested_p (loop1, loop0))
|
||||||
{
|
{
|
||||||
if (code == PLUS_EXPR)
|
if (code == PLUS_EXPR)
|
||||||
return build_polynomial_chrec
|
return build_polynomial_chrec
|
||||||
|
@ -142,6 +144,10 @@ chrec_fold_plus_poly_poly (enum tree_code code,
|
||||||
CHREC_RIGHT (poly0));
|
CHREC_RIGHT (poly0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This function should never be called for chrecs of loops that
|
||||||
|
do not belong to the same loop nest. */
|
||||||
|
gcc_assert (loop0 == loop1);
|
||||||
|
|
||||||
if (code == PLUS_EXPR)
|
if (code == PLUS_EXPR)
|
||||||
{
|
{
|
||||||
left = chrec_fold_plus
|
left = chrec_fold_plus
|
||||||
|
@ -175,6 +181,8 @@ chrec_fold_multiply_poly_poly (tree type,
|
||||||
{
|
{
|
||||||
tree t0, t1, t2;
|
tree t0, t1, t2;
|
||||||
int var;
|
int var;
|
||||||
|
struct loop *loop0 = get_chrec_loop (poly0);
|
||||||
|
struct loop *loop1 = get_chrec_loop (poly1);
|
||||||
|
|
||||||
gcc_assert (poly0);
|
gcc_assert (poly0);
|
||||||
gcc_assert (poly1);
|
gcc_assert (poly1);
|
||||||
|
@ -186,20 +194,22 @@ chrec_fold_multiply_poly_poly (tree type,
|
||||||
/* {a, +, b}_1 * {c, +, d}_2 -> {c*{a, +, b}_1, +, d}_2,
|
/* {a, +, b}_1 * {c, +, d}_2 -> {c*{a, +, b}_1, +, d}_2,
|
||||||
{a, +, b}_2 * {c, +, d}_1 -> {a*{c, +, d}_1, +, b}_2,
|
{a, +, b}_2 * {c, +, d}_1 -> {a*{c, +, d}_1, +, b}_2,
|
||||||
{a, +, b}_x * {c, +, d}_x -> {a*c, +, a*d + b*c + b*d, +, 2*b*d}_x. */
|
{a, +, b}_x * {c, +, d}_x -> {a*c, +, a*d + b*c + b*d, +, 2*b*d}_x. */
|
||||||
if (CHREC_VARIABLE (poly0) < CHREC_VARIABLE (poly1))
|
if (flow_loop_nested_p (loop0, loop1))
|
||||||
/* poly0 is a constant wrt. poly1. */
|
/* poly0 is a constant wrt. poly1. */
|
||||||
return build_polynomial_chrec
|
return build_polynomial_chrec
|
||||||
(CHREC_VARIABLE (poly1),
|
(CHREC_VARIABLE (poly1),
|
||||||
chrec_fold_multiply (type, CHREC_LEFT (poly1), poly0),
|
chrec_fold_multiply (type, CHREC_LEFT (poly1), poly0),
|
||||||
CHREC_RIGHT (poly1));
|
CHREC_RIGHT (poly1));
|
||||||
|
|
||||||
if (CHREC_VARIABLE (poly1) < CHREC_VARIABLE (poly0))
|
if (flow_loop_nested_p (loop1, loop0))
|
||||||
/* poly1 is a constant wrt. poly0. */
|
/* poly1 is a constant wrt. poly0. */
|
||||||
return build_polynomial_chrec
|
return build_polynomial_chrec
|
||||||
(CHREC_VARIABLE (poly0),
|
(CHREC_VARIABLE (poly0),
|
||||||
chrec_fold_multiply (type, CHREC_LEFT (poly0), poly1),
|
chrec_fold_multiply (type, CHREC_LEFT (poly0), poly1),
|
||||||
CHREC_RIGHT (poly0));
|
CHREC_RIGHT (poly0));
|
||||||
|
|
||||||
|
gcc_assert (loop0 == loop1);
|
||||||
|
|
||||||
/* poly0 and poly1 are two polynomials in the same variable,
|
/* poly0 and poly1 are two polynomials in the same variable,
|
||||||
{a, +, b}_x * {c, +, d}_x -> {a*c, +, a*d + b*c + b*d, +, 2*b*d}_x. */
|
{a, +, b}_x * {c, +, d}_x -> {a*c, +, a*d + b*c + b*d, +, 2*b*d}_x. */
|
||||||
|
|
||||||
|
@ -492,9 +502,10 @@ chrec_evaluate (unsigned var, tree chrec, tree n, unsigned int k)
|
||||||
{
|
{
|
||||||
tree arg0, arg1, binomial_n_k;
|
tree arg0, arg1, binomial_n_k;
|
||||||
tree type = TREE_TYPE (chrec);
|
tree type = TREE_TYPE (chrec);
|
||||||
|
struct loop *var_loop = get_loop (var);
|
||||||
|
|
||||||
while (TREE_CODE (chrec) == POLYNOMIAL_CHREC
|
while (TREE_CODE (chrec) == POLYNOMIAL_CHREC
|
||||||
&& CHREC_VARIABLE (chrec) > var)
|
&& flow_loop_nested_p (var_loop, get_chrec_loop (chrec)))
|
||||||
chrec = CHREC_LEFT (chrec);
|
chrec = CHREC_LEFT (chrec);
|
||||||
|
|
||||||
if (TREE_CODE (chrec) == POLYNOMIAL_CHREC
|
if (TREE_CODE (chrec) == POLYNOMIAL_CHREC
|
||||||
|
@ -631,26 +642,32 @@ tree
|
||||||
hide_evolution_in_other_loops_than_loop (tree chrec,
|
hide_evolution_in_other_loops_than_loop (tree chrec,
|
||||||
unsigned loop_num)
|
unsigned loop_num)
|
||||||
{
|
{
|
||||||
|
struct loop *loop = get_loop (loop_num), *chloop;
|
||||||
if (automatically_generated_chrec_p (chrec))
|
if (automatically_generated_chrec_p (chrec))
|
||||||
return chrec;
|
return chrec;
|
||||||
|
|
||||||
switch (TREE_CODE (chrec))
|
switch (TREE_CODE (chrec))
|
||||||
{
|
{
|
||||||
case POLYNOMIAL_CHREC:
|
case POLYNOMIAL_CHREC:
|
||||||
if (CHREC_VARIABLE (chrec) == loop_num)
|
chloop = get_chrec_loop (chrec);
|
||||||
|
|
||||||
|
if (chloop == loop)
|
||||||
return build_polynomial_chrec
|
return build_polynomial_chrec
|
||||||
(loop_num,
|
(loop_num,
|
||||||
hide_evolution_in_other_loops_than_loop (CHREC_LEFT (chrec),
|
hide_evolution_in_other_loops_than_loop (CHREC_LEFT (chrec),
|
||||||
loop_num),
|
loop_num),
|
||||||
CHREC_RIGHT (chrec));
|
CHREC_RIGHT (chrec));
|
||||||
|
|
||||||
else if (CHREC_VARIABLE (chrec) < loop_num)
|
else if (flow_loop_nested_p (chloop, loop))
|
||||||
/* There is no evolution in this loop. */
|
/* There is no evolution in this loop. */
|
||||||
return initial_condition (chrec);
|
return initial_condition (chrec);
|
||||||
|
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
gcc_assert (flow_loop_nested_p (loop, chloop));
|
||||||
return hide_evolution_in_other_loops_than_loop (CHREC_LEFT (chrec),
|
return hide_evolution_in_other_loops_than_loop (CHREC_LEFT (chrec),
|
||||||
loop_num);
|
loop_num);
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return chrec;
|
return chrec;
|
||||||
|
@ -666,6 +683,7 @@ chrec_component_in_loop_num (tree chrec,
|
||||||
bool right)
|
bool right)
|
||||||
{
|
{
|
||||||
tree component;
|
tree component;
|
||||||
|
struct loop *loop = get_loop (loop_num), *chloop;
|
||||||
|
|
||||||
if (automatically_generated_chrec_p (chrec))
|
if (automatically_generated_chrec_p (chrec))
|
||||||
return chrec;
|
return chrec;
|
||||||
|
@ -673,7 +691,9 @@ chrec_component_in_loop_num (tree chrec,
|
||||||
switch (TREE_CODE (chrec))
|
switch (TREE_CODE (chrec))
|
||||||
{
|
{
|
||||||
case POLYNOMIAL_CHREC:
|
case POLYNOMIAL_CHREC:
|
||||||
if (CHREC_VARIABLE (chrec) == loop_num)
|
chloop = get_chrec_loop (chrec);
|
||||||
|
|
||||||
|
if (chloop == loop)
|
||||||
{
|
{
|
||||||
if (right)
|
if (right)
|
||||||
component = CHREC_RIGHT (chrec);
|
component = CHREC_RIGHT (chrec);
|
||||||
|
@ -693,14 +713,17 @@ chrec_component_in_loop_num (tree chrec,
|
||||||
component);
|
component);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (CHREC_VARIABLE (chrec) < loop_num)
|
else if (flow_loop_nested_p (chloop, loop))
|
||||||
/* There is no evolution part in this loop. */
|
/* There is no evolution part in this loop. */
|
||||||
return NULL_TREE;
|
return NULL_TREE;
|
||||||
|
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
gcc_assert (flow_loop_nested_p (loop, chloop));
|
||||||
return chrec_component_in_loop_num (CHREC_LEFT (chrec),
|
return chrec_component_in_loop_num (CHREC_LEFT (chrec),
|
||||||
loop_num,
|
loop_num,
|
||||||
right);
|
right);
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (right)
|
if (right)
|
||||||
|
@ -742,10 +765,12 @@ reset_evolution_in_loop (unsigned loop_num,
|
||||||
tree chrec,
|
tree chrec,
|
||||||
tree new_evol)
|
tree new_evol)
|
||||||
{
|
{
|
||||||
|
struct loop *loop = get_loop (loop_num);
|
||||||
|
|
||||||
gcc_assert (chrec_type (chrec) == chrec_type (new_evol));
|
gcc_assert (chrec_type (chrec) == chrec_type (new_evol));
|
||||||
|
|
||||||
if (TREE_CODE (chrec) == POLYNOMIAL_CHREC
|
if (TREE_CODE (chrec) == POLYNOMIAL_CHREC
|
||||||
&& CHREC_VARIABLE (chrec) > loop_num)
|
&& flow_loop_nested_p (loop, get_chrec_loop (chrec)))
|
||||||
{
|
{
|
||||||
tree left = reset_evolution_in_loop (loop_num, CHREC_LEFT (chrec),
|
tree left = reset_evolution_in_loop (loop_num, CHREC_LEFT (chrec),
|
||||||
new_evol);
|
new_evol);
|
||||||
|
|
|
@ -464,10 +464,12 @@ compute_overall_effect_of_inner_loop (struct loop *loop, tree evolution_fn)
|
||||||
return chrec_dont_know;
|
return chrec_dont_know;
|
||||||
|
|
||||||
else if (TREE_CODE (evolution_fn) == POLYNOMIAL_CHREC)
|
else if (TREE_CODE (evolution_fn) == POLYNOMIAL_CHREC)
|
||||||
{
|
|
||||||
if (CHREC_VARIABLE (evolution_fn) >= (unsigned) loop->num)
|
|
||||||
{
|
{
|
||||||
struct loop *inner_loop = get_chrec_loop (evolution_fn);
|
struct loop *inner_loop = get_chrec_loop (evolution_fn);
|
||||||
|
|
||||||
|
if (inner_loop == loop
|
||||||
|
|| flow_loop_nested_p (loop, inner_loop))
|
||||||
|
{
|
||||||
tree nb_iter = number_of_latch_executions (inner_loop);
|
tree nb_iter = number_of_latch_executions (inner_loop);
|
||||||
|
|
||||||
if (nb_iter == chrec_dont_know)
|
if (nb_iter == chrec_dont_know)
|
||||||
|
@ -646,18 +648,21 @@ add_to_evolution_1 (unsigned loop_nb, tree chrec_before, tree to_add,
|
||||||
tree at_stmt)
|
tree at_stmt)
|
||||||
{
|
{
|
||||||
tree type, left, right;
|
tree type, left, right;
|
||||||
|
struct loop *loop = get_loop (loop_nb), *chloop;
|
||||||
|
|
||||||
switch (TREE_CODE (chrec_before))
|
switch (TREE_CODE (chrec_before))
|
||||||
{
|
{
|
||||||
case POLYNOMIAL_CHREC:
|
case POLYNOMIAL_CHREC:
|
||||||
if (CHREC_VARIABLE (chrec_before) <= loop_nb)
|
chloop = get_chrec_loop (chrec_before);
|
||||||
|
if (chloop == loop
|
||||||
|
|| flow_loop_nested_p (chloop, loop))
|
||||||
{
|
{
|
||||||
unsigned var;
|
unsigned var;
|
||||||
|
|
||||||
type = chrec_type (chrec_before);
|
type = chrec_type (chrec_before);
|
||||||
|
|
||||||
/* When there is no evolution part in this loop, build it. */
|
/* When there is no evolution part in this loop, build it. */
|
||||||
if (CHREC_VARIABLE (chrec_before) < loop_nb)
|
if (chloop != loop)
|
||||||
{
|
{
|
||||||
var = loop_nb;
|
var = loop_nb;
|
||||||
left = chrec_before;
|
left = chrec_before;
|
||||||
|
@ -679,6 +684,8 @@ add_to_evolution_1 (unsigned loop_nb, tree chrec_before, tree to_add,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
gcc_assert (flow_loop_nested_p (loop, chloop));
|
||||||
|
|
||||||
/* Search the evolution in LOOP_NB. */
|
/* Search the evolution in LOOP_NB. */
|
||||||
left = add_to_evolution_1 (loop_nb, CHREC_LEFT (chrec_before),
|
left = add_to_evolution_1 (loop_nb, CHREC_LEFT (chrec_before),
|
||||||
to_add, at_stmt);
|
to_add, at_stmt);
|
||||||
|
|
|
@ -88,7 +88,7 @@ tree_ssa_unswitch_loops (void)
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
|
||||||
/* Go through inner loops (only original ones). */
|
/* Go through inner loops (only original ones). */
|
||||||
FOR_EACH_LOOP (li, loop, LI_ONLY_OLD | LI_ONLY_INNERMOST)
|
FOR_EACH_LOOP (li, loop, LI_ONLY_INNERMOST)
|
||||||
{
|
{
|
||||||
changed |= tree_unswitch_single_loop (loop, 0);
|
changed |= tree_unswitch_single_loop (loop, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2175,7 +2175,7 @@ vectorize_loops (void)
|
||||||
than all previously defined loops. This fact allows us to run
|
than all previously defined loops. This fact allows us to run
|
||||||
only over initial loops skipping newly generated ones. */
|
only over initial loops skipping newly generated ones. */
|
||||||
vect_loops_num = number_of_loops ();
|
vect_loops_num = number_of_loops ();
|
||||||
FOR_EACH_LOOP (li, loop, LI_ONLY_OLD)
|
FOR_EACH_LOOP (li, loop, 0)
|
||||||
{
|
{
|
||||||
loop_vec_info loop_vinfo;
|
loop_vec_info loop_vinfo;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue