OSDN Git Service

gcc/
[pf3gnuchains/gcc-fork.git] / gcc / graphite.c
index 86b0eae..4e1a969 100644 (file)
@@ -717,16 +717,24 @@ outermost_loop_in_scop (scop_p scop, basic_block bb)
   return nest;
 }
 
+/* Returns the block preceding the entry of SCOP.  */
+
+static basic_block
+block_before_scop (scop_p scop)
+{
+  return SESE_ENTRY (SCOP_REGION (scop))->src;
+}
+
 /* Return true when EXPR is an affine function in LOOP with parameters
-   instantiated relative to outermost_loop.  */
+   instantiated relative to SCOP_ENTRY.  */
 
 static bool
-loop_affine_expr (struct loop *outermost_loop, struct loop *loop, tree expr)
+loop_affine_expr (basic_block scop_entry, struct loop *loop, tree expr)
 {
-  int n = outermost_loop->num;
+  int n = scop_entry->loop_father->num;
   tree scev = analyze_scalar_evolution (loop, expr);
 
-  scev = instantiate_scev (outermost_loop, loop, scev);
+  scev = instantiate_scev (scop_entry, loop, scev);
 
   return (evolution_function_is_invariant_p (scev, n)
          || evolution_function_is_affine_multivariate_p (scev, n));
@@ -751,11 +759,11 @@ is_simple_operand (loop_p loop, gimple stmt, tree op)
 }
 
 /* Return true only when STMT is simple enough for being handled by
-   Graphite.  This depends on OUTERMOST_LOOP, as the parametetrs are
-   initialized relative to this loop.  */
+   Graphite.  This depends on SCOP_ENTRY, as the parametetrs are
+   initialized relatively to this basic block.  */
 
 static bool
-stmt_simple_for_scop_p (struct loop *outermost_loop, gimple stmt)
+stmt_simple_for_scop_p (basic_block scop_entry, gimple stmt)
 {
   basic_block bb = gimple_bb (stmt);
   struct loop *loop = bb->loop_father;
@@ -791,11 +799,11 @@ stmt_simple_for_scop_p (struct loop *outermost_loop, gimple stmt)
              || code == GE_EXPR))
           return false;
 
-       if (!outermost_loop)
+       if (!scop_entry)
          return false;
 
        FOR_EACH_SSA_TREE_OPERAND (op, stmt, op_iter, SSA_OP_ALL_USES)
-         if (!loop_affine_expr (outermost_loop, loop, op))
+         if (!loop_affine_expr (scop_entry, loop, op))
            return false;
 
        return true;
@@ -850,18 +858,17 @@ stmt_simple_for_scop_p (struct loop *outermost_loop, gimple stmt)
 }
 
 /* Returns the statement of BB that contains a harmful operation: that
-   can be a function call with side effects, data dependences that
-   cannot be computed in OUTERMOST_LOOP, the induction variables are
-   not linear with respect to OUTERMOST_LOOP, etc.  The current open
+   can be a function call with side effects, the induction variables
+   are not linear with respect to SCOP_ENTRY, etc.  The current open
    scop should end before this statement.  */
 
 static gimple
-harmful_stmt_in_bb (struct loop *outermost_loop, basic_block bb)
+harmful_stmt_in_bb (basic_block scop_entry, basic_block bb)
 {
   gimple_stmt_iterator gsi;
 
   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
-    if (!stmt_simple_for_scop_p (outermost_loop, gsi_stmt (gsi)))
+    if (!stmt_simple_for_scop_p (scop_entry, gsi_stmt (gsi)))
       return gsi_stmt (gsi);
 
   return NULL;
@@ -1048,20 +1055,28 @@ struct scopdet_info
 };
 
 static struct scopdet_info build_scops_1 (edge, VEC (scop_p, heap) **,
-                                          loop_p, loop_p);
+                                          loop_p);
 
 /* Checks, if a bb can be added to a SCoP.  */
 
 static struct scopdet_info 
