Polly - Memory access optimizations

WARNING: This project was part of the Google Summer of Code 2011. Tt is currently not finished, but it is in the design and implementation stage. The Ideas/Plans described here may not yet be implemented in Polly and may be changed during the actual implementation.

This project adds memory access transformations to Polly. In many cases changing the memory access pattern yields to better data locality or removes dependences that would otherwise block transformations.

An examples which uses this feature is given below.

Consider the following loop
for (i = 0; i < 8; i++)
  sum += A[i];
Through memory access transformations this loop can be executed in parallel. It can be transformed to
// Create and initialize an array 'tmp' with size 4
for (i = 0; i < 8; i++)
  tmp[i % 4] += A[i];
sum = tmp[0] + tmp[1] + tmp[2] + tmp[3];
Optimizers like PluTo can schedule the code such that an outer, parallel loop is created:
parfor (ii = 0; ii < 4; ii++) {
  tmp[ii] = 0;
  for (i = ii * 2; i < (ii+1) * 2; i++)
    tmp[ii] += A[i];
  }
sum = tmp[0] + tmp[1] + tmp[2] + tmp[3];

TODO

Step 1

Polly exports its polyhedral description in a JSCoP file. Define how memory layout transformations are expressed in Polly and in the JSCOP file. Example:

Consider the following loop.

for (i = 0; i < 12; i++)
  A[i] = 0;
In the JSCOP file the memory accesses are represented as follows.
"accesses": [{
        "kind": "write",
                "relation": "{ Stmt[i] -> A[i] }"
}]
To perform a transformation we generate the following code:
for (i = 0; i < 12; i++)
  A[0] = i;
The representation in the JSCoP file is:
"accesses": [{
        "kind": "read",
                "relation": "{ Stmt[i] -> A[0] }"
}]
We need to detect this access function change.

Step 2

Update the code generation module to reflect the access function change made in Step 1.

Step 2.1 Code generation for a constant

In the JSCOP file an access function which has variables is changed to a constant. Code is generated to reflect this change. Let the content of original JSCOP file be:
"accesses" : [{
        "kind" : "read",
                 "relation" : "{ Stmt_for_body[i0] -> MemRef_A[i0] }"
}]
The transformed JSCOP file is:
"accesses" : [{
        "kind" : "read",
                 "relation" : "{ Stmt_for_body[i0] -> MemRef_A[10] }"
}]
Code is generated for this change.

Step 2.2 Code generation for coefficients

The coefficients of induction variables are changed here. Let the original JSCOP file be:
"accesses" : [{
      "kind" : "read",
               "relation" : "{ Stmt_for_body3[i0, i1] -> MemRef_A[32i0+i1] }"
}]
The transformed JSCOP file is:
"accesses" : [{
      "kind" : "read",
               "relation" : "{ Stmt_for_body3[i0, i1] -> MemRef_A[16i0+2i1+5] }"
}]
Code is generated for this change.