[polly] r233501 - Strip constant factors from SCoP parameters

Johannes Doerfert doerfert at cs.uni-saarland.de
Sun Mar 29 13:45:09 PDT 2015


Author: jdoerfert
Date: Sun Mar 29 15:45:09 2015
New Revision: 233501

URL: http://llvm.org/viewvc/llvm-project?rev=233501&view=rev
Log:
Strip constant factors from SCoP parameters

  This will strip the constant factor of a parameter befor we add it to
  the SCoP. As a result the access functions are simplified, e.g., for
  the attached test case.


Added:
    polly/trunk/test/ScopInfo/constant_factor_in_parameter.ll
Modified:
    polly/trunk/include/polly/Support/SCEVValidator.h
    polly/trunk/lib/Analysis/ScopInfo.cpp
    polly/trunk/lib/Support/SCEVValidator.cpp
    polly/trunk/test/ScopInfo/multidim_single_and_multidim_array.ll

Modified: polly/trunk/include/polly/Support/SCEVValidator.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/Support/SCEVValidator.h?rev=233501&r1=233500&r2=233501&view=diff
==============================================================================
--- polly/trunk/include/polly/Support/SCEVValidator.h (original)
+++ polly/trunk/include/polly/Support/SCEVValidator.h Sun Mar 29 15:45:09 2015
@@ -51,6 +51,15 @@ std::vector<const llvm::SCEV *>
 getParamsInAffineExpr(const llvm::Region *R, const llvm::SCEV *Expression,
                       llvm::ScalarEvolution &SE,
                       const llvm::Value *BaseAddress = 0);
+
+/// @brief Extract the constant factors from the multiplication @p M.
+///
+/// @param M  A potential SCEV multiplication.
+/// @param SE The ScalarEvolution analysis to create new SCEVs.
+///
+/// @returns The constant factor in @p M and the rest of @p M.
+std::pair<const llvm::SCEV *, const llvm::SCEV *>
+extractConstantFactor(const llvm::SCEV *M, llvm::ScalarEvolution &SE);
 }
 
 #endif

Modified: polly/trunk/lib/Analysis/ScopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopInfo.cpp?rev=233501&r1=233500&r2=233501&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopInfo.cpp (original)
+++ polly/trunk/lib/Analysis/ScopInfo.cpp Sun Mar 29 15:45:09 2015
@@ -194,22 +194,15 @@ __isl_give isl_pw_aff *SCEVAffinator::vi
 }
 
 __isl_give isl_pw_aff *SCEVAffinator::visitMulExpr(const SCEVMulExpr *Expr) {
-  isl_pw_aff *Product = visit(Expr->getOperand(0));
-
-  for (int i = 1, e = Expr->getNumOperands(); i < e; ++i) {
-    isl_pw_aff *NextOperand = visit(Expr->getOperand(i));
-
-    if (!isl_pw_aff_is_cst(Product) && !isl_pw_aff_is_cst(NextOperand)) {
-      isl_pw_aff_free(Product);
-      isl_pw_aff_free(NextOperand);
-      return nullptr;
-    }
-
-    Product = isl_pw_aff_mul(Product, NextOperand);
-  }
-
-  // TODO: Check for NSW and NUW.
-  return Product;
+  // Divide Expr into a constant part and the rest. Then visit both and multiply
+  // the result to obtain the representation for Expr. While the second part of
+  // ConstantAndLeftOverPair might still be a SCEVMulExpr we will not get to
+  // this point again. The reason is that if it is a multiplication it consists
+  // only of parameters and we will stop in the visit(const SCEV *) function and
+  // return the isl_pw_aff for that parameter.
+  auto ConstantAndLeftOverPair = extractConstantFactor(Expr, *S->getSE());
+  return isl_pw_aff_mul(visit(ConstantAndLeftOverPair.first),
+                        visit(ConstantAndLeftOverPair.second));
 }
 
 __isl_give isl_pw_aff *SCEVAffinator::visitUDivExpr(const SCEVUDivExpr *Expr) {
@@ -1246,6 +1239,7 @@ void Scop::setContext(__isl_take isl_set
 
 void Scop::addParams(std::vector<const SCEV *> NewParameters) {
   for (const SCEV *Parameter : NewParameters) {
+    Parameter = extractConstantFactor(Parameter, *SE).second;
     if (ParameterIds.find(Parameter) != ParameterIds.end())
       continue;
 

Modified: polly/trunk/lib/Support/SCEVValidator.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Support/SCEVValidator.cpp?rev=233501&r1=233500&r2=233501&view=diff
==============================================================================
--- polly/trunk/lib/Support/SCEVValidator.cpp (original)
+++ polly/trunk/lib/Support/SCEVValidator.cpp Sun Mar 29 15:45:09 2015
@@ -562,4 +562,23 @@ std::vector<const SCEV *> getParamsInAff
 
   return Result.getParameters();
 }
+
+std::pair<const SCEV *, const SCEV *>
+extractConstantFactor(const SCEV *S, ScalarEvolution &SE) {
+
+  const SCEV *LeftOver = SE.getConstant(S->getType(), 1);
+  const SCEV *ConstPart = SE.getConstant(S->getType(), 1);
+
+  const SCEVMulExpr *M = dyn_cast<SCEVMulExpr>(S);
+  if (!M)
+    return std::make_pair(ConstPart, S);
+
+  for (const SCEV *Op : M->operands())
+    if (isa<SCEVConstant>(Op))
+      ConstPart = SE.getMulExpr(ConstPart, Op);
+    else
+      LeftOver = SE.getMulExpr(LeftOver, Op);
+
+  return std::make_pair(ConstPart, LeftOver);
+}
 }

Added: polly/trunk/test/ScopInfo/constant_factor_in_parameter.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/constant_factor_in_parameter.ll?rev=233501&view=auto
==============================================================================
--- polly/trunk/test/ScopInfo/constant_factor_in_parameter.ll (added)
+++ polly/trunk/test/ScopInfo/constant_factor_in_parameter.ll Sun Mar 29 15:45:09 2015
@@ -0,0 +1,43 @@
+; RUN: opt %loadPolly -analyze -polly-scops -polly-detect-unprofitable < %s | FileCheck %s
+;
+; Check that the constant part of the N * M * 4 expression is not part of the
+; parameter but explicit in the access function. This can avoid existentially
+; quantified variables, e.g., when computing the stride.
+;
+; CHECK: p1: (%N * %M)
+; CHECK: [N, p_1] -> { Stmt_for_body[i0] -> MemRef_A[4p_1 + i0] };
+;
+;    void f(int *A, int N, int M) {
+;      for (int i = 0; i < N; i++)
+;        A[i + N * M * 4] = i;
+;    }
+;
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @f(i32* %A, i32 %N, i32 %M) {
+entry:
+  %tmp = sext i32 %N to i64
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
+  %cmp = icmp slt i64 %indvars.iv, %tmp
+  br i1 %cmp, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %mul = mul nsw i32 %N, %M
+  %mul2 = mul nsw i32 %mul, 4
+  %tmp2 = sext i32 %mul2 to i64
+  %tmp3 = add nsw i64 %indvars.iv, %tmp2
+  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %tmp3
+  %tmp4 = trunc i64 %indvars.iv to i32
+  store i32 %tmp4, i32* %arrayidx, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body
+  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+  br label %for.cond
+
+for.end:                                          ; preds = %for.cond
+  ret void
+}

Modified: polly/trunk/test/ScopInfo/multidim_single_and_multidim_array.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/multidim_single_and_multidim_array.ll?rev=233501&r1=233500&r2=233501&view=diff
==============================================================================
--- polly/trunk/test/ScopInfo/multidim_single_and_multidim_array.ll (original)
+++ polly/trunk/test/ScopInfo/multidim_single_and_multidim_array.ll Sun Mar 29 15:45:09 2015
@@ -20,14 +20,14 @@ target datalayout = "e-m:e-i64:64-f80:12
 ; CHECK-NOT: Stmt_for_i_1
 
 ; NONAFFINE: p0: %n
-; NONAFFINE: p1: (4 * (-1 + %n) * %n)
+; NONAFFINE: p1: ((-1 + %n) * %n)
 ; NONAFFINE: Statements {
 ; NONAFFINE:   Stmt_for_i_1
 ; NONAFFINE:         MayWriteAccess :=   [Reduction Type: NONE]
 ; NONAFFINE:             [n, p_1] -> { Stmt_for_i_1[i0] -> MemRef_X[o0] : o0 >= -2305843009213693952 and o0 <= 2305843009213693949 };
 ; NONAFFINE:   Stmt_for_i_2
 ; NONAFFINE:         MustWriteAccess :=  [Reduction Type: NONE]
-; NONAFFINE:             [n, p_1] -> { Stmt_for_i_2[i0] -> MemRef_X[o0] : 4o0 = p_1 + 4i0 };
+; NONAFFINE:             [n, p_1] -> { Stmt_for_i_2[i0] -> MemRef_X[p_1 + i0] };
 
 ; DELIN: Stmt_for_i_1
 ; DELIN:   MustWriteAccess :=





More information about the llvm-commits mailing list