Make demanded bits lazy
authorJames Molloy <james.molloy@arm.com>
Thu, 8 Oct 2015 12:39:50 +0000 (12:39 +0000)
committerJames Molloy <james.molloy@arm.com>
Thu, 8 Oct 2015 12:39:50 +0000 (12:39 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@249685 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Analysis/DemandedBits.h
lib/Analysis/DemandedBits.cpp

index 1b1b9c5391887836be8aed15878fb02519b600e8..d7562a5585c88f6bba49bf57069ebf3148306166 100644 (file)
@@ -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;
index 721d42b51878145986f2b1d19d649074716c718d..775cbac4c53ed4089761e92b042b8a9c4ee463fa 100644 (file)
@@ -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);
 }