[LLVMdev] [DragonEgg] [Polly] Should we expect DragonEgg to produce identical LLVM IR for identical GIMPLE?

Duncan Sands baldrick at free.fr
Tue Jan 1 05:45:08 PST 2013


Hi Dmitry,

>
> In our compiler we use a modified version LLVM Polly, which is very sensitive to
> proper code generation. Among the number of limitations, the loop region
> (enclosed by phi node on induction variable and branch) is required to be free
> of additional memory-dependent branches. In other words, there must be no
> conditional "br" instructions below phi nodes. The problem we are facing is that
> from *identical* GIMPLE for 3d loop used in different contexts DragonEgg may
> generate LLVM IR either conforming the described limitation, or violating it.

the gimple isn't the same at all (see below).  The differences are directly
reflected in the unoptimized LLVM IR, turning up as additional memory loads
in the "bad" version.  In addition, the Fortran isn't really the same either:
Fortran semantics allows the compiler to assume that the parameters of your
new function "compute" (which are all passed in by reference, i.e. as pointers)
do not alias each other or anything else in sight (i.e. they get the "restrict"
qualifier in the gimple, noalias in the LLVM IR).  Thus by factorizing the loop
into "compute" you are actually giving the compiler more information.

Summary:
   (1) as far as I can see the unoptimized LLVM IR is a direct reflection of
the gimple: the differences for the loop part come directly from differences
in the gimple;
   (2) the optimizers do a better good when you have "compute" partly because you
provided them with additional aliasing information; this better optimized
version then gets inlined into MAIN__.
   (3) this leaves the question of whether in the bad version it is logically
possible for the optimizers to deduce the same aliasing information as is
handed to them for free in the good version.  To work this out it would be
nice to have a smaller testcase.

Ciao, Duncan.

PS: Gimple differences for the loop part.  I replaced all variable indices and
such with X otherwise they get in the way of the diffing.

  <bb X>:
    # k_X = PHI <k_X(X), k_X(X)>
-  D.X_X = ny;
+  D.X_X = *ny_X(D);
    j_X = X;
    if (j_X <= D.X_X)
      goto <bb X>;
@@ -16,7 +74,7 @@

  <bb X>:
    # j_X = PHI <j_X(X), j_X(X)>
-  D.X_X = nx;
+  D.X_X = *nx_X(D);
    i_X = X;
    if (i_X <= D.X_X)
      goto <bb X>;
@@ -25,48 +83,36 @@

  <bb X>:
    # i_X = PHI <i_X(X), i_X(X)>
-  D.X_X = xy.data;
    D.X_X = (integer(kind=X)) i_X;
    D.X_X = (integer(kind=X)) k_X;
-  D.X_X = xy.dim[X].stride;
-  D.X_X = D.X_X * D.X_X;
+  D.X_X = D.X_X * stride.X_X;
    D.X_X = (integer(kind=X)) j_X;
-  D.X_X = xy.dim[X].stride;
-  D.X_X = D.X_X * D.X_X;
+  D.X_X = D.X_X * stride.X_X;
    D.X_X = D.X_X + D.X_X;
    D.X_X = D.X_X + D.X_X;
-  D.X_X = xy.offset;
-  D.X_X = D.X_X + D.X_X;
-  D.X_X = x.data;
+  D.X_X = D.X_X + offset.X_X;
    D.X_X = (integer(kind=X)) i_X;
    D.X_X = (integer(kind=X)) k_X;
-  D.X_X = x.dim[X].stride;
-  D.X_X = D.X_X * D.X_X;
+  D.X_X = D.X_X * stride.X_X;
    D.X_X = (integer(kind=X)) j_X;
-  D.X_X = x.dim[X].stride;
-  D.X_X = D.X_X * D.X_X;
+  D.X_X = D.X_X * stride.X_X;
    D.X_X = D.X_X + D.X_X;
    D.X_X = D.X_X + D.X_X;
-  D.X_X = x.offset;
-  D.X_X = D.X_X + D.X_X;
-  D.X_X = MEM[(real(kind=X)[X:] *)D.X_X][D.X_X];
+  D.X_X = D.X_X + offset.X_X;
+  D.X_X = *x_X(D)[D.X_X];
    D.X_X = sinf (D.X_X);
    D.X_X = asinf (D.X_X);
-  D.X_X = y.data;
    D.X_X = (integer(kind=X)) i_X;
-  D.X_X = y.dim[X].stride;
-  D.X_X = y.dim[X].stride;
-  D.X_X = D.X_X + D.X_X;
+  D.X_X = stride.X_X + stride.X_X;
    D.X_X = (integer(kind=X)) k_X;
    D.X_X = D.X_X * D.X_X;
    D.X_X = D.X_X + D.X_X;
-  D.X_X = y.offset;
-  D.X_X = D.X_X + D.X_X;
-  D.X_X = MEM[(real(kind=X)[X:] *)D.X_X][D.X_X];
+  D.X_X = D.X_X + offset.X_X;
+  D.X_X = *y_X(D)[D.X_X];
    D.X_X = cosf (D.X_X);
    D.X_X = acosf (D.X_X);
    D.X_X = D.X_X + D.X_X;
-  MEM[(real(kind=X)[X:] *)D.X_X][D.X_X] = D.X_X;
+  *xy_X(D)[D.X_X] = D.X_X;
    D.X_X = i_X == D.X_X;
    i_X = i_X + X;
    if (D.X_X != X)




More information about the llvm-dev mailing list