/* Loop manipulation code for GNU compiler.
- Copyright (C) 2002-2013 Free Software Foundation, Inc.
+ Copyright (C) 2002-2015 Free Software Foundation, Inc.
This file is part of GCC.
#include "config.h"
#include "system.h"
#include "coretypes.h"
-#include "tm.h"
+#include "backend.h"
#include "rtl.h"
-#include "basic-block.h"
+#include "tree.h"
+#include "gimple.h"
+#include "cfghooks.h"
+#include "cfganal.h"
#include "cfgloop.h"
-#include "tree-flow.h"
+#include "fold-const.h"
+#include "internal-fn.h"
+#include "gimple-iterator.h"
+#include "gimplify-me.h"
+#include "tree-ssa-loop-manip.h"
#include "dumpfile.h"
static void copy_loops_to (struct loop **, int,
gcc_assert (EDGE_COUNT (e->dest->preds) <= 1);
/* Find bbs in the path. */
- *bbs = XNEWVEC (basic_block, n_basic_blocks);
+ *bbs = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun));
return dfs_enumerate_from (e->dest, 0, rpe_enum_p, *bbs,
- n_basic_blocks, e->dest);
+ n_basic_blocks_for_fn (cfun), e->dest);
}
/* Fix placement of basic block BB inside loop hierarchy --
FOR_EACH_EDGE (e, ei, bb->succs)
{
- if (e->dest == EXIT_BLOCK_PTR)
+ if (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
continue;
act = e->dest->loop_father;
}
/* Fix placements of basic blocks inside loop hierarchy stored in loops; i.e.
- enforce condition condition stated in description of fix_bb_placement. We
+ enforce condition stated in description of fix_bb_placement. We
start from basic block FROM that had some of its successors removed, so that
his placement no longer has to be correct, and iteratively fix placement of
its predecessors that may change if placement of FROM changed. Also fix
|| from == base_loop->header)
return;
- in_queue = sbitmap_alloc (last_basic_block);
+ in_queue = sbitmap_alloc (last_basic_block_for_fn (cfun));
bitmap_clear (in_queue);
bitmap_set_bit (in_queue, from->index);
/* Prevent us from going out of the base_loop. */
if (!fix_loop_placement (from->loop_father, irred_invalidated))
continue;
target_loop = loop_outer (from->loop_father);
+ if (loop_closed_ssa_invalidated)
+ {
+ basic_block *bbs = get_loop_body (from->loop_father);
+ for (unsigned i = 0; i < from->loop_father->num_nodes; ++i)
+ bitmap_set_bit (loop_closed_ssa_invalidated, bbs[i]->index);
+ free (bbs);
+ }
}
else
{
/* Ordinary basic block. */
if (!fix_bb_placement (from))
continue;
+ target_loop = from->loop_father;
if (loop_closed_ssa_invalidated)
bitmap_set_bit (loop_closed_ssa_invalidated, from->index);
- target_loop = from->loop_father;
}
FOR_EACH_EDGE (e, ei, from->succs)
nrem = find_path (e, &rem_bbs);
n_bord_bbs = 0;
- bord_bbs = XNEWVEC (basic_block, n_basic_blocks);
- seen = sbitmap_alloc (last_basic_block);
+ bord_bbs = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun));
+ seen = sbitmap_alloc (last_basic_block_for_fn (cfun));
bitmap_clear (seen);
/* Find "border" hexes -- i.e. those with predecessor in removed path. */
bitmap_set_bit (seen, rem_bbs[i]->index);
if (!irred_invalidated)
FOR_EACH_EDGE (ae, ei, e->src->succs)
- if (ae != e && ae->dest != EXIT_BLOCK_PTR && !bitmap_bit_p (seen, ae->dest->index)
+ if (ae != e && ae->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)
+ && !bitmap_bit_p (seen, ae->dest->index)
&& ae->flags & EDGE_IRREDUCIBLE_LOOP)
- irred_invalidated = true;
+ {
+ irred_invalidated = true;
+ break;
+ }
+
for (i = 0; i < nrem; i++)
{
bb = rem_bbs[i];
FOR_EACH_EDGE (ae, ei, rem_bbs[i]->succs)
- if (ae->dest != EXIT_BLOCK_PTR && !bitmap_bit_p (seen, ae->dest->index))
+ if (ae->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)
+ && !bitmap_bit_p (seen, ae->dest->index))
{
bitmap_set_bit (seen, ae->dest->index);
bord_bbs[n_bord_bbs++] = ae->dest;
flow_loop_tree_node_add (outer, loop);
/* Find its nodes. */
- bbs = XNEWVEC (basic_block, n_basic_blocks);
- n = get_loop_body_with_size (loop, bbs, n_basic_blocks);
+ bbs = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun));
+ n = get_loop_body_with_size (loop, bbs, n_basic_blocks_for_fn (cfun));
for (i = 0; i < n; i++)
{
basic_block *body;
unsigned i;
- seen = sbitmap_alloc (last_basic_block);
+ seen = sbitmap_alloc (last_basic_block_for_fn (cfun));
bitmap_clear (seen);
body = get_loop_body (loop);
basic_block cond_bb, true_bb, false_bb, join_bb;
edge e_true, e_false, exit_edge;
- gimple cond_stmt;
+ gcond *cond_stmt;
tree simple_cond;
gimple_stmt_iterator gsi;
struct loop *loop;
gimple_stmt_iterator gsi;
gimple_seq stmts;
- gimple cond_expr;
+ gcond *cond_expr;
tree exit_test;
edge exit_e;
int prob;
remove_bb_from_loops (body[i]);
add_bb_to_loop (body[i], loop_outer (loop));
}
- free(body);
+ free (body);
while (loop->inner)
{
target->any_estimate = loop->any_estimate;
target->nb_iterations_estimate = loop->nb_iterations_estimate;
target->estimate_state = loop->estimate_state;
+ target->warned_aggressive_loop_optimizations
+ |= loop->warned_aggressive_loop_optimizations;
}
/* Copies copy of LOOP as subloop of TARGET loop, placing newly
/* We do not allow entry block to be the loop preheader, since we
cannot emit code there. */
- if (single_entry->src == ENTRY_BLOCK_PTR)
+ if (single_entry->src == ENTRY_BLOCK_PTR_FOR_FN (cfun))
need_forwarder_block = true;
else
{
void
create_preheaders (int flags)
{
- loop_iterator li;
struct loop *loop;
if (!current_loops)
return;
- FOR_EACH_LOOP (li, loop, 0)
+ FOR_EACH_LOOP (loop, 0)
create_preheader (loop, flags);
loops_state_set (LOOPS_HAVE_PREHEADERS);
}
void
force_single_succ_latches (void)
{
- loop_iterator li;
struct loop *loop;
edge e;
- FOR_EACH_LOOP (li, loop, 0)
+ FOR_EACH_LOOP (loop, 0)
{
if (loop->latch != loop->header && single_succ_p (loop->latch))
continue;