I've attached the patch, which contains generation of Gimple code from
isl_ast_node_block.

However, I've found out a problem. The following example:

int k = 50;
static int __attribute__((noinline))
foo ()
{
  int i, res;
  for (i = 0, res = 0; i < k; i++)
    res += i;

  return res;
}

extern void abort ();

int
main (void)
{
  int res = foo ();


  if (res != 1225)
    abort ();

  return 0;
}.

produces the following code, which executes without error:

ISL AST generated by ISL:
{
  for (int c1 = 0; c1 < k.0; c1 += 1)
    S_4(c1);
  S_6();
}

Gimple code:
loop_0 (header = 0, latch = 1, niter = )
{
  bb_2 (preds = {bb_0 }, succs = {bb_3 bb_8 })
  {
    <bb 2>:
    # VUSE <.MEM_3(D)>
    k.0_9 = k;
    if (k.0_9 > 0)
      goto <bb 3>;
    else
      goto <bb 8>;

  }
  bb_3 (preds = {bb_2 }, succs = {bb_4 bb_7 })
  {
    <bb 3>:
    # .MEM_8 = VDEF <.MEM_3(D)>
    phi_out_of_ssa.5[0] = 0;
    _20 = k.0_9 > 0;
    if (_20 != 0)
      goto <bb 4>;
    else
      goto <bb 7>;

  }
  bb_4 (preds = {bb_3 }, succs = {bb_5 })
  {
    <bb 4>:
    _21 = (signed long) k.0_9;
    _22 = _21 + -1;

  }
  bb_7 (preds = {bb_5 bb_3 }, succs = {bb_8 })
  {
    <bb 7>:
    # .MEM_30 = PHI <.MEM_29(5), .MEM_8(3)>
    # VUSE <.MEM_30>
    res_32 = Close_Phi.6[0];
    # .MEM_33 = VDEF <.MEM_30>
    Cross_BB_scalar_dependence.7[0] = res_32;
    # VUSE <.MEM_33>
    res_17 = Cross_BB_scalar_dependence.7[0];
    _16 = res_17;

  }
  bb_8 (preds = {bb_7 bb_2 }, succs = {bb_1 })
  {
    <bb 8>:
    # res_12 = PHI <_16(7), 0(2)>
    # .MEM_2 = PHI <.MEM_33(7), .MEM_3(D)(2)>
    # VUSE <.MEM_2>
    return res_12;

  }
  loop_2 (header = 5, latch = 6, niter = (unsigned long) ((signed
long) k.0_9 + -1), upper_bound = 9223372036854775806)
  {
    bb_5 (preds = {bb_4 bb_6 }, succs = {bb_6 bb_7 })
    {
      <bb 5>:
      # graphite_IV.8_23 = PHI <0(4), graphite_IV.8_24(6)>
      # .MEM_31 = PHI <.MEM_8(4), .MEM_29(6)>
      # VUSE <.MEM_31>
      res_25 = phi_out_of_ssa.5[0];
      _27 = (int) graphite_IV.8_23;
      res_26 = res_25 + _27;
      # .MEM_28 = VDEF <.MEM_31>
      Close_Phi.6[0] = res_26;
      # .MEM_29 = VDEF <.MEM_28>
      phi_out_of_ssa.5[0] = res_26;
      graphite_IV.8_24 = graphite_IV.8_23 + 1;
      if (graphite_IV.8_23 < _22)
        goto <bb 6>;
      else
        goto <bb 7>;

    }
    bb_6 (preds = {bb_5 }, succs = {bb_5 })
    {
      <bb 6>:
      goto <bb 5>;

    }
  }
}

It is similar to the original code:

loop_0 (header = 0, latch = 1, niter = )
{
  bb_2 (preds = {bb_0 }, succs = {bb_3 bb_8 })
  {
    <bb 2>:
    # VUSE <.MEM_3(D)>
    k.0_9 = k;
    if (k.0_9 > 0)
      goto <bb 3>;
    else
      goto <bb 8>;

  }
  bb_3 (preds = {bb_2 }, succs = {bb_5 })
  {
    <bb 3>:
    # .MEM_8 = VDEF <.MEM_3(D)>
    phi_out_of_ssa.5[0] = 0;
    goto <bb 5>;

  }
  bb_4 (preds = {bb_7 }, succs = {bb_8 })
  {
    <bb 4>:
    # .MEM_19 = PHI <.MEM_18(7)>
    # VUSE <.MEM_19>
    res_17 = Cross_BB_scalar_dependence.7[0];
    _16 = res_17;
    goto <bb 8>;

  }
  bb_7 (preds = {bb_5 }, succs = {bb_4 })
  {
    <bb 7>:
    # VUSE <.MEM_13>
    res_4 = Close_Phi.6[0];
    # .MEM_18 = VDEF <.MEM_13>
    Cross_BB_scalar_dependence.7[0] = res_4;
    goto <bb 4>;

  }
  bb_8 (preds = {bb_4 bb_2 }, succs = {bb_1 })
  {
    <bb 8>:
    # res_12 = PHI <_16(4), 0(2)>
    # .MEM_2 = PHI <.MEM_19(4), .MEM_3(D)(2)>
    # VUSE <.MEM_2>
    return res_12;

  }
  loop_1 (header = 5, latch = 6, niter = , upper_bound = 2147483646)
  {
    bb_5 (preds = {bb_3 bb_6 }, succs = {bb_6 bb_7 })
    {
      <bb 5>:
      # i_10 = PHI <0(3), i_6(6)>
      # .MEM_1 = PHI <.MEM_8(3), .MEM_13(6)>
      # VUSE <.MEM_1>
      res_11 = phi_out_of_ssa.5[0];
      res_5 = res_11 + i_10;
      # .MEM_7 = VDEF <.MEM_1>
      Close_Phi.6[0] = res_5;
      # .MEM_13 = VDEF <.MEM_7>
      phi_out_of_ssa.5[0] = res_5;
      i_6 = i_10 + 1;
      if (i_6 < k.0_9)
        goto <bb 6>;
      else
        goto <bb 7>;

    }
    bb_6 (preds = {bb_5 }, succs = {bb_5 })
    {
      <bb 6>:
      goto <bb 5>;

    }
  }
}

