summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-loop-ivcanon.c
diff options
context:
space:
mode:
authormrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>2013-10-20 23:47:35 +0000
committermrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>2013-10-20 23:47:35 +0000
commit6b40961666f073231ed8a76e6e33deeda063cde7 (patch)
tree8247eb4232e8be98b7f61bd68bab2fd1a9f06ca3 /gcc/tree-ssa-loop-ivcanon.c
parente6b1b76450af5f98696ecedd4bd9a0ed18cdb2a6 (diff)
parentfc1ce0cf396bf638746d546a557158d87f13849b (diff)
Merge in trunk.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/wide-int@203881 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-loop-ivcanon.c')
-rw-r--r--gcc/tree-ssa-loop-ivcanon.c201
1 files changed, 182 insertions, 19 deletions
diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c
index d9de8d37dd13..b2e2c34f39ca 100644
--- a/gcc/tree-ssa-loop-ivcanon.c
+++ b/gcc/tree-ssa-loop-ivcanon.c
@@ -49,6 +49,7 @@ along with GCC; see the file COPYING3. If not see
#include "flags.h"
#include "tree-inline.h"
#include "target.h"
+#include "tree-cfgcleanup.h"
/* Specifies types of loops that may be unrolled. */
@@ -107,23 +108,6 @@ create_canonical_iv (struct loop *loop, edge exit, tree niter)
update_stmt (cond);
}
-/* Computes an estimated number of insns in LOOP, weighted by WEIGHTS. */
-
-unsigned
-tree_num_loop_insns (struct loop *loop, eni_weights *weights)
-{
- basic_block *body = get_loop_body (loop);
- gimple_stmt_iterator gsi;
- unsigned size = 0, i;
-
- for (i = 0; i < loop->num_nodes; i++)
- for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi); gsi_next (&gsi))
- size += estimate_num_insns (gsi_stmt (gsi), weights);
- free (body);
-
- return size;
-}
-
/* Describe size of loop as detected by tree_estimate_loop_size. */
struct loop_size
{
@@ -422,7 +406,7 @@ estimated_unrolled_size (struct loop_size *size,
loop-niter identified as having undefined effect in the last iteration.
The other cases are hopefully rare and will be cleaned up later. */
-edge
+static edge
loop_edge_to_cancel (struct loop *loop)
{
vec<edge> exits;
@@ -597,7 +581,7 @@ static vec<int> loops_to_unloop_nunroll;
LOOP_CLOSED_SSA_INVALIDATED is used to bookkepp the case
when we need to go into loop closed SSA form. */
-void
+static void
unloop_loops (bitmap loop_closed_ssa_invalidated,
bool *irred_invalidated)
{
@@ -1252,3 +1236,182 @@ tree_unroll_loops_completely (bool may_increase_size, bool unroll_outer)
return 0;
}
+
+/* Canonical induction variable creation pass. */
+
+static unsigned int
+tree_ssa_loop_ivcanon (void)
+{
+ if (number_of_loops (cfun) <= 1)
+ return 0;
+
+ return canonicalize_induction_variables ();
+}
+
+static bool
+gate_tree_ssa_loop_ivcanon (void)
+{
+ return flag_tree_loop_ivcanon != 0;
+}
+
+namespace {
+
+const pass_data pass_data_iv_canon =
+{
+ GIMPLE_PASS, /* type */
+ "ivcanon", /* name */
+ OPTGROUP_LOOP, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_LOOP_IVCANON, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
+};
+
+class pass_iv_canon : public gimple_opt_pass
+{
+public:
+ pass_iv_canon (gcc::context *ctxt)
+ : gimple_opt_pass (pass_data_iv_canon, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_tree_ssa_loop_ivcanon (); }
+ unsigned int execute () { return tree_ssa_loop_ivcanon (); }
+
+}; // class pass_iv_canon
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_iv_canon (gcc::context *ctxt)
+{
+ return new pass_iv_canon (ctxt);
+}
+
+/* Complete unrolling of loops. */
+
+static unsigned int
+tree_complete_unroll (void)
+{
+ if (number_of_loops (cfun) <= 1)
+ return 0;
+
+ return tree_unroll_loops_completely (flag_unroll_loops
+ || flag_peel_loops
+ || optimize >= 3, true);
+}
+
+static bool
+gate_tree_complete_unroll (void)
+{
+ return true;
+}
+
+namespace {
+
+const pass_data pass_data_complete_unroll =
+{
+ GIMPLE_PASS, /* type */
+ "cunroll", /* name */
+ OPTGROUP_LOOP, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_COMPLETE_UNROLL, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
+};
+
+class pass_complete_unroll : public gimple_opt_pass
+{
+public:
+ pass_complete_unroll (gcc::context *ctxt)
+ : gimple_opt_pass (pass_data_complete_unroll, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_tree_complete_unroll (); }
+ unsigned int execute () { return tree_complete_unroll (); }
+
+}; // class pass_complete_unroll
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_complete_unroll (gcc::context *ctxt)
+{
+ return new pass_complete_unroll (ctxt);
+}
+
+/* Complete unrolling of inner loops. */
+
+static unsigned int
+tree_complete_unroll_inner (void)
+{
+ unsigned ret = 0;
+
+ loop_optimizer_init (LOOPS_NORMAL
+ | LOOPS_HAVE_RECORDED_EXITS);
+ if (number_of_loops (cfun) > 1)
+ {
+ scev_initialize ();
+ ret = tree_unroll_loops_completely (optimize >= 3, false);
+ free_numbers_of_iterations_estimates ();
+ scev_finalize ();
+ }
+ loop_optimizer_finalize ();
+
+ return ret;
+}
+
+static bool
+gate_tree_complete_unroll_inner (void)
+{
+ return optimize >= 2;
+}
+
+namespace {
+
+const pass_data pass_data_complete_unrolli =
+{
+ GIMPLE_PASS, /* type */
+ "cunrolli", /* name */
+ OPTGROUP_LOOP, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_COMPLETE_UNROLL, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_flow, /* todo_flags_finish */
+};
+
+class pass_complete_unrolli : public gimple_opt_pass
+{
+public:
+ pass_complete_unrolli (gcc::context *ctxt)
+ : gimple_opt_pass (pass_data_complete_unrolli, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_tree_complete_unroll_inner (); }
+ unsigned int execute () { return tree_complete_unroll_inner (); }
+
+}; // class pass_complete_unrolli
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_complete_unrolli (gcc::context *ctxt)
+{
+ return new pass_complete_unrolli (ctxt);
+}
+
+