-scopdet_edge_info (edge ee, loop_p outermost_loop,
+scopdet_edge_info (edge ee,
                   VEC (scop_p, heap) **scops, gbb_type type, gimple *stmt)
               
 {
   basic_block bb = ee->dest;
   struct loop *loop = bb->loop_father;
   struct scopdet_info result;
+  basic_block scop_entry;
+
+  if (VEC_length (scop_p, *scops) != 0)
+    scop_entry = block_before_scop (VEC_last (scop_p, *scops));
+  else if (loop->header)
+    scop_entry = loop->header;
+  else
+    scop_entry = ENTRY_BLOCK_PTR;
 
-  *stmt = harmful_stmt_in_bb (outermost_loop, bb);
+  *stmt = harmful_stmt_in_bb (scop_entry, bb);
   result.difficult = (*stmt != NULL);
   result.last = NULL;
 
@@ -1084,7 +1099,7 @@ scopdet_edge_info (edge ee, loop_p outermost_loop,
         VEC (scop_p, heap) *tmp_scops = VEC_alloc (scop_p, heap, 3);
         struct scopdet_info sinfo;
 
-        sinfo = build_scops_1 (ee, &tmp_scops, loop, outermost_loop);
+        sinfo = build_scops_1 (ee, &tmp_scops, loop);
 
         result.last = single_exit (bb->loop_father);
 
@@ -1117,20 +1132,18 @@ scopdet_edge_info (edge ee, loop_p outermost_loop,
     case GBB_LOOP_MULT_EXIT_HEADER:
       {
         /* XXX: Handle loop nests with the same header.  */
-        /* XXX: Handle iterative optimization of outermost_loop.  */
         /* XXX: For now we just do not join loops with multiple exits. If the 
            exits lead to the same bb it may be possible to join the loop.  */
         VEC (scop_p, heap) *tmp_scops = VEC_alloc (scop_p, heap, 3);
         VEC (edge, heap) *exits = get_loop_exit_edges (loop);
         edge e;
         int i;
-        build_scops_1 (ee, &tmp_scops, loop, outermost_loop);
+        build_scops_1 (ee, &tmp_scops, loop);
 
         for (i = 0; VEC_iterate (edge, exits, i, e); i++)
           if (dominated_by_p (CDI_DOMINATORS, e->dest, e->src)
               && e->dest->loop_father == loop_outer (loop))
-            build_scops_1 (e, &tmp_scops, e->dest->loop_father,
-                           outermost_loop);
+            build_scops_1 (e, &tmp_scops, e->dest->loop_father);
 
         result.next = NULL; 
         result.last = NULL;
@@ -1199,7 +1212,7 @@ scopdet_edge_info (edge ee, loop_p outermost_loop,
                continue;
              }
 
-           sinfo = build_scops_1 (e, &tmp_scops, loop, outermost_loop);
+           sinfo = build_scops_1 (e, &tmp_scops, loop);
 
            result.exits |= sinfo.exits;
            result.last = sinfo.last;
@@ -1261,10 +1274,9 @@ scopdet_edge_info (edge ee, loop_p outermost_loop,
              e = split_block (dom_bb, NULL);
 
            if (loop_depth (loop) > loop_depth (dom_bb->loop_father))
-             sinfo = build_scops_1 (e, &tmp_scops, loop_outer (loop),
-                                    outermost_loop);
+             sinfo = build_scops_1 (e, &tmp_scops, loop_outer (loop));
            else
-             sinfo = build_scops_1 (e, &tmp_scops, loop, outermost_loop);
+             sinfo = build_scops_1 (e, &tmp_scops, loop);
                                            
                                      
            result.exits |= sinfo.exits; 
@@ -1335,8 +1347,7 @@ end_scop (scop_p scop, edge exit, bool split_entry)
 /* Creates the SCoPs and writes entry and exit points for every SCoP.  */
 
 static struct scopdet_info 
-build_scops_1 (edge start, VEC (scop_p, heap) **scops, loop_p loop,
-              loop_p outermost_loop)
+build_scops_1 (edge start, VEC (scop_p, heap) **scops, loop_p loop)
 {
   edge current = start;
 
@@ -1357,7 +1368,7 @@ build_scops_1 (edge start, VEC (scop_p, heap) **scops, loop_p loop,
      and can only be added if all bbs in deeper layers are simple.  */
   while (current != NULL)
     {
-      sinfo = scopdet_edge_info (current, outermost_loop, scops,
+      sinfo = scopdet_edge_info (current, scops,
                                 get_bb_type (current->dest, loop), &stmt);
 
       if (!in_scop && !(sinfo.exits || sinfo.difficult))
@@ -1433,7 +1444,7 @@ static void
 build_scops (void)
 {
   struct loop *loop = current_loops->tree_root;
-  build_scops_1 (single_succ_edge (ENTRY_BLOCK_PTR), &current_scops, loop, loop);
+  build_scops_1 (single_succ_edge (ENTRY_BLOCK_PTR), &current_scops, loop);
 }
 
 /* Gather the basic blocks belonging to the SCOP.  */
@@ -1531,8 +1542,9 @@ scop_record_loop (scop_p scop, struct loop *loop)
        oldiv->name = IDENTIFIER_POINTER (DECL_NAME (oldiv->t));
       else
        {
-         char *n = XNEWVEC (char, 16);
-         sprintf (n, "D.%u", DECL_UID (oldiv->t));
+         int len = 2 + 16;
+         char *n = XNEWVEC (char, len);
+         snprintf (n, len, "D.%u", DECL_UID (oldiv->t));
          oldiv->name = n;
        }
       oldiv->loop = loop;
@@ -1895,19 +1907,15 @@ idx_record_params (tree base, tree *idx, void *dta)
       tree scev;
       scop_p scop = data->scop;
       struct loop *loop = data->loop;
+      Value one;
 
       scev = analyze_scalar_evolution (loop, *idx);
-      scev = instantiate_scev (outermost_loop_in_scop (scop, loop->header),
-                              loop, scev);
-
-      {
-       Value one;
+      scev = instantiate_scev (block_before_scop (scop), loop, scev);
 
-       value_init (one);
-       value_set_si (one, 1);
-       scan_tree_for_params (scop, scev, NULL, 0, one, false);
-       value_clear (one);
-      }
+      value_init (one);
+      value_set_si (one, 1);
+      scan_tree_for_params (scop, scev, NULL, 0, one, false);
+      value_clear (one);
     }
 
   return true;
@@ -1957,11 +1965,11 @@ find_params_in_bb (scop_p scop, basic_block bb)
           
           lhs = gimple_cond_lhs (stmt);
           lhs = analyze_scalar_evolution (loop, lhs);
-          lhs = instantiate_scev (nest, loop, lhs);
+          lhs = instantiate_scev (block_before_scop (scop), loop, lhs);
 
           rhs = gimple_cond_rhs (stmt);
           rhs = analyze_scalar_evolution (loop, rhs);
-          rhs = instantiate_scev (nest, loop, rhs);
+          rhs = instantiate_scev (block_before_scop (scop), loop, rhs);
 
           value_init (one);
           scan_tree_for_params (scop, lhs, NULL, 0, one, false);
@@ -1981,13 +1989,14 @@ save_var_name (char **nv, int i, name_tree p)
 
   if (name)
     {
-      nv[i] = XNEWVEC (char, strlen (name) + 12);
-      sprintf (nv[i], "%s_%12d", name, SSA_NAME_VERSION (p->t));
+      int len = strlen (name) + 16;
+      nv[i] = XNEWVEC (char, len);
+      snprintf (nv[i], len, "%s_%d", name, SSA_NAME_VERSION (p->t));
     }
   else
     {
-      nv[i] = XNEWVEC (char, 12);
-      sprintf (nv[i], "T_%12d", SSA_NAME_VERSION (p->t));
+      nv[i] = XNEWVEC (char, 16);
+      snprintf (nv[i], 2 + 16, "T_%d", SSA_NAME_VERSION (p->t));
     }
 
   p->name = nv[i];
@@ -2037,8 +2046,9 @@ initialize_cloog_names (scop_p scop)
 
   for (i = 0; i < nb_iterators; i++)
     {
-      iterators[i] = XNEWVEC (char, 18 + 12);
-      sprintf (iterators[i], "graphite_iterator_%d", i);
+      int len = 18 + 16;
+      iterators[i] = XNEWVEC (char, len);
+      snprintf (iterators[i], len, "graphite_iterator_%d", i);
     }
 
   cloog_names_set_nb_iterators (cloog_program_names (SCOP_PROG (scop)),
@@ -2048,8 +2058,9 @@ initialize_cloog_names (scop_p scop)
 
   for (i = 0; i < nb_scattering; i++)
     {
-      scattering[i] = XNEWVEC (char, 2 + 12);
-      sprintf (scattering[i], "s_%d", i);
+      int len = 2 + 16;
+      scattering[i] = XNEWVEC (char, len);
+      snprintf (scattering[i], len, "s_%d", i);
     }
 
   cloog_names_set_nb_scattering (cloog_program_names (SCOP_PROG (scop)),
@@ -2081,8 +2092,7 @@ find_scop_parameters (scop_p scop)
        continue;
 
       nb_iters = analyze_scalar_evolution (loop, nb_iters);
-      nb_iters = instantiate_scev (outermost_loop_in_scop (scop, loop->header),
-                                  loop, nb_iters);
+      nb_iters = instantiate_scev (block_before_scop (scop), loop, nb_iters);
       scan_tree_for_params (scop, nb_iters, NULL, 0, one, false);
     }
 
@@ -2209,10 +2219,10 @@ build_loop_iteration_domains (scop_p scop, struct loop *loop,
       row++;
       value_set_si (cstr->p[row][0], 1);
       value_set_si (cstr->p[row][loop_col], -1);
+
       nb_iters = analyze_scalar_evolution (loop, nb_iters);
-      nb_iters = 
-        instantiate_scev (outermost_loop_in_scop (scop, loop->header),
-                         loop, nb_iters);
+      nb_iters = instantiate_scev (block_before_scop (scop), loop, nb_iters);
+
       value_init (one);
       value_set_si (one, 1);
       scan_tree_for_params (scop, nb_iters, cstr, row, one, false);
@@ -2333,15 +2343,15 @@ add_conditions_to_domain (graphite_bb_p gb)
             tree left;
             tree right;
             loop_p loop = GBB_BB (gb)->loop_father;
-            loop_p outermost = outermost_loop_in_scop (scop, GBB_BB (gb));
 
             left = gimple_cond_lhs (stmt);
             right = gimple_cond_rhs (stmt);
 
             left = analyze_scalar_evolution (loop, left);
             right = analyze_scalar_evolution (loop, right);
-            left = instantiate_scev (outermost, loop, left);
-            right = instantiate_scev (outermost, loop, right);
+
+            left = instantiate_scev (block_before_scop (scop), loop, left);
+            right = instantiate_scev (block_before_scop (scop), loop, right);
 
             code = gimple_cond_code (stmt);
 
@@ -3974,13 +3984,13 @@ gbb_can_be_ignored (graphite_bb_p gb)
              XXX: Just a heuristic, that needs further investigation.  */
           case GIMPLE_ASSIGN:
            {
-             tree var =  gimple_assign_lhs (stmt);
+             tree var = gimple_assign_lhs (stmt);
              var = analyze_scalar_evolution (loop, var);
-             var = instantiate_scev (outermost_loop_in_scop (scop,
-                                                             GBB_BB (gb)),
-                                     loop, var);
+             var = instantiate_scev (block_before_scop (scop), loop, var);
+
              if (TREE_CODE (var) == SCEV_NOT_KNOWN)
                return false;
+
              break;
            }
           /* Otherwise not ignoreable.  */
@@ -4794,12 +4804,6 @@ graphite_transform_loops (void)
 void
 graphite_transform_loops (void)
 {
-  if (dump_file && (dump_flags & TDF_DETAILS))
-    {
-      fprintf (dump_file, "Graphite loop optimizations cannot be used.\n");
-      fprintf (dump_file, "GCC has not been configured with the required "
-              "libraries for Graphite loop optimizations.");
-    }
   sorry ("Graphite loop optimizations cannot be used");
 }