aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog65
-rw-r--r--gcc/cfgloop.c145
-rw-r--r--gcc/cfgloop.h142
-rw-r--r--gcc/cfgloopanal.c16
-rw-r--r--gcc/cfgloopmanip.c58
-rw-r--r--gcc/doc/loop.texi21
-rw-r--r--gcc/loop-doloop.c8
-rw-r--r--gcc/loop-init.c15
-rw-r--r--gcc/loop-invariant.c24
-rw-r--r--gcc/loop-unroll.c49
-rw-r--r--gcc/loop-unswitch.c13
-rw-r--r--gcc/modulo-sched.c20
-rw-r--r--gcc/predict.c6
-rw-r--r--gcc/tree-cfg.c8
-rw-r--r--gcc/tree-chrec.c5
-rw-r--r--gcc/tree-chrec.h8
-rw-r--r--gcc/tree-data-ref.c8
-rw-r--r--gcc/tree-data-ref.h4
-rw-r--r--gcc/tree-if-conv.c9
-rw-r--r--gcc/tree-loop-linear.c8
-rw-r--r--gcc/tree-scalar-evolution.c37
-rw-r--r--gcc/tree-scalar-evolution.h8
-rw-r--r--gcc/tree-ssa-loop-ch.c7
-rw-r--r--gcc/tree-ssa-loop-im.c25
-rw-r--r--gcc/tree-ssa-loop-ivcanon.c22
-rw-r--r--gcc/tree-ssa-loop-ivopts.c17
-rw-r--r--gcc/tree-ssa-loop-niter.c16
-rw-r--r--gcc/tree-ssa-loop-prefetch.c8
-rw-r--r--gcc/tree-ssa-loop-unswitch.c14
-rw-r--r--gcc/tree-vectorizer.c16
-rw-r--r--gcc/tree-vectorizer.h3
-rw-r--r--gcc/tree-vrp.c3
-rw-r--r--gcc/tree.h6
33 files changed, 396 insertions, 418 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 60ff40a..cabbcd17 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c
index 5a58fb2..52e1ab0 100644
--- a/gcc/cfgloop.c
+++ b/gcc/cfgloop.c
@@ -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];
-
- loops->tree_root = 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;
+
+ 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))
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index fa0a456..d523acf 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -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. */
diff --git a/gcc/cfgloopanal.c b/gcc/cfgloopanal.c
index 16b3b461..5a91897 100644
--- a/gcc/cfgloopanal.c
+++ b/gcc/cfgloopanal.c
@@ -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];
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
index 180a475..83d4e4c 100644
--- a/gcc/cfgloopmanip.c
+++ b/gcc/cfgloopmanip.c
@@ -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)
{
diff --git a/gcc/doc/loop.texi b/gcc/doc/loop.texi
index 642a523..354241f 100644
--- a/gcc/doc/loop.texi
+++ b/gcc/doc/loop.texi
@@ -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
diff --git a/gcc/loop-doloop.c b/gcc/loop-doloop.c
index 093ec30..ef42c60 100644
--- a/gcc/loop-doloop.c
+++ b/gcc/loop-doloop.c
@@ -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);
}
diff --git a/gcc/loop-init.c b/gcc/loop-init.c
index 35727c0..32e56b3 100644
--- a/gcc/loop-init.c
+++ b/gcc/loop-init.c
@@ -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);
diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c
index d4258f0..4c6e8bc 100644
--- a/gcc/loop-invariant.c
+++ b/gcc/loop-invariant.c
@@ -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;
diff --git a/gcc/loop-unroll.c b/gcc/loop-unroll.c
index 776b2e1..3a79dcc 100644
--- a/gcc/loop-unroll.c
+++ b/gcc/loop-unroll.c
@@ -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;
}
}
diff --git a/gcc/loop-unswitch.c b/gcc/loop-unswitch.c
index db236e8..82cf1ea 100644
--- a/gcc/loop-unswitch.c
+++ b/gcc/loop-unswitch.c
@@ -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);
diff --git a/gcc/modulo-sched.c b/gcc/modulo-sched.c
index 4160e998..3352e20 100644
--- a/gcc/modulo-sched.c
+++ b/gcc/modulo-sched.c
@@ -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)
diff --git a/gcc/predict.c b/gcc/predict.c
index 4b5344b..534258f 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -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;
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index e4733a2..59a32ea 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -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);
}
}
}
diff --git a/gcc/tree-chrec.c b/gcc/tree-chrec.c
index a74a49c..01d0bf9 100644
--- a/gcc/tree-chrec.c
+++ b/gcc/tree-chrec.c
@@ -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);
diff --git a/gcc/tree-chrec.h b/gcc/tree-chrec.h
index bc5c778..c22867b 100644
--- a/gcc/tree-chrec.h
+++ b/gcc/tree-chrec.h
@@ -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. */
diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
index 7ed14f0..96d57a0 100644
--- a/gcc/tree-data-ref.c
+++ b/gcc/tree-data-ref.c
@@ -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);
diff --git a/gcc/tree-data-ref.h b/gcc/tree-data-ref.h
index 2d23dce..8c6ee41 100644
--- a/gcc/tree-data-ref.h
+++ b/gcc/tree-data-ref.h
@@ -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. */
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
index 2f30435..e97824f 100644
--- a/gcc/tree-if-conv.c
+++ b/gcc/tree-if-conv.c
@@ -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;
diff --git a/gcc/tree-loop-linear.c b/gcc/tree-loop-linear.c
index 0c1c685..61fdee3 100644
--- a/gcc/tree-loop-linear.c
+++ b/gcc/tree-loop-linear.c
@@ -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);
diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c
index b882d45..c668bf2 100644
--- a/gcc/tree-scalar-evolution.c
+++ b/gcc/tree-scalar-evolution.c
@@ -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);
diff --git a/gcc/tree-scalar-evolution.h b/gcc/tree-scalar-evolution.h
index ad3ddd5..98855b9 100644
--- a/gcc/tree-scalar-evolution.h
+++ b/gcc/tree-scalar-evolution.h
@@ -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 */
diff --git a/gcc/tree-ssa-loop-ch.c b/gcc/tree-ssa-loop-ch.c
index bcbc514..e1d5af8 100644
--- a/gcc/tree-ssa-loop-ch.c
+++ b/gcc/tree-ssa-loop-ch.c
@@ -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
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index 9fd0eba..9bdffa2 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -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.
diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c
index 7dcb0da..6326801 100644
--- a/gcc/tree-ssa-loop-ivcanon.c
+++ b/gcc/tree-ssa-loop-ivcanon.c
@@ -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
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 0132fc9..1aea162 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -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);
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index de9ce1c..bff08a0 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -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);
}
}
diff --git a/gcc/tree-ssa-loop-prefetch.c b/gcc/tree-ssa-loop-prefetch.c
index 114d0e3..5f39b8d 100644
--- a/gcc/tree-ssa-loop-prefetch.c
+++ b/gcc/tree-ssa-loop-prefetch.c
@@ -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);
diff --git a/gcc/tree-ssa-loop-unswitch.c b/gcc/tree-ssa-loop-unswitch.c
index 3c58e8c..52465db 100644
--- a/gcc/tree-ssa-loop-unswitch.c
+++ b/gcc/tree-ssa-loop-unswitch.c
@@ -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);
}
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index 9974343..d948c99 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -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;
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index 0c026b1..325f402 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -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;
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index eb28ca9..8e9d3ca 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -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;
diff --git a/gcc/tree.h b/gcc/tree.h
index 98be968..4e42c9b 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -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)