]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/graphite-scop-detection.c
Correct a function pre/postcondition [PR102403].
[thirdparty/gcc.git] / gcc / graphite-scop-detection.c
index 43716f184485c5b9e0f855f5e0ed1bb30ebe8e05..3e729b159b095d5471df2afeb520e2cf0811b808 100644 (file)
@@ -1,5 +1,5 @@
 /* Detection of Static Control Parts (SCoP) for Graphite.
-   Copyright (C) 2009-2018 Free Software Foundation, Inc.
+   Copyright (C) 2009-2021 Free Software Foundation, Inc.
    Contributed by Sebastian Pop <sebastian.pop@amd.com> and
    Tobias Grosser <grosser@fim.uni-passau.de>.
 
@@ -19,7 +19,7 @@ You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
-#define USES_ISL
+#define INCLUDE_ISL
 
 #include "config.h"
 
@@ -30,7 +30,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "backend.h"
 #include "cfghooks.h"
 #include "domwalk.h"
-#include "params.h"
 #include "tree.h"
 #include "gimple.h"
 #include "ssa.h"
@@ -555,14 +554,19 @@ scop_detection::can_represent_loop (loop_p loop, sese_l scop)
   tree niter;
   struct tree_niter_desc niter_desc;
 
-  return single_exit (loop)
-    && !(loop_preheader_edge (loop)->flags & EDGE_IRREDUCIBLE_LOOP)
+  /* We can only handle do {} while () style loops correctly.  */
+  edge exit = single_exit (loop);
+  if (!exit
+      || !single_pred_p (loop->latch)
+      || exit->src != single_pred (loop->latch)
+      || !empty_block_p (loop->latch))
+    return false;
+
+  return !(loop_preheader_edge (loop)->flags & EDGE_IRREDUCIBLE_LOOP)
     && number_of_iterations_exit (loop, single_exit (loop), &niter_desc, false)
     && niter_desc.control.no_overflow
     && (niter = number_of_latch_executions (loop))
     && !chrec_contains_undetermined (niter)
-    && !chrec_contains_undetermined (scalar_evolution_in_region (scop,
-                                                                loop, niter))
     && graphite_can_represent_expr (scop, loop, niter);
 }
 
@@ -590,6 +594,15 @@ scop_detection::add_scop (sese_l s)
 {
   gcc_assert (s);
 
+  /* If the exit edge is fake discard the SCoP for now as we're removing the
+     fake edges again after analysis.  */
+  if (s.exit->flags & EDGE_FAKE)
+    {
+      DEBUG_PRINT (dp << "[scop-detection-fail] Discarding infinite loop SCoP: ";
+                  print_sese (dump_file, s));
+      return;
+    }
+
   /* Include the BB with the loop-closed SSA PHI nodes, we need this
      block in the region for code-generating out-of-SSA copies.
      canonicalize_loop_closed_ssa makes sure that is in proper shape.  */
@@ -883,6 +896,10 @@ scop_detection::graphite_can_represent_scev (sese_l scop, tree scev)
        return false;
       return graphite_can_represent_scev (scop, CHREC_LEFT (scev));
 
+    case ADDR_EXPR:
+      /* We cannot encode addresses for ISL.  */
+      return false;
+
     default:
       break;
     }
@@ -904,7 +921,7 @@ bool
 scop_detection::graphite_can_represent_expr (sese_l scop, loop_p loop,
                                             tree expr)
 {
-  tree scev = scalar_evolution_in_region (scop, loop, expr);
+  tree scev = cached_scalar_evolution_in_region (scop, loop, expr);
   return graphite_can_represent_scev (scop, scev);
 }
 
@@ -1027,7 +1044,31 @@ scop_detection::stmt_simple_for_scop_p (sese_l scop, gimple *stmt,
 
     case GIMPLE_ASSIGN:
     case GIMPLE_CALL:
-      return true;
+      {
+       tree op, lhs = gimple_get_lhs (stmt);
+       ssa_op_iter i;
+       /* If we are not going to instantiate the stmt do not require
+          its operands to be instantiatable at this point.  */
+       if (lhs
+           && TREE_CODE (lhs) == SSA_NAME
+           && scev_analyzable_p (lhs, scop))
+         return true;
+       /* Verify that if we can analyze operands at their def site we
+          also can represent them when analyzed at their uses.  */
+       FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_USE)
+         if (scev_analyzable_p (op, scop)
+             && chrec_contains_undetermined
+                  (cached_scalar_evolution_in_region (scop,
+                                                      bb->loop_father, op)))
+           {
+             DEBUG_PRINT (dp << "[scop-detection-fail] "
+                          << "Graphite cannot code-gen stmt:\n";
+                          print_gimple_stmt (dump_file, stmt, 0,
+                                             TDF_VOPS | TDF_MEMSYMS));
+             return false;
+           }
+       return true;
+      }
 
     default:
       /* These nodes cut a new scope.  */
@@ -1061,16 +1102,13 @@ static void
 assign_parameter_index_in_region (tree name, sese_info_p region)
 {
   gcc_assert (TREE_CODE (name) == SSA_NAME
-             && INTEGRAL_TYPE_P (TREE_TYPE (name))
              && ! defined_in_sese_p (name, region->region));
-
   int i;
   tree p;
   FOR_EACH_VEC_ELT (region->params, i, p)
     if (p == name)
       return;
 
-  i = region->params.length ();
   region->params.safe_push (name);
 }
 
@@ -1144,13 +1182,15 @@ find_params_in_bb (sese_info_p region, gimple_poly_bb_p gbb)
 
   /* Find parameters in conditional statements.  */
   gimple *stmt;
-  loop_p loop = GBB_BB (gbb)->loop_father;
   FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb), i, stmt)
     {
-      tree lhs = scalar_evolution_in_region (region->region, loop,
-                                            gimple_cond_lhs (stmt));
-      tree rhs = scalar_evolution_in_region (region->region, loop,
-                                            gimple_cond_rhs (stmt));
+      loop_p loop = gimple_bb (stmt)->loop_father;
+      tree lhs = cached_scalar_evolution_in_region (region->region, loop,
+                                                   gimple_cond_lhs (stmt));
+      tree rhs = cached_scalar_evolution_in_region (region->region, loop,
+                                                   gimple_cond_rhs (stmt));
+      gcc_assert (!chrec_contains_undetermined (lhs)
+                 && !chrec_contains_undetermined (rhs));
 
       scan_tree_for_params (region, lhs);
       scan_tree_for_params (region, rhs);
@@ -1222,9 +1262,7 @@ build_cross_bb_scalars_def (scop_p scop, tree def, basic_block def_bb,
        && (def_bb != gimple_bb (use_stmt) && !is_gimple_debug (use_stmt)))
       {
        add_write (writes, def);
-       /* This is required by the FOR_EACH_IMM_USE_STMT when we want to break
-          before all the uses have been visited.  */
-       BREAK_FROM_IMM_USE_STMT (imm_iter);
+       break;
       }
 }
 
@@ -1373,9 +1411,13 @@ build_alias_set (scop_p scop)
   int i, j;
   int *all_vertices;
 
+  struct loop *nest
+    = find_common_loop (scop->scop_info->region.entry->dest->loop_father,
+                       scop->scop_info->region.exit->src->loop_father);
+
   FOR_EACH_VEC_ELT (scop->drs, i, dr1)
     for (j = i+1; scop->drs.iterate (j, &dr2); j++)
-      if (dr_may_alias_p (dr1->dr, dr2->dr, true))
+      if (dr_may_alias_p (dr1->dr, dr2->dr, nest))
        {
          /* Dependences in the same alias set need to be handled
             by just looking at DR_ACCESS_FNs.  */
@@ -1447,8 +1489,8 @@ gather_bbs::before_dom_children (basic_block bb)
       tree nb_iters = number_of_latch_executions (loop);
       if (chrec_contains_symbols (nb_iters))
        {
-         nb_iters = scalar_evolution_in_region (region->region,
-                                                loop, nb_iters);
+         nb_iters = cached_scalar_evolution_in_region (region->region,
+                                                       loop, nb_iters);
          scan_tree_for_params (region, nb_iters);
        }
     }
@@ -1593,7 +1635,7 @@ build_scops (vec<scop_p> *scops)
          continue;
        }
 
-      unsigned max_arrays = PARAM_VALUE (PARAM_GRAPHITE_MAX_ARRAYS_PER_SCOP);
+      unsigned max_arrays = param_graphite_max_arrays_per_scop;
       if (max_arrays > 0
          && scop->drs.length () >= max_arrays)
        {
@@ -1606,7 +1648,7 @@ build_scops (vec<scop_p> *scops)
        }
 
       find_scop_parameters (scop);
-      graphite_dim_t max_dim = PARAM_VALUE (PARAM_GRAPHITE_MAX_NB_SCOP_PARAMS);
+      graphite_dim_t max_dim = param_graphite_max_nb_scop_params;
       if (max_dim > 0
          && scop_nb_params (scop) > max_dim)
        {