diff options
| author | Tobias Grosser <tobias@grosser.es> | 2017-09-25 20:27:15 +0000 |
|---|---|---|
| committer | Tobias Grosser <tobias@grosser.es> | 2017-09-25 20:27:15 +0000 |
| commit | 5e531dfef41bb7cf451481e01552a31c598fdeac (patch) | |
| tree | a74a434965a2f6d882c9600bdf0d1eef03c657e9 | |
| parent | 01414bdc2c23f24e255d4b068f90938035f1149a (diff) | |
| download | bcm5719-llvm-5e531dfef41bb7cf451481e01552a31c598fdeac.tar.gz bcm5719-llvm-5e531dfef41bb7cf451481e01552a31c598fdeac.zip | |
[ScopInfo] Allow invariant loads in branch conditions
In case the value used in a branch condition is a load instruction, assume this
load to be invariant.
llvm-svn: 314146
| -rw-r--r-- | polly/lib/Analysis/ScopDetection.cpp | 6 | ||||
| -rw-r--r-- | polly/lib/Analysis/ScopInfo.cpp | 12 | ||||
| -rw-r--r-- | polly/test/ScopInfo/invariant_load_branch_condition.ll | 51 |
3 files changed, 67 insertions, 2 deletions
diff --git a/polly/lib/Analysis/ScopDetection.cpp b/polly/lib/Analysis/ScopDetection.cpp index df3acd15e06..38b7be1d1b0 100644 --- a/polly/lib/Analysis/ScopDetection.cpp +++ b/polly/lib/Analysis/ScopDetection.cpp @@ -595,6 +595,12 @@ bool ScopDetection::isValidBranch(BasicBlock &BB, BranchInst *BI, return true; } + if (auto Load = dyn_cast<LoadInst>(Condition)) + if (!IsLoopBranch) { + Context.RequiredILS.insert(Load); + return true; + } + // Non constant conditions of branches need to be ICmpInst. if (!isa<ICmpInst>(Condition)) { if (!IsLoopBranch && AllowNonAffineSubRegions && diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp index dbf38042382..2cdf2cba59b 100644 --- a/polly/lib/Analysis/ScopInfo.cpp +++ b/polly/lib/Analysis/ScopInfo.cpp @@ -1540,9 +1540,18 @@ bool buildConditionSets(Scop &S, BasicBlock *BB, Value *Condition, TerminatorInst *TI, Loop *L, __isl_keep isl_set *Domain, DenseMap<BasicBlock *, isl::set> &InvalidDomainMap, SmallVectorImpl<__isl_give isl_set *> &ConditionSets) { + ScalarEvolution &SE = *S.getSE(); isl_set *ConsequenceCondSet = nullptr; - if (auto *PHI = dyn_cast<PHINode>(Condition)) { + if (auto Load = dyn_cast<LoadInst>(Condition)) { + const SCEV *LHSSCEV = SE.getSCEVAtScope(Load, L); + const SCEV *RHSSCEV = SE.getZero(LHSSCEV->getType()); + bool NonNeg = false; + isl_pw_aff *LHS = getPwAff(S, BB, InvalidDomainMap, LHSSCEV, NonNeg); + isl_pw_aff *RHS = getPwAff(S, BB, InvalidDomainMap, RHSSCEV, NonNeg); + ConsequenceCondSet = + buildConditionSet(ICmpInst::ICMP_SLE, LHS, RHS, Domain); + } else if (auto *PHI = dyn_cast<PHINode>(Condition)) { auto *Unique = dyn_cast<ConstantInt>( getUniqueNonErrorValue(PHI, &S.getRegion(), *S.getLI(), *S.getDT())); @@ -1583,7 +1592,6 @@ bool buildConditionSets(Scop &S, BasicBlock *BB, Value *Condition, assert(ICond && "Condition of exiting branch was neither constant nor ICmp!"); - ScalarEvolution &SE = *S.getSE(); LoopInfo &LI = *S.getLI(); DominatorTree &DT = *S.getDT(); Region &R = S.getRegion(); diff --git a/polly/test/ScopInfo/invariant_load_branch_condition.ll b/polly/test/ScopInfo/invariant_load_branch_condition.ll new file mode 100644 index 00000000000..7e0bbdfb97d --- /dev/null +++ b/polly/test/ScopInfo/invariant_load_branch_condition.ll @@ -0,0 +1,51 @@ +; RUN: opt %loadPolly -polly-scops -analyze \ +; RUN: -polly-invariant-load-hoisting < %s | FileCheck %s + +; CHECK: Invariant Accesses: { +; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0] +; CHECK-NEXT: [val] -> { Stmt_next[] -> MemRef_ptr[0] }; +; CHECK-NEXT: Execution Context: [val] -> { : } +; CHECK-NEXT: } + +; CHECK: Statements { +; CHECK-NEXT: Stmt_a +; CHECK-NEXT: Domain := +; CHECK-NEXT: [val] -> { Stmt_a[] : val = -1 }; +; CHECK-NEXT: Schedule := +; CHECK-NEXT: [val] -> { Stmt_a[] -> [1, 0] }; +; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0] +; CHECK-NEXT: [val] -> { Stmt_a[] -> MemRef_X[0] }; +; CHECK-NEXT: Stmt_loop +; CHECK-NEXT: Domain := +; CHECK-NEXT: [val] -> { Stmt_loop[i0] : val = 0 and 0 <= i0 <= 1025 }; +; CHECK-NEXT: Schedule := +; CHECK-NEXT: [val] -> { Stmt_loop[i0] -> [0, i0] }; +; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0] +; CHECK-NEXT: [val] -> { Stmt_loop[i0] -> MemRef_X[0] }; +; CHECK-NEXT: } + +define void @foo(i1* %ptr, float* %X) { +entry: + br label %next + +next: + %val = load i1, i1* %ptr + br i1 %val, label %a, label %loop + +a: + store float 1.0, float* %X + br label %merge + +loop: + %indvar = phi i64 [0, %next], [%indvar.next, %loop] + store float 1.0, float* %X + %indvar.next = add nsw i64 %indvar, 1 + %cmp = icmp sle i64 %indvar, 1024 + br i1 %cmp, label %loop, label %merge + +merge: + br label %exit + +exit: + ret void +} |

