diff options
Diffstat (limited to 'gcc')
33 files changed, 396 insertions, 418 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 60ff40a5e82..cabbcd17280 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 5a58fb257c1..52e1ab0c6a2 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 fa0a456fc56..d523acf001c 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 16b3b46118e..5a9189787ea 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 180a4757ee9..83d4e4c0e13 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 642a52374d4..354241f14c7 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 093ec30f708..ef42c609198 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 35727c06b84..32e56b32a6a 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 d4258f057c3..4c6e8bc9f9c 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 776b2e1f6b1..3a79dcca943 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 db236e89e27..82cf1eaeeeb 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 4160e998c1b..3352e20adcd 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 4b5344b7481..534258f39ce 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 e4733a2012f..59a32ea6fff 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 a74a49c3972..01d0bf9217a 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 bc5c7782201..c22867ba0d2 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 7ed14f0e55a..96d57a06e73 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 2d23dce8207..8c6ee416d32 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 2f304356efb..e97824f5185 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 0c1c685d002..61fdee3f068 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 b882d458b88..c668bf22ddf 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 ad3ddd5035c..98855b93e26 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 bcbc514dfbf..e1d5af8a04c 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 9fd0eba16a0..9bdffa23ab1 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 7dcb0da01da..63268017670 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 0132fc9cdb4..1aea162fe2c 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 de9ce1c2ea4..bff08a0796b 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 114d0e3ebe0..5f39b8d2bfd 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 3c58e8c54b7..52465db8611 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 9974343dce7..d948c99558a 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 0c026b14d0c..325f4024d9f 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 eb28ca9cb5c..8e9d3cad7a5 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 98be968af50..4e42c9b1e20 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) |