summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Grosser <tobias@grosser.es>2017-09-25 20:27:15 +0000
committerTobias Grosser <tobias@grosser.es>2017-09-25 20:27:15 +0000
commit5e531dfef41bb7cf451481e01552a31c598fdeac (patch)
treea74a434965a2f6d882c9600bdf0d1eef03c657e9
parent01414bdc2c23f24e255d4b068f90938035f1149a (diff)
downloadbcm5719-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.cpp6
-rw-r--r--polly/lib/Analysis/ScopInfo.cpp12
-rw-r--r--polly/test/ScopInfo/invariant_load_branch_condition.ll51
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
+}
OpenPOWER on IntegriCloud