Fix PR48648: Handle CLAST assignments.
authorSebastian Pop <sebastian.pop@amd.com>
Thu, 28 Jul 2011 21:57:10 +0000 (21:57 +0000)
committerSebastian Pop <spop@gcc.gnu.org>
Thu, 28 Jul 2011 21:57:10 +0000 (21:57 +0000)
The CLAST produced by CLooG-ISL contains an assignment and GCC chokes
on it.  The exact CLAST contains an assignment followed by an if:

scat_1 = max(0,ceild(T_4-7,8));
if (scat_1 <= min(1,floord(T_4-1,8))) {
  S7(scat_1);
}

This is equivalent to a loop that iterates only once, and so CLooG
generates an assignment followed by an if instead of a loop.  This is
an important optimization that was improved in ISL, that allows
if-conversion: imagine GCC having to figure out that a loop like the
following actually iterates only once, and can be converted to an if:

for (scat_1 = max(0,ceild(T_4-7,8)); scat_1 <= min(1,floord(T_4-1,8)); scat_1++)
  S7(scat_1);

This patch implements the translation of CLAST assignments.
Bootstrapped and tested on amd64-linux.

2011-07-28  Sebastian Pop  <sebastian.pop@amd.com>

PR middle-end/48648
* graphite-clast-to-gimple.c (clast_get_body_of_loop): Handle
CLAST assignments.
(translate_clast): Same.
(translate_clast_assignment): New.

* gcc.dg/graphite/id-pr48648.c: New.

From-SVN: r176901

gcc/ChangeLog
gcc/graphite-clast-to-gimple.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/graphite/id-pr48648.c [new file with mode: 0644]

index cc9ea358476cadba06d0bedaf52e6c6201cccb4e..b07bed5bbb02f9eea33917983f1d4b263d2d196f 100644 (file)
@@ -1,3 +1,11 @@
+2011-07-28  Sebastian Pop  <sebastian.pop@amd.com>
+
+       PR middle-end/48648
+       * graphite-clast-to-gimple.c (clast_get_body_of_loop): Handle
+       CLAST assignments.
+       (translate_clast): Same.
+       (translate_clast_assignment): New.
+
 2011-07-28  Sebastian Pop  <sebastian.pop@amd.com>
 
        PR tree-optimization/49876
index a911eb64c14aa7bfcbba1f30ee29675374bad806..7bb1d232282b42fac7ca9a6fe6444060df1e12d3 100644 (file)
@@ -816,6 +816,9 @@ clast_get_body_of_loop (struct clast_stmt *stmt)
   if (CLAST_STMT_IS_A (stmt, stmt_block))
     return clast_get_body_of_loop (((struct clast_block *) stmt)->body);
 
+  if (CLAST_STMT_IS_A (stmt, stmt_ass))
+    return clast_get_body_of_loop (stmt->next);
+
   gcc_unreachable ();
 }
 
@@ -1125,6 +1128,44 @@ translate_clast_for (loop_p context_loop, struct clast_for *stmt, edge next_e,
   return last_e;
 }
 
+/* Translates a clast assignment STMT to gimple.
+
+   - NEXT_E is the edge where new generated code should be attached.
+   - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping.  */
+
+static edge
+translate_clast_assignment (struct clast_assignment *stmt, edge next_e,
+                           int level, ivs_params_p ip)
+{
+  gimple_seq stmts;
+  mpz_t v1, v2;
+  tree type, new_name, var;
+  edge res = single_succ_edge (split_edge (next_e));
+  struct clast_expr *expr = (struct clast_expr *) stmt->RHS;
+
+  mpz_init (v1);
+  mpz_init (v2);
+  type = type_for_clast_expr (expr, ip, v1, v2);
+  var = create_tmp_var (type, "graphite_var");
+  new_name = force_gimple_operand (clast_to_gcc_expression (type, expr, ip),
+                                  &stmts, true, var);
+  add_referenced_var (var);
+  if (stmts)
+    {
+      gsi_insert_seq_on_edge (next_e, stmts);
+      gsi_commit_edge_inserts ();
+    }
+
+  save_clast_name_index (ip->newivs_index, stmt->LHS,
+                        VEC_length (tree, *(ip->newivs)), level, v1, v2);
+  VEC_safe_push (tree, heap, *(ip->newivs), new_name);
+
+  mpz_clear (v1);
+  mpz_clear (v2);
+
+  return res;
+}
+
 /* Translates a clast guard statement STMT to gimple.
 
    - NEXT_E is the edge where new generated code should be attached.
@@ -1175,6 +1216,10 @@ translate_clast (loop_p context_loop, struct clast_stmt *stmt, edge next_e,
   else if (CLAST_STMT_IS_A (stmt, stmt_block))
     next_e = translate_clast (context_loop, ((struct clast_block *) stmt)->body,
                              next_e, bb_pbb_mapping, level, ip);
+
+  else if (CLAST_STMT_IS_A (stmt, stmt_ass))
+    next_e = translate_clast_assignment ((struct clast_assignment *) stmt,
+                                        next_e, level, ip);
   else
     gcc_unreachable();
 
index 9e9efb19b6460c8228819252d3b28e857d9250be..85daf9f7092b388ac9525f30c3b8c0e12068665b 100644 (file)
@@ -1,3 +1,8 @@
+2011-07-22  Sebastian Pop  <sebastian.pop@amd.com>
+
+       PR middle-end/48648
+       * gcc.dg/graphite/id-pr48648.c: New.
+
 2011-07-28  Jakub Jelinek  <jakub@redhat.com>
 
        PR fortran/31067
diff --git a/gcc/testsuite/gcc.dg/graphite/id-pr48648.c b/gcc/testsuite/gcc.dg/graphite/id-pr48648.c
new file mode 100644 (file)
index 0000000..ff58ec2
--- /dev/null
@@ -0,0 +1,21 @@
+/* { dg-options "-O -fgraphite-identity" } */
+
+void *foo(const void *a);
+
+void bug48648()
+{
+  unsigned char a[2];
+  long b;
+  int i;
+
+  for(i = 0; i < 2; i++) {
+    if (b <= 0)
+      a[i] = 0;
+    else if (b >= 8)
+      a[i] = 0;
+    else
+      a[i] = 0;
+    b -= 8;
+  }
+  foo(&a);
+}