If we change the name of variable k to n:

int n = 50;
static int __attribute__((noinline))
foo ()
{
  int i, res;
  for (i = 0, res = 0; i < n; i++)
    res += i;

  return res;
}

extern void abort ();

int
main (void)
{
  int res = foo ();


  if (res != 1225)
    abort ();

  return 0;
}

the following code will be produced, which gives wrong result

ISL AST generated by ISL:
{
  S_6();
  for (int c1 = 0; c1 < n.0; c1 += 1)
    S_4(c1);
}

Gimple code:
loop_0 (header = 0, latch = 1, niter = )
{
  bb_2 (preds = {bb_0 }, succs = {bb_3 bb_8 })
  {
    <bb 2>:
    # VUSE <.MEM_3(D)>
    n.0_9 = n;
    if (n.0_9 > 0)
      goto <bb 3>;
    else
      goto <bb 8>;

  }
  bb_3 (preds = {bb_2 }, succs = {bb_4 bb_7 })
  {
    <bb 3>:
    # .MEM_8 = VDEF <.MEM_3(D)>
    phi_out_of_ssa.5[0] = 0;
    # VUSE <.MEM_8>
    res_20 = Close_Phi.6[0];
    # .MEM_21 = VDEF <.MEM_8>
    Cross_BB_scalar_dependence.7[0] = res_20;
    _22 = n.0_9 > 0;
    if (_22 != 0)
      goto <bb 4>;
    else
      goto <bb 7>;

  }
  bb_4 (preds = {bb_3 }, succs = {bb_5 })
  {
    <bb 4>:
    _23 = (signed long) n.0_9;
    _24 = _23 + -1;

  }
  bb_7 (preds = {bb_5 bb_3 }, succs = {bb_8 })
  {
    <bb 7>:
    # .MEM_32 = PHI <.MEM_31(5), .MEM_21(3)>
    # VUSE <.MEM_32>
    res_17 = Cross_BB_scalar_dependence.7[0];
    _16 = res_17;

  }
  bb_8 (preds = {bb_7 bb_2 }, succs = {bb_1 })
  {
    <bb 8>:
    # res_12 = PHI <_16(7), 0(2)>
    # .MEM_2 = PHI <.MEM_32(7), .MEM_3(D)(2)>
    # VUSE <.MEM_2>
    return res_12;

  }
  loop_2 (header = 5, latch = 6, niter = (unsigned long) ((signed
long) n.0_9 + -1), upper_bound = 9223372036854775806)
  {
    bb_5 (preds = {bb_4 bb_6 }, succs = {bb_6 bb_7 })
    {
      <bb 5>:
      # graphite_IV.8_25 = PHI <0(4), graphite_IV.8_26(6)>
      # .MEM_33 = PHI <.MEM_21(4), .MEM_31(6)>
      # VUSE <.MEM_33>
      res_27 = phi_out_of_ssa.5[0];
      _29 = (int) graphite_IV.8_25;
      res_28 = res_27 + _29;
      # .MEM_30 = VDEF <.MEM_33>
      Close_Phi.6[0] = res_28;
      # .MEM_31 = VDEF <.MEM_30>
      phi_out_of_ssa.5[0] = res_28;
      graphite_IV.8_26 = graphite_IV.8_25 + 1;
      if (graphite_IV.8_25 < _24)
        goto <bb 6>;
      else
        goto <bb 7>;

    }
    bb_6 (preds = {bb_5 }, succs = {bb_5 })
    {
      <bb 6>:
      goto <bb 5>;

    }
  }
}

