forked from OSchip/llvm-project
[CodeGen] Add flag to code-generate most memory access expressions
Introduce the new flag -polly-codegen-generate-expressions which forces Polly to code generate AST expressions instead of using our SCEV based access expression generation even for cases where the original memory access relation was not changed and the SCEV based access expression could be code generated without any issue. This is an experimental option for better testing the isl ast expression generation. The default behavior of Polly remains unchanged. We also exclude a couple of cases for which the AST expression is not yet working. llvm-svn: 287694
This commit is contained in:
parent
198955536e
commit
b3c3d149b9
|
@ -597,8 +597,6 @@ private:
|
|||
isl_map *NewAccessRelation;
|
||||
// @}
|
||||
|
||||
bool isAffine() const { return IsAffine; }
|
||||
|
||||
__isl_give isl_basic_map *createBasicAccessMap(ScopStmt *Statement);
|
||||
|
||||
void assumeNoOutOfBound();
|
||||
|
@ -1037,6 +1035,9 @@ public:
|
|||
|
||||
/// Print the MemoryAccess to stderr.
|
||||
void dump() const;
|
||||
|
||||
/// Is the memory access affine?
|
||||
bool isAffine() const { return IsAffine; }
|
||||
};
|
||||
|
||||
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
|
||||
|
|
|
@ -65,6 +65,15 @@ static cl::opt<bool> PollyGenerateRTCPrint(
|
|||
cl::desc("Emit code that prints the runtime check result dynamically."),
|
||||
cl::Hidden, cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
|
||||
|
||||
// If this option is set we always use the isl AST generator to regenerate
|
||||
// memory accesses. Without this option set we regenerate expressions using the
|
||||
// original SCEV expressions and only generate new expressions in case the
|
||||
// access relation has been changed and consequently must be regenerated.
|
||||
static cl::opt<bool> PollyGenerateExpressions(
|
||||
"polly-codegen-generate-expressions",
|
||||
cl::desc("Generate AST expressions for unmodified and modified accesses"),
|
||||
cl::Hidden, cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
|
||||
|
||||
__isl_give isl_ast_expr *
|
||||
IslNodeBuilder::getUpperBound(__isl_keep isl_ast_node *For,
|
||||
ICmpInst::Predicate &Predicate) {
|
||||
|
@ -728,9 +737,23 @@ IslNodeBuilder::createNewAccesses(ScopStmt *Stmt,
|
|||
Stmt->setAstBuild(Build);
|
||||
|
||||
for (auto *MA : *Stmt) {
|
||||
if (!MA->hasNewAccessRelation())
|
||||
continue;
|
||||
if (!MA->hasNewAccessRelation()) {
|
||||
if (PollyGenerateExpressions) {
|
||||
if (!MA->isAffine())
|
||||
continue;
|
||||
if (MA->getLatestScopArrayInfo()->getBasePtrOriginSAI())
|
||||
continue;
|
||||
|
||||
auto *BasePtr =
|
||||
dyn_cast<Instruction>(MA->getLatestScopArrayInfo()->getBasePtr());
|
||||
if (BasePtr && Stmt->getParent()->getRegion().contains(BasePtr))
|
||||
continue;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
assert(MA->isAffine() &&
|
||||
"Only affine memory accesses can be code generated");
|
||||
assert(!MA->getLatestScopArrayInfo()->getBasePtrOriginSAI() &&
|
||||
"Generating new index expressions to indirect arrays not working");
|
||||
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
; RUN: opt %loadPolly -polly-codegen -polly-codegen-generate-expressions=false \
|
||||
; RUN: -S < %s | FileCheck %s -check-prefix=SCEV
|
||||
; RUN: opt %loadPolly -polly-codegen -polly-codegen-generate-expressions=true \
|
||||
; RUN: -S < %s | FileCheck %s -check-prefix=ASTEXPR
|
||||
;
|
||||
; void foo(float A[]) {
|
||||
; for (long i = 0; i < 100; i++)
|
||||
; A[i % 4] += 10;
|
||||
; }
|
||||
|
||||
; SCEV: polly.stmt.bb2: ; preds = %polly.loop_header
|
||||
; SCEV-NEXT: %p_tmp = srem i64 %polly.indvar, 4
|
||||
; SCEV-NEXT: %p_tmp3 = getelementptr inbounds float, float* %A, i64 %p_tmp
|
||||
; SCEV-NEXT: %tmp4_p_scalar_ = load float, float* %p_tmp3, align 4, !alias.scope !0, !noalias !2
|
||||
; SCEV-NEXT: %p_tmp5 = fadd float %tmp4_p_scalar_, 1.000000e+01
|
||||
; SCEV-NEXT: store float %p_tmp5, float* %p_tmp3, align 4, !alias.scope !0, !noalias !2
|
||||
; SCEV-NEXT: %polly.indvar_next = add nsw i64 %polly.indvar, 1
|
||||
; SCEV-NEXT: %polly.loop_cond = icmp sle i64 %polly.indvar, 98
|
||||
; SCEV-NEXT: br i1 %polly.loop_cond, label %polly.loop_header, label %polly.loop_exit
|
||||
|
||||
; ASTEXPR: polly.stmt.bb2: ; preds = %polly.loop_header
|
||||
; ASTEXPR-NEXT: %pexp.pdiv_r = urem i64 %polly.indvar, 4
|
||||
; ASTEXPR-NEXT: %polly.access.A = getelementptr float, float* %A, i64 %pexp.pdiv_r
|
||||
; ASTEXPR-NEXT: %tmp4_p_scalar_ = load float, float* %polly.access.A, align 4, !alias.scope !0, !noalias !2
|
||||
; ASTEXPR-NEXT: %p_tmp5 = fadd float %tmp4_p_scalar_, 1.000000e+01
|
||||
; ASTEXPR-NEXT: %pexp.pdiv_r1 = urem i64 %polly.indvar, 4
|
||||
; ASTEXPR-NEXT: %polly.access.A2 = getelementptr float, float* %A, i64 %pexp.pdiv_r1
|
||||
; ASTEXPR-NEXT: store float %p_tmp5, float* %polly.access.A2, align 4, !alias.scope !0, !noalias !2
|
||||
; ASTEXPR-NEXT: %polly.indvar_next = add nsw i64 %polly.indvar, 1
|
||||
; ASTEXPR-NEXT: %polly.loop_cond = icmp sle i64 %polly.indvar, 98
|
||||
; ASTEXPR-NEXT: br i1 %polly.loop_cond, label %polly.loop_header, label %polly.loop_exit
|
||||
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
|
||||
define void @foo(float* %A) {
|
||||
bb:
|
||||
br label %bb1
|
||||
|
||||
bb1: ; preds = %bb6, %bb
|
||||
%i.0 = phi i64 [ 0, %bb ], [ %tmp7, %bb6 ]
|
||||
%exitcond = icmp ne i64 %i.0, 100
|
||||
br i1 %exitcond, label %bb2, label %bb8
|
||||
|
||||
bb2: ; preds = %bb1
|
||||
%tmp = srem i64 %i.0, 4
|
||||
%tmp3 = getelementptr inbounds float, float* %A, i64 %tmp
|
||||
%tmp4 = load float, float* %tmp3, align 4
|
||||
%tmp5 = fadd float %tmp4, 1.000000e+01
|
||||
store float %tmp5, float* %tmp3, align 4
|
||||
br label %bb6
|
||||
|
||||
bb6: ; preds = %bb2
|
||||
%tmp7 = add nuw nsw i64 %i.0, 1
|
||||
br label %bb1
|
||||
|
||||
bb8: ; preds = %bb1
|
||||
ret void
|
||||
}
|
Loading…
Reference in New Issue