+2006-11-25 Zdenek Dvorak <dvorakz@suse.cz>
+
+ * tree-vrp.c (execute_vrp): Do not pass loops structure through
+ arguments.
+ * loop-unswitch.c (unswitch_loops, unswitch_single_loop,
+ unswitch_loop): Ditto.
+ * tree-loop-linear.c (linear_transform_loops): Ditto.
+ * tree-ssa-loop-im.c (determine_lsm, tree_ssa_lim_initialize,
+ tree_ssa_lim): Ditto.
+ * tree-ssa-loop-niter.c (estimate_numbers_of_iterations,
+ free_numbers_of_iterations_estimates): Ditto.
+ * tree-ssa-loop-unswitch.c (tree_ssa_unswitch_loops,
+ tree_unswitch_single_loop, tree_unswitch_loop): Ditto.
+ * cfgloopmanip.c (fix_bb_placement, fix_bb_placements,
+ remove_path, add_loop, loopify, unloop, fix_loop_placements,
+ place_new_loop, duplicate_loop, duplicate_subloops,
+ update_single_exit_for_duplicated_loops, copy_loops_to,
+ duplicate_loop_to_header_edge, create_preheaders,
+ force_single_succ_latches, loop_version, fix_loop_structure):
+ Ditto.
+ * tree-ssa-loop-manip.c (tree_duplicate_loop_to_header_edge,
+ tree_unroll_loop): Ditto.
+ * tree-ssa-loop-ch.c (copy_loop_headers): Ditto.
+ * tree-scalar-evolution.c (select_loops_exit_conditions,
+ scev_initialize, scev_analysis): Ditto.
+ * tree-scalar-evolution.h (scev_initialize): Ditto.
+ * cfghooks.c (cfg_hook_duplicate_loop_to_header_edge): Ditto.
+ * cfgloopanal.c (mark_irreducible_loops, mark_loop_exit_edges): Ditto.
+ * tree-ssa-loop-ivopts.c (tree_ssa_iv_optimize): Ditto.
+ * modulo-sched.c (sms_schedule): Ditto.
+ * tree-ssa-dom.c (tree_ssa_dominator_optimize): Ditto.
+ * loop-init.c (loop_optimizer_init, rtl_move_loop_invariants,
+ rtl_unswitch, rtl_unroll_and_peel_loops, rtl_doloop): Ditto.
+ * ifcvt.c (if_convert): Ditto.
+ * tree-ssa-loop-ivcanon.c (try_unroll_loop_completely,
+ canonicalize_loop_induction_variables,
+ canonicalize_induction_variables,
+ tree_unroll_loops_completely, remove_empty_loops): Ditto.
+ * tree-ssa-loop.c (tree_ssa_loop_init, tree_ssa_loop_im,
+ tree_ssa_loop_unswitch, tree_vectorize, tree_linear_transform,
+ tree_ssa_loop_ivcanon, tree_ssa_empty_loop, tree_ssa_loop_bounds,
+ tree_complete_unroll, tree_ssa_loop_prefetch, tree_ssa_loop_ivopts,
+ tree_ssa_loop_done): Ditto.
+ * predict.c (predict_loops, tree_estimate_probability, estimate_loops,
+ estimate_bb_frequencies): Ditto.
+ * tree-vectorizer.c (slpeel_tree_duplicate_loop_to_edge_cfg,
+ slpeel_tree_peel_loop_to_edge, vectorize_loops): Ditto.
+ * loop-unroll.c (unroll_and_peel_loops, peel_loops_completely,
+ decide_unrolling_and_peeling, peel_loop_completely,
+ unroll_loop_constant_iterations, unroll_loop_runtime_iterations,
+ peel_loop_simple, unroll_loop_stupid): Ditto.
+ * loop-doloop.c (doloop_optimize_loops): Ditto.
+ * tree-cfgcleanup.c (cleanup_tree_cfg_loop): Ditto.
+ * loop-invariant.c (move_loop_invariants): Ditto.
+ * tree-ssa-dce.c (tree_ssa_dce_loop): Ditto.
+ * tree-ssa-loop-prefetch.c (loop_prefetch_arrays,
+ tree_ssa_prefetch_arrays): Ditto.
+ * lambda-code.c (gcc_loopnest_to_lambda_loopnest, perfect_nestify):
+ Ditto.
+ * tree-vect-transform.c (vect_do_peeling_for_loop_bound,
+ vect_do_peeling_for_alignment, vect_transform_loop): Ditto.
+ * cfgloop.c (flow_loops_cfg_dump, flow_loops_dump,
+ mark_single_exit_loops, cancel_loop, cancel_loop_tree,
+ verify_loop_structure): Ditto.
+ * tree-flow.h (vectorize_loops, tree_ssa_lim, tree_ssa_unswitch_loops,
+ canonicalize_induction_variables, tree_unroll_loops_completely,
+ tree_ssa_prefetch_arrays, remove_empty_loops, tree_ssa_iv_optimize,
+ estimate_numbers_of_iterations, free_numbers_of_iterations_estimates,
+ tree_duplicate_loop_to_header_edge, tree_ssa_loop_version,
+ tree_unroll_loop, linear_transform_loops): Declaration changed.
+ * basic-block.h: Remove declaration of struct loops.
+ * cfghooks.h (struct cfg_hooks): Change type of
+ cfg_hook_duplicate_loop_to_header_edge.
+ (cfg_hook_duplicate_loop_to_header_edge): Declaration changed.
+ * tree-vectorizer.h (slpeel_tree_peel_loop_to_edge,
+ vect_transform_loop): Declaration changed.
+ * lambda.h (gcc_loopnest_to_lambda_loopnest): Declaration changed.
+ * cfgloop.h (flow_loops_dump, fix_loop_structure,
+ mark_irreducible_loops, mark_single_exit_loops, mark_loop_exit_edges,
+ cancel_loop_tree, create_preheaders, force_single_succ_latches,
+ verify_loop_structure, duplicate_loop, duplicate_loop_to_header_edge,
+ loopify, loop_version, remove_path, unswitch_loops,
+ unroll_and_peel_loops, doloop_optimize_loops, move_loop_invariants):
+ Declaration changed.
+
2006-11-24 Uros Bizjak <ubizjak@gmail.com>
- config/i386/i386.md (UNSPEC_TRUNC_NOOP): New unspec definition.
+ * config/i386/i386.md (UNSPEC_TRUNC_NOOP): New unspec definition.
(X87MODEF): New mode macro.
(ssemodefsuffix): New mode attribute.
(truncxf<mode>2_i387_noop_unspec): New insn pattern.
(fmodsf3, fmoddf3, remaindersf3, remainderdf3): Use noop
truncation patterns.
- reg-stack.c (get_true_reg): Handle UNSPEC_TRUNC_NOOP.
+ * reg-stack.c (get_true_reg): Handle UNSPEC_TRUNC_NOOP.
2006-11-24 Jakub Jelinek <jakub@redhat.com>
/* Declared in cfgloop.h. */
struct loop;
-struct loops;
/* Declared in tree-flow.h. */
struct edge_prediction;
than duplicate_loop_to_header_edge when we are in tree mode. */
bool
cfg_hook_duplicate_loop_to_header_edge (struct loop *loop, edge e,
- struct loops *loops, unsigned int ndupl,
+ unsigned int ndupl,
sbitmap wont_exit, edge orig,
edge *to_remove,
unsigned int *n_to_remove, int flags)
{
gcc_assert (cfg_hooks->cfg_hook_duplicate_loop_to_header_edge);
- return cfg_hooks->cfg_hook_duplicate_loop_to_header_edge (loop, e, loops,
+ return cfg_hooks->cfg_hook_duplicate_loop_to_header_edge (loop, e,
ndupl, wont_exit,
orig, to_remove,
n_to_remove, flags);
/* A hook for duplicating loop in CFG, currently this is used
in loop versioning. */
bool (*cfg_hook_duplicate_loop_to_header_edge) (struct loop *loop, edge e,
- struct loops *loops,
unsigned int ndupl,
sbitmap wont_exit,
edge orig, edge *to_remove,
extern void execute_on_growing_pred (edge);
extern void execute_on_shrinking_pred (edge);
extern bool cfg_hook_duplicate_loop_to_header_edge (struct loop *loop, edge,
- struct loops *loops,
unsigned int ndupl,
sbitmap wont_exit,
edge orig, edge *to_remove,
#define HEADER_BLOCK(B) (* (int *) (B)->aux)
#define LATCH_EDGE(E) (*(int *) (E)->aux)
-static void flow_loops_cfg_dump (const struct loops *, FILE *);
+static void flow_loops_cfg_dump (FILE *);
static void establish_preds (struct loop *);
static void canonicalize_loop_headers (void);
static bool glb_enum_p (basic_block, void *);
/* Dump loop related CFG information. */
static void
-flow_loops_cfg_dump (const struct loops *loops, FILE *file)
+flow_loops_cfg_dump (FILE *file)
{
basic_block bb;
- if (! loops->num || ! file)
+ if (!file)
return;
FOR_EACH_BB (bb)
loop_dump_aux (loop, file, verbose);
}
-/* Dump the loop information specified by LOOPS to the stream FILE,
+/* Dump the loop information about loops to the stream FILE,
using auxiliary dump callback function LOOP_DUMP_AUX if non null. */
void
-flow_loops_dump (const struct loops *loops, FILE *file, void (*loop_dump_aux) (const struct loop *, FILE *, int), int verbose)
+flow_loops_dump (FILE *file, void (*loop_dump_aux) (const struct loop *, FILE *, int), int verbose)
{
- int i;
- int num_loops;
+ unsigned i;
- num_loops = loops->num;
- if (! num_loops || ! file)
+ if (!current_loops || ! file)
return;
- fprintf (file, ";; %d loops found\n", num_loops);
+ fprintf (file, ";; %d loops found\n", current_loops->num);
- for (i = 0; i < num_loops; i++)
+ for (i = 0; i < current_loops->num; i++)
{
- struct loop *loop = loops->parray[i];
+ struct loop *loop = current_loops->parray[i];
if (!loop)
continue;
}
if (verbose)
- flow_loops_cfg_dump (loops, file);
+ flow_loops_cfg_dump (file);
}
/* Free data allocated for LOOP. */
return num_nodes;
}
-/* For each loop in the lOOPS tree that has just a single exit
- record the exit edge. */
+/* For each loop that has just a single exit, record the exit edge. */
void
-mark_single_exit_loops (struct loops *loops)
+mark_single_exit_loops (void)
{
basic_block bb;
edge e;
struct loop *loop;
unsigned i;
- for (i = 1; i < loops->num; i++)
+ for (i = 1; i < current_loops->num; i++)
{
- loop = loops->parray[i];
+ loop = current_loops->parray[i];
if (loop)
set_single_exit (loop, NULL);
}
FOR_EACH_BB (bb)
{
edge_iterator ei;
- if (bb->loop_father == loops->tree_root)
+ if (bb->loop_father == current_loops->tree_root)
continue;
FOR_EACH_EDGE (e, ei, bb->succs)
{
}
}
- for (i = 1; i < loops->num; i++)
+ for (i = 1; i < current_loops->num; i++)
{
- loop = loops->parray[i];
+ loop = current_loops->parray[i];
if (!loop)
continue;
set_single_exit (loop, NULL);
}
- loops->state |= LOOPS_HAVE_MARKED_SINGLE_EXITS;
+ current_loops->state |= LOOPS_HAVE_MARKED_SINGLE_EXITS;
}
static void
/* Cancels the LOOP; it must be innermost one. */
static void
-cancel_loop (struct loops *loops, struct loop *loop)
+cancel_loop (struct loop *loop)
{
basic_block *bbs;
unsigned i;
flow_loop_tree_node_remove (loop);
/* Remove loop from loops array. */
- loops->parray[loop->num] = NULL;
+ current_loops->parray[loop->num] = NULL;
/* Free loop data. */
flow_loop_free (loop);
/* Cancels LOOP and all its subloops. */
void
-cancel_loop_tree (struct loops *loops, struct loop *loop)
+cancel_loop_tree (struct loop *loop)
{
while (loop->inner)
- cancel_loop_tree (loops, loop->inner);
- cancel_loop (loops, loop);
+ cancel_loop_tree (loop->inner);
+ cancel_loop (loop);
}
-/* Checks that LOOPS are all right:
+/* Checks that information about loops is correct
-- sizes of loops are all right
-- results of get_loop_body really belong to the loop
-- loop header have just single entry edge and single latch edge
-- irreducible loops are correctly marked
*/
void
-verify_loop_structure (struct loops *loops)
+verify_loop_structure (void)
{
unsigned *sizes, i, j;
sbitmap irreds;
edge e;
/* Check sizes. */
- sizes = XCNEWVEC (unsigned, loops->num);
+ sizes = XCNEWVEC (unsigned, current_loops->num);
sizes[0] = 2;
FOR_EACH_BB (bb)
for (loop = bb->loop_father; loop; loop = loop->outer)
sizes[loop->num]++;
- for (i = 0; i < loops->num; i++)
+ for (i = 0; i < current_loops->num; i++)
{
- if (!loops->parray[i])
+ if (!current_loops->parray[i])
continue;
- if (loops->parray[i]->num_nodes != sizes[i])
+ if (current_loops->parray[i]->num_nodes != sizes[i])
{
error ("size of loop %d should be %d, not %d",
- i, sizes[i], loops->parray[i]->num_nodes);
+ i, sizes[i], current_loops->parray[i]->num_nodes);
err = 1;
}
}
/* Check get_loop_body. */
- for (i = 1; i < loops->num; i++)
+ for (i = 1; i < current_loops->num; i++)
{
- loop = loops->parray[i];
+ loop = current_loops->parray[i];
if (!loop)
continue;
bbs = get_loop_body (loop);
}
/* Check headers and latches. */
- for (i = 1; i < loops->num; i++)
+ for (i = 1; i < current_loops->num; i++)
{
- loop = loops->parray[i];
+ loop = current_loops->parray[i];
if (!loop)
continue;
- if ((loops->state & LOOPS_HAVE_PREHEADERS)
+ if ((current_loops->state & LOOPS_HAVE_PREHEADERS)
&& EDGE_COUNT (loop->header->preds) != 2)
{
error ("loop %d's header does not have exactly 2 entries", i);
err = 1;
}
- if (loops->state & LOOPS_HAVE_SIMPLE_LATCHES)
+ if (current_loops->state & LOOPS_HAVE_SIMPLE_LATCHES)
{
if (!single_succ_p (loop->latch))
{
error ("loop %d's header does not belong directly to it", i);
err = 1;
}
- if ((loops->state & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
+ if ((current_loops->state & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
&& (loop_latch_edge (loop)->flags & EDGE_IRREDUCIBLE_LOOP))
{
error ("loop %d's latch is marked as part of irreducible region", i);
}
/* Check irreducible loops. */
- if (loops->state & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
+ if (current_loops->state & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
{
/* Record old info. */
irreds = sbitmap_alloc (last_basic_block);
}
/* Recount it. */
- mark_irreducible_loops (loops);
+ mark_irreducible_loops ();
/* Compare. */
FOR_EACH_BB (bb)
}
/* Check the single_exit. */
- if (loops->state & LOOPS_HAVE_MARKED_SINGLE_EXITS)
+ if (current_loops->state & LOOPS_HAVE_MARKED_SINGLE_EXITS)
{
- memset (sizes, 0, sizeof (unsigned) * loops->num);
+ memset (sizes, 0, sizeof (unsigned) * current_loops->num);
FOR_EACH_BB (bb)
{
edge_iterator ei;
- if (bb->loop_father == loops->tree_root)
+ if (bb->loop_father == current_loops->tree_root)
continue;
FOR_EACH_EDGE (e, ei, bb->succs)
{
}
}
- for (i = 1; i < loops->num; i++)
+ for (i = 1; i < current_loops->num; i++)
{
- loop = loops->parray[i];
+ loop = current_loops->parray[i];
if (!loop)
continue;
/* Loop recognition. */
extern int flow_loops_find (struct loops *);
extern void flow_loops_free (struct loops *);
-extern void flow_loops_dump (const struct loops *, FILE *,
+extern void flow_loops_dump (FILE *,
void (*)(const struct loop *, FILE *, int), int);
extern void flow_loop_dump (const struct loop *, FILE *,
void (*)(const struct loop *, FILE *, int), int);
extern void flow_loop_free (struct loop *);
int flow_loop_nodes_find (basic_block, struct loop *);
-void fix_loop_structure (struct loops *, bitmap changed_bbs);
-void mark_irreducible_loops (struct loops *);
-void mark_single_exit_loops (struct loops *);
+void fix_loop_structure (bitmap changed_bbs);
+void mark_irreducible_loops (void);
+void mark_single_exit_loops (void);
/* Loop data structure manipulation/querying. */
extern void flow_loop_tree_node_add (struct loop *, struct loop *);
extern int average_num_loop_insns (struct loop *);
extern unsigned get_loop_level (const struct loop *);
extern bool loop_exit_edge_p (const struct loop *, edge);
-extern void mark_loop_exit_edges (struct loops *);
+extern void mark_loop_exit_edges (void);
/* Loops & cfg manipulation. */
extern basic_block *get_loop_body (const struct loop *);
extern void add_bb_to_loop (basic_block, struct loop *);
extern void remove_bb_from_loops (basic_block);
-extern void cancel_loop_tree (struct loops *, struct loop *);
+extern void cancel_loop_tree (struct loop *);
extern int fix_loop_placement (struct loop *);
CP_SIMPLE_PREHEADERS = 1
};
-extern void create_preheaders (struct loops *, int);
-extern void force_single_succ_latches (struct loops *);
+extern void create_preheaders (int);
+extern void force_single_succ_latches (void);
-extern void verify_loop_structure (struct loops *);
+extern void verify_loop_structure (void);
/* Loop analysis. */
extern bool just_once_each_iteration_p (const struct loop *, basic_block);
#define DLTHE_FLAG_COMPLETTE_PEEL 4 /* Update frequencies expecting
a complete peeling. */
-extern struct loop * duplicate_loop (struct loops *, struct loop *,
- struct loop *);
-extern bool duplicate_loop_to_header_edge (struct loop *, edge, struct loops *,
+extern struct loop * duplicate_loop (struct loop *, struct loop *);
+extern bool duplicate_loop_to_header_edge (struct loop *, edge,
unsigned, sbitmap, edge, edge *,
unsigned *, int);
-extern struct loop *loopify (struct loops *, edge, edge,
+extern struct loop *loopify (edge, edge,
basic_block, edge, edge, bool);
-struct loop * loop_version (struct loops *, struct loop *, void *,
+struct loop * loop_version (struct loop *, void *,
basic_block *, bool);
-extern bool remove_path (struct loops *, edge);
+extern bool remove_path (edge);
/* Induction variable analysis. */
extern void loop_optimizer_finalize (void);
/* Optimization passes. */
-extern void unswitch_loops (struct loops *);
+extern void unswitch_loops (void);
enum
{
UAP_UNROLL_ALL = 4 /* Enables unrolling of all loops. */
};
-extern void unroll_and_peel_loops (struct loops *, int);
-extern void doloop_optimize_loops (struct loops *);
-extern void move_loop_invariants (struct loops *);
+extern void unroll_and_peel_loops (int);
+extern void doloop_optimize_loops (void);
+extern void move_loop_invariants (void);
#endif /* GCC_CFGLOOP_H */
#define BB_REPR(BB) ((BB)->index + 1)
void
-mark_irreducible_loops (struct loops *loops)
+mark_irreducible_loops (void)
{
basic_block act;
edge e;
edge_iterator ei;
int i, src, dest;
struct graph *g;
- int num = loops ? loops->num : 1;
+ int num = current_loops ? current_loops->num : 1;
int *queue1 = XNEWVEC (int, last_basic_block + num);
int *queue2 = XNEWVEC (int, last_basic_block + num);
int nq, depth;
src = BB_REPR (act);
dest = BB_REPR (e->dest);
- if (loops)
+ if (current_loops)
{
/* Ignore latch edges. */
if (e->dest->loop_father->header == e->dest
queue1[nq++] = BB_REPR (act);
}
for (i = 1; i < num; i++)
- if (loops->parray[i])
- queue1[nq++] = LOOP_REPR (loops->parray[i]);
+ if (current_loops->parray[i])
+ queue1[nq++] = LOOP_REPR (current_loops->parray[i]);
dfs (g, queue1, nq, queue2, false);
for (i = 0; i < nq; i++)
queue1[i] = queue2[nq - i - 1];
free (queue1);
free (queue2);
- if (loops)
- loops->state |= LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS;
+ if (current_loops)
+ current_loops->state |= LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS;
}
/* Counts number of insns inside LOOP. */
return cost;
}
-/* Sets EDGE_LOOP_EXIT flag for all exits of LOOPS. */
+/* Sets EDGE_LOOP_EXIT flag for all loop exits. */
void
-mark_loop_exit_edges (struct loops *loops)
+mark_loop_exit_edges (void)
{
basic_block bb;
edge e;
- if (loops->num <= 1)
+ if (!current_loops)
return;
FOR_EACH_BB (bb)
#include "cfghooks.h"
#include "output.h"
-static void duplicate_subloops (struct loops *, struct loop *, struct loop *);
-static void copy_loops_to (struct loops *, struct loop **, int,
+static void duplicate_subloops (struct loop *, struct loop *);
+static void copy_loops_to (struct loop **, int,
struct loop *);
static void loop_redirect_edge (edge, basic_block);
static bool loop_delete_branch_edge (edge, int);
static bool rpe_enum_p (basic_block, void *);
static int find_path (edge, basic_block **);
static bool alp_enum_p (basic_block, void *);
-static void fix_loop_placements (struct loops *, struct loop *, bool *);
-static bool fix_bb_placement (struct loops *, basic_block);
-static void fix_bb_placements (struct loops *, basic_block, bool *);
-static void place_new_loop (struct loops *, struct loop *);
+static void fix_loop_placements (struct loop *, bool *);
+static bool fix_bb_placement (basic_block);
+static void fix_bb_placements (basic_block, bool *);
+static void place_new_loop (struct loop *);
static void scale_loop_frequencies (struct loop *, int, int);
static basic_block create_preheader (struct loop *, int);
-static void unloop (struct loops *, struct loop *, bool *);
+static void unloop (struct loop *, bool *);
#define RDIV(X,Y) (((X) + (Y) / 2) / (Y))
n_basic_blocks, e->dest);
}
-/* Fix placement of basic block BB inside loop hierarchy stored in LOOPS --
+/* Fix placement of basic block BB inside loop hierarchy --
Let L be a loop to that BB belongs. Then every successor of BB must either
1) belong to some superloop of loop L, or
2) be a header of loop K such that K->outer is superloop of L
false if the placement of BB was already correct (provided that placements
of its successors are correct). */
static bool
-fix_bb_placement (struct loops *loops, basic_block bb)
+fix_bb_placement (basic_block bb)
{
edge e;
edge_iterator ei;
- struct loop *loop = loops->tree_root, *act;
+ struct loop *loop = current_loops->tree_root, *act;
FOR_EACH_EDGE (e, ei, bb->succs)
{
IRRED_INVALIDATED is set to true. */
static void
-fix_bb_placements (struct loops *loops, basic_block from,
+fix_bb_placements (basic_block from,
bool *irred_invalidated)
{
sbitmap in_queue;
fix_loop_placement. */
base_loop = from->loop_father;
- if (base_loop == loops->tree_root)
+ if (base_loop == current_loops->tree_root)
return;
in_queue = sbitmap_alloc (last_basic_block);
else
{
/* Ordinary basic block. */
- if (!fix_bb_placement (loops, from))
+ if (!fix_bb_placement (from))
continue;
}
}
/* Removes path beginning at edge E, i.e. remove basic blocks dominated by E
- and update loop structure stored in LOOPS and dominators. Return true if
- we were able to remove the path, false otherwise (and nothing is affected
- then). */
+ and update loop structures and dominators. Return true if we were able
+ to remove the path, false otherwise (and nothing is affected then). */
bool
-remove_path (struct loops *loops, edge e)
+remove_path (edge e)
{
edge ae;
basic_block *rem_bbs, *bord_bbs, *dom_bbs, from, bb;
while (e->src->loop_father->outer
&& dominated_by_p (CDI_DOMINATORS,
e->src->loop_father->latch, e->dest))
- unloop (loops, e->src->loop_father, &irred_invalidated);
+ unloop (e->src->loop_father, &irred_invalidated);
/* Identify the path. */
nrem = find_path (e, &rem_bbs);
free (rem_bbs);
for (i = 0; i < nreml; i++)
- cancel_loop_tree (loops, deleted_loop[i]);
+ cancel_loop_tree (deleted_loop[i]);
free (deleted_loop);
/* Find blocks whose dominators may be affected. */
/* Fix placements of basic blocks inside loops and the placement of
loops in the loop tree. */
- fix_bb_placements (loops, from, &irred_invalidated);
- fix_loop_placements (loops, from->loop_father, &irred_invalidated);
+ fix_bb_placements (from, &irred_invalidated);
+ fix_loop_placements (from->loop_father, &irred_invalidated);
if (irred_invalidated
- && (loops->state & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS) != 0)
- mark_irreducible_loops (loops);
+ && (current_loops->state & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS) != 0)
+ mark_irreducible_loops ();
return true;
}
}
/* Given LOOP structure with filled header and latch, find the body of the
- corresponding loop and add it to LOOPS tree. Insert the LOOP as a son of
+ corresponding loop and add it to loops tree. Insert the LOOP as a son of
outer. */
static void
-add_loop (struct loops *loops, struct loop *loop, struct loop *outer)
+add_loop (struct loop *loop, struct loop *outer)
{
basic_block *bbs;
int i, n;
/* Add it to loop structure. */
- place_new_loop (loops, loop);
+ place_new_loop (loop);
flow_loop_tree_node_add (outer, loop);
/* Find its nodes. */
}
/* Make area between HEADER_EDGE and LATCH_EDGE a loop by connecting
- latch to header and update loop tree stored in LOOPS and dominators
+ latch to header and update loop tree and dominators
accordingly. Everything between them plus LATCH_EDGE destination must
be dominated by HEADER_EDGE destination, and back-reachable from
LATCH_EDGE source. HEADER_EDGE is redirected to basic block SWITCH_BB,
Returns newly created loop. */
struct loop *
-loopify (struct loops *loops, edge latch_edge, edge header_edge,
+loopify (edge latch_edge, edge header_edge,
basic_block switch_bb, edge true_edge, edge false_edge,
bool redirect_all_edges)
{
set_immediate_dominator (CDI_DOMINATORS, succ_bb, switch_bb);
/* Compute new loop. */
- add_loop (loops, loop, outer);
+ add_loop (loop, outer);
/* Add switch_bb to appropriate loop. */
if (switch_bb->loop_father)
return loop;
}
-/* Remove the latch edge of a LOOP and update LOOPS tree to indicate that
+/* Remove the latch edge of a LOOP and update loops to indicate that
the LOOP was removed. After this function, original loop latch will
have no successor, which caller is expected to fix somehow.
invalid, IRRED_INVALIDATED is set to true. */
static void
-unloop (struct loops *loops, struct loop *loop, bool *irred_invalidated)
+unloop (struct loop *loop, bool *irred_invalidated)
{
basic_block *body;
struct loop *ploop;
/* Remove the loop and free its data. */
flow_loop_tree_node_remove (loop);
- loops->parray[loop->num] = NULL;
+ current_loops->parray[loop->num] = NULL;
flow_loop_free (loop);
remove_edge (single_succ_edge (latch));
/* We do not pass IRRED_INVALIDATED to fix_bb_placements here, as even if
there is an irreducible region inside the cancelled loop, the flags will
be still correct. */
- fix_bb_placements (loops, latch, &dummy);
+ fix_bb_placements (latch, &dummy);
}
/* Fix placement of LOOP inside loop tree, i.e. find the innermost superloop
invalidate the information about irreducible regions. */
static void
-fix_loop_placements (struct loops *loops, struct loop *loop,
- bool *irred_invalidated)
+fix_loop_placements (struct loop *loop, bool *irred_invalidated)
{
struct loop *outer;
for its preheader, because the successor is the header and belongs
to the loop. So call fix_bb_placements to fix up the placement
of the preheader and (possibly) of its predecessors. */
- fix_bb_placements (loops, loop_preheader_edge (loop)->src,
+ fix_bb_placements (loop_preheader_edge (loop)->src,
irred_invalidated);
loop = outer;
}
}
-/* Creates place for a new LOOP in LOOPS structure. */
+/* Creates place for a new LOOP in loops structure. */
static void
-place_new_loop (struct loops *loops, struct loop *loop)
+place_new_loop (struct loop *loop)
{
- loops->parray =
- xrealloc (loops->parray, (loops->num + 1) * sizeof (struct loop *));
- loops->parray[loops->num] = loop;
+ current_loops->parray =
+ xrealloc (current_loops->parray, (current_loops->num + 1) * sizeof (struct loop *));
+ current_loops->parray[current_loops->num] = loop;
- loop->num = loops->num++;
+ loop->num = current_loops->num++;
}
/* Copies copy of LOOP as subloop of TARGET loop, placing newly
- created loop into LOOPS structure. */
+ created loop into loops structure. */
struct loop *
-duplicate_loop (struct loops *loops, struct loop *loop, struct loop *target)
+duplicate_loop (struct loop *loop, struct loop *target)
{
struct loop *cloop;
cloop = XCNEW (struct loop);
- place_new_loop (loops, cloop);
+ place_new_loop (cloop);
/* Mark the new loop as copy of LOOP. */
loop->copy = cloop;
}
/* Copies structure of subloops of LOOP into TARGET loop, placing
- newly created loops into loop tree stored in LOOPS. */
+ newly created loops into loop tree. */
static void
-duplicate_subloops (struct loops *loops, struct loop *loop, struct loop *target)
+duplicate_subloops (struct loop *loop, struct loop *target)
{
struct loop *aloop, *cloop;
for (aloop = loop->inner; aloop; aloop = aloop->next)
{
- cloop = duplicate_loop (loops, aloop, target);
- duplicate_subloops (loops, aloop, cloop);
+ cloop = duplicate_loop (aloop, target);
+ duplicate_subloops (aloop, cloop);
}
}
/* Copies structure of subloops of N loops, stored in array COPIED_LOOPS,
- into TARGET loop, placing newly created loops into loop tree LOOPS. */
+ into TARGET loop, placing newly created loops into loop tree. */
static void
-copy_loops_to (struct loops *loops, struct loop **copied_loops, int n, struct loop *target)
+copy_loops_to (struct loop **copied_loops, int n, struct loop *target)
{
struct loop *aloop;
int i;
for (i = 0; i < n; i++)
{
- aloop = duplicate_loop (loops, copied_loops[i], target);
- duplicate_subloops (loops, copied_loops[i], aloop);
+ aloop = duplicate_loop (copied_loops[i], target);
+ duplicate_subloops (copied_loops[i], aloop);
}
}
}
/* Duplicates body of LOOP to given edge E NDUPL times. Takes care of updating
- LOOPS structure and dominators. E's destination must be LOOP header for
+ loop structure and dominators. E's destination must be LOOP header for
this to work, i.e. it must be entry or latch edge of this loop; these are
unique, as the loops must have preheaders for this function to work
correctly (in case E is latch, the function unrolls the loop, if E is entry
flow through them) into TO_REMOVE array. Returns false if duplication is
impossible. */
bool
-duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops,
+duplicate_loop_to_header_edge (struct loop *loop, edge e,
unsigned int ndupl, sbitmap wont_exit,
edge orig, edge *to_remove,
unsigned int *n_to_remove, int flags)
}
/* Update the information about single exits. */
- if (loops->state & LOOPS_HAVE_MARKED_SINGLE_EXITS)
+ if (current_loops->state & LOOPS_HAVE_MARKED_SINGLE_EXITS)
update_single_exits_after_duplication (bbs, n, target);
/* Record exit edge in original loop body. */
for (j = 0; j < ndupl; j++)
{
/* Copy loops. */
- copy_loops_to (loops, orig_loops, n_orig_loops, target);
+ copy_loops_to (orig_loops, n_orig_loops, target);
/* Copy bbs. */
copy_bbs (bbs, n, new_bbs, spec_edges, 2, new_spec_edges, loop,
place_after);
place_after = new_spec_edges[SE_LATCH]->src;
- if (loops->state & LOOPS_HAVE_MARKED_SINGLE_EXITS)
+ if (current_loops->state & LOOPS_HAVE_MARKED_SINGLE_EXITS)
{
for (i = 0; i < n; i++)
bbs[i]->flags |= BB_DUPLICATED;
return dummy;
}
-/* Create preheaders for each loop from loop tree stored in LOOPS; for meaning
- of FLAGS see create_preheader. */
+/* Create preheaders for each loop; for meaning of FLAGS see create_preheader. */
+
void
-create_preheaders (struct loops *loops, int flags)
+create_preheaders (int flags)
{
unsigned i;
- for (i = 1; i < loops->num; i++)
- create_preheader (loops->parray[i], flags);
- loops->state |= LOOPS_HAVE_PREHEADERS;
+ for (i = 1; i < current_loops->num; i++)
+ create_preheader (current_loops->parray[i], flags);
+ current_loops->state |= LOOPS_HAVE_PREHEADERS;
}
-/* Forces all loop latches of loops from loop tree LOOPS to have only single
- successor. */
+/* Forces all loop latches to have only single successor. */
+
void
-force_single_succ_latches (struct loops *loops)
+force_single_succ_latches (void)
{
unsigned i;
struct loop *loop;
edge e;
- for (i = 1; i < loops->num; i++)
+ for (i = 1; i < current_loops->num; i++)
{
- loop = loops->parray[i];
+ loop = current_loops->parray[i];
if (loop->latch != loop->header && single_succ_p (loop->latch))
continue;
split_edge (e);
}
- loops->state |= LOOPS_HAVE_SIMPLE_LATCHES;
+ current_loops->state |= LOOPS_HAVE_SIMPLE_LATCHES;
}
/* This function is called from loop_version. It splits the entry edge
instruction stream, otherwise it is placed before LOOP. */
struct loop *
-loop_version (struct loops *loops, struct loop * loop,
+loop_version (struct loop *loop,
void *cond_expr, basic_block *condition_bb,
bool place_after)
{
first_head = entry->dest;
/* Duplicate loop. */
- if (!cfg_hook_duplicate_loop_to_header_edge (loop, entry, loops, 1,
+ if (!cfg_hook_duplicate_loop_to_header_edge (loop, entry, 1,
NULL, NULL, NULL, NULL, 0))
return NULL;
latch_edge = single_succ_edge (get_bb_copy (loop->latch));
extract_cond_bb_edges (cond_bb, &true_edge, &false_edge);
- nloop = loopify (loops,
- latch_edge,
+ nloop = loopify (latch_edge,
single_pred_edge (get_bb_copy (loop->header)),
cond_bb, true_edge, false_edge,
false /* Do not redirect all edges. */);
return nloop;
}
-/* The structure of LOOPS might have changed. Some loops might get removed
+/* The structure of loops might have changed. Some loops might get removed
(and their headers and latches were set to NULL), loop exists might get
removed (thus the loop nesting may be wrong), and some blocks and edges
were changed (so the information about bb --> loop mapping does not have
marked in it. */
void
-fix_loop_structure (struct loops *loops, bitmap changed_bbs)
+fix_loop_structure (bitmap changed_bbs)
{
basic_block bb;
struct loop *loop, *ploop;
FOR_EACH_BB (bb)
{
bb->aux = (void *) (size_t) bb->loop_father->depth;
- bb->loop_father = loops->tree_root;
+ bb->loop_father = current_loops->tree_root;
}
/* Remove the dead loops from structures. */
- loops->tree_root->num_nodes = n_basic_blocks;
- for (i = 1; i < loops->num; i++)
+ current_loops->tree_root->num_nodes = n_basic_blocks;
+ for (i = 1; i < current_loops->num; i++)
{
- loop = loops->parray[i];
+ loop = current_loops->parray[i];
if (!loop)
continue;
/* Remove the loop and free its data. */
flow_loop_tree_node_remove (loop);
- loops->parray[loop->num] = NULL;
+ current_loops->parray[loop->num] = NULL;
flow_loop_free (loop);
}
/* Rescan the bodies of loops, starting from the outermost. */
- loop = loops->tree_root;
+ loop = current_loops->tree_root;
while (1)
{
if (loop->inner)
else
{
while (!loop->next
- && loop != loops->tree_root)
+ && loop != current_loops->tree_root)
loop = loop->outer;
- if (loop == loops->tree_root)
+ if (loop == current_loops->tree_root)
break;
loop = loop->next;
}
/* Now fix the loop nesting. */
- for (i = 1; i < loops->num; i++)
+ for (i = 1; i < current_loops->num; i++)
{
- loop = loops->parray[i];
+ loop = current_loops->parray[i];
if (!loop)
continue;
bb->aux = NULL;
}
- if (loops->state & LOOPS_HAVE_MARKED_SINGLE_EXITS)
- mark_single_exit_loops (loops);
- if (loops->state & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
- mark_irreducible_loops (loops);
+ if (current_loops->state & LOOPS_HAVE_MARKED_SINGLE_EXITS)
+ mark_single_exit_loops ();
+ if (current_loops->state & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
+ mark_irreducible_loops ();
}
loop_optimizer_init (0);
if (current_loops)
{
- mark_loop_exit_edges (current_loops);
+ mark_loop_exit_edges ();
loop_optimizer_finalize ();
}
free_dominance_info (CDI_DOMINATORS);
Fourier-Motzkin elimination is used to compute the bounds of the base space
of the lattice. */
-static bool perfect_nestify (struct loops *,
- struct loop *, VEC(tree,heap) *,
+static bool perfect_nestify (struct loop *, VEC(tree,heap) *,
VEC(tree,heap) *, VEC(int,heap) *,
VEC(tree,heap) *);
/* Lattice stuff that is internal to the code generation algorithm. */
during this process. */
lambda_loopnest
-gcc_loopnest_to_lambda_loopnest (struct loops *currloops,
- struct loop *loop_nest,
+gcc_loopnest_to_lambda_loopnest (struct loop *loop_nest,
VEC(tree,heap) **inductionvars,
VEC(tree,heap) **invariants)
{
if (!perfect_nest)
{
- if (!perfect_nestify (currloops, loop_nest,
- lboundvars, uboundvars, steps, *inductionvars))
+ if (!perfect_nestify (loop_nest, lboundvars, uboundvars, steps,
+ *inductionvars))
{
if (dump_file)
fprintf (dump_file,
}
/* Transform the loop nest into a perfect nest, if possible.
- LOOPS is the current struct loops *
LOOP is the loop nest to transform into a perfect nest
LBOUNDS are the lower bounds for the loops to transform
UBOUNDS are the upper bounds for the loops to transform
Return FALSE if we can't make this loop into a perfect nest. */
static bool
-perfect_nestify (struct loops *loops,
- struct loop *loop,
+perfect_nestify (struct loop *loop,
VEC(tree,heap) *lbounds,
VEC(tree,heap) *ubounds,
VEC(int,heap) *steps,
make_edge (latchbb, headerbb, EDGE_FALLTHRU);
/* Update the loop structures. */
- newloop = duplicate_loop (loops, loop, olddest->loop_father);
+ newloop = duplicate_loop (loop, olddest->loop_father);
newloop->header = headerbb;
newloop->latch = latchbb;
set_single_exit (newloop, e);
lambda_loopnest lambda_loopnest_new (int, int);
lambda_loopnest lambda_loopnest_transform (lambda_loopnest, lambda_trans_matrix);
struct loop;
-struct loops;
bool perfect_nest_p (struct loop *);
void print_lambda_loopnest (FILE *, lambda_loopnest, char);
lambda_body_vector lambda_body_vector_compute_new (lambda_trans_matrix,
lambda_body_vector);
void print_lambda_body_vector (FILE *, lambda_body_vector);
-lambda_loopnest gcc_loopnest_to_lambda_loopnest (struct loops *,
- struct loop *,
+lambda_loopnest gcc_loopnest_to_lambda_loopnest (struct loop *,
VEC(tree,heap) **,
VEC(tree,heap) **);
void lambda_loopnest_to_gcc_loopnest (struct loop *,
return true;
}
-/* This is the main entry point. Process all LOOPS using doloop_optimize. */
+/* This is the main entry point. Process all loops using doloop_optimize. */
void
-doloop_optimize_loops (struct loops *loops)
+doloop_optimize_loops (void)
{
unsigned i;
struct loop *loop;
- for (i = 1; i < loops->num; i++)
+ for (i = 1; i < current_loops->num; i++)
{
- loop = loops->parray[i];
+ loop = current_loops->parray[i];
if (!loop)
continue;
#ifdef ENABLE_CHECKING
verify_dominators (CDI_DOMINATORS);
- verify_loop_structure (loops);
+ verify_loop_structure ();
#endif
}
#endif /* HAVE_doloop_end */
/* Create pre-headers. */
if (flags & LOOPS_HAVE_PREHEADERS)
- create_preheaders (current_loops, CP_SIMPLE_PREHEADERS);
+ create_preheaders (CP_SIMPLE_PREHEADERS);
/* Force all latches to have only single successor. */
if (flags & LOOPS_HAVE_SIMPLE_LATCHES)
- force_single_succ_latches (current_loops);
+ force_single_succ_latches ();
/* Mark irreducible loops. */
if (flags & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
- mark_irreducible_loops (current_loops);
+ mark_irreducible_loops ();
if (flags & LOOPS_HAVE_MARKED_SINGLE_EXITS)
- mark_single_exit_loops (current_loops);
+ mark_single_exit_loops ();
/* Dump loops. */
- flow_loops_dump (current_loops, dump_file, NULL, 1);
+ flow_loops_dump (dump_file, NULL, 1);
#ifdef ENABLE_CHECKING
verify_dominators (CDI_DOMINATORS);
- verify_loop_structure (current_loops);
+ verify_loop_structure ();
#endif
}
rtl_move_loop_invariants (void)
{
if (current_loops)
- move_loop_invariants (current_loops);
+ move_loop_invariants ();
return 0;
}
rtl_unswitch (void)
{
if (current_loops)
- unswitch_loops (current_loops);
+ unswitch_loops ();
return 0;
}
if (flag_unroll_all_loops)
flags |= UAP_UNROLL_ALL;
- unroll_and_peel_loops (current_loops, flags);
+ unroll_and_peel_loops (flags);
}
return 0;
}
{
#ifdef HAVE_doloop_end
if (current_loops)
- doloop_optimize_loops (current_loops);
+ doloop_optimize_loops ();
#endif
return 0;
}
loop->aux = NULL;
}
-/* Move the invariants out of the LOOPS. */
+/* Move the invariants out of the loops. */
void
-move_loop_invariants (struct loops *loops)
+move_loop_invariants (void)
{
struct loop *loop;
unsigned i;
df_chain_add_problem (df, DF_UD_CHAIN);
/* Process the loops, innermost first. */
- loop = loops->tree_root;
+ loop = current_loops->tree_root;
while (loop->inner)
loop = loop->inner;
- while (loop != loops->tree_root)
+ while (loop != current_loops->tree_root)
{
move_single_loop_invariants (loop);
loop = loop->outer;
}
- for (i = 1; i < loops->num; i++)
- if (loops->parray[i])
- free_loop_data (loops->parray[i]);
+ for (i = 1; i < current_loops->num; i++)
+ if (current_loops->parray[i])
+ free_loop_data (current_loops->parray[i]);
df_finish (df);
df = NULL;
basic_block loop_preheader; /* The loop preheader basic block. */
};
-static void decide_unrolling_and_peeling (struct loops *, int);
-static void peel_loops_completely (struct loops *, int);
+static void decide_unrolling_and_peeling (int);
+static void peel_loops_completely (int);
static void decide_peel_simple (struct loop *, int);
static void decide_peel_once_rolling (struct loop *, int);
static void decide_peel_completely (struct loop *, int);
static void decide_unroll_stupid (struct loop *, int);
static void decide_unroll_constant_iterations (struct loop *, int);
static void decide_unroll_runtime_iterations (struct loop *, int);
-static void peel_loop_simple (struct loops *, struct loop *);
-static void peel_loop_completely (struct loops *, struct loop *);
-static void unroll_loop_stupid (struct loops *, struct loop *);
-static void unroll_loop_constant_iterations (struct loops *, struct loop *);
-static void unroll_loop_runtime_iterations (struct loops *, struct loop *);
+static void peel_loop_simple (struct loop *);
+static void peel_loop_completely (struct loop *);
+static void unroll_loop_stupid (struct loop *);
+static void unroll_loop_constant_iterations (struct loop *);
+static void unroll_loop_runtime_iterations (struct loop *);
static struct opt_info *analyze_insns_in_loop (struct loop *);
static void opt_info_start_duplication (struct opt_info *);
static void apply_opt_in_copies (struct opt_info *, unsigned, bool, bool);
/* Unroll and/or peel (depending on FLAGS) LOOPS. */
void
-unroll_and_peel_loops (struct loops *loops, int flags)
+unroll_and_peel_loops (int flags)
{
struct loop *loop, *next;
bool check;
/* First perform complete loop peeling (it is almost surely a win,
and affects parameters for further decision a lot). */
- peel_loops_completely (loops, flags);
+ peel_loops_completely (flags);
/* Now decide rest of unrolling and peeling. */
- decide_unrolling_and_peeling (loops, flags);
+ decide_unrolling_and_peeling (flags);
- loop = loops->tree_root;
+ loop = current_loops->tree_root;
while (loop->inner)
loop = loop->inner;
/* Scan the loops, inner ones first. */
- while (loop != loops->tree_root)
+ while (loop != current_loops->tree_root)
{
if (loop->next)
{
/* Already done. */
gcc_unreachable ();
case LPT_PEEL_SIMPLE:
- peel_loop_simple (loops, loop);
+ peel_loop_simple (loop);
break;
case LPT_UNROLL_CONSTANT:
- unroll_loop_constant_iterations (loops, loop);
+ unroll_loop_constant_iterations (loop);
break;
case LPT_UNROLL_RUNTIME:
- unroll_loop_runtime_iterations (loops, loop);
+ unroll_loop_runtime_iterations (loop);
break;
case LPT_UNROLL_STUPID:
- unroll_loop_stupid (loops, loop);
+ unroll_loop_stupid (loop);
break;
case LPT_NONE:
check = false;
{
#ifdef ENABLE_CHECKING
verify_dominators (CDI_DOMINATORS);
- verify_loop_structure (loops);
+ verify_loop_structure ();
#endif
}
loop = next;
return true;
}
-/* Check whether to peel LOOPS (depending on FLAGS) completely and do so. */
+/* Depending on FLAGS, check whether to peel loops completely and do so. */
static void
-peel_loops_completely (struct loops *loops, int flags)
+peel_loops_completely (int flags)
{
struct loop *loop;
unsigned i;
/* Scan the loops, the inner ones first. */
- for (i = loops->num - 1; i > 0; i--)
+ for (i = current_loops->num - 1; i > 0; i--)
{
- loop = loops->parray[i];
+ loop = current_loops->parray[i];
if (!loop)
continue;
if (loop->lpt_decision.decision == LPT_PEEL_COMPLETELY)
{
- peel_loop_completely (loops, loop);
+ peel_loop_completely (loop);
#ifdef ENABLE_CHECKING
verify_dominators (CDI_DOMINATORS);
- verify_loop_structure (loops);
+ verify_loop_structure ();
#endif
}
}
}
-/* Decide whether unroll or peel LOOPS (depending on FLAGS) and how much. */
+/* Decide whether unroll or peel loops (depending on FLAGS) and how much. */
static void
-decide_unrolling_and_peeling (struct loops *loops, int flags)
+decide_unrolling_and_peeling (int flags)
{
- struct loop *loop = loops->tree_root, *next;
+ struct loop *loop = current_loops->tree_root, *next;
while (loop->inner)
loop = loop->inner;
/* Scan the loops, inner ones first. */
- while (loop != loops->tree_root)
+ while (loop != current_loops->tree_root)
{
if (loop->next)
{
body; i++;
*/
static void
-peel_loop_completely (struct loops *loops, struct loop *loop)
+peel_loop_completely (struct loop *loop)
{
sbitmap wont_exit;
unsigned HOST_WIDE_INT npeel;
opt_info_start_duplication (opt_info);
ok = duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
- loops, npeel,
+ npeel,
wont_exit, desc->out_edge,
remove_edges, &n_remove_edges,
DLTHE_FLAG_UPDATE_FREQ
/* Remove the exit edges. */
for (i = 0; i < n_remove_edges; i++)
- remove_path (loops, remove_edges[i]);
+ remove_path (remove_edges[i]);
free (remove_edges);
}
/* Now remove the unreachable part of the last iteration and cancel
the loop. */
- remove_path (loops, ein);
+ remove_path (ein);
if (dump_file)
fprintf (dump_file, ";; Peeled loop completely, %d times\n", (int) npeel);
}
*/
static void
-unroll_loop_constant_iterations (struct loops *loops, struct loop *loop)
+unroll_loop_constant_iterations (struct loop *loop)
{
unsigned HOST_WIDE_INT niter;
unsigned exit_mod;
{
opt_info_start_duplication (opt_info);
ok = duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
- loops, exit_mod,
+ exit_mod,
wont_exit, desc->out_edge,
remove_edges, &n_remove_edges,
DLTHE_FLAG_UPDATE_FREQ
opt_info_start_duplication (opt_info);
ok = duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
- loops, exit_mod + 1,
+ exit_mod + 1,
wont_exit, desc->out_edge,
remove_edges, &n_remove_edges,
DLTHE_FLAG_UPDATE_FREQ
opt_info_start_duplication (opt_info);
ok = duplicate_loop_to_header_edge (loop, loop_latch_edge (loop),
- loops, max_unroll,
+ max_unroll,
wont_exit, desc->out_edge,
remove_edges, &n_remove_edges,
DLTHE_FLAG_UPDATE_FREQ
/* Remove the edges. */
for (i = 0; i < n_remove_edges; i++)
- remove_path (loops, remove_edges[i]);
+ remove_path (remove_edges[i]);
free (remove_edges);
if (dump_file)
}
*/
static void
-unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop)
+unroll_loop_runtime_iterations (struct loop *loop)
{
rtx old_niter, niter, init_code, branch_code, tmp;
unsigned i, j, p;
SET_BIT (wont_exit, 1);
ezc_swtch = loop_preheader_edge (loop)->src;
ok = duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
- loops, 1,
- wont_exit, desc->out_edge,
+ 1, wont_exit, desc->out_edge,
remove_edges, &n_remove_edges,
DLTHE_FLAG_UPDATE_FREQ);
gcc_assert (ok);
if (i != n_peel - 1 || !last_may_exit)
SET_BIT (wont_exit, 1);
ok = duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
- loops, 1,
- wont_exit, desc->out_edge,
+ 1, wont_exit, desc->out_edge,
remove_edges, &n_remove_edges,
DLTHE_FLAG_UPDATE_FREQ);
gcc_assert (ok);
opt_info_start_duplication (opt_info);
ok = duplicate_loop_to_header_edge (loop, loop_latch_edge (loop),
- loops, max_unroll,
+ max_unroll,
wont_exit, desc->out_edge,
remove_edges, &n_remove_edges,
DLTHE_FLAG_UPDATE_FREQ
/* Remove the edges. */
for (i = 0; i < n_remove_edges; i++)
- remove_path (loops, remove_edges[i]);
+ remove_path (remove_edges[i]);
free (remove_edges);
/* We must be careful when updating the number of iterations due to
end: ;
*/
static void
-peel_loop_simple (struct loops *loops, struct loop *loop)
+peel_loop_simple (struct loop *loop)
{
sbitmap wont_exit;
unsigned npeel = loop->lpt_decision.times;
opt_info_start_duplication (opt_info);
ok = duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
- loops, npeel, wont_exit,
+ npeel, wont_exit,
NULL, NULL,
NULL, DLTHE_FLAG_UPDATE_FREQ
| (opt_info
}
*/
static void
-unroll_loop_stupid (struct loops *loops, struct loop *loop)
+unroll_loop_stupid (struct loop *loop)
{
sbitmap wont_exit;
unsigned nunroll = loop->lpt_decision.times;
opt_info_start_duplication (opt_info);
ok = duplicate_loop_to_header_edge (loop, loop_latch_edge (loop),
- loops, nunroll, wont_exit,
+ nunroll, wont_exit,
NULL, NULL, NULL,
DLTHE_FLAG_UPDATE_FREQ
| (opt_info
containing subloops would not be very large compared to complications
with handling this case. */
-static struct loop *unswitch_loop (struct loops *, struct loop *,
- basic_block, rtx, rtx);
-static void unswitch_single_loop (struct loops *, struct loop *, rtx, int);
+static struct loop *unswitch_loop (struct loop *, basic_block, rtx, rtx);
+static void unswitch_single_loop (struct loop *, rtx, int);
static rtx may_unswitch_on (basic_block, struct loop *, rtx *);
/* Prepare a sequence comparing OP0 with OP1 using COMP and jumping to LABEL if
return seq;
}
-/* Main entry point. Perform loop unswitching on all suitable LOOPS. */
+/* Main entry point. Perform loop unswitching on all suitable loops. */
void
-unswitch_loops (struct loops *loops)
+unswitch_loops (void)
{
int i, num;
struct loop *loop;
/* Go through inner loops (only original ones). */
- num = loops->num;
+ num = current_loops->num;
for (i = 1; i < num; i++)
{
/* Removed loop? */
- loop = loops->parray[i];
+ loop = current_loops->parray[i];
if (!loop)
continue;
if (loop->inner)
continue;
- unswitch_single_loop (loops, loop, NULL_RTX, 0);
+ unswitch_single_loop (loop, NULL_RTX, 0);
#ifdef ENABLE_CHECKING
verify_dominators (CDI_DOMINATORS);
- verify_loop_structure (loops);
+ verify_loop_structure ();
#endif
}
number of unswitchings done; do not allow it to grow too much, it is too
easy to create example on that the code would grow exponentially. */
static void
-unswitch_single_loop (struct loops *loops, struct loop *loop,
- rtx cond_checked, int num)
+unswitch_single_loop (struct loop *loop, rtx cond_checked, int num)
{
basic_block *bbs;
struct loop *nloop;
{
/* Remove false path. */
e = FALLTHRU_EDGE (bbs[i]);
- remove_path (loops, e);
+ remove_path (e);
free (bbs);
repeat = 1;
}
{
/* Remove true path. */
e = BRANCH_EDGE (bbs[i]);
- remove_path (loops, e);
+ remove_path (e);
free (bbs);
repeat = 1;
}
fprintf (dump_file, ";; Unswitching loop\n");
/* Unswitch the loop on this condition. */
- nloop = unswitch_loop (loops, loop, bbs[i], cond, cinsn);
+ nloop = unswitch_loop (loop, bbs[i], cond, cinsn);
gcc_assert (nloop);
/* Invoke itself on modified loops. */
- unswitch_single_loop (loops, nloop, rconds, num + 1);
- unswitch_single_loop (loops, loop, conds, num + 1);
+ unswitch_single_loop (nloop, rconds, num + 1);
+ unswitch_single_loop (loop, conds, num + 1);
free_EXPR_LIST_node (conds);
if (rcond)
NULL, it is the insn in that COND is compared. */
static struct loop *
-unswitch_loop (struct loops *loops, struct loop *loop, basic_block unswitch_on,
- rtx cond, rtx cinsn)
+unswitch_loop (struct loop *loop, basic_block unswitch_on, rtx cond, rtx cinsn)
{
edge entry, latch_edge, true_edge, false_edge, e;
basic_block switch_bb, unswitch_on_alt;
entry->flags &= ~EDGE_IRREDUCIBLE_LOOP;
zero_bitmap = sbitmap_alloc (2);
sbitmap_zero (zero_bitmap);
- if (!duplicate_loop_to_header_edge (loop, entry, loops, 1,
+ if (!duplicate_loop_to_header_edge (loop, entry, 1,
zero_bitmap, NULL, NULL, NULL, 0))
{
sbitmap_free (zero_bitmap);
}
/* Loopify from the copy of LOOP body, constructing the new loop. */
- nloop = loopify (loops, latch_edge,
+ nloop = loopify (latch_edge,
single_pred_edge (get_bb_copy (loop->header)), switch_bb,
BRANCH_EDGE (switch_bb), FALLTHRU_EDGE (switch_bb), true);
/* Remove branches that are now unreachable in new loops. */
- remove_path (loops, true_edge);
- remove_path (loops, false_edge);
+ remove_path (true_edge);
+ remove_path (false_edge);
/* One of created loops do not have to be subloop of the outer loop now,
so fix its placement in loop data structure. */
rtx comp_rtx = gen_rtx_fmt_ee (GT, VOIDmode, count_reg,
GEN_INT(stage_count));
- nloop = loop_version (current_loops, loop, comp_rtx,
- &condition_bb, true);
+ nloop = loop_version (loop, comp_rtx, &condition_bb, true);
}
/* Set new iteration count of loop kernel. */
static void combine_predictions_for_insn (rtx, basic_block);
static void dump_prediction (FILE *, enum br_predictor, int, basic_block, int);
-static void estimate_bb_frequencies (struct loops *);
static void predict_paths_leading_to (basic_block, int *, enum br_predictor, enum prediction);
static bool last_basic_block_p (basic_block);
static void compute_function_frequency (void);
static void choose_function_section (void);
static bool can_predict_insn_p (rtx);
+static void estimate_bb_frequencies (void);
/* Information we hold about each branch predictor.
Filled using information from predict.def. */
}
}
-/* Predict edge probabilities by exploiting loop structure.
- When RTLSIMPLELOOPS is set, attempt to count number of iterations by analyzing
- RTL otherwise use tree based approach. */
+/* Predict edge probabilities by exploiting loop structure. */
+
static void
-predict_loops (struct loops *loops_info)
+predict_loops (void)
{
unsigned i;
- scev_initialize (loops_info);
+ scev_initialize ();
/* Try to predict out blocks in a loop that are not part of a
natural loop. */
- for (i = 1; i < loops_info->num; i++)
+ for (i = 1; i < current_loops->num; i++)
{
basic_block bb, *bbs;
unsigned j, n_exits;
- struct loop *loop = loops_info->parray[i];
+ struct loop *loop = current_loops->parray[i];
VEC (edge, heap) *exits;
struct tree_niter_desc niter_desc;
edge ex;
loop_optimizer_init (0);
if (current_loops && dump_file && (dump_flags & TDF_DETAILS))
- flow_loops_dump (current_loops, dump_file, NULL, 0);
+ flow_loops_dump (dump_file, NULL, 0);
add_noreturn_fake_exit_edges ();
connect_infinite_loops_to_exit ();
tree_bb_level_predictions ();
- mark_irreducible_loops (current_loops);
+ mark_irreducible_loops ();
if (current_loops)
- predict_loops (current_loops);
+ predict_loops ();
FOR_EACH_BB (bb)
{
combine_predictions_for_bb (bb);
strip_builtin_expect ();
- estimate_bb_frequencies (current_loops);
+ estimate_bb_frequencies ();
free_dominance_info (CDI_POST_DOMINATORS);
remove_fake_exit_edges ();
loop_optimizer_finalize ();
}
}
-/* Propates frequencies through structure of LOOPS. */
+/* Propates frequencies through structure of loops. */
static void
-estimate_loops (struct loops *loops)
+estimate_loops (void)
{
bitmap tovisit = BITMAP_ALLOC (NULL);
basic_block bb;
/* Start by estimating the frequencies in the loops. */
- if (loops)
- estimate_loops_at_level (loops->tree_root->inner);
+ if (current_loops)
+ estimate_loops_at_level (current_loops->tree_root->inner);
/* Now propagate the frequencies through all the blocks. */
FOR_ALL_BB (bb)
/* Estimate basic blocks frequency by given branch probabilities. */
static void
-estimate_bb_frequencies (struct loops *loops)
+estimate_bb_frequencies (void)
{
basic_block bb;
sreal freq_max;
/* First compute probabilities locally for each loop from innermost
to outermost to examine probabilities for back edges. */
- estimate_loops (loops);
+ estimate_loops ();
memcpy (&freq_max, &real_zero, sizeof (real_zero));
FOR_EACH_BB (bb)
if (changed)
{
bitmap changed_bbs = BITMAP_ALLOC (NULL);
- fix_loop_structure (current_loops, changed_bbs);
+ fix_loop_structure (changed_bbs);
calculate_dominance_info (CDI_DOMINATORS);
/* This usually does nothing. But sometimes parts of cfg that originally
BITMAP_FREE (changed_bbs);
#ifdef ENABLE_CHECKING
- verify_loop_structure (current_loops);
+ verify_loop_structure ();
#endif
scev_reset ();
}
};
/* In tree-vectorizer.c */
-unsigned vectorize_loops (struct loops *);
+unsigned vectorize_loops (void);
extern bool vect_can_force_dr_alignment_p (tree, unsigned int);
extern tree get_vectype_for_scalar_type (tree);
/* In tree-ssa-loop*.c */
-void tree_ssa_lim (struct loops *);
-unsigned int tree_ssa_unswitch_loops (struct loops *);
-unsigned int canonicalize_induction_variables (struct loops *);
-unsigned int tree_unroll_loops_completely (struct loops *, bool);
-unsigned int tree_ssa_prefetch_arrays (struct loops *);
-unsigned int remove_empty_loops (struct loops *);
-void tree_ssa_iv_optimize (struct loops *);
+void tree_ssa_lim (void);
+unsigned int tree_ssa_unswitch_loops (void);
+unsigned int canonicalize_induction_variables (void);
+unsigned int tree_unroll_loops_completely (bool);
+unsigned int tree_ssa_prefetch_arrays (void);
+unsigned int remove_empty_loops (void);
+void tree_ssa_iv_optimize (void);
bool number_of_iterations_exit (struct loop *, edge,
struct tree_niter_desc *niter, bool);
tree find_loop_niter (struct loop *, edge *);
tree loop_niter_by_eval (struct loop *, edge);
tree find_loop_niter_by_eval (struct loop *, edge *);
-void estimate_numbers_of_iterations (struct loops *);
+void estimate_numbers_of_iterations (void);
bool scev_probably_wraps_p (tree, tree, tree, struct loop *, bool);
bool convert_affine_scev (struct loop *, tree, tree *, tree *, tree, bool);
enum ev_direction {EV_DIR_GROWS, EV_DIR_DECREASES, EV_DIR_UNKNOWN};
enum ev_direction scev_direction (tree);
-void free_numbers_of_iterations_estimates (struct loops *);
+void free_numbers_of_iterations_estimates (void);
void free_numbers_of_iterations_estimates_loop (struct loop *);
void rewrite_into_loop_closed_ssa (bitmap, unsigned);
void verify_loop_closed_ssa (void);
bool *);
basic_block ip_end_pos (struct loop *);
basic_block ip_normal_pos (struct loop *);
-bool tree_duplicate_loop_to_header_edge (struct loop *, edge, struct loops *,
+bool tree_duplicate_loop_to_header_edge (struct loop *, edge,
unsigned int, sbitmap,
edge, edge *,
unsigned int *, int);
-struct loop *tree_ssa_loop_version (struct loops *, struct loop *, tree,
+struct loop *tree_ssa_loop_version (struct loop *, tree,
basic_block *);
tree expand_simple_operations (tree);
void substitute_in_loop_info (struct loop *, tree, tree);
edge single_dom_exit (struct loop *);
bool can_unroll_loop_p (struct loop *loop, unsigned factor,
struct tree_niter_desc *niter);
-void tree_unroll_loop (struct loops *, struct loop *, unsigned,
+void tree_unroll_loop (struct loop *, unsigned,
edge, struct tree_niter_desc *);
bool contains_abnormal_ssa_name_p (tree);
bool sra_type_can_be_decomposed_p (tree);
/* In tree-loop-linear.c */
-extern void linear_transform_loops (struct loops *);
+extern void linear_transform_loops (void);
/* In tree-ssa-loop-ivopts.c */
bool expr_invariant_in_loop_p (struct loop *, tree);
return trans;
}
-/* Perform a set of linear transforms on LOOPS. */
+/* Perform a set of linear transforms on loops. */
void
-linear_transform_loops (struct loops *loops)
+linear_transform_loops (void)
{
bool modified = false;
unsigned int i;
VEC(tree,heap) *oldivs = NULL;
VEC(tree,heap) *invariants = NULL;
- for (i = 1; i < loops->num; i++)
+ for (i = 1; i < current_loops->num; i++)
{
unsigned int depth = 0;
VEC (ddr_p, heap) *dependence_relations;
VEC (data_reference_p, heap) *datarefs;
- struct loop *loop_nest = loops->parray[i];
+ struct loop *loop_nest = current_loops->parray[i];
struct loop *temp;
lambda_loopnest before, after;
lambda_trans_matrix trans;
goto free_and_continue;
}
- before = gcc_loopnest_to_lambda_loopnest (loops, loop_nest, &oldivs,
+ before = gcc_loopnest_to_lambda_loopnest (loop_nest, &oldivs,
&invariants);
if (!before)
initializes the EXIT_CONDITIONS array. */
static void
-select_loops_exit_conditions (struct loops *loops,
- VEC(tree,heap) **exit_conditions)
+select_loops_exit_conditions (VEC(tree,heap) **exit_conditions)
{
- struct loop *function_body = loops->parray[0];
+ struct loop *function_body = current_loops->tree_root;
get_exit_conditions_rec (function_body->inner, exit_conditions);
}
/* Initialize the analysis of scalar evolutions for LOOPS. */
void
-scev_initialize (struct loops *loops)
+scev_initialize (void)
{
unsigned i;
- current_loops = loops;
scalar_evolution_info = htab_create (100, hash_scev_info,
eq_scev_info, del_scev_info);
initialize_scalar_evolutions_analyzer ();
- for (i = 1; i < loops->num; i++)
- if (loops->parray[i])
- loops->parray[i]->nb_iterations = NULL_TREE;
+ for (i = 1; i < current_loops->num; i++)
+ if (current_loops->parray[i])
+ current_loops->parray[i]->nb_iterations = NULL_TREE;
}
/* Cleans up the information cached by the scalar evolutions analysis. */
VEC(tree,heap) *exit_conditions;
exit_conditions = VEC_alloc (tree, heap, 37);
- select_loops_exit_conditions (current_loops, &exit_conditions);
+ select_loops_exit_conditions (&exit_conditions);
if (dump_file && (dump_flags & TDF_STATS))
analyze_scalar_evolution_for_all_loop_phi_nodes (&exit_conditions);
extern tree number_of_iterations_in_loop (struct loop *);
extern tree get_loop_exit_condition (struct loop *);
-extern void scev_initialize (struct loops *loops);
+extern void scev_initialize (void);
extern void scev_reset (void);
extern void scev_finalize (void);
extern tree analyze_scalar_evolution (struct loop *, tree);
tree_ssa_dce_loop (void)
{
perform_tree_ssa_dce (/*aggressive=*/false);
- free_numbers_of_iterations_estimates (current_loops);
+ free_numbers_of_iterations_estimates ();
scev_reset ();
return 0;
}
loop_optimizer_init (0);
if (current_loops)
{
- mark_loop_exit_edges (current_loops);
+ mark_loop_exit_edges ();
loop_optimizer_finalize ();
}
return 0;
#ifdef ENABLE_CHECKING
- verify_loop_structure (current_loops);
+ verify_loop_structure ();
#endif
bbs = XNEWVEC (basic_block, n_basic_blocks);
}
/* Try to perform store motion for all memory references modified inside
- any of LOOPS. */
+ loops. */
static void
-determine_lsm (struct loops *loops)
+determine_lsm (void)
{
struct loop *loop;
- if (!loops->tree_root->inner)
+ if (!current_loops->tree_root->inner)
return;
/* Pass the loops from the outermost and perform the store motion as
suitable. */
- loop = loops->tree_root->inner;
+ loop = current_loops->tree_root->inner;
while (1)
{
determine_lsm_loop (loop);
while (!loop->next)
{
loop = loop->outer;
- if (loop == loops->tree_root)
+ if (loop == current_loops->tree_root)
{
bsi_commit_edge_inserts ();
return;
fill_always_executed_in (loop, contains_call);
}
-/* Compute the global information needed by the loop invariant motion pass.
- LOOPS is the loop tree. */
+/* Compute the global information needed by the loop invariant motion pass. */
static void
-tree_ssa_lim_initialize (struct loops *loops)
+tree_ssa_lim_initialize (void)
{
sbitmap contains_call = sbitmap_alloc (last_basic_block);
block_stmt_iterator bsi;
SET_BIT (contains_call, bb->index);
}
- for (loop = loops->tree_root->inner; loop; loop = loop->next)
+ for (loop = current_loops->tree_root->inner; loop; loop = loop->next)
fill_always_executed_in (loop, contains_call);
sbitmap_free (contains_call);
}
}
-/* Moves invariants from LOOPS. Only "expensive" invariants are moved out --
+/* Moves invariants from loops. Only "expensive" invariants are moved out --
i.e. those that are likely to be win regardless of the register pressure. */
void
-tree_ssa_lim (struct loops *loops)
+tree_ssa_lim (void)
{
- tree_ssa_lim_initialize (loops);
+ tree_ssa_lim_initialize ();
/* For each statement determine the outermost loop in that it is
invariant and cost for computing the invariant. */
/* For each memory reference determine whether it is possible to hoist it
out of the loop. Force the necessary invariants to be moved out of the
loops as well. */
- determine_lsm (loops);
+ determine_lsm ();
/* Move the expressions that are expensive enough. */
move_computations ();
return unr_insns;
}
-/* Tries to unroll LOOP completely, i.e. NITER times. LOOPS is the
- loop tree. UL determines which loops we are allowed to unroll.
+/* Tries to unroll LOOP completely, i.e. NITER times.
+ UL determines which loops we are allowed to unroll.
EXIT is the exit of the loop that should be eliminated. */
static bool
-try_unroll_loop_completely (struct loops *loops ATTRIBUTE_UNUSED,
- struct loop *loop,
+try_unroll_loop_completely (struct loop *loop,
edge exit, tree niter,
enum unroll_level ul)
{
RESET_BIT (wont_exit, 0);
if (!tree_duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
- loops, n_unroll, wont_exit,
+ n_unroll, wont_exit,
exit, edges_to_remove,
&n_to_remove,
DLTHE_FLAG_UPDATE_FREQ
return true;
}
-/* Adds a canonical induction variable to LOOP if suitable. LOOPS is the loops
- tree. CREATE_IV is true if we may create a new iv. UL determines
+/* Adds a canonical induction variable to LOOP if suitable.
+ CREATE_IV is true if we may create a new iv. UL determines
which loops we are allowed to completely unroll. If TRY_EVAL is true, we try
to determine the number of iterations of a loop by direct evaluation.
Returns true if cfg is changed. */
static bool
-canonicalize_loop_induction_variables (struct loops *loops, struct loop *loop,
+canonicalize_loop_induction_variables (struct loop *loop,
bool create_iv, enum unroll_level ul,
bool try_eval)
{
fprintf (dump_file, " times.\n");
}
- if (try_unroll_loop_completely (loops, loop, exit, niter, ul))
+ if (try_unroll_loop_completely (loop, exit, niter, ul))
return true;
if (create_iv)
}
/* The main entry point of the pass. Adds canonical induction variables
- to the suitable LOOPS. */
+ to the suitable loops. */
unsigned int
-canonicalize_induction_variables (struct loops *loops)
+canonicalize_induction_variables (void)
{
unsigned i;
struct loop *loop;
bool changed = false;
- for (i = 1; i < loops->num; i++)
+ for (i = 1; i < current_loops->num; i++)
{
- loop = loops->parray[i];
+ loop = current_loops->parray[i];
if (loop)
- changed |= canonicalize_loop_induction_variables (loops, loop,
+ changed |= canonicalize_loop_induction_variables (loop,
true, UL_SINGLE_ITER,
true);
}
size of the code does not increase. */
unsigned int
-tree_unroll_loops_completely (struct loops *loops, bool may_increase_size)
+tree_unroll_loops_completely (bool may_increase_size)
{
unsigned i;
struct loop *loop;
bool changed = false;
enum unroll_level ul;
- for (i = 1; i < loops->num; i++)
+ for (i = 1; i < current_loops->num; i++)
{
- loop = loops->parray[i];
+ loop = current_loops->parray[i];
if (!loop)
continue;
ul = UL_ALL;
else
ul = UL_NO_GROWTH;
- changed |= canonicalize_loop_induction_variables (loops, loop,
+ changed |= canonicalize_loop_induction_variables (loop,
false, ul,
!flag_tree_loop_ivcanon);
}
return true;
}
-/* Remove the empty LOOPS. */
+/* Remove the empty loops. */
unsigned int
-remove_empty_loops (struct loops *loops)
+remove_empty_loops (void)
{
bool changed = false;
struct loop *loop;
- for (loop = loops->tree_root->inner; loop; loop = loop->next)
+ for (loop = current_loops->tree_root->inner; loop; loop = loop->next)
try_remove_empty_loop (loop, &changed);
if (changed)
return changed;
}
-/* Main entry point. Optimizes induction variables in LOOPS. */
+/* Main entry point. Optimizes induction variables in loops. */
void
-tree_ssa_iv_optimize (struct loops *loops)
+tree_ssa_iv_optimize (void)
{
struct loop *loop;
struct ivopts_data data;
tree_ssa_iv_optimize_init (&data);
/* Optimize the loops starting with the innermost ones. */
- loop = loops->tree_root;
+ loop = current_loops->tree_root;
while (loop->inner)
loop = loop->inner;
/* Scan the loops, inner ones first. */
- while (loop != loops->tree_root)
+ while (loop != current_loops->tree_root)
{
if (dump_file && (dump_flags & TDF_DETAILS))
flow_loop_dump (loop, dump_file, NULL, 1);
bool
tree_duplicate_loop_to_header_edge (struct loop *loop, edge e,
- struct loops *loops,
unsigned int ndupl, sbitmap wont_exit,
edge orig, edge *to_remove,
unsigned int *n_to_remove, int flags)
{
unsigned first_new_block;
- if (!(loops->state & LOOPS_HAVE_SIMPLE_LATCHES))
+ if (!(current_loops->state & LOOPS_HAVE_SIMPLE_LATCHES))
return false;
- if (!(loops->state & LOOPS_HAVE_PREHEADERS))
+ if (!(current_loops->state & LOOPS_HAVE_PREHEADERS))
return false;
#ifdef ENABLE_CHECKING
#endif
first_new_block = last_basic_block;
- if (!duplicate_loop_to_header_edge (loop, e, loops, ndupl, wont_exit,
+ if (!duplicate_loop_to_header_edge (loop, e, ndupl, wont_exit,
orig, to_remove, n_to_remove, flags))
return false;
*exit_bound = bound;
}
-/* Unroll LOOP FACTOR times. LOOPS is the loops tree. DESC describes
- number of iterations of LOOP. EXIT is the exit of the loop to that
- DESC corresponds.
-
+/* Unroll LOOP FACTOR times. DESC describes number of iterations of LOOP.
+ EXIT is the exit of the loop to that DESC corresponds.
+
If N is number of iterations of the loop and MAY_BE_ZERO is the condition
under that loop exits in the first iteration even if N != 0,
} */
void
-tree_unroll_loop (struct loops *loops, struct loop *loop, unsigned factor,
+tree_unroll_loop (struct loop *loop, unsigned factor,
edge exit, struct tree_niter_desc *desc)
{
tree dont_exit, exit_if, ctr_before, ctr_after;
&enter_main_cond, &exit_base, &exit_step,
&exit_cmp, &exit_bound);
- new_loop = loop_version (loops, loop, enter_main_cond, NULL, true);
+ new_loop = loop_version (loop, enter_main_cond, NULL, true);
gcc_assert (new_loop != NULL);
update_ssa (TODO_update_ssa);
wont_exit = sbitmap_alloc (factor);
sbitmap_ones (wont_exit);
ok = tree_duplicate_loop_to_header_edge
- (loop, loop_latch_edge (loop), loops, factor - 1,
+ (loop, loop_latch_edge (loop), factor - 1,
wont_exit, NULL, NULL, NULL, DLTHE_FLAG_UPDATE_FREQ);
free (wont_exit);
gcc_assert (ok);
#ifdef ENABLE_CHECKING
verify_flow_info ();
verify_dominators (CDI_DOMINATORS);
- verify_loop_structure (loops);
+ verify_loop_structure ();
verify_loop_closed_ssa ();
#endif
}
compute_estimated_nb_iterations (loop);
}
-/* Records estimates on numbers of iterations of LOOPS. */
+/* Records estimates on numbers of iterations of loops. */
void
-estimate_numbers_of_iterations (struct loops *loops)
+estimate_numbers_of_iterations (void)
{
unsigned i;
struct loop *loop;
- for (i = 1; i < loops->num; i++)
+ for (i = 1; i < current_loops->num; i++)
{
- loop = loops->parray[i];
+ loop = current_loops->parray[i];
if (loop)
estimate_numbers_of_iterations_loop (loop);
}
loop->bounds = NULL;
}
-/* Frees the information on upper bounds on numbers of iterations of LOOPS. */
+/* Frees the information on upper bounds on numbers of iterations of loops. */
void
-free_numbers_of_iterations_estimates (struct loops *loops)
+free_numbers_of_iterations_estimates (void)
{
unsigned i;
struct loop *loop;
- for (i = 1; i < loops->num; i++)
+ for (i = 1; i < current_loops->num; i++)
{
- loop = loops->parray[i];
+ loop = current_loops->parray[i];
if (loop)
free_numbers_of_iterations_estimates_loop (loop);
}
}
/* Issue prefetch instructions for array references in LOOP. Returns
- true if the LOOP was unrolled. LOOPS is the array containing all
- loops. */
+ true if the LOOP was unrolled. */
static bool
-loop_prefetch_arrays (struct loops *loops, struct loop *loop)
+loop_prefetch_arrays (struct loop *loop)
{
struct mem_ref_group *refs;
unsigned ahead, ninsns, unroll_factor;
iterations so that we do not issue superfluous prefetches. */
if (unroll_factor != 1)
{
- tree_unroll_loop (loops, loop, unroll_factor,
+ tree_unroll_loop (loop, unroll_factor,
single_dom_exit (loop), &desc);
unrolled = true;
}
return unrolled;
}
-/* Issue prefetch instructions for array references in LOOPS. */
+/* Issue prefetch instructions for array references in loops. */
unsigned int
-tree_ssa_prefetch_arrays (struct loops *loops)
+tree_ssa_prefetch_arrays (void)
{
unsigned i;
struct loop *loop;
here. */
gcc_assert ((PREFETCH_BLOCK & (PREFETCH_BLOCK - 1)) == 0);
- for (i = loops->num - 1; i > 0; i--)
+ for (i = current_loops->num - 1; i > 0; i--)
{
- loop = loops->parray[i];
+ loop = current_loops->parray[i];
if (!loop)
continue;
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "Processing loop %d:\n", loop->num);
- unrolled |= loop_prefetch_arrays (loops, loop);
+ unrolled |= loop_prefetch_arrays (loop);
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "\n\n");
tree-ssa-loop-im.c ensures that all the suitable conditions are in this
shape. */
-static struct loop *tree_unswitch_loop (struct loops *, struct loop *, basic_block,
- tree);
-static bool tree_unswitch_single_loop (struct loops *, struct loop *, int);
+static struct loop *tree_unswitch_loop (struct loop *, basic_block, tree);
+static bool tree_unswitch_single_loop (struct loop *, int);
static tree tree_may_unswitch_on (basic_block, struct loop *);
-/* Main entry point. Perform loop unswitching on all suitable LOOPS. */
+/* Main entry point. Perform loop unswitching on all suitable loops. */
unsigned int
-tree_ssa_unswitch_loops (struct loops *loops)
+tree_ssa_unswitch_loops (void)
{
int i, num;
struct loop *loop;
bool changed = false;
/* Go through inner loops (only original ones). */
- num = loops->num;
+ num = current_loops->num;
for (i = 1; i < num; i++)
{
/* Removed loop? */
- loop = loops->parray[i];
+ loop = current_loops->parray[i];
if (!loop)
continue;
if (loop->inner)
continue;
- changed |= tree_unswitch_single_loop (loops, loop, 0);
+ changed |= tree_unswitch_single_loop (loop, 0);
}
if (changed)
grow exponentially. */
static bool
-tree_unswitch_single_loop (struct loops *loops, struct loop *loop, int num)
+tree_unswitch_single_loop (struct loop *loop, int num)
{
basic_block *bbs;
struct loop *nloop;
initialize_original_copy_tables ();
/* Unswitch the loop on this condition. */
- nloop = tree_unswitch_loop (loops, loop, bbs[i], cond);
+ nloop = tree_unswitch_loop (loop, bbs[i], cond);
if (!nloop)
{
free_original_copy_tables ();
free_original_copy_tables ();
/* Invoke itself on modified loops. */
- tree_unswitch_single_loop (loops, nloop, num + 1);
- tree_unswitch_single_loop (loops, loop, num + 1);
+ tree_unswitch_single_loop (nloop, num + 1);
+ tree_unswitch_single_loop (loop, num + 1);
free (bbs);
return true;
}
if impossible, new loop otherwise. */
static struct loop *
-tree_unswitch_loop (struct loops *loops, struct loop *loop,
+tree_unswitch_loop (struct loop *loop,
basic_block unswitch_on, tree cond)
{
basic_block condition_bb;
gcc_assert (EDGE_COUNT (unswitch_on->succs) == 2);
gcc_assert (loop->inner == NULL);
- return loop_version (loops, loop, unshare_expr (cond),
+ return loop_version (loop, unshare_expr (cond),
&condition_bb, false);
}
if (!current_loops)
return 0;
- scev_initialize (current_loops);
+ scev_initialize ();
return 0;
}
if (!current_loops)
return 0;
- tree_ssa_lim (current_loops);
+ tree_ssa_lim ();
return 0;
}
if (!current_loops)
return 0;
- return tree_ssa_unswitch_loops (current_loops);
+ return tree_ssa_unswitch_loops ();
}
static bool
static unsigned int
tree_vectorize (void)
{
- return vectorize_loops (current_loops);
+ return vectorize_loops ();
}
static bool
if (!current_loops)
return 0;
- linear_transform_loops (current_loops);
+ linear_transform_loops ();
return 0;
}
if (!current_loops)
return 0;
- return canonicalize_induction_variables (current_loops);
+ return canonicalize_induction_variables ();
}
static bool
if (!current_loops)
return 0;
- return remove_empty_loops (current_loops);
+ return remove_empty_loops ();
}
struct tree_opt_pass pass_empty_loop =
if (!current_loops)
return 0;
- estimate_numbers_of_iterations (current_loops);
+ estimate_numbers_of_iterations ();
scev_reset ();
return 0;
}
if (!current_loops)
return 0;
- return tree_unroll_loops_completely (current_loops,
- flag_unroll_loops
- || flag_peel_loops
- || optimize >= 3);
+ return tree_unroll_loops_completely (flag_unroll_loops
+ || flag_peel_loops
+ || optimize >= 3);
}
static bool
if (!current_loops)
return 0;
- return tree_ssa_prefetch_arrays (current_loops);
+ return tree_ssa_prefetch_arrays ();
}
static bool
if (!current_loops)
return 0;
- tree_ssa_iv_optimize (current_loops);
+ tree_ssa_iv_optimize ();
return 0;
}
if (!current_loops)
return 0;
- free_numbers_of_iterations_estimates (current_loops);
+ free_numbers_of_iterations_estimates ();
scev_finalize ();
loop_optimizer_finalize ();
return 0;
static tree vect_gen_niters_for_prolog_loop (loop_vec_info, tree);
static void vect_update_init_of_dr (struct data_reference *, tree niters);
static void vect_update_inits_of_drs (loop_vec_info, tree);
-static void vect_do_peeling_for_alignment (loop_vec_info, struct loops *);
-static void vect_do_peeling_for_loop_bound
- (loop_vec_info, tree *, struct loops *);
static int vect_min_worthwhile_factor (enum tree_code);
NITERS / VECTORIZATION_FACTOR times (this value is placed into RATIO). */
static void
-vect_do_peeling_for_loop_bound (loop_vec_info loop_vinfo, tree *ratio,
- struct loops *loops)
+vect_do_peeling_for_loop_bound (loop_vec_info loop_vinfo, tree *ratio)
{
tree ni_name, ratio_mult_vf_name;
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
&ratio_mult_vf_name, ratio);
loop_num = loop->num;
- new_loop = slpeel_tree_peel_loop_to_edge (loop, loops, single_exit (loop),
+ new_loop = slpeel_tree_peel_loop_to_edge (loop, single_exit (loop),
ratio_mult_vf_name, ni_name, false);
gcc_assert (new_loop);
gcc_assert (loop_num == loop->num);
peeling is recorded in LOOP_VINFO_UNALIGNED_DR. */
static void
-vect_do_peeling_for_alignment (loop_vec_info loop_vinfo, struct loops *loops)
+vect_do_peeling_for_alignment (loop_vec_info loop_vinfo)
{
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
tree niters_of_prolog_loop, ni_name;
/* Peel the prolog loop and iterate it niters_of_prolog_loop. */
new_loop =
- slpeel_tree_peel_loop_to_edge (loop, loops, loop_preheader_edge (loop),
+ slpeel_tree_peel_loop_to_edge (loop, loop_preheader_edge (loop),
niters_of_prolog_loop, ni_name, true);
gcc_assert (new_loop);
#ifdef ENABLE_CHECKING
stmts in the loop, and update the loop exit condition. */
void
-vect_transform_loop (loop_vec_info loop_vinfo,
- struct loops *loops ATTRIBUTE_UNUSED)
+vect_transform_loop (loop_vec_info loop_vinfo)
{
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
cond_expr = vect_create_cond_for_align_checks (loop_vinfo,
&cond_expr_stmt_list);
initialize_original_copy_tables ();
- nloop = loop_version (loops, loop, cond_expr, &condition_bb, true);
+ nloop = loop_version (loop, cond_expr, &condition_bb, true);
free_original_copy_tables();
/** Loop versioning violates an assumption we try to maintain during
Only one data ref with unknown store is allowed. */
if (LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo))
- vect_do_peeling_for_alignment (loop_vinfo, loops);
+ vect_do_peeling_for_alignment (loop_vinfo);
/* If the loop has a symbolic number of iterations 'n' (i.e. it's not a
compile time constant), or it is a constant that doesn't divide by the
if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
|| (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
&& LOOP_VINFO_INT_NITERS (loop_vinfo) % vectorization_factor != 0))
- vect_do_peeling_for_loop_bound (loop_vinfo, &ratio, loops);
+ vect_do_peeling_for_loop_bound (loop_vinfo, &ratio);
else
ratio = build_int_cst (TREE_TYPE (LOOP_VINFO_NITERS (loop_vinfo)),
LOOP_VINFO_INT_NITERS (loop_vinfo) / vectorization_factor);
/*************************************************************************
Simple Loop Peeling Utilities
*************************************************************************/
-static struct loop *slpeel_tree_duplicate_loop_to_edge_cfg
- (struct loop *, struct loops *, edge);
static void slpeel_update_phis_for_duplicate_loop
(struct loop *, struct loop *, bool after);
static void slpeel_update_phi_nodes_for_guard1
on E which is either the entry or exit of LOOP. */
static struct loop *
-slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *loop, struct loops *loops,
- edge e)
+slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *loop, edge e)
{
struct loop *new_loop;
basic_block *new_bbs, *bbs;
}
/* Generate new loop structure. */
- new_loop = duplicate_loop (loops, loop, loop->outer);
+ new_loop = duplicate_loop (loop, loop->outer);
if (!new_loop)
{
free (bbs);
*/
struct loop*
-slpeel_tree_peel_loop_to_edge (struct loop *loop, struct loops *loops,
+slpeel_tree_peel_loop_to_edge (struct loop *loop,
edge e, tree first_niters,
tree niters, bool update_first_loop_count)
{
orig_exit_bb:
*/
- if (!(new_loop = slpeel_tree_duplicate_loop_to_edge_cfg (loop, loops, e)))
+ if (!(new_loop = slpeel_tree_duplicate_loop_to_edge_cfg (loop, e)))
{
loop_loc = find_loop_location (loop);
if (dump_file && (dump_flags & TDF_DETAILS))
Entry Point to loop vectorization phase. */
unsigned
-vectorize_loops (struct loops *loops)
+vectorize_loops (void)
{
unsigned int i;
unsigned int num_vectorized_loops = 0;
/* 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 = loops->num;
+ vect_loops_num = current_loops->num;
for (i = 1; i < vect_loops_num; i++)
{
loop_vec_info loop_vinfo;
- struct loop *loop = loops->parray[i];
+ struct loop *loop = current_loops->parray[i];
if (!loop)
continue;
if (!loop_vinfo || !LOOP_VINFO_VECTORIZABLE_P (loop_vinfo))
continue;
- vect_transform_loop (loop_vinfo, loops);
+ vect_transform_loop (loop_vinfo);
num_vectorized_loops++;
}
vect_loop_location = UNKNOWN_LOC;
for (i = 1; i < vect_loops_num; i++)
{
- struct loop *loop = loops->parray[i];
+ struct loop *loop = current_loops->parray[i];
loop_vec_info loop_vinfo;
if (!loop)
divide by the vectorization factor, and to peel the first few iterations
to force the alignment of data references in the loop. */
extern struct loop *slpeel_tree_peel_loop_to_edge
- (struct loop *, struct loops *, edge, tree, tree, bool);
+ (struct loop *, edge, tree, tree, bool);
extern void slpeel_make_loop_iterate_ntimes (struct loop *, tree);
extern bool slpeel_can_duplicate_loop_p (struct loop *, edge);
#ifdef ENABLE_CHECKING
extern bool vectorizable_live_operation (tree, block_stmt_iterator *, tree *);
extern bool vectorizable_reduction (tree, block_stmt_iterator *, tree *);
/* Driver for transformation stage. */
-extern void vect_transform_loop (loop_vec_info, struct loops *);
+extern void vect_transform_loop (loop_vec_info);
/*************************************************************************
Vectorization Debug Information - in tree-vectorizer.c
loop_optimizer_init (LOOPS_NORMAL);
if (current_loops)
- scev_initialize (current_loops);
+ scev_initialize ();
vrp_initialize ();
ssa_propagate (vrp_visit_stmt, vrp_visit_phi_node);