It seems that isl produce some illegal transformation, because in the
last case it uses the old version of variable res:

  bb_7 (preds = {bb_5 bb_3 }, succs = {bb_8 })
  {
    <bb 7>:
    # .MEM_32 = PHI <.MEM_31(5), .MEM_21(3)>
    # VUSE <.MEM_32>
    res_17 = Cross_BB_scalar_dependence.7[0];
    _16 = res_17;

  }

The original Gimple code for the second example is similar to the first one:

loop_0 (header = 0, latch = 1, niter = )
{
  bb_2 (preds = {bb_0 }, succs = {bb_3 bb_8 })
  {
    <bb 2>:
    # VUSE <.MEM_3(D)>
    n.0_9 = n;
    if (n.0_9 > 0)
      goto <bb 3>;
    else
      goto <bb 8>;

  }
  bb_3 (preds = {bb_2 }, succs = {bb_5 })
  {
    <bb 3>:
    # .MEM_8 = VDEF <.MEM_3(D)>
    phi_out_of_ssa.5[0] = 0;
    goto <bb 5>;

  }
  bb_4 (preds = {bb_7 }, succs = {bb_8 })
  {
    <bb 4>:
    # .MEM_19 = PHI <.MEM_18(7)>
    # VUSE <.MEM_19>
    res_17 = Cross_BB_scalar_dependence.7[0];
    _16 = res_17;
    goto <bb 8>;

  }
  bb_7 (preds = {bb_5 }, succs = {bb_4 })
  {
    <bb 7>:
    # VUSE <.MEM_13>
    res_4 = Close_Phi.6[0];
    # .MEM_18 = VDEF <.MEM_13>
    Cross_BB_scalar_dependence.7[0] = res_4;
    goto <bb 4>;

  }
  bb_8 (preds = {bb_4 bb_2 }, succs = {bb_1 })
  {
    <bb 8>:
    # res_12 = PHI <_16(4), 0(2)>
    # .MEM_2 = PHI <.MEM_19(4), .MEM_3(D)(2)>
    # VUSE <.MEM_2>
    return res_12;

  }
  loop_1 (header = 5, latch = 6, niter = , upper_bound = 2147483646)
  {
    bb_5 (preds = {bb_3 bb_6 }, succs = {bb_6 bb_7 })
    {
      <bb 5>:
      # i_10 = PHI <0(3), i_6(6)>
      # .MEM_1 = PHI <.MEM_8(3), .MEM_13(6)>
      # VUSE <.MEM_1>
      res_11 = phi_out_of_ssa.5[0];
      res_5 = res_11 + i_10;
      # .MEM_7 = VDEF <.MEM_1>
      Close_Phi.6[0] = res_5;
      # .MEM_13 = VDEF <.MEM_7>
      phi_out_of_ssa.5[0] = res_5;
      i_6 = i_10 + 1;
      if (i_6 < n.0_9)
        goto <bb 6>;
      else
        goto <bb 7>;

    }
    bb_6 (preds = {bb_5 }, succs = {bb_5 })
    {
      <bb 6>:
      goto <bb 5>;

    }
  }
}

Do you know anything about this issue? Should we use some options to
avoid illegal transformations (I haven't fount them)? Is it possible
to manually update SSA form to use the last versions of variables (I
haven't found such possibilities)?

P.S. There are other examples of wrong generations, but it is
difficult to find the reason of errors in them.

P.S. CLooG generates the same code for both examples:

CLAST generated by CLooG:
for (scat_1=0;scat_1<=k.0_9-1;scat_1++) {
  (scat_1);
}
();

--
                                   Cheers, Roman Gareev.
Index: gcc/graphite-isl-ast-to-gimple.c
===================================================================
--- gcc/graphite-isl-ast-to-gimple.c    (revision 212888)
+++ gcc/graphite-isl-ast-to-gimple.c    (working copy)
@@ -547,6 +547,26 @@
   return last_e;
 }
 
+/* Translates an isl_ast_node_block to Gimple. */
+
+static edge
+translate_isl_ast_node_block (loop_p context_loop,
+                             __isl_keep isl_ast_node *node,
+                             edge next_e, ivs_params &ip)
+{
+  gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_block);
+  isl_ast_node_list *node_list = isl_ast_node_block_get_children (node);
+  int i;
+  for (i = 0; i < isl_ast_node_list_n_ast_node (node_list); i++)
+    {
+      isl_ast_node *tmp_node = isl_ast_node_list_get_ast_node (node_list, i);
+      next_e = translate_isl_ast (context_loop, tmp_node, next_e, ip);
+      isl_ast_node_free (tmp_node);
+    }
+  isl_ast_node_list_free (node_list);
+  return next_e;
+}
+
 /* Translates an ISL AST node NODE to GCC representation in the
    context of a SESE.  */
 
@@ -570,7 +590,8 @@
       return next_e;
 
     case isl_ast_node_block:
-      return next_e;
+      return translate_isl_ast_node_block (context_loop, node,
+                                          next_e, ip);
 
     default:
       gcc_unreachable ();

Reply via email to