diff options
author | Tobias Grosser <tobias@grosser.es> | 2016-06-11 19:26:08 +0000 |
---|---|---|
committer | Tobias Grosser <tobias@grosser.es> | 2016-06-11 19:26:08 +0000 |
commit | 423642a59701ce381d9d4120929e5cc8c27f8489 (patch) | |
tree | 1710b8192563b06074c9d27fb4cb033542e24185 /polly | |
parent | 3fc09f7be672dd1adf4e0d939aa86badcdfd5df8 (diff) | |
download | bcm5719-llvm-423642a59701ce381d9d4120929e5cc8c27f8489.tar.gz bcm5719-llvm-423642a59701ce381d9d4120929e5cc8c27f8489.zip |
Recommit: "Look through IntToPtr & PtrToInt instructions"
IntToPtr and PtrToInt instructions are basically no-ops that we can handle as
such. In order to generate them properly as parameters we had to improve the
ScopExpander, though the change is the first in the direction of a more
aggressive scalar synthetization.
This patch was originally contributed by Johannes Doerfert in r271888, but was
in conflict with the revert in r272483. This is a recommit with some minor
adjustment to the test cases to take care of differing instruction names.
llvm-svn: 272485
Diffstat (limited to 'polly')
-rw-r--r-- | polly/lib/Support/SCEVAffinator.cpp | 4 | ||||
-rw-r--r-- | polly/lib/Support/SCEVValidator.cpp | 4 | ||||
-rw-r--r-- | polly/lib/Support/ScopHelper.cpp | 29 | ||||
-rw-r--r-- | polly/test/Isl/CodeGen/inner_scev_sdiv_2.ll | 5 | ||||
-rw-r--r-- | polly/test/Isl/CodeGen/ptrtoint_as_parameter.ll | 34 | ||||
-rw-r--r-- | polly/test/ScopInfo/int2ptr_ptr2int.ll | 71 | ||||
-rw-r--r-- | polly/test/ScopInfo/int2ptr_ptr2int_2.ll | 72 |
7 files changed, 210 insertions, 9 deletions
diff --git a/polly/lib/Support/SCEVAffinator.cpp b/polly/lib/Support/SCEVAffinator.cpp index bff074761e0..347c12f60fd 100644 --- a/polly/lib/Support/SCEVAffinator.cpp +++ b/polly/lib/Support/SCEVAffinator.cpp @@ -565,6 +565,10 @@ __isl_give PWACtx SCEVAffinator::visitSRemInstruction(Instruction *SRem) { __isl_give PWACtx SCEVAffinator::visitUnknown(const SCEVUnknown *Expr) { if (Instruction *I = dyn_cast<Instruction>(Expr->getValue())) { switch (I->getOpcode()) { + case Instruction::IntToPtr: + return visit(SE.getSCEVAtScope(I->getOperand(0), getScope())); + case Instruction::PtrToInt: + return visit(SE.getSCEVAtScope(I->getOperand(0), getScope())); case Instruction::SDiv: return visitSDivInstruction(I); case Instruction::SRem: diff --git a/polly/lib/Support/SCEVValidator.cpp b/polly/lib/Support/SCEVValidator.cpp index 85bf815a21d..4b8516338e6 100644 --- a/polly/lib/Support/SCEVValidator.cpp +++ b/polly/lib/Support/SCEVValidator.cpp @@ -368,6 +368,10 @@ public: if (Instruction *I = dyn_cast<Instruction>(Expr->getValue())) { switch (I->getOpcode()) { + case Instruction::IntToPtr: + return visit(SE.getSCEVAtScope(I->getOperand(0), Scope)); + case Instruction::PtrToInt: + return visit(SE.getSCEVAtScope(I->getOperand(0), Scope)); case Instruction::Load: return visitLoadInstruction(I, Expr); case Instruction::SDiv: diff --git a/polly/lib/Support/ScopHelper.cpp b/polly/lib/Support/ScopHelper.cpp index 8e7fb1edfff..d2c544d098d 100644 --- a/polly/lib/Support/ScopHelper.cpp +++ b/polly/lib/Support/ScopHelper.cpp @@ -246,6 +246,27 @@ private: const Region &R; ValueMapT *VMap; + const SCEV *visitGenericInst(const SCEVUnknown *E, Instruction *Inst, + Instruction *IP) { + if (!Inst || !R.contains(Inst)) + return E; + + assert(!Inst->mayThrow() && !Inst->mayReadOrWriteMemory() && + !isa<PHINode>(Inst)); + + auto *InstClone = Inst->clone(); + for (auto &Op : Inst->operands()) { + assert(SE.isSCEVable(Op->getType())); + auto *OpSCEV = SE.getSCEV(Op); + auto *OpClone = expandCodeFor(OpSCEV, Op->getType(), IP); + InstClone->replaceUsesOfWith(Op, OpClone); + } + + InstClone->setName(Name + Inst->getName()); + InstClone->insertBefore(IP); + return SE.getSCEV(InstClone); + } + const SCEV *visitUnknown(const SCEVUnknown *E) { // If a value mapping was given try if the underlying value is remapped. @@ -259,15 +280,11 @@ private: return visit(NewE); } + Instruction *StartIP = R.getEnteringBlock()->getTerminator(); Instruction *Inst = dyn_cast<Instruction>(E->getValue()); if (!Inst || (Inst->getOpcode() != Instruction::SRem && Inst->getOpcode() != Instruction::SDiv)) - return E; - - if (!R.contains(Inst)) - return E; - - Instruction *StartIP = R.getEnteringBlock()->getTerminator(); + return visitGenericInst(E, Inst, StartIP); const SCEV *LHSScev = SE.getSCEV(Inst->getOperand(0)); const SCEV *RHSScev = SE.getSCEV(Inst->getOperand(1)); diff --git a/polly/test/Isl/CodeGen/inner_scev_sdiv_2.ll b/polly/test/Isl/CodeGen/inner_scev_sdiv_2.ll index b98846a469e..9b925443300 100644 --- a/polly/test/Isl/CodeGen/inner_scev_sdiv_2.ll +++ b/polly/test/Isl/CodeGen/inner_scev_sdiv_2.ll @@ -3,10 +3,9 @@ ; The SCEV expression in this test case refers to a sequence of sdiv ; instructions, which are part of different bbs in the SCoP. When code ; generating the parameter expressions, the code that is generated by the SCEV -; expander has still references to the in-scop instructions, which is invalid. +; expander has still references to the in-scop instructions, which was invalid. ; -; CHECK: polly.split_new_and_old: -; CHECK-NOT: = sdiv i64 0, -4 +; CHECK: polly.start ; target triple = "x86_64-unknown-linux-gnu" diff --git a/polly/test/Isl/CodeGen/ptrtoint_as_parameter.ll b/polly/test/Isl/CodeGen/ptrtoint_as_parameter.ll new file mode 100644 index 00000000000..1bbb9dd27ff --- /dev/null +++ b/polly/test/Isl/CodeGen/ptrtoint_as_parameter.ll @@ -0,0 +1,34 @@ +; RUN: opt %loadPolly -polly-codegen -S < %s | FileCheck %s +; +; CHECK: polly.split_new_and_old: +; CHECK-NEXT: %pollysub.ptr.lhs.cast263 = ptrtoint i8* inttoptr (i64 1 to i8*) to i64 +; +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +; Function Attrs: nounwind uwtable +define void @XS_MIME__QuotedPrint_encode_qp() { +entry: + %Perl_sv_len = alloca i64, align 8 + br label %if.end + +if.end: ; preds = %entry + br label %while.cond + +while.cond: ; preds = %cond.true270, %if.then260, %if.end + %p.0 = phi i8* [ null, %if.end ], [ %p.4, %if.then260 ], [ %p.4, %cond.true270 ] + br i1 undef, label %if.then260, label %while.body210 + +while.body210: ; preds = %while.cond + unreachable + +if.then260: ; preds = %while.cond + %p.4 = getelementptr inbounds i8, i8* null, i64 1 + %sub.ptr.lhs.cast263 = ptrtoint i8* %p.4 to i64 + %sub.ptr.sub265 = sub i64 %sub.ptr.lhs.cast263, 0 + %div = udiv i64 0, %sub.ptr.sub265 + %cmp268 = icmp ult i64 0, %div + br i1 %cmp268, label %cond.true270, label %while.cond + +cond.true270: ; preds = %if.then260 + br label %while.cond +} diff --git a/polly/test/ScopInfo/int2ptr_ptr2int.ll b/polly/test/ScopInfo/int2ptr_ptr2int.ll new file mode 100644 index 00000000000..0979ebaebba --- /dev/null +++ b/polly/test/ScopInfo/int2ptr_ptr2int.ll @@ -0,0 +1,71 @@ +; RUN: opt %loadPolly -analyze -polly-scops < %s | FileCheck %s +; RUN: opt %loadPolly -S -polly-codegen < %s | FileCheck %s --check-prefix=IR +; +; void f(long *A, long *ptr, long val) { +; for (long i = 0; i < 100; i++) { +; long ptrV = ((long)(ptr + 1)) + 1; +; long valP = (long)(((long *)(val + 1)) + 1); +; A[ptrV] += A[valP]; +; } +; } +; +; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 0] +; CHECK-NEXT: [val, ptr] -> { Stmt_for_body[i0] -> MemRef_A[9 + val] }; +; CHECK-NEXT: ReadAccess := [Reduction Type: +] [Scalar: 0] +; CHECK-NEXT: [val, ptr] -> { Stmt_for_body[i0] -> MemRef_A[9 + ptr] }; +; CHECK-NEXT: MustWriteAccess := [Reduction Type: +] [Scalar: 0] +; CHECK-NEXT: [val, ptr] -> { Stmt_for_body[i0] -> MemRef_A[9 + ptr] }; +; +; IR: polly.stmt.for.body: +; IR-NEXT: %p_tmp = ptrtoint i64* %scevgep to i64 +; IR-NEXT: %p_add = add nsw i64 %p_tmp, 1 +; IR-NEXT: %p_tmp1 = inttoptr i64 %10 to i64* +; IR-NEXT: %p_add.ptr2 = getelementptr inbounds i64, i64* %p_tmp1, i64 1 +; IR-NEXT: %p_tmp2 = ptrtoint i64* %p_add.ptr2 to i64 +; IR-NEXT: %p_arrayidx = getelementptr inbounds i64, i64* %A, i64 %p_tmp2 +; IR-NEXT: %tmp3_p_scalar_ = load i64, i64* %p_arrayidx +; IR-NEXT: %p_arrayidx3 = getelementptr inbounds i64, i64* %A, i64 %p_add +; IR-NEXT: %tmp4_p_scalar_ = load i64, i64* %p_arrayidx3 +; IR-NEXT: %p_add4 = add nsw i64 %tmp4_p_scalar_, %tmp3_p_scalar_ +; IR-NEXT: store i64 %p_add4, i64* %p_arrayidx3 +; +; IR: polly.loop_preheader: +; IR-NEXT: %scevgep = getelementptr i64, i64* %ptr, i64 1 +; IR-NEXT: %10 = add i64 %val, 1 +; IR-NEXT: br label %polly.loop_header +; +; +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @f(i64* %A, i64* %ptr, i64 %val) { +entry: + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %i.0 = phi i64 [ 0, %entry ], [ %inc, %for.inc ] + %exitcond = icmp ne i64 %i.0, 100 + br i1 %exitcond, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %add.ptr = getelementptr inbounds i64, i64* %ptr, i64 1 + %tmp = ptrtoint i64* %add.ptr to i64 + %add = add nsw i64 %tmp, 1 + %add1 = add nsw i64 %val, 1 + %tmp1 = inttoptr i64 %add1 to i64* + %add.ptr2 = getelementptr inbounds i64, i64* %tmp1, i64 1 + %tmp2 = ptrtoint i64* %add.ptr2 to i64 + %arrayidx = getelementptr inbounds i64, i64* %A, i64 %tmp2 + %tmp3 = load i64, i64* %arrayidx + %arrayidx3 = getelementptr inbounds i64, i64* %A, i64 %add + %tmp4 = load i64, i64* %arrayidx3 + %add4 = add nsw i64 %tmp4, %tmp3 + store i64 %add4, i64* %arrayidx3 + br label %for.inc + +for.inc: ; preds = %for.body + %inc = add nuw nsw i64 %i.0, 1 + br label %for.cond + +for.end: ; preds = %for.cond + ret void +} diff --git a/polly/test/ScopInfo/int2ptr_ptr2int_2.ll b/polly/test/ScopInfo/int2ptr_ptr2int_2.ll new file mode 100644 index 00000000000..e47e181c97b --- /dev/null +++ b/polly/test/ScopInfo/int2ptr_ptr2int_2.ll @@ -0,0 +1,72 @@ +; RUN: opt %loadPolly -analyze -polly-scops < %s | FileCheck %s +; RUN: opt %loadPolly -S -polly-codegen < %s | FileCheck %s --check-prefix=IR +; +; void f(long *A, long *B, long *ptr, long val) { +; for (long i = 0; i < 100; i++) { +; long ptrV = ((long)(ptr + 1)) + 1; +; long valP = (long)(((long *)(val + 1)) + 1); +; A[ptrV] += B[valP]; +; } +; } +; +; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 0] +; CHECK-NEXT: [val, ptr] -> { Stmt_for_body[i0] -> MemRef_B[9 + val] }; +; CHECK-NEXT: Execution Context: [val, ptr] -> { : val <= 9223372036854775806 } +; +; CHECK: ReadAccess := [Reduction Type: +] [Scalar: 0] +; CHECK-NEXT: [val, ptr] -> { Stmt_for_body[i0] -> MemRef_A[9 + ptr] }; +; CHECK-NEXT: MustWriteAccess := [Reduction Type: +] [Scalar: 0] +; CHECK-NEXT: [val, ptr] -> { Stmt_for_body[i0] -> MemRef_A[9 + ptr] }; +; +; IR: polly.stmt.for.body: +; IR-NEXT: %p_tmp = ptrtoint i64* %scevgep to i64 +; IR-NEXT: %p_add = add nsw i64 %p_tmp, 1 +; IR-NEXT: %p_tmp1 = inttoptr i64 %26 to i64* +; IR-NEXT: %p_add.ptr2 = getelementptr inbounds i64, i64* %p_tmp1, i64 1 +; IR-NEXT: %p_tmp2 = ptrtoint i64* %p_add.ptr2 to i64 +; IR-NEXT: %p_arrayidx = getelementptr inbounds i64, i64* %B, i64 %p_tmp2 +; IR-NEXT: %p_arrayidx3 = getelementptr inbounds i64, i64* %A, i64 %p_add +; IR-NEXT: %tmp4_p_scalar_ = load i64, i64* %p_arrayidx3 +; IR-NEXT: %p_add4 = add nsw i64 %tmp4_p_scalar_, %polly.preload.tmp3.merge +; IR-NEXT: store i64 %p_add4, i64* %p_arrayidx3 +; +; IR: polly.loop_preheader: +; IR-NEXT: %scevgep = getelementptr i64, i64* %ptr, i64 1 +; IR-NEXT: %26 = add i64 %val, 1 +; IR-NEXT: br label %polly.loop_header +; +; +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @f(i64* %A, i64* %B, i64* %ptr, i64 %val) { +entry: + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %i.0 = phi i64 [ 0, %entry ], [ %inc, %for.inc ] + %exitcond = icmp ne i64 %i.0, 100 + br i1 %exitcond, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %add.ptr = getelementptr inbounds i64, i64* %ptr, i64 1 + %tmp = ptrtoint i64* %add.ptr to i64 + %add = add nsw i64 %tmp, 1 + %add1 = add nsw i64 %val, 1 + %tmp1 = inttoptr i64 %add1 to i64* + %add.ptr2 = getelementptr inbounds i64, i64* %tmp1, i64 1 + %tmp2 = ptrtoint i64* %add.ptr2 to i64 + %arrayidx = getelementptr inbounds i64, i64* %B, i64 %tmp2 + %tmp3 = load i64, i64* %arrayidx + %arrayidx3 = getelementptr inbounds i64, i64* %A, i64 %add + %tmp4 = load i64, i64* %arrayidx3 + %add4 = add nsw i64 %tmp4, %tmp3 + store i64 %add4, i64* %arrayidx3 + br label %for.inc + +for.inc: ; preds = %for.body + %inc = add nuw nsw i64 %i.0, 1 + br label %for.cond + +for.end: ; preds = %for.cond + ret void +} |