[llvm] 23524fd - [ValueTracking] Replace recursion with Worklist
Vitaly Buka via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 27 14:45:04 PDT 2020
Author: Vitaly Buka
Date: 2020-08-27T14:44:49-07:00
New Revision: 23524fdecef990dffc619d3463b1977cfb946136
URL: https://github.com/llvm/llvm-project/commit/23524fdecef990dffc619d3463b1977cfb946136
DIFF: https://github.com/llvm/llvm-project/commit/23524fdecef990dffc619d3463b1977cfb946136.diff
LOG: [ValueTracking] Replace recursion with Worklist
Now findAllocaForValue can handle nontrivial phi cycles.
Added:
Modified:
llvm/lib/Analysis/ValueTracking.cpp
llvm/unittests/Analysis/ValueTrackingTest.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index bcb182a6dc1d..74097bbb2151 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -4330,57 +4330,44 @@ bool llvm::getUnderlyingObjectsForCodeGen(const Value *V,
return true;
}
-static AllocaInst *
-findAllocaForValue(Value *V, DenseMap<Value *, AllocaInst *> &AllocaForValue,
- bool OffsetZero) {
- if (AllocaInst *AI = dyn_cast<AllocaInst>(V))
- return AI;
- // See if we've already calculated (or started to calculate) alloca for a
- // given value.
- auto I = AllocaForValue.find(V);
- if (I != AllocaForValue.end())
- return I->second;
- // Store 0 while we're calculating alloca for value V to avoid
- // infinite recursion if the value references itself.
- AllocaForValue[V] = nullptr;
- AllocaInst *Res = nullptr;
- if (CastInst *CI = dyn_cast<CastInst>(V))
- Res = findAllocaForValue(CI->getOperand(0), AllocaForValue, OffsetZero);
- else if (PHINode *PN = dyn_cast<PHINode>(V)) {
- for (Value *IncValue : PN->incoming_values()) {
- // Allow self-referencing phi-nodes.
- if (IncValue == PN)
- continue;
- AllocaInst *IncValueAI =
- findAllocaForValue(IncValue, AllocaForValue, OffsetZero);
- // AI for incoming values should exist and should all be equal.
- if (IncValueAI == nullptr || (Res != nullptr && IncValueAI != Res))
+AllocaInst *llvm::findAllocaForValue(Value *V, bool OffsetZero) {
+ AllocaInst *Result = nullptr;
+ SmallPtrSet<Value *, 4> Visited;
+ SmallVector<Value *, 4> Worklist;
+
+ auto AddWork = [&](Value *V) {
+ if (Visited.insert(V).second)
+ Worklist.push_back(V);
+ };
+
+ AddWork(V);
+ do {
+ V = Worklist.pop_back_val();
+ assert(Visited.count(V));
+
+ if (AllocaInst *AI = dyn_cast<AllocaInst>(V)) {
+ if (Result && Result != AI)
return nullptr;
- Res = IncValueAI;
- }
- } else if (auto *SI = dyn_cast<SelectInst>(V)) {
- Res = findAllocaForValue(SI->getTrueValue(), AllocaForValue, OffsetZero);
- if (!Res)
- return nullptr;
- AllocaInst *F =
- findAllocaForValue(SI->getFalseValue(), AllocaForValue, OffsetZero);
- if (F != Res)
- return nullptr;
- } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(V)) {
- if (OffsetZero && !GEP->hasAllZeroIndices())
+ Result = AI;
+ } else if (CastInst *CI = dyn_cast<CastInst>(V)) {
+ AddWork(CI->getOperand(0));
+ } else if (PHINode *PN = dyn_cast<PHINode>(V)) {
+ for (Value *IncValue : PN->incoming_values())
+ AddWork(IncValue);
+ } else if (auto *SI = dyn_cast<SelectInst>(V)) {
+ AddWork(SI->getTrueValue());
+ AddWork(SI->getFalseValue());
+ } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(V)) {
+ if (OffsetZero && !GEP->hasAllZeroIndices())
+ return nullptr;
+ AddWork(GEP->getPointerOperand());
+ } else {
return nullptr;
- Res = findAllocaForValue(GEP->getPointerOperand(), AllocaForValue,
- OffsetZero);
- }
- if (Res)
- AllocaForValue[V] = Res;
- return Res;
-}
+ }
+ } while (!Worklist.empty());
-AllocaInst *llvm::findAllocaForValue(Value *V, bool OffsetZero) {
- DenseMap<Value *, AllocaInst *> AllocaForValue;
- return ::findAllocaForValue(V, AllocaForValue, OffsetZero);
-}
+ return Result;
+};
static bool onlyUsedByLifetimeMarkersOrDroppableInstsHelper(
const Value *V, bool AllowLifetime, bool AllowDroppable) {
diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp
index d60bdbb4a29b..3df5dc1fb82d 100644
--- a/llvm/unittests/Analysis/ValueTrackingTest.cpp
+++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp
@@ -1532,7 +1532,7 @@ const FindAllocaForValueTestParams FindAllocaForValueTests[] = {
exit:
ret void
})",
- false, false},
+ true, false},
{R"(
define void @test(i1 %cond, i64* %a) {
More information about the llvm-commits
mailing list