[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