PR c++/68795: fix uninitialized close_paren_loc in cp_parser_postfix_expression
[gcc.git] / gcc / graphite.c
index cb8cc7ecd478bb7ebf31647130a6d86b70fcf33c..3236006f066adb02a0d2f9f06aca596fb5cc1fd1 100644 (file)
@@ -1,5 +1,5 @@
 /* Gimple Represented as Polyhedra.
-   Copyright (C) 2006-2013 Free Software Foundation, Inc.
+   Copyright (C) 2006-2016 Free Software Foundation, Inc.
    Contributed by Sebastian Pop <sebastian.pop@inria.fr>.
 
 This file is part of GCC.
@@ -25,50 +25,34 @@ along with GCC; see the file COPYING3.  If not see
    An early description of this pass can be found in the GCC Summit'06
    paper "GRAPHITE: Polyhedral Analyses and Optimizations for GCC".
    The wiki page http://gcc.gnu.org/wiki/Graphite contains pointers to
-   the related work.
+   the related work.  */
 
-   One important document to read is CLooG's internal manual:
-   http://repo.or.cz/w/cloog-ppl.git?a=blob_plain;f=doc/cloog.texi;hb=HEAD
-   that describes the data structure of loops used in this file, and
-   the functions that are used for transforming the code.  */
+#define USES_ISL
 
 #include "config.h"
-
-#ifdef HAVE_cloog
-#include <isl/set.h>
-#include <isl/map.h>
-#include <isl/options.h>
-#include <isl/union_map.h>
-#include <cloog/cloog.h>
-#include <cloog/isl/domain.h>
-#include <cloog/isl/cloog.h>
-#endif
-
 #include "system.h"
 #include "coretypes.h"
+#include "backend.h"
 #include "diagnostic-core.h"
-#include "tree.h"
-#include "tree-ssa.h"
-#include "tree-dump.h"
 #include "cfgloop.h"
-#include "tree-chrec.h"
+#include "tree-pass.h"
+#include "params.h"
+#include "pretty-print.h"
+
+#ifdef HAVE_isl
+#include "cfghooks.h"
+#include "tree.h"
+#include "gimple.h"
+#include "fold-const.h"
+#include "gimple-iterator.h"
+#include "tree-cfg.h"
+#include "tree-ssa-loop.h"
 #include "tree-data-ref.h"
 #include "tree-scalar-evolution.h"
-#include "sese.h"
 #include "dbgcnt.h"
 #include "tree-parloops.h"
-#include "tree-pass.h"
 #include "tree-cfgcleanup.h"
-
-#ifdef HAVE_cloog
-
-#include "graphite-poly.h"
-#include "graphite-scop-detection.h"
-#include "graphite-clast-to-gimple.h"
-#include "graphite-sese-to-poly.h"
-#include "graphite-htab.h"
-
-CloogState *cloog_state;
+#include "graphite.h"
 
 /* Print global statistics to FILE.  */
 
@@ -86,7 +70,7 @@ print_global_statistics (FILE* file)
 
   basic_block bb;
 
-  FOR_ALL_BB (bb)
+  FOR_ALL_BB_FN (bb, cfun)
     {
       gimple_stmt_iterator psi;
 
@@ -142,12 +126,12 @@ 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;
 
-      if (!bb_in_sese_p (bb, SCOP_REGION (scop)))
+      if (!bb_in_sese_p (bb, scop->scop_info->region))
        continue;
 
       n_bbs++;
@@ -165,13 +149,23 @@ print_graphite_scop_statistics (FILE* file, scop_p scop)
          n_p_stmts += bb->count;
        }
 
-      if (loop->header == bb && loop_in_sese_p (loop, SCOP_REGION (scop)))
+      if (loop->header == bb && loop_in_sese_p (loop, scop->scop_info->region))
        {
          n_loops++;
          n_p_loops += bb->count;
        }
     }
 
+  fprintf (file, "\nFunction Name: %s\n", current_function_name ());
+
+  edge scop_begin = scop->scop_info->region.entry;
+  edge scop_end = scop->scop_info->region.exit;
+
+  fprintf (file, "\nSCoP (entry_edge (bb_%d, bb_%d), ",
+          scop_begin->src->index, scop_begin->dest->index);
+  fprintf (file, "exit_edge (bb_%d, bb_%d))",
+          scop_end->src->index, scop_end->dest->index);
+
   fprintf (file, "\nSCoP statistics (");
   fprintf (file, "BBS:%ld, ", n_bbs);
   fprintf (file, "LOOPS:%ld, ", n_loops);
@@ -195,6 +189,10 @@ print_graphite_statistics (FILE* file, vec<scop_p> scops)
 
   FOR_EACH_VEC_ELT (scops, i, scop)
     print_graphite_scop_statistics (file, scop);
+
+  /* Print the loop structure.  */
+  print_loops (file, 2);
+  print_loops (file, 3);
 }
 
 /* Initialize graphite: when there are no loops returns false.  */
@@ -202,13 +200,30 @@ print_graphite_statistics (FILE* file, vec<scop_p> scops)
 static bool
 graphite_initialize (isl_ctx *ctx)
 {
-  if (number_of_loops (cfun) <= 1
+  int min_loops = PARAM_VALUE (PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION);
+  int max_bbs = PARAM_VALUE (PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION);
+  int nbbs = n_basic_blocks_for_fn (cfun);
+  int nloops = number_of_loops (cfun);
+
+  if (nloops <= min_loops
       /* 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))
+      || (nbbs > max_bbs))
     {
       if (dump_file && (dump_flags & TDF_DETAILS))
-       print_global_statistics (dump_file);
+       {
+         if (nloops <= min_loops)
+           fprintf (dump_file, "\nFunction does not have enough loops: "
+                    "PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION = %d.\n",
+                    min_loops);
+
+         else if (nbbs > max_bbs)
+           fprintf (dump_file, "\nFunction has too many basic blocks: "
+                    "PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION = %d.\n", max_bbs);
+
+         fprintf (dump_file, "\nnumber of SCoPs: 0\n");
+         print_global_statistics (dump_file);
+       }
 
       isl_ctx_free (ctx);
       return false;
@@ -218,10 +233,11 @@ graphite_initialize (isl_ctx *ctx)
   recompute_all_dominators ();
   initialize_original_copy_tables ();
 
-  cloog_state = cloog_isl_state_malloc (ctx);
-
   if (dump_file && dump_flags)
-    dump_function_to_file (current_function_decl, dump_file, dump_flags);
+    {
+      dump_function_to_file (current_function_decl, dump_file, dump_flags);
+      print_loops (dump_file, 3);
+    }
 
   return true;
 }
@@ -232,22 +248,37 @@ graphite_initialize (isl_ctx *ctx)
 static void
 graphite_finalize (bool need_cfg_cleanup_p)
 {
+  free_dominance_info (CDI_POST_DOMINATORS);
   if (need_cfg_cleanup_p)
     {
+      free_dominance_info (CDI_DOMINATORS);
       scev_reset ();
       cleanup_tree_cfg ();
-      profile_status = PROFILE_ABSENT;
-      release_recorded_exits ();
+      profile_status_for_fn (cfun) = PROFILE_ABSENT;
+      release_recorded_exits (cfun);
       tree_estimate_probability ();
     }
 
-  cloog_state_free (cloog_state);
   free_original_copy_tables ();
 
   if (dump_file && dump_flags)
     print_loops (dump_file, 3);
 }
 
+/* Deletes all scops in SCOPS.  */
+
+static void
+free_scops (vec<scop_p> scops)
+{
+  int i;
+  scop_p scop;
+
+  FOR_EACH_VEC_ELT (scops, i, scop)
+    free_scop (scop);
+
+  scops.release ();
+}
+
 isl_ctx *the_isl_ctx;
 
 /* Perform a set of linear transforms on the loops of the current
@@ -260,7 +291,6 @@ graphite_transform_loops (void)
   scop_p scop;
   bool need_cfg_cleanup_p = false;
   vec<scop_p> scops = vNULL;
-  bb_pbb_htab_type bb_pbb_mapping;
   isl_ctx *ctx;
 
   /* If a function is parallel it was most probably already run through graphite
@@ -282,42 +312,45 @@ graphite_transform_loops (void)
       print_global_statistics (dump_file);
     }
 
-  bb_pbb_mapping.create (10);
-
   FOR_EACH_VEC_ELT (scops, i, scop)
     if (dbg_cnt (graphite_scop))
       {
-       scop->ctx = ctx;
-       build_poly_scop (scop);
-
-       if (POLY_SCOP_P (scop)
-           && apply_poly_transforms (scop)
-           && gloog (scop, bb_pbb_mapping))
-         need_cfg_cleanup_p = true;
+       scop->isl_context = ctx;
+       if (!build_poly_scop (scop))
+         continue;
+
+       if (!apply_poly_transforms (scop))
+         continue;
+
+       need_cfg_cleanup_p = true;
+       /* When code generation is not successful, do not continue
+          generating code for the next scops: the IR has to be cleaned up
+          and could be in an inconsistent state.  */
+       if (!graphite_regenerate_ast_isl (scop))
+         break;
       }
 
-  bb_pbb_mapping.dispose ();
   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.  */
 
 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 (void)
+graphite_transforms (struct function *fun)
 {
-  if (!current_loops)
+  if (number_of_loops (fun) <= 1)
     return 0;
 
   graphite_transform_loops ();
@@ -330,12 +363,9 @@ 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
+  if (flag_graphite_identity
       || flag_loop_parallelize_all
-      || flag_loop_optimize_isl)
+      || flag_loop_nest_optimize)
     flag_graphite = 1;
 
   return flag_graphite != 0;
@@ -348,8 +378,6 @@ const pass_data pass_data_graphite =
   GIMPLE_PASS, /* type */
   "graphite0", /* name */
   OPTGROUP_LOOP, /* optinfo_flags */
-  true, /* has_gate */
-  false, /* has_execute */
   TV_GRAPHITE, /* tv_id */
   ( PROP_cfg | PROP_ssa ), /* properties_required */
   0, /* properties_provided */
@@ -366,7 +394,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_graphite_transforms (); }
+  virtual bool gate (function *) { return gate_graphite_transforms (); }
 
 }; // class pass_graphite
 
@@ -385,8 +413,6 @@ const pass_data pass_data_graphite_transforms =
   GIMPLE_PASS, /* type */
   "graphite", /* name */
   OPTGROUP_LOOP, /* optinfo_flags */
-  true, /* has_gate */
-  true, /* has_execute */
   TV_GRAPHITE_TRANSFORMS, /* tv_id */
   ( PROP_cfg | PROP_ssa ), /* properties_required */
   0, /* properties_provided */
@@ -403,8 +429,8 @@ public:
   {}
 
   /* opt_pass methods: */
-  bool gate () { return gate_graphite_transforms (); }
-  unsigned int execute () { return graphite_transforms (); }
+  virtual bool gate (function *) { return gate_graphite_transforms (); }
+  virtual unsigned int execute (function *fun) { return graphite_transforms (fun); }
 
 }; // class pass_graphite_transforms