diff options
author | James Molloy <james.molloy@arm.com> | 2015-10-08 12:39:50 +0000 |
---|---|---|
committer | James Molloy <james.molloy@arm.com> | 2015-10-08 12:39:50 +0000 |
commit | ab9fdb922677a884a79854579204e3e8a06345c5 (patch) | |
tree | ec3d7cc9c1d7dfd4d992146f2f1319561593a5e2 | |
parent | b751bfb9bd245627ae9497d8a2a6d1d04961abe4 (diff) | |
download | bcm5719-llvm-ab9fdb922677a884a79854579204e3e8a06345c5.tar.gz bcm5719-llvm-ab9fdb922677a884a79854579204e3e8a06345c5.zip |
Make demanded bits lazy
The algorithm itself is still eager, but it doesn't get run until a
query function is called. This greatly reduces the compile-time impact
of requiring DemandedBits when at runtime it is not often used.
NFCI.
llvm-svn: 249685
-rw-r--r-- | llvm/include/llvm/Analysis/DemandedBits.h | 3 | ||||
-rw-r--r-- | llvm/lib/Analysis/DemandedBits.cpp | 26 |
2 files changed, 22 insertions, 7 deletions
diff --git a/llvm/include/llvm/Analysis/DemandedBits.h b/llvm/include/llvm/Analysis/DemandedBits.h index 1b1b9c53918..d7562a5585c 100644 --- a/llvm/include/llvm/Analysis/DemandedBits.h +++ b/llvm/include/llvm/Analysis/DemandedBits.h @@ -49,6 +49,7 @@ struct DemandedBits : public FunctionPass { bool isInstructionDead(Instruction *I); private: + void performAnalysis(); void determineLiveOperandBits(const Instruction *UserI, const Instruction *I, unsigned OperandNo, const APInt &AOut, APInt &AB, @@ -57,6 +58,8 @@ private: AssumptionCache *AC; DominatorTree *DT; + Function *F; + bool Analyzed; // The set of visited instructions (non-integer-typed only). SmallPtrSet<Instruction*, 128> Visited; diff --git a/llvm/lib/Analysis/DemandedBits.cpp b/llvm/lib/Analysis/DemandedBits.cpp index 721d42b5187..775cbac4c53 100644 --- a/llvm/lib/Analysis/DemandedBits.cpp +++ b/llvm/lib/Analysis/DemandedBits.cpp @@ -51,7 +51,7 @@ INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_END(DemandedBits, "demanded-bits", "Demanded bits analysis", false, false) -DemandedBits::DemandedBits() : FunctionPass(ID) { +DemandedBits::DemandedBits() : FunctionPass(ID), F(nullptr), Analyzed(false) { initializeDemandedBitsPass(*PassRegistry::getPassRegistry()); } @@ -243,17 +243,27 @@ void DemandedBits::determineLiveOperandBits( } } -bool DemandedBits::runOnFunction(Function& F) { - AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F); - DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); +bool DemandedBits::runOnFunction(Function& Fn) { + F = &Fn; + Analyzed = false; + return false; +} +void DemandedBits::performAnalysis() { + if (Analyzed) + // Analysis already completed for this function. + return; + Analyzed = true; + AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(*F); + DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); + Visited.clear(); AliveBits.clear(); SmallVector<Instruction*, 128> Worklist; // Collect the set of "root" instructions that are known live. - for (Instruction &I : instructions(F)) { + for (Instruction &I : instructions(*F)) { if (!isAlwaysLive(&I)) continue; @@ -340,11 +350,11 @@ bool DemandedBits::runOnFunction(Function& F) { } } } - - return false; } APInt DemandedBits::getDemandedBits(Instruction *I) { + performAnalysis(); + const DataLayout &DL = I->getParent()->getModule()->getDataLayout(); if (AliveBits.count(I)) return AliveBits[I]; @@ -352,6 +362,8 @@ APInt DemandedBits::getDemandedBits(Instruction *I) { } bool DemandedBits::isInstructionDead(Instruction *I) { + performAnalysis(); + return !Visited.count(I) && AliveBits.find(I) == AliveBits.end() && !isAlwaysLive(I); } |