ipa-cp.c (ipcp_cloning_candidate_p): Use opt_for_fn.
[gcc.git] / gcc / graphite.c
index 6b393d65736f3102d7d291e89ce0a469852860a5..59d5a136cfc104527b4b3f1a3190b50e845ec02a 100644 (file)
@@ -1,5 +1,5 @@
 /* Gimple Represented as Polyhedra.
-   Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+   Copyright (C) 2006-2014 Free Software Foundation, Inc.
    Contributed by Sebastian Pop <sebastian.pop@inria.fr>.
 
 This file is part of GCC.
@@ -33,40 +33,54 @@ along with GCC; see the file COPYING3.  If not see
    the functions that are used for transforming the code.  */
 
 #include "config.h"
+
+#ifdef HAVE_isl
+#include <isl/set.h>
+#include <isl/map.h>
+#include <isl/options.h>
+#include <isl/union_map.h>
+#endif
+
 #include "system.h"
 #include "coretypes.h"
-#include "tm.h"
-#include "ggc.h"
+#include "diagnostic-core.h"
 #include "tree.h"
-#include "rtl.h"
+#include "predict.h"
+#include "vec.h"
+#include "hashtab.h"
+#include "hash-set.h"
+#include "machmode.h"
+#include "tm.h"
+#include "hard-reg-set.h"
+#include "input.h"
+#include "function.h"
+#include "dominance.h"
+#include "cfg.h"
 #include "basic-block.h"
-#include "diagnostic.h"
-#include "tree-flow.h"
-#include "toplev.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
+#include "gimple.h"
+#include "gimple-iterator.h"
+#include "tree-cfg.h"
+#include "tree-ssa-loop.h"
 #include "tree-dump.h"
-#include "timevar.h"
 #include "cfgloop.h"
 #include "tree-chrec.h"
 #include "tree-data-ref.h"
 #include "tree-scalar-evolution.h"
-#include "tree-pass.h"
-#include "value-prof.h"
-#include "pointer-set.h"
-#include "gimple.h"
 #include "sese.h"
-#include "predict.h"
 #include "dbgcnt.h"
+#include "tree-parloops.h"
+#include "tree-pass.h"
+#include "tree-cfgcleanup.h"
 
-#ifdef HAVE_cloog
+#ifdef HAVE_isl
 
-#include "cloog/cloog.h"
-#include "ppl_c.h"
-#include "graphite-cloog-compat.h"
-#include "graphite-ppl.h"
-#include "graphite.h"
 #include "graphite-poly.h"
 #include "graphite-scop-detection.h"
-#include "graphite-clast-to-gimple.h"
+#include "graphite-isl-ast-to-gimple.h"
 #include "graphite-sese-to-poly.h"
 
 /* Print global statistics to FILE.  */
@@ -85,7 +99,7 @@ print_global_statistics (FILE* file)
 
   basic_block bb;
 
-  FOR_ALL_BB (bb)
+  FOR_ALL_BB_FN (bb, cfun)
     {
       gimple_stmt_iterator psi;
 
@@ -100,7 +114,7 @@ print_global_statistics (FILE* file)
          n_p_loops += bb->count;
        }
 
-      if (VEC_length (edge, bb->succs) > 1)
+      if (EDGE_COUNT (bb->succs) > 1)
        {
          n_conditions++;
          n_p_conditions += bb->count;
@@ -141,7 +155,7 @@ print_graphite_scop_statistics (FILE* file, scop_p scop)
 
   basic_block bb;
 
-  FOR_ALL_BB (bb)
+  FOR_ALL_BB_FN (bb, cfun)
     {
       gimple_stmt_iterator psi;
       loop_p loop = bb->loop_father;
@@ -152,7 +166,7 @@ print_graphite_scop_statistics (FILE* file, scop_p scop)
       n_bbs++;
       n_p_bbs += bb->count;
 
-      if (VEC_length (edge, bb->succs) > 1)
+      if (EDGE_COUNT (bb->succs) > 1)
        {
          n_conditions++;
          n_p_conditions += bb->count;
@@ -186,31 +200,31 @@ print_graphite_scop_statistics (FILE* file, scop_p scop)
 /* Print statistics for SCOPS to FILE.  */
 
 static void
-print_graphite_statistics (FILE* file, VEC (scop_p, heap) *scops)
+print_graphite_statistics (FILE* file, vec<scop_p> scops)
 {
   int i;
 
   scop_p scop;
 
-  FOR_EACH_VEC_ELT (scop_p, scops, i, scop)
+  FOR_EACH_VEC_ELT (scops, i, scop)
     print_graphite_scop_statistics (file, scop);
 }
 
 /* Initialize graphite: when there are no loops returns false.  */
 
 static bool
-graphite_initialize (void)
+graphite_initialize (isl_ctx *ctx)
 {
-  int ppl_initialized;
-
-  if (number_of_loops () <= 1
+  if (number_of_loops (cfun) <= 1
       /* FIXME: This limit on the number of basic blocks of a function
         should be removed when the SCOP detection is faster.  */
-      || n_basic_blocks > PARAM_VALUE (PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION))
+      || (n_basic_blocks_for_fn (cfun) >
+         PARAM_VALUE (PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION)))
     {
       if (dump_file && (dump_flags & TDF_DETAILS))
        print_global_statistics (dump_file);
 
+      isl_ctx_free (ctx);
       return false;
     }
 
@@ -218,11 +232,6 @@ graphite_initialize (void)
   recompute_all_dominators ();
   initialize_original_copy_tables ();
 
-  ppl_initialized = ppl_initialize ();
-  gcc_assert (ppl_initialized == 0);
-
-  cloog_initialize ();
-
   if (dump_file && dump_flags)
     dump_function_to_file (current_function_decl, dump_file, dump_flags);
 
@@ -239,19 +248,19 @@ graphite_finalize (bool need_cfg_cleanup_p)
     {
       scev_reset ();
       cleanup_tree_cfg ();
-      profile_status = PROFILE_ABSENT;
+      profile_status_for_fn (cfun) = PROFILE_ABSENT;
       release_recorded_exits ();
       tree_estimate_probability ();
     }
 
-  cloog_finalize ();
-  ppl_finalize ();
   free_original_copy_tables ();
 
   if (dump_file && dump_flags)
     print_loops (dump_file, 3);
 }
 
+isl_ctx *the_isl_ctx;
+
 /* Perform a set of linear transforms on the loops of the current
    function.  */
 
@@ -261,13 +270,20 @@ graphite_transform_loops (void)
   int i;
   scop_p scop;
   bool need_cfg_cleanup_p = false;
-  VEC (scop_p, heap) *scops = NULL;
-  htab_t bb_pbb_mapping;
-  sbitmap reductions;
+  vec<scop_p> scops = vNULL;
+  isl_ctx *ctx;
 
-  if (!graphite_initialize ())
+  /* If a function is parallel it was most probably already run through graphite
+     once. No need to run again.  */
+  if (parallelized_function_p (cfun->decl))
     return;
 
+  ctx = isl_ctx_alloc ();
+  isl_options_set_on_error (ctx, ISL_ON_ERROR_ABORT);
+  if (!graphite_initialize (ctx))
+    return;
+
+  the_isl_ctx = ctx;
   build_scops (&scops);
 
   if (dump_file && (dump_flags & TDF_DETAILS))
@@ -276,46 +292,133 @@ graphite_transform_loops (void)
       print_global_statistics (dump_file);
     }
 
-  bb_pbb_mapping = htab_create (10, bb_pbb_map_hash, eq_bb_pbb_map, free);
-  reductions = sbitmap_alloc (last_basic_block * 2);
-  sbitmap_zero (reductions);
-
-  FOR_EACH_VEC_ELT (scop_p, scops, i, scop)
-    if (dbg_cnt (graphite_scop))
-      rewrite_commutative_reductions_out_of_ssa (SCOP_REGION (scop),
-                                                reductions);
-
-  FOR_EACH_VEC_ELT (scop_p, scops, i, scop)
+  FOR_EACH_VEC_ELT (scops, i, scop)
     if (dbg_cnt (graphite_scop))
       {
-       rewrite_reductions_out_of_ssa (scop);
-       rewrite_cross_bb_scalar_deps_out_of_ssa (scop);
-       build_scop_bbs (scop, reductions);
-      }
-
-  sbitmap_free (reductions);
+       scop->ctx = ctx;
+       build_poly_scop (scop);
 
-  FOR_EACH_VEC_ELT (scop_p, scops, i, scop)
-    if (dbg_cnt (graphite_scop))
-      build_poly_scop (scop);
+       if (POLY_SCOP_P (scop)
+           && apply_poly_transforms (scop)
+           && graphite_regenerate_ast_isl (scop))
+         need_cfg_cleanup_p = true;
 
-  FOR_EACH_VEC_ELT (scop_p, scops, i, scop)
-    if (POLY_SCOP_P (scop)
-       && apply_poly_transforms (scop)
-       && gloog (scop, bb_pbb_mapping))
-      need_cfg_cleanup_p = true;
+      }
 
-  htab_delete (bb_pbb_mapping);
   free_scops (scops);
   graphite_finalize (need_cfg_cleanup_p);
+  the_isl_ctx = NULL;
+  isl_ctx_free (ctx);
 }
 
-#else /* If Cloog is not available: #ifndef HAVE_cloog.  */
+#else /* If ISL is not available: #ifndef HAVE_isl.  */
 
-void
+static void
 graphite_transform_loops (void)
 {
-  sorry ("Graphite loop optimizations cannot be used");
+  sorry ("Graphite loop optimizations cannot be used (ISL is not available).");
 }
 
 #endif
+
+
+static unsigned int
+graphite_transforms (struct function *fun)
+{
+  if (number_of_loops (fun) <= 1)
+    return 0;
+
+  graphite_transform_loops ();
+
+  return 0;
+}
+
+static bool
+gate_graphite_transforms (void)
+{
+  /* Enable -fgraphite pass if any one of the graphite optimization flags
+     is turned on.  */
+  if (flag_loop_block
+      || flag_loop_interchange
+      || flag_loop_strip_mine
+      || flag_graphite_identity
+      || flag_loop_parallelize_all
+      || flag_loop_optimize_isl
+      || flag_loop_unroll_jam)
+    flag_graphite = 1;
+
+  return flag_graphite != 0;
+}
+
+namespace {
+
+const pass_data pass_data_graphite =
+{
+  GIMPLE_PASS, /* type */
+  "graphite0", /* name */
+  OPTGROUP_LOOP, /* optinfo_flags */
+  TV_GRAPHITE, /* tv_id */
+  ( PROP_cfg | PROP_ssa ), /* properties_required */
+  0, /* properties_provided */
+  0, /* properties_destroyed */
+  0, /* todo_flags_start */
+  0, /* todo_flags_finish */
+};
+
+class pass_graphite : public gimple_opt_pass
+{
+public:
+  pass_graphite (gcc::context *ctxt)
+    : gimple_opt_pass (pass_data_graphite, ctxt)
+  {}
+
+  /* opt_pass methods: */
+  virtual bool gate (function *) { return gate_graphite_transforms (); }
+
+}; // class pass_graphite
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_graphite (gcc::context *ctxt)
+{
+  return new pass_graphite (ctxt);
+}
+
+namespace {
+
+const pass_data pass_data_graphite_transforms =
+{
+  GIMPLE_PASS, /* type */
+  "graphite", /* name */
+  OPTGROUP_LOOP, /* optinfo_flags */
+  TV_GRAPHITE_TRANSFORMS, /* tv_id */
+  ( PROP_cfg | PROP_ssa ), /* properties_required */
+  0, /* properties_provided */
+  0, /* properties_destroyed */
+  0, /* todo_flags_start */
+  0, /* todo_flags_finish */
+};
+
+class pass_graphite_transforms : public gimple_opt_pass
+{
+public:
+  pass_graphite_transforms (gcc::context *ctxt)
+    : gimple_opt_pass (pass_data_graphite_transforms, ctxt)
+  {}
+
+  /* opt_pass methods: */
+  virtual bool gate (function *) { return gate_graphite_transforms (); }
+  virtual unsigned int execute (function *fun) { return graphite_transforms (fun); }
+
+}; // class pass_graphite_transforms
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_graphite_transforms (gcc::context *ctxt)
+{
+  return new pass_graphite_transforms (ctxt);
+}
+
+