tree-vrp.c (adjust_range_with_scev): Use get_chrec_loop.

* tree-vrp.c (adjust_range_with_scev): Use get_chrec_loop.
	* loop-unswitch.c (unswitch_loops): Use FOR_EACH_LOOP.
	* tree-loop-linear.c (linear_transform_loops): Ditto.
	* tree-ssa-loop-im.c (determine_lsm): Ditto.
	* tree-ssa-loop-niter.c (estimate_numbers_of_iterations,
	free_numbers_of_iterations_estimates): Ditto.
	* tree_ssa_unswitch_loops (tree_ssa_unswitch_loops): Ditto.
	* tree-ssa-loop-ch.c (copy_loop_headers): Ditto.
	* tree-ssa-loop-ivopts.c (tree_ssa_iv_optimize): Ditto.
	* modulo-sched.c (sms_schedule): Ditto.
	* tree-ssa-loop-ivcanon.c (canonicalize_induction_variables,
	tree_unroll_loops_completely): Ditto.
	* predict.c (predict_loops): Ditto.
	* tree-if-conv.c (main_tree_if_conversion): Ditto.
	* loop-unroll.c (unroll_and_peel_loops, peel_loops_completely,
	decide_unrolling_and_peeling): Ditto.
	* cfgloopmanip.c (unloop): Use delete_loop.
	(place_new_loop): Access larray vector instead of parray.
	(create_preheaders, force_single_succ_latches,
	fix_loop_structure): Use FOR_EACH_LOOP and delete_loop..
	* loop-doloop.c (doloop_optimize_loops): Ditto.
	* loop-invariant.c (move_loop_invariants): Ditto.
	* tree-cfg.c (replace_uses_by): Ditto.
	* tree-ssa-loop-prefetch.c (tree_ssa_prefetch_arrays): Ditto.
	* tree-chrec.h (CHREC_VAR, CHREC_LEFT, CHREC_RIGHT, CHREC_VARIABLE):
	Moved to ...
	* tree.h (CHREC_VAR, CHREC_LEFT, CHREC_RIGHT, CHREC_VARIABLE):
	... here.
	* tree-scalar-evolution.c (chrec_contains_symbols_defined_in_loop,
	compute_overall_effect_of_inner_loop, chrec_is_positive): Use
	get_loop and get_chrec_loop.
	(number_of_iterations_for_all_loops): Use number_of_loops.
	(scev_initialize, scev_reset, scev_const_prop): Use FOR_EACH_LOOP.
	* tree-scalar-evolution.h (get_chrec_loop): New inline function.
	* cfgloopanal.c (mark_irreducible_loops): Use number_of_loops,
	and FOR_EACH_LOOP.
	* tree-chrec.c (evolution_function_is_invariant_rec_p,
	chrec_convert_1): Use get_loop and get_chrec_loop.
	* loop-init.c (loop_optimizer_init): Use number_of_loops.
	(loop_optimizer_init): Use FOR_EACH_LOOP.
	* tree-vectorizer.c (vect_loops_num): Removed.
	(vectorize_loops): Store number of loops locally.  Use
	FOR_EACH_LOOP and get_loop.
	* tree-vectorizer.h (vect_loops_num): Removed.
	* tree-data-ref.c (get_number_of_iters_for_loop): Use get_loop.
	(find_data_references_in_loop): Do not set parallel_p.
	* tree-data-ref.h: Do not declare VEC(loop_p).
	* cfgloop.c (flow_loops_dump, mark_single_exit_loops,
	verify_loop_structure): Use FOR_EACH_LOOP.
	(flow_loops_free): Use FOR_EACH_LOOP, free larray vector.
	(initialize_loops_parallel_p): Removed.
	(flow_loops_find): Push the loops into a vector.
	(delete_loop): New function.
	(cancel_loop): Use delete_loop.
	* cfgloop.h: Declare VEC(loop_p).
	(struct loop): Remove parallel_p field.
	(struct loops): Replace num and parray field by larray vector.
	Remove shared_headers field.
	(delete_loop): Declare.
	(get_loop, get_loops, number_of_loops, fel_next, fel_init,
	FOR_EACH_LOOP): New.
	* doc/loop.tex: Document new accessor functions.

From-SVN: r119713
This commit is contained in:
Zdenek Dvorak 2006-12-10 23:17:15 +01:00 committed by Zdenek Dvorak
parent 7290d709ef
commit 42fd6772c6
33 changed files with 395 additions and 417 deletions

View File

@ -1,3 +1,68 @@
2006-12-10 Zdenek Dvorak <dvorakz@suse.cz>
* tree-vrp.c (adjust_range_with_scev): Use get_chrec_loop.
* loop-unswitch.c (unswitch_loops): Use FOR_EACH_LOOP.
* tree-loop-linear.c (linear_transform_loops): Ditto.
* tree-ssa-loop-im.c (determine_lsm): Ditto.
* tree-ssa-loop-niter.c (estimate_numbers_of_iterations,
free_numbers_of_iterations_estimates): Ditto.
* tree_ssa_unswitch_loops (tree_ssa_unswitch_loops): Ditto.
* tree-ssa-loop-ch.c (copy_loop_headers): Ditto.
* tree-ssa-loop-ivopts.c (tree_ssa_iv_optimize): Ditto.
* modulo-sched.c (sms_schedule): Ditto.
* tree-ssa-loop-ivcanon.c (canonicalize_induction_variables,
tree_unroll_loops_completely): Ditto.
* predict.c (predict_loops): Ditto.
* tree-if-conv.c (main_tree_if_conversion): Ditto.
* loop-unroll.c (unroll_and_peel_loops, peel_loops_completely,
decide_unrolling_and_peeling): Ditto.
* cfgloopmanip.c (unloop): Use delete_loop.
(place_new_loop): Access larray vector instead of parray.
(create_preheaders, force_single_succ_latches,
fix_loop_structure): Use FOR_EACH_LOOP and delete_loop..
* loop-doloop.c (doloop_optimize_loops): Ditto.
* loop-invariant.c (move_loop_invariants): Ditto.
* tree-cfg.c (replace_uses_by): Ditto.
* tree-ssa-loop-prefetch.c (tree_ssa_prefetch_arrays): Ditto.
* tree-chrec.h (CHREC_VAR, CHREC_LEFT, CHREC_RIGHT, CHREC_VARIABLE):
Moved to ...
* tree.h (CHREC_VAR, CHREC_LEFT, CHREC_RIGHT, CHREC_VARIABLE):
... here.
* tree-scalar-evolution.c (chrec_contains_symbols_defined_in_loop,
compute_overall_effect_of_inner_loop, chrec_is_positive): Use
get_loop and get_chrec_loop.
(number_of_iterations_for_all_loops): Use number_of_loops.
(scev_initialize, scev_reset, scev_const_prop): Use FOR_EACH_LOOP.
* tree-scalar-evolution.h (get_chrec_loop): New inline function.
* cfgloopanal.c (mark_irreducible_loops): Use number_of_loops,
and FOR_EACH_LOOP.
* tree-chrec.c (evolution_function_is_invariant_rec_p,
chrec_convert_1): Use get_loop and get_chrec_loop.
* loop-init.c (loop_optimizer_init): Use number_of_loops.
(loop_optimizer_init): Use FOR_EACH_LOOP.
* tree-vectorizer.c (vect_loops_num): Removed.
(vectorize_loops): Store number of loops locally. Use
FOR_EACH_LOOP and get_loop.
* tree-vectorizer.h (vect_loops_num): Removed.
* tree-data-ref.c (get_number_of_iters_for_loop): Use get_loop.
(find_data_references_in_loop): Do not set parallel_p.
* tree-data-ref.h: Do not declare VEC(loop_p).
* cfgloop.c (flow_loops_dump, mark_single_exit_loops,
verify_loop_structure): Use FOR_EACH_LOOP.
(flow_loops_free): Use FOR_EACH_LOOP, free larray vector.
(initialize_loops_parallel_p): Removed.
(flow_loops_find): Push the loops into a vector.
(delete_loop): New function.
(cancel_loop): Use delete_loop.
* cfgloop.h: Declare VEC(loop_p).
(struct loop): Remove parallel_p field.
(struct loops): Replace num and parray field by larray vector.
Remove shared_headers field.
(delete_loop): Declare.
(get_loop, get_loops, number_of_loops, fel_next, fel_init,
FOR_EACH_LOOP): New.
* doc/loop.tex: Document new accessor functions.
2006-12-10 Andrew MacLeod <amacleod@redhat.com>
* common.opt (-ftree-lrs): Remove live range splitting option.

View File

@ -128,20 +128,16 @@ flow_loop_dump (const struct loop *loop, FILE *file,
void
flow_loops_dump (FILE *file, void (*loop_dump_aux) (const struct loop *, FILE *, int), int verbose)
{
unsigned i;
loop_iterator li;
struct loop *loop;
if (!current_loops || ! file)
return;
fprintf (file, ";; %d loops found\n", current_loops->num);
fprintf (file, ";; %d loops found\n", number_of_loops ());
for (i = 0; i < current_loops->num; i++)
FOR_EACH_LOOP (li, loop, LI_INCLUDE_ROOT)
{
struct loop *loop = current_loops->parray[i];
if (!loop)
continue;
flow_loop_dump (loop, file, loop_dump_aux, verbose);
}
@ -163,25 +159,22 @@ flow_loop_free (struct loop *loop)
void
flow_loops_free (struct loops *loops)
{
if (loops->parray)
if (loops->larray)
{
unsigned i;
gcc_assert (loops->num);
loop_p loop;
/* Free the loop descriptors. */
for (i = 0; i < loops->num; i++)
for (i = 0; VEC_iterate (loop_p, loops->larray, i, loop); i++)
{
struct loop *loop = loops->parray[i];
if (!loop)
continue;
flow_loop_free (loop);
}
free (loops->parray);
loops->parray = NULL;
VEC_free (loop_p, heap, loops->larray);
loops->larray = NULL;
}
}
@ -242,13 +235,11 @@ mark_single_exit_loops (void)
basic_block bb;
edge e;
struct loop *loop;
unsigned i;
loop_iterator li;
for (i = 1; i < current_loops->num; i++)
FOR_EACH_LOOP (li, loop, 0)
{
loop = current_loops->parray[i];
if (loop)
set_single_exit (loop, NULL);
set_single_exit (loop, NULL);
}
FOR_EACH_BB (bb)
@ -278,12 +269,8 @@ mark_single_exit_loops (void)
}
}
for (i = 1; i < current_loops->num; i++)
FOR_EACH_LOOP (li, loop, 0)
{
loop = current_loops->parray[i];
if (!loop)
continue;
if (single_exit (loop) == single_succ_edge (ENTRY_BLOCK_PTR))
set_single_exit (loop, NULL);
}
@ -499,20 +486,6 @@ canonicalize_loop_headers (void)
#endif
}
/* Initialize all the parallel_p fields of the loops structure to true. */
static void
initialize_loops_parallel_p (struct loops *loops)
{
unsigned int i;
for (i = 0; i < loops->num; i++)
{
struct loop *loop = loops->parray[i];
loop->parallel_p = true;
}
}
/* Find all the natural loops in the function and save in LOOPS structure and
recalculate loop_depth information in basic block structures.
Return the number of natural loops found. */
@ -528,6 +501,7 @@ flow_loops_find (struct loops *loops)
int *rc_order;
basic_block header;
basic_block bb;
struct loop *root;
memset (loops, 0, sizeof *loops);
@ -594,26 +568,21 @@ flow_loops_find (struct loops *loops)
}
/* Allocate loop structures. */
loops->parray = XCNEWVEC (struct loop *, num_loops + 1);
loops->larray = VEC_alloc (loop_p, heap, num_loops + 1);
/* Dummy loop containing whole function. */
loops->parray[0] = XCNEW (struct loop);
loops->parray[0]->next = NULL;
loops->parray[0]->inner = NULL;
loops->parray[0]->outer = NULL;
loops->parray[0]->depth = 0;
loops->parray[0]->pred = NULL;
loops->parray[0]->num_nodes = n_basic_blocks;
loops->parray[0]->latch = EXIT_BLOCK_PTR;
loops->parray[0]->header = ENTRY_BLOCK_PTR;
ENTRY_BLOCK_PTR->loop_father = loops->parray[0];
EXIT_BLOCK_PTR->loop_father = loops->parray[0];
root = XCNEW (struct loop);
root->num_nodes = n_basic_blocks;
root->latch = EXIT_BLOCK_PTR;
root->header = ENTRY_BLOCK_PTR;
ENTRY_BLOCK_PTR->loop_father = root;
EXIT_BLOCK_PTR->loop_father = root;
loops->tree_root = loops->parray[0];
VEC_quick_push (loop_p, loops->larray, root);
loops->tree_root = root;
/* Find and record information about all the natural loops
in the CFG. */
loops->num = 1;
FOR_EACH_BB (bb)
bb->loop_father = loops->tree_root;
@ -639,7 +608,8 @@ flow_loops_find (struct loops *loops)
header = BASIC_BLOCK (rc_order[b]);
loop = loops->parray[num_loops] = XCNEW (struct loop);
loop = XCNEW (struct loop);
VEC_quick_push (loop_p, loops->larray, loop);
loop->header = header;
loop->num = num_loops;
@ -662,9 +632,6 @@ flow_loops_find (struct loops *loops)
loop->num_nodes = flow_loop_nodes_find (loop->header, loop);
}
loops->num = num_loops;
initialize_loops_parallel_p (loops);
free (dfs_order);
free (rc_order);
}
@ -672,7 +639,7 @@ flow_loops_find (struct loops *loops)
sbitmap_free (headers);
loops->state = 0;
return loops->num;
return VEC_length (loop_p, loops->larray);
}
/* Return nonzero if basic block BB belongs to LOOP. */
@ -924,6 +891,21 @@ find_common_loop (struct loop *loop_s, struct loop *loop_d)
return loop_s;
}
/* Removes LOOP from structures and frees its data. */
void
delete_loop (struct loop *loop)
{
/* Remove the loop from structure. */
flow_loop_tree_node_remove (loop);
/* Remove loop from loops array. */
VEC_replace (loop_p, current_loops->larray, loop->num, NULL);
/* Free loop data. */
flow_loop_free (loop);
}
/* Cancels the LOOP; it must be innermost one. */
static void
@ -939,14 +921,7 @@ cancel_loop (struct loop *loop)
for (i = 0; i < loop->num_nodes; i++)
bbs[i]->loop_father = loop->outer;
/* Remove the loop from structure. */
flow_loop_tree_node_remove (loop);
/* Remove loop from loops array. */
current_loops->parray[loop->num] = NULL;
/* Free loop data. */
flow_loop_free (loop);
delete_loop (loop);
}
/* Cancels LOOP and all its subloops. */
@ -974,52 +949,48 @@ verify_loop_structure (void)
struct loop *loop;
int err = 0;
edge e;
unsigned num = number_of_loops ();
loop_iterator li;
/* Check sizes. */
sizes = XCNEWVEC (unsigned, current_loops->num);
sizes = XCNEWVEC (unsigned, num);
sizes[0] = 2;
FOR_EACH_BB (bb)
for (loop = bb->loop_father; loop; loop = loop->outer)
sizes[loop->num]++;
for (i = 0; i < current_loops->num; i++)
FOR_EACH_LOOP (li, loop, LI_INCLUDE_ROOT)
{
if (!current_loops->parray[i])
continue;
i = loop->num;
if (current_loops->parray[i]->num_nodes != sizes[i])
if (loop->num_nodes != sizes[i])
{
error ("size of loop %d should be %d, not %d",
i, sizes[i], current_loops->parray[i]->num_nodes);
i, sizes[i], loop->num_nodes);
err = 1;
}
}
/* Check get_loop_body. */
for (i = 1; i < current_loops->num; i++)
FOR_EACH_LOOP (li, loop, 0)
{
loop = current_loops->parray[i];
if (!loop)
continue;
bbs = get_loop_body (loop);
for (j = 0; j < loop->num_nodes; j++)
if (!flow_bb_inside_loop_p (loop, bbs[j]))
{
error ("bb %d do not belong to loop %d",
bbs[j]->index, i);
bbs[j]->index, loop->num);
err = 1;
}
free (bbs);
}
/* Check headers and latches. */
for (i = 1; i < current_loops->num; i++)
FOR_EACH_LOOP (li, loop, 0)
{
loop = current_loops->parray[i];
if (!loop)
continue;
i = loop->num;
if ((current_loops->state & LOOPS_HAVE_PREHEADERS)
&& EDGE_COUNT (loop->header->preds) != 2)
@ -1120,7 +1091,7 @@ verify_loop_structure (void)
/* Check the single_exit. */
if (current_loops->state & LOOPS_HAVE_MARKED_SINGLE_EXITS)
{
memset (sizes, 0, sizeof (unsigned) * current_loops->num);
memset (sizes, 0, sizeof (unsigned) * num);
FOR_EACH_BB (bb)
{
edge_iterator ei;
@ -1154,11 +1125,9 @@ verify_loop_structure (void)
}
}
for (i = 1; i < current_loops->num; i++)
FOR_EACH_LOOP (li, loop, 0)
{
loop = current_loops->parray[i];
if (!loop)
continue;
i = loop->num;
if (sizes[i] == 1
&& !single_exit (loop))

View File

@ -146,12 +146,6 @@ struct loop
EXIT_BLOCK_PTR do not count. Do not use directly; this field should
only be accessed via single_exit/set_single_exit functions. */
edge single_exit_;
/* True when the loop does not carry data dependences, and
consequently the iterations can be executed in any order. False
when the loop carries data dependences, or when the property is
not decidable. */
bool parallel_p;
};
/* Flags for state of loop structure. */
@ -166,26 +160,21 @@ enum
#define LOOPS_NORMAL (LOOPS_HAVE_PREHEADERS | LOOPS_HAVE_SIMPLE_LATCHES \
| LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
typedef struct loop *loop_p;
DEF_VEC_P (loop_p);
DEF_VEC_ALLOC_P (loop_p, heap);
/* Structure to hold CFG information about natural loops within a function. */
struct loops
{
/* Number of natural loops in the function. */
unsigned num;
/* State of loops. */
int state;
/* We store just pointers to loops here.
Note that a loop in this array may actually be NULL, if the loop
has been removed and the entire loops structure has not been
recomputed since that time. */
struct loop **parray;
/* Array of the loops. */
VEC (loop_p, heap) *larray;
/* Pointer to root of loop hierarchy tree. */
struct loop *tree_root;
/* Headers shared by multiple loops that should be merged. */
sbitmap shared_headers;
};
/* Loop recognition. */
@ -231,6 +220,7 @@ extern void add_bb_to_loop (basic_block, struct loop *);
extern void remove_bb_from_loops (basic_block);
extern void cancel_loop_tree (struct loop *);
extern void delete_loop (struct loop *);
extern int fix_loop_placement (struct loop *);
@ -375,6 +365,124 @@ simple_loop_desc (struct loop *loop)
return (struct niter_desc *) loop->aux;
}
/* Accessors for the loop structures. */
/* Returns the loop with index NUM from current_loops. */
static inline struct loop *
get_loop (unsigned num)
{
return VEC_index (loop_p, current_loops->larray, num);
}
/* Returns the list of loops in current_loops. */
static inline VEC (loop_p, heap) *
get_loops (void)
{
if (!current_loops)
return NULL;
return current_loops->larray;
}
/* Returns the number of loops in current_loops (including the removed
ones and the fake loop that forms the root of the loop tree). */
static inline unsigned
number_of_loops (void)
{
if (!current_loops)
return 0;
return VEC_length (loop_p, current_loops->larray);
}
/* Loop iterators. */
/* Flags for loop iteration. */
enum li_flags
{
LI_INCLUDE_ROOT, /* Include the fake root of the loop tree. */
LI_FROM_INNERMOST, /* Iterate over the loops in the reverse order,
starting from innermost ones. */
LI_ONLY_INNERMOST, /* Iterate only over innermost loops. */
LI_ONLY_OLD /* Do not traverse the loops created during the
traversal (this is the default behavior with
LI_FROM_INNERMOST). */
};
/* The iterator for loops. */
typedef struct
{
int idx; /* Index of the actual loop. */
int end; /* Only loops before end should be traversed. */
} loop_iterator;
static inline void
fel_next (loop_iterator *li, loop_p *loop, unsigned flags)
{
if (flags & LI_FROM_INNERMOST)
{
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++;
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;
}
}
*loop = NULL;
}
static inline void
fel_init (loop_iterator *li, loop_p *loop, unsigned flags)
{
if (!current_loops)
{
li->idx = 0;
li->end = 0;
*loop = NULL;
return;
}
if (flags & LI_FROM_INNERMOST)
{
li->idx = number_of_loops ();
li->end = (flags & LI_INCLUDE_ROOT) ? -1 : 0;
}
else
{
li->idx = (flags & LI_INCLUDE_ROOT) ? -1 : 0;
li->end = number_of_loops ();
}
fel_next (li, loop, flags);
}
#define FOR_EACH_LOOP(LI, LOOP, FLAGS) \
for (fel_init (&(LI), &(LOOP), FLAGS); \
(LOOP); \
fel_next (&(LI), &(LOOP), FLAGS))
/* The properties of the target. */
extern unsigned target_avail_regs; /* Number of available registers. */

View File

@ -273,11 +273,12 @@ mark_irreducible_loops (void)
edge_iterator ei;
int i, src, dest;
struct graph *g;
int num = current_loops ? current_loops->num : 1;
int num = current_loops ? number_of_loops () : 1;
int *queue1 = XNEWVEC (int, last_basic_block + num);
int *queue2 = XNEWVEC (int, last_basic_block + num);
int nq, depth;
struct loop *cloop;
struct loop *cloop, *loop;
loop_iterator li;
/* Reset the flags. */
FOR_BB_BETWEEN (act, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
@ -343,9 +344,14 @@ mark_irreducible_loops (void)
{
queue1[nq++] = BB_REPR (act);
}
for (i = 1; i < num; i++)
if (current_loops->parray[i])
queue1[nq++] = LOOP_REPR (current_loops->parray[i]);
if (current_loops)
{
FOR_EACH_LOOP (li, loop, 0)
{
queue1[nq++] = LOOP_REPR (loop);
}
}
dfs (g, queue1, nq, queue2, false);
for (i = 0; i < nq; i++)
queue1[i] = queue2[nq - i - 1];

View File

@ -552,9 +552,7 @@ unloop (struct loop *loop, bool *irred_invalidated)
}
/* Remove the loop and free its data. */
flow_loop_tree_node_remove (loop);
current_loops->parray[loop->num] = NULL;
flow_loop_free (loop);
delete_loop (loop);
remove_edge (single_succ_edge (latch));
@ -634,11 +632,8 @@ fix_loop_placements (struct loop *loop, bool *irred_invalidated)
static void
place_new_loop (struct loop *loop)
{
current_loops->parray =
xrealloc (current_loops->parray, (current_loops->num + 1) * sizeof (struct loop *));
current_loops->parray[current_loops->num] = loop;
loop->num = current_loops->num++;
loop->num = number_of_loops ();
VEC_safe_push (loop_p, heap, current_loops->larray, loop);
}
/* Copies copy of LOOP as subloop of TARGET loop, placing newly
@ -1195,9 +1190,11 @@ create_preheader (struct loop *loop, int flags)
void
create_preheaders (int flags)
{
unsigned i;
for (i = 1; i < current_loops->num; i++)
create_preheader (current_loops->parray[i], flags);
loop_iterator li;
struct loop *loop;
FOR_EACH_LOOP (li, loop, 0)
create_preheader (loop, flags);
current_loops->state |= LOOPS_HAVE_PREHEADERS;
}
@ -1206,13 +1203,12 @@ create_preheaders (int flags)
void
force_single_succ_latches (void)
{
unsigned i;
loop_iterator li;
struct loop *loop;
edge e;
for (i = 1; i < current_loops->num; i++)
FOR_EACH_LOOP (li, loop, 0)
{
loop = current_loops->parray[i];
if (loop->latch != loop->header && single_succ_p (loop->latch))
continue;
@ -1392,7 +1388,7 @@ fix_loop_structure (bitmap changed_bbs)
{
basic_block bb;
struct loop *loop, *ploop;
unsigned i;
loop_iterator li;
/* Remove the old bb -> loop mapping. */
FOR_EACH_BB (bb)
@ -1403,12 +1399,8 @@ fix_loop_structure (bitmap changed_bbs)
/* Remove the dead loops from structures. */
current_loops->tree_root->num_nodes = n_basic_blocks;
for (i = 1; i < current_loops->num; i++)
FOR_EACH_LOOP (li, loop, 0)
{
loop = current_loops->parray[i];
if (!loop)
continue;
loop->num_nodes = 0;
if (loop->header)
continue;
@ -1421,38 +1413,18 @@ fix_loop_structure (bitmap changed_bbs)
}
/* Remove the loop and free its data. */
flow_loop_tree_node_remove (loop);
current_loops->parray[loop->num] = NULL;
flow_loop_free (loop);
delete_loop (loop);
}
/* Rescan the bodies of loops, starting from the outermost. */
loop = current_loops->tree_root;
while (1)
FOR_EACH_LOOP (li, loop, 0)
{
if (loop->inner)
loop = loop->inner;
else
{
while (!loop->next
&& loop != current_loops->tree_root)
loop = loop->outer;
if (loop == current_loops->tree_root)
break;
loop = loop->next;
}
loop->num_nodes = flow_loop_nodes_find (loop->header, loop);
}
/* Now fix the loop nesting. */
for (i = 1; i < current_loops->num; i++)
FOR_EACH_LOOP (li, loop, 0)
{
loop = current_loops->parray[i];
if (!loop)
continue;
bb = loop_preheader_edge (loop)->src;
if (bb->loop_father != loop->outer)
{

View File

@ -63,20 +63,25 @@ The root of this tree is a fake loop that contains all blocks in the
function. Each of the loops is represented in a @code{struct loop}
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
the corresponding field of the @code{parray} field of 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
super-loop. The indices do not have to be continuous, there may be
empty (@code{NULL}) entries in the @code{parray} created by deleting
loops. The index of a loop never changes. The first unused index is
stored in the @code{num} field of the loops structure.
empty (@code{NULL}) entries in the @code{larray} created by deleting
loops. The index of a loop never changes.
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 given index. @code{number_of_loops} function returns number of
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
the direction of traversal and the set of loops visited.
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
one @code{struct loops} structure initialized at the same time for each
CFG. It is recommended to use the global variable @code{current_loops}
to contain the @code{struct loops} structure, especially if the loop
structures are updated throughout several passes. Many of the loop
manipulation functions assume that dominance information is up-to-date.
CFG. The global variable @code{current_loops} contains the
@code{struct loops} structure. Many of the loop manipulation functions
assume that dominance information is up-to-date.
The loops are analyzed through @code{loop_optimizer_init} function. The
argument of this function is a set of flags represented in an integer

View File

@ -621,15 +621,11 @@ doloop_optimize (struct loop *loop)
void
doloop_optimize_loops (void)
{
unsigned i;
loop_iterator li;
struct loop *loop;
for (i = 1; i < current_loops->num; i++)
FOR_EACH_LOOP (li, loop, 0)
{
loop = current_loops->parray[i];
if (!loop)
continue;
doloop_optimize (loop);
}

View File

@ -68,9 +68,10 @@ loop_optimizer_init (unsigned flags)
flow_loops_find (loops);
current_loops = loops;
if (current_loops->num <= 1)
if (number_of_loops () <= 1)
{
/* No loops. */
/* No loops (the 1 returned by number_of_loops corresponds to the fake
loop that we put as a root of the loop tree). */
loop_optimizer_finalize ();
return;
}
@ -104,15 +105,17 @@ loop_optimizer_init (unsigned flags)
void
loop_optimizer_finalize (void)
{
unsigned i;
loop_iterator li;
struct loop *loop;
basic_block bb;
if (!current_loops)
return;
for (i = 1; i < current_loops->num; i++)
if (current_loops->parray[i])
free_simple_loop_desc (current_loops->parray[i]);
FOR_EACH_LOOP (li, loop, 0)
{
free_simple_loop_desc (loop);
}
/* Clean up. */
flow_loops_free (current_loops);

View File

@ -1318,33 +1318,21 @@ void
move_loop_invariants (void)
{
struct loop *loop;
unsigned i;
loop_iterator li;
df = df_init (DF_HARD_REGS | DF_EQUIV_NOTES);
df_chain_add_problem (df, DF_UD_CHAIN);
/* Process the loops, innermost first. */
loop = current_loops->tree_root;
while (loop->inner)
loop = loop->inner;
while (loop != current_loops->tree_root)
FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
{
move_single_loop_invariants (loop);
if (loop->next)
{
loop = loop->next;
while (loop->inner)
loop = loop->inner;
}
else
loop = loop->outer;
}
for (i = 1; i < current_loops->num; i++)
if (current_loops->parray[i])
free_loop_data (current_loops->parray[i]);
FOR_EACH_LOOP (li, loop, 0)
{
free_loop_data (loop);
}
df_finish (df);
df = NULL;

View File

@ -144,8 +144,9 @@ static rtx get_expansion (struct var_to_expand *);
void
unroll_and_peel_loops (int flags)
{
struct loop *loop, *next;
struct loop *loop;
bool check;
loop_iterator li;
/* First perform complete loop peeling (it is almost surely a win,
and affects parameters for further decision a lot). */
@ -154,22 +155,9 @@ unroll_and_peel_loops (int flags)
/* Now decide rest of unrolling and peeling. */
decide_unrolling_and_peeling (flags);
loop = current_loops->tree_root;
while (loop->inner)
loop = loop->inner;
/* Scan the loops, inner ones first. */
while (loop != current_loops->tree_root)
FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
{
if (loop->next)
{
next = loop->next;
while (next->inner)
next = next->inner;
}
else
next = loop->outer;
check = true;
/* And perform the appropriate transformations. */
switch (loop->lpt_decision.decision)
@ -202,7 +190,6 @@ unroll_and_peel_loops (int flags)
verify_loop_structure ();
#endif
}
loop = next;
}
iv_analysis_done ();
@ -234,15 +221,11 @@ static void
peel_loops_completely (int flags)
{
struct loop *loop;
unsigned i;
loop_iterator li;
/* Scan the loops, the inner ones first. */
for (i = current_loops->num - 1; i > 0; i--)
FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
{
loop = current_loops->parray[i];
if (!loop)
continue;
loop->lpt_decision.decision = LPT_NONE;
if (dump_file)
@ -271,23 +254,12 @@ peel_loops_completely (int flags)
static void
decide_unrolling_and_peeling (int flags)
{
struct loop *loop = current_loops->tree_root, *next;
while (loop->inner)
loop = loop->inner;
struct loop *loop;
loop_iterator li;
/* Scan the loops, inner ones first. */
while (loop != current_loops->tree_root)
FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
{
if (loop->next)
{
next = loop->next;
while (next->inner)
next = next->inner;
}
else
next = loop->outer;
loop->lpt_decision.decision = LPT_NONE;
if (dump_file)
@ -298,7 +270,6 @@ decide_unrolling_and_peeling (int flags)
{
if (dump_file)
fprintf (dump_file, ";; Not considering loop, cold area\n");
loop = next;
continue;
}
@ -308,7 +279,6 @@ decide_unrolling_and_peeling (int flags)
if (dump_file)
fprintf (dump_file,
";; Not considering loop, cannot duplicate\n");
loop = next;
continue;
}
@ -317,7 +287,6 @@ decide_unrolling_and_peeling (int flags)
{
if (dump_file)
fprintf (dump_file, ";; Not considering loop, is not innermost\n");
loop = next;
continue;
}
@ -334,8 +303,6 @@ decide_unrolling_and_peeling (int flags)
decide_unroll_stupid (loop, flags);
if (loop->lpt_decision.decision == LPT_NONE)
decide_peel_simple (loop, flags);
loop = next;
}
}

View File

@ -138,22 +138,13 @@ compare_and_jump_seq (rtx op0, rtx op1, enum rtx_code comp, rtx label, int prob,
void
unswitch_loops (void)
{
int i, num;
loop_iterator li;
struct loop *loop;
/* Go through inner loops (only original ones). */
num = current_loops->num;
for (i = 1; i < num; i++)
FOR_EACH_LOOP (li, loop, LI_ONLY_OLD | LI_ONLY_INNERMOST)
{
/* Removed loop? */
loop = current_loops->parray[i];
if (!loop)
continue;
if (loop->inner)
continue;
unswitch_single_loop (loop, NULL_RTX, 0);
#ifdef ENABLE_CHECKING
verify_dominators (CDI_DOMINATORS);

View File

@ -878,12 +878,11 @@ sms_schedule (void)
ddg_ptr *g_arr, g;
int * node_order;
int maxii;
unsigned i,num_loops;
loop_iterator li;
partial_schedule_ptr ps;
struct df *df;
basic_block bb = NULL;
/* vars to the versioning only if needed*/
struct loop * nloop;
struct loop *loop, *nloop;
basic_block condition_bb = NULL;
edge latch_edge;
gcov_type trip_count = 0;
@ -921,16 +920,14 @@ sms_schedule (void)
/* Allocate memory to hold the DDG array one entry for each loop.
We use loop->num as index into this array. */
g_arr = XCNEWVEC (ddg_ptr, current_loops->num);
g_arr = XCNEWVEC (ddg_ptr, number_of_loops ());
/* Build DDGs for all the relevant loops and hold them in G_ARR
indexed by the loop index. */
for (i = 0; i < current_loops->num; i++)
FOR_EACH_LOOP (li, loop, 0)
{
rtx head, tail;
rtx count_reg;
struct loop *loop = current_loops->parray[i];
/* For debugging. */
if ((passes++ > MAX_SMS_LOOP_NUMBER) && (MAX_SMS_LOOP_NUMBER != -1))
@ -1019,7 +1016,7 @@ sms_schedule (void)
continue;
}
g_arr[i] = g;
g_arr[loop->num] = g;
}
/* Release Data Flow analysis data structures. */
@ -1027,18 +1024,15 @@ sms_schedule (void)
df = NULL;
/* We don't want to perform SMS on new loops - created by versioning. */
num_loops = current_loops->num;
/* Go over the built DDGs and perfrom SMS for each one of them. */
for (i = 0; i < num_loops; i++)
FOR_EACH_LOOP (li, loop, LI_ONLY_OLD)
{
rtx head, tail;
rtx count_reg, count_init;
int mii, rec_mii;
unsigned stage_count = 0;
HOST_WIDEST_INT loop_count = 0;
struct loop *loop = current_loops->parray[i];
if (! (g = g_arr[i]))
if (! (g = g_arr[loop->num]))
continue;
if (dump_file)

View File

@ -630,17 +630,17 @@ combine_predictions_for_bb (basic_block bb)
static void
predict_loops (void)
{
unsigned i;
loop_iterator li;
struct loop *loop;
scev_initialize ();
/* Try to predict out blocks in a loop that are not part of a
natural loop. */
for (i = 1; i < current_loops->num; i++)
FOR_EACH_LOOP (li, loop, 0)
{
basic_block bb, *bbs;
unsigned j, n_exits;
struct loop *loop = current_loops->parray[i];
VEC (edge, heap) *exits;
struct tree_niter_desc niter_desc;
edge ex;

View File

@ -1245,7 +1245,6 @@ replace_uses_by (tree name, tree val)
use_operand_p use;
tree stmt;
edge e;
unsigned i;
FOR_EACH_IMM_USE_STMT (stmt, imm_iter, name)
{
@ -1286,12 +1285,11 @@ replace_uses_by (tree name, tree val)
if (current_loops)
{
struct loop *loop;
loop_iterator li;
for (i = 0; i < current_loops->num; i++)
FOR_EACH_LOOP (li, loop, 0)
{
loop = current_loops->parray[i];
if (loop)
substitute_in_loop_info (loop, name, val);
substitute_in_loop_info (loop, name, val);
}
}
}

View File

@ -939,8 +939,7 @@ evolution_function_is_invariant_rec_p (tree chrec, int loopnum)
return true;
if (TREE_CODE (chrec) == SSA_NAME
&& expr_invariant_in_loop_p (current_loops->parray[loopnum],
chrec))
&& expr_invariant_in_loop_p (get_loop (loopnum), chrec))
return true;
if (TREE_CODE (chrec) == POLYNOMIAL_CHREC)
@ -1280,7 +1279,7 @@ chrec_convert_1 (tree type, tree chrec, tree at_stmt,
if (!evolution_function_is_affine_p (chrec))
goto keep_cast;
loop = current_loops->parray[CHREC_VARIABLE (chrec)];
loop = get_chrec_loop (chrec);
base = CHREC_LEFT (chrec);
step = CHREC_RIGHT (chrec);

View File

@ -22,14 +22,6 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#ifndef GCC_TREE_CHREC_H
#define GCC_TREE_CHREC_H
/* Accessors for the chains of recurrences. */
#define CHREC_VAR(NODE) TREE_OPERAND (NODE, 0)
#define CHREC_LEFT(NODE) TREE_OPERAND (NODE, 1)
#define CHREC_RIGHT(NODE) TREE_OPERAND (NODE, 2)
#define CHREC_VARIABLE(NODE) TREE_INT_CST_LOW (CHREC_VAR (NODE))
/* The following trees are unique elements. Thus the comparison of another
element to these elements should be done on the pointer to these trees,
and not on their value. */

View File

@ -2304,7 +2304,7 @@ analyze_ziv_subscript (tree chrec_a,
static tree
get_number_of_iters_for_loop (int loopnum)
{
struct loop *loop = current_loops->parray[loopnum];
struct loop *loop = get_loop (loopnum);
tree numiter = number_of_iterations_in_loop (loop);
if (TREE_CODE (numiter) == INTEGER_CST)
@ -4109,7 +4109,6 @@ find_data_references_in_loop (struct loop *loop,
block_stmt_iterator bsi;
bbs = get_loop_body (loop);
loop->parallel_p = true;
for (i = 0; i < loop->num_nodes; i++)
{
@ -4137,16 +4136,11 @@ find_data_references_in_loop (struct loop *loop,
DR_OFFSET_MISALIGNMENT (res) = NULL_TREE;
DR_MEMTAG (res) = NULL_TREE;
DR_PTR_INFO (res) = NULL;
loop->parallel_p = false;
VEC_safe_push (data_reference_p, heap, *datarefs, res);
free (bbs);
return chrec_dont_know;
}
/* When there are no defs in the loop, the loop is parallel. */
if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS))
loop->parallel_p = false;
}
}
free (bbs);

View File

@ -224,10 +224,6 @@ DEF_VEC_ALLOC_P (subscript_p, heap);
#define SUB_LAST_CONFLICT(SUB) SUB->last_conflict
#define SUB_DISTANCE(SUB) SUB->distance
typedef struct loop *loop_p;
DEF_VEC_P(loop_p);
DEF_VEC_ALLOC_P (loop_p, heap);
/* A data_dependence_relation represents a relation between two
data_references A and B. */

View File

@ -1092,19 +1092,14 @@ bb_with_exit_edge_p (struct loop *loop, basic_block bb)
static unsigned int
main_tree_if_conversion (void)
{
unsigned i, loop_num;
loop_iterator li;
struct loop *loop;
if (!current_loops)
return 0;
loop_num = current_loops->num;
for (i = 0; i < loop_num; i++)
FOR_EACH_LOOP (li, loop, 0)
{
loop = current_loops->parray[i];
if (!loop)
continue;
tree_if_conversion (loop, true);
}
return 0;

View File

@ -242,16 +242,16 @@ void
linear_transform_loops (void)
{
bool modified = false;
unsigned int i;
loop_iterator li;
VEC(tree,heap) *oldivs = NULL;
VEC(tree,heap) *invariants = NULL;
struct loop *loop_nest;
for (i = 1; i < current_loops->num; i++)
FOR_EACH_LOOP (li, loop_nest, 0)
{
unsigned int depth = 0;
VEC (ddr_p, heap) *dependence_relations;
VEC (data_reference_p, heap) *datarefs;
struct loop *loop_nest = current_loops->parray[i];
struct loop *temp;
lambda_loopnest before, after;
lambda_trans_matrix trans;
@ -270,7 +270,7 @@ linear_transform_loops (void)
...
}
} */
if (!loop_nest || !loop_nest->inner || !single_exit (loop_nest))
if (!loop_nest->inner || !single_exit (loop_nest))
continue;
VEC_truncate (tree, oldivs, 0);
VEC_truncate (tree, invariants, 0);

View File

@ -375,7 +375,7 @@ chrec_contains_symbols_defined_in_loop (tree chrec, unsigned loop_nb)
{
tree def = SSA_NAME_DEF_STMT (chrec);
struct loop *def_loop = loop_containing_stmt (def);
struct loop *loop = current_loops->parray[loop_nb];
struct loop *loop = get_loop (loop_nb);
if (def_loop == NULL)
return false;
@ -467,8 +467,7 @@ compute_overall_effect_of_inner_loop (struct loop *loop, tree evolution_fn)
{
if (CHREC_VARIABLE (evolution_fn) >= (unsigned) loop->num)
{
struct loop *inner_loop =
current_loops->parray[CHREC_VARIABLE (evolution_fn)];
struct loop *inner_loop = get_chrec_loop (evolution_fn);
tree nb_iter = number_of_iterations_in_loop (inner_loop);
if (nb_iter == chrec_dont_know)
@ -534,9 +533,7 @@ chrec_is_positive (tree chrec, bool *value)
if (!evolution_function_is_affine_p (chrec))
return false;
nb_iter = number_of_iterations_in_loop
(current_loops->parray[CHREC_VARIABLE (chrec)]);
nb_iter = number_of_iterations_in_loop (get_chrec_loop (chrec));
if (chrec_contains_undetermined (nb_iter))
return false;
@ -2530,7 +2527,7 @@ number_of_iterations_for_all_loops (VEC(tree,heap) **exit_conditions)
fprintf (dump_file, "-----------------------------------------\n");
fprintf (dump_file, "%d\tnb_chrec_dont_know_loops\n", nb_chrec_dont_know_loops);
fprintf (dump_file, "%d\tnb_static_loops\n", nb_static_loops);
fprintf (dump_file, "%d\tnb_total_loops\n", current_loops->num);
fprintf (dump_file, "%d\tnb_total_loops\n", number_of_loops ());
fprintf (dump_file, "-----------------------------------------\n");
fprintf (dump_file, ")\n\n");
@ -2747,7 +2744,8 @@ initialize_scalar_evolutions_analyzer (void)
void
scev_initialize (void)
{
unsigned i;
loop_iterator li;
struct loop *loop;
scalar_evolution_info = htab_create (100, hash_scev_info,
eq_scev_info, del_scev_info);
@ -2755,9 +2753,10 @@ scev_initialize (void)
initialize_scalar_evolutions_analyzer ();
for (i = 1; i < current_loops->num; i++)
if (current_loops->parray[i])
current_loops->parray[i]->nb_iterations = NULL_TREE;
FOR_EACH_LOOP (li, loop, 0)
{
loop->nb_iterations = NULL_TREE;
}
}
/* Cleans up the information cached by the scalar evolutions analysis. */
@ -2765,18 +2764,16 @@ scev_initialize (void)
void
scev_reset (void)
{
unsigned i;
loop_iterator li;
struct loop *loop;
if (!scalar_evolution_info || !current_loops)
return;
htab_empty (scalar_evolution_info);
for (i = 1; i < current_loops->num; i++)
FOR_EACH_LOOP (li, loop, 0)
{
loop = current_loops->parray[i];
if (loop)
loop->nb_iterations = NULL_TREE;
loop->nb_iterations = NULL_TREE;
}
}
@ -2890,6 +2887,7 @@ scev_const_prop (void)
struct loop *loop, *ex_loop;
bitmap ssa_names_to_remove = NULL;
unsigned i;
loop_iterator li;
if (!current_loops)
return 0;
@ -2931,7 +2929,6 @@ scev_const_prop (void)
if (ssa_names_to_remove)
{
bitmap_iterator bi;
unsigned i;
EXECUTE_IF_SET_IN_BITMAP (ssa_names_to_remove, 0, i, bi)
{
@ -2947,16 +2944,12 @@ scev_const_prop (void)
}
/* Now the regular final value replacement. */
for (i = current_loops->num - 1; i > 0; i--)
FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
{
edge exit;
tree def, rslt, ass, niter;
block_stmt_iterator bsi;
loop = current_loops->parray[i];
if (!loop)
continue;
/* If we do not know exact number of iterations of the loop, we cannot
replace the final value. */
exit = single_exit (loop);

View File

@ -36,4 +36,12 @@ unsigned int scev_const_prop (void);
extern bool simple_iv (struct loop *, tree, tree, affine_iv *, bool);
/* Returns the loop of the polynomial chrec CHREC. */
static inline struct loop *
get_chrec_loop (tree chrec)
{
return get_loop (CHREC_VARIABLE (chrec));
}
#endif /* GCC_TREE_SCALAR_EVOLUTION_H */

View File

@ -123,7 +123,7 @@ do_while_loop_p (struct loop *loop)
static unsigned int
copy_loop_headers (void)
{
unsigned i;
loop_iterator li;
struct loop *loop;
basic_block header;
edge exit, entry;
@ -144,14 +144,11 @@ copy_loop_headers (void)
copied_bbs = XNEWVEC (basic_block, n_basic_blocks);
bbs_size = n_basic_blocks;
for (i = 1; i < current_loops->num; i++)
FOR_EACH_LOOP (li, loop, 0)
{
/* Copy at most 20 insns. */
int limit = 20;
loop = current_loops->parray[i];
if (!loop)
continue;
header = loop->header;
/* If the loop is already a do-while style one (either because it was

View File

@ -1377,34 +1377,17 @@ static void
determine_lsm (void)
{
struct loop *loop;
if (!current_loops->tree_root->inner)
return;
loop_iterator li;
/* Pass the loops from the outermost and perform the store motion as
suitable. */
loop = current_loops->tree_root->inner;
while (1)
FOR_EACH_LOOP (li, loop, 0)
{
determine_lsm_loop (loop);
if (loop->inner)
{
loop = loop->inner;
continue;
}
while (!loop->next)
{
loop = loop->outer;
if (loop == current_loops->tree_root)
{
bsi_commit_edge_inserts ();
return;
}
}
loop = loop->next;
}
bsi_commit_edge_inserts ();
}
/* Fills ALWAYS_EXECUTED_IN information for basic blocks of LOOP, i.e.

View File

@ -332,18 +332,15 @@ canonicalize_loop_induction_variables (struct loop *loop,
unsigned int
canonicalize_induction_variables (void)
{
unsigned i;
loop_iterator li;
struct loop *loop;
bool changed = false;
for (i = 1; i < current_loops->num; i++)
FOR_EACH_LOOP (li, loop, 0)
{
loop = current_loops->parray[i];
if (loop)
changed |= canonicalize_loop_induction_variables (loop,
true, UL_SINGLE_ITER,
true);
changed |= canonicalize_loop_induction_variables (loop,
true, UL_SINGLE_ITER,
true);
}
/* Clean up the information about numbers of iterations, since brute force
@ -362,18 +359,13 @@ canonicalize_induction_variables (void)
unsigned int
tree_unroll_loops_completely (bool may_increase_size)
{
unsigned i;
loop_iterator li;
struct loop *loop;
bool changed = false;
enum unroll_level ul;
for (i = 1; i < current_loops->num; i++)
FOR_EACH_LOOP (li, loop, 0)
{
loop = current_loops->parray[i];
if (!loop)
continue;
if (may_increase_size && maybe_hot_bb_p (loop->header))
ul = UL_ALL;
else

View File

@ -5889,30 +5889,17 @@ tree_ssa_iv_optimize (void)
{
struct loop *loop;
struct ivopts_data data;
loop_iterator li;
tree_ssa_iv_optimize_init (&data);
/* Optimize the loops starting with the innermost ones. */
loop = current_loops->tree_root;
while (loop->inner)
loop = loop->inner;
/* Scan the loops, inner ones first. */
while (loop != current_loops->tree_root)
FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
{
if (dump_file && (dump_flags & TDF_DETAILS))
flow_loop_dump (loop, dump_file, NULL, 1);
tree_ssa_iv_optimize_loop (&data, loop);
if (loop->next)
{
loop = loop->next;
while (loop->inner)
loop = loop->inner;
}
else
loop = loop->outer;
}
tree_ssa_iv_optimize_finalize (&data);

View File

@ -2024,14 +2024,12 @@ estimate_numbers_of_iterations_loop (struct loop *loop)
void
estimate_numbers_of_iterations (void)
{
unsigned i;
loop_iterator li;
struct loop *loop;
for (i = 1; i < current_loops->num; i++)
FOR_EACH_LOOP (li, loop, 0)
{
loop = current_loops->parray[i];
if (loop)
estimate_numbers_of_iterations_loop (loop);
estimate_numbers_of_iterations_loop (loop);
}
}
@ -2246,14 +2244,12 @@ free_numbers_of_iterations_estimates_loop (struct loop *loop)
void
free_numbers_of_iterations_estimates (void)
{
unsigned i;
loop_iterator li;
struct loop *loop;
for (i = 1; i < current_loops->num; i++)
FOR_EACH_LOOP (li, loop, 0)
{
loop = current_loops->parray[i];
if (loop)
free_numbers_of_iterations_estimates_loop (loop);
free_numbers_of_iterations_estimates_loop (loop);
}
}

View File

@ -998,7 +998,7 @@ fail:
unsigned int
tree_ssa_prefetch_arrays (void)
{
unsigned i;
loop_iterator li;
struct loop *loop;
bool unrolled = false;
int todo_flags = 0;
@ -1043,12 +1043,8 @@ tree_ssa_prefetch_arrays (void)
here. */
gcc_assert ((PREFETCH_BLOCK & (PREFETCH_BLOCK - 1)) == 0);
for (i = current_loops->num - 1; i > 0; i--)
FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
{
loop = current_loops->parray[i];
if (!loop)
continue;
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "Processing loop %d:\n", loop->num);

View File

@ -82,23 +82,13 @@ static tree tree_may_unswitch_on (basic_block, struct loop *);
unsigned int
tree_ssa_unswitch_loops (void)
{
int i, num;
loop_iterator li;
struct loop *loop;
bool changed = false;
/* Go through inner loops (only original ones). */
num = current_loops->num;
for (i = 1; i < num; i++)
FOR_EACH_LOOP (li, loop, LI_ONLY_OLD | LI_ONLY_INNERMOST)
{
/* Removed loop? */
loop = current_loops->parray[i];
if (!loop)
continue;
if (loop->inner)
continue;
changed |= tree_unswitch_single_loop (loop, 0);
}

View File

@ -174,9 +174,6 @@ FILE *vect_dump;
to mark that it's uninitialized. */
enum verbosity_levels vect_verbosity_level = MAX_VERBOSITY_LEVEL;
/* Number of loops, at the beginning of vectorization. */
unsigned int vect_loops_num;
/* Loop location. */
static LOC vect_loop_location;
@ -2157,6 +2154,9 @@ vectorize_loops (void)
{
unsigned int i;
unsigned int num_vectorized_loops = 0;
unsigned int vect_loops_num;
loop_iterator li;
struct loop *loop;
/* Fix the verbosity level if not defined explicitly by the user. */
vect_set_dump_settings ();
@ -2170,14 +2170,10 @@ vectorize_loops (void)
/* If some loop was duplicated, it gets bigger number
than all previously defined loops. This fact allows us to run
only over initial loops skipping newly generated ones. */
vect_loops_num = current_loops->num;
for (i = 1; i < vect_loops_num; i++)
vect_loops_num = number_of_loops ();
FOR_EACH_LOOP (li, loop, LI_ONLY_OLD)
{
loop_vec_info loop_vinfo;
struct loop *loop = current_loops->parray[i];
if (!loop)
continue;
vect_loop_location = find_loop_location (loop);
loop_vinfo = vect_analyze_loop (loop);
@ -2201,9 +2197,9 @@ vectorize_loops (void)
for (i = 1; i < vect_loops_num; i++)
{
struct loop *loop = current_loops->parray[i];
loop_vec_info loop_vinfo;
loop = get_loop (i);
if (!loop)
continue;
loop_vinfo = loop->aux;

View File

@ -327,9 +327,6 @@ known_alignment_for_access_p (struct data_reference *data_ref_info)
extern FILE *vect_dump;
extern enum verbosity_levels vect_verbosity_level;
/* Number of loops, at the beginning of vectorization. */
extern unsigned int vect_loops_num;
/* Bitmap of virtual variables to be renamed. */
extern bitmap vect_vnames_to_rename;

View File

@ -1998,8 +1998,7 @@ adjust_range_with_scev (value_range_t *vr, struct loop *loop, tree stmt,
or decreases, ... */
dir == EV_DIR_UNKNOWN
/* ... or if it may wrap. */
|| scev_probably_wraps_p (init, step, stmt,
current_loops->parray[CHREC_VARIABLE (chrec)],
|| scev_probably_wraps_p (init, step, stmt, get_chrec_loop (chrec),
true))
return;

View File

@ -1587,6 +1587,12 @@ struct tree_constructor GTY(())
#define COND_EXPR_THEN(NODE) (TREE_OPERAND (COND_EXPR_CHECK (NODE), 1))
#define COND_EXPR_ELSE(NODE) (TREE_OPERAND (COND_EXPR_CHECK (NODE), 2))
/* Accessors for the chains of recurrences. */
#define CHREC_VAR(NODE) TREE_OPERAND (POLYNOMIAL_CHREC_CHECK (NODE), 0)
#define CHREC_LEFT(NODE) TREE_OPERAND (POLYNOMIAL_CHREC_CHECK (NODE), 1)
#define CHREC_RIGHT(NODE) TREE_OPERAND (POLYNOMIAL_CHREC_CHECK (NODE), 2)
#define CHREC_VARIABLE(NODE) TREE_INT_CST_LOW (CHREC_VAR (NODE))
/* LABEL_EXPR accessor. This gives access to the label associated with
the given label expression. */
#define LABEL_EXPR_LABEL(NODE) TREE_OPERAND (LABEL_EXPR_CHECK (NODE), 0)