diff options
author | Anna Thomas <anna@azul.com> | 2016-05-03 14:58:21 +0000 |
---|---|---|
committer | Anna Thomas <anna@azul.com> | 2016-05-03 14:58:21 +0000 |
commit | bf6a9dfb624392539decc46172181488b2fcf02b (patch) | |
tree | 1c26acc065855f356aaa60c4d95f4dc75cecf860 /lib/Analysis/CaptureTracking.cpp | |
parent | 0e6cb51702c08d9977c98892e3fdc423bc63b0a8 (diff) |
Fold compares irrespective of whether allocation can be elided
Summary
When a non-escaping pointer is compared to a global value, the
comparison can be folded even if the corresponding malloc/allocation
call cannot be elided.
We need to make sure the global value is not null, since comparisons to
null cannot be folded.
In future, we should also handle cases when the the comparison
instruction dominates the pointer escape.
Reviewers: sanjoy
Subscribers s.egerton, llvm-commits
Differential Revision: http://reviews.llvm.org/D19549
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@268390 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/CaptureTracking.cpp')
-rw-r--r-- | lib/Analysis/CaptureTracking.cpp | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/lib/Analysis/CaptureTracking.cpp b/lib/Analysis/CaptureTracking.cpp index 5125a63b81b..5997975085b 100644 --- a/lib/Analysis/CaptureTracking.cpp +++ b/lib/Analysis/CaptureTracking.cpp @@ -300,7 +300,7 @@ void llvm::PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker) { Worklist.push_back(&UU); } break; - case Instruction::ICmp: + case Instruction::ICmp: { // Don't count comparisons of a no-alias return value against null as // captures. This allows us to ignore comparisons of malloc results // with null, for example. @@ -309,11 +309,19 @@ void llvm::PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker) { if (CPN->getType()->getAddressSpace() == 0) if (isNoAliasCall(V->stripPointerCasts())) break; + // Comparison against value stored in global variable. Given the pointer + // does not escape, its value cannot be guessed and stored separately in a + // global variable. + unsigned OtherIndex = (I->getOperand(0) == V) ? 1 : 0; + auto *LI = dyn_cast<LoadInst>(I->getOperand(OtherIndex)); + if (LI && isa<GlobalVariable>(LI->getPointerOperand())) + break; // Otherwise, be conservative. There are crazy ways to capture pointers // using comparisons. if (Tracker->captured(U)) return; break; + } default: // Something else - be conservative and say it is captured. if (Tracker->captured(U)) |