From eb902a750997d4409333167175428397d6cfceb4 Mon Sep 17 00:00:00 2001 From: Philip Reames Date: Fri, 24 Jul 2015 00:02:11 +0000 Subject: [PATCH] [RewriteStatepointsForGC] Use a worklist algorithm for first part of base pointer algorithm [NFC] The new code should hopefully be equivalent to the old code; it just uses a worklist to track instructions which need to visited rather than iterating over all instructions visited each time. This should be faster, but the primary benefit is that the purpose should be more clear and the diff of adding another instruction type (forthcoming) much more obvious. Differential Revision: http://reviews.llvm.org/D11480 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@243071 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Scalar/RewriteStatepointsForGC.cpp | 75 ++++++++++--------- 1 file changed, 39 insertions(+), 36 deletions(-) diff --git a/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp b/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp index 56d53621b8a..e9f8a6c158a 100644 --- a/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp +++ b/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp @@ -720,47 +720,50 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &cache) { // analougous to pessimistic data flow and would likely lead to an // overall worse solution. + auto isExpectedBDVType = [](Value *BDV) { + return isa(BDV) || isa(BDV); + }; + + // Once populated, will contain a mapping from each potentially non-base BDV + // to a lattice value (described above) which corresponds to that BDV. ConflictStateMapTy states; - states[def] = BDVState(); // Recursively fill in all phis & selects reachable from the initial one // for which we don't already know a definite base value for - // TODO: This should be rewritten with a worklist - bool done = false; - while (!done) { - done = true; - // Since we're adding elements to 'states' as we run, we can't keep - // iterators into the set. - SmallVector Keys; - Keys.reserve(states.size()); - for (auto Pair : states) { - Value *V = Pair.first; - Keys.push_back(V); - } - for (Value *v : Keys) { - assert(!isKnownBaseResult(v) && "why did it get added?"); - if (PHINode *phi = dyn_cast(v)) { - assert(phi->getNumIncomingValues() > 0 && - "zero input phis are illegal"); - for (Value *InVal : phi->incoming_values()) { - Value *local = findBaseOrBDV(InVal, cache); - if (!isKnownBaseResult(local) && states.find(local) == states.end()) { - states[local] = BDVState(); - done = false; - } - } - } else if (SelectInst *sel = dyn_cast(v)) { - Value *local = findBaseOrBDV(sel->getTrueValue(), cache); - if (!isKnownBaseResult(local) && states.find(local) == states.end()) { - states[local] = BDVState(); - done = false; - } - local = findBaseOrBDV(sel->getFalseValue(), cache); - if (!isKnownBaseResult(local) && states.find(local) == states.end()) { - states[local] = BDVState(); - done = false; - } + /* scope */ { + DenseSet Visited; + SmallVector Worklist; + Worklist.push_back(def); + Visited.insert(def); + while (!Worklist.empty()) { + Value *Current = Worklist.pop_back_val(); + assert(!isKnownBaseResult(Current) && "why did it get added?"); + + auto visitIncomingValue = [&](Value *InVal) { + Value *Base = findBaseOrBDV(InVal, cache); + if (isKnownBaseResult(Base)) + // Known bases won't need new instructions introduced and can be + // ignored safely + return; + assert(isExpectedBDVType(Base) && "the only non-base values " + "we see should be base defining values"); + if (Visited.insert(Base).second) + Worklist.push_back(Base); + }; + if (PHINode *Phi = dyn_cast(Current)) { + for (Value *InVal : Phi->incoming_values()) + visitIncomingValue(InVal); + } else { + SelectInst *Sel = cast(Current); + visitIncomingValue(Sel->getTrueValue()); + visitIncomingValue(Sel->getFalseValue()); } } + // The frontier of visited instructions are the ones we might need to + // duplicate, so fill in the starting state for the optimistic algorithm + // that follows. + for (Value *BDV : Visited) { + states[BDV] = BDVState(); + } } if (TraceLSP) { -- 2.34.1