ScopInfo: Split start value from SCEVAddRecExpr to enable parameter sharing.

SCoP invariant parameters with the different start value would deter parameter
sharing. For example, when compiling the following C code:

  void foo(float *input) {
    for (long j = 0; j < 8; j++) {
      // SCoP begin
      for (long i = 0; i < 8; i++) {
        float x = input[j * 64 + i + 1];
        input[j * 64 + i] = x * x;
      }
    }
  }

Polly would creat two parameters for these memory accesses:

    p_0: {0,+,256}
    p_2: {4,+,256}
    [j * 64 + i + 1] => MemRef_input[o0] : 4o0 = p_1 + 4i0
    [j * 64 + i]     => MemRef_input[o0] : 4o0 = p_0 + 4i0

These parameters only differ from start value. To enable parameter sharing,
we split the start value from SCEVAddRecExpr, so they would share a single
parameter that always has zero start value:

    p0: {0,+,256}<%for.cond1.preheader>
    [j * 64 + i + 1] => MemRef_input[o0] : 4o0 = 4 + p_1 + 4i0
    [j * 64 + i]     => MemRef_input[o0] : 4o0 = p_0 + 4i0

Such translation can make the polly-dependence much faster.

Contributed-by: Star Tan <tanmx_star@yeah.net>
llvm-svn: 187728
diff --git a/polly/lib/Support/SCEVValidator.cpp b/polly/lib/Support/SCEVValidator.cpp
index afb41a4..0c71956 100644
--- a/polly/lib/Support/SCEVValidator.cpp
+++ b/polly/lib/Support/SCEVValidator.cpp
@@ -278,7 +278,22 @@
 
     assert(Start.isConstant() && Recurrence.isConstant() &&
            "Expected 'Start' and 'Recurrence' to be constant");
-    return ValidatorResult(SCEVType::PARAM, Expr);
+
+    // Directly generate ValidatorResult for Expr if 'start' is zero.
+    if (Expr->getStart()->isZero())
+      return ValidatorResult(SCEVType::PARAM, Expr);
+
+    // Translate AddRecExpr from '{start, +, inc}' into 'start + {0, +, inc}'
+    // if 'start' is not zero.
+    const SCEV *ZeroStartExpr = SE.getAddRecExpr(
+        SE.getConstant(Expr->getStart()->getType(), 0),
+        Expr->getStepRecurrence(SE), Expr->getLoop(), SCEV::FlagAnyWrap);
+
+    ValidatorResult ZeroStartResult =
+        ValidatorResult(SCEVType::PARAM, ZeroStartExpr);
+    ZeroStartResult.addParamsFrom(Start);
+
+    return ZeroStartResult;
   }
 
   class ValidatorResult visitSMaxExpr(const SCEVSMaxExpr *Expr) {