Index: lib/Transforms/Scalar/ADCE.cpp =================================================================== --- lib/Transforms/Scalar/ADCE.cpp +++ lib/Transforms/Scalar/ADCE.cpp @@ -15,6 +15,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Transforms/Scalar/ADCE.h" + #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" @@ -35,8 +36,28 @@ STATISTIC(NumRemoved, "Number of instructions removed"); -static void collectLiveScopes(const DILocalScope &LS, - SmallPtrSetImpl &AliveScopes) { +namespace { +class AgggressiveDeadCodeElimination { + Function &F; + // Instructions known to be live + SmallPtrSet Alive; + // Instructions known to be live where we need to mark + // reaching definitions as live + SmallVector Worklist; + // Debug info scopes around a live instruction + SmallPtrSet AliveScopes; + + void collectLiveScopes(const DILocalScope &LS); + void collectLiveScopes(const DILocation &DL); + bool isInstrumentsConstant(Instruction &I); +public: + AgggressiveDeadCodeElimination(Function &F) : F(F) {} + bool aggressiveDCE(); +}; +} + +void AgggressiveDeadCodeElimination::collectLiveScopes( + const DILocalScope &LS) { if (!AliveScopes.insert(&LS).second) return; @@ -44,27 +65,26 @@ return; // Tail-recurse through the scope chain. - collectLiveScopes(cast(*LS.getScope()), AliveScopes); + collectLiveScopes(cast(*LS.getScope())); } -static void collectLiveScopes(const DILocation &DL, - SmallPtrSetImpl &AliveScopes) { +void AgggressiveDeadCodeElimination::collectLiveScopes(const DILocation &DL) { // Even though DILocations are not scopes, shove them into AliveScopes so we // don't revisit them. if (!AliveScopes.insert(&DL).second) return; // Collect live scopes from the scope chain. - collectLiveScopes(*DL.getScope(), AliveScopes); + collectLiveScopes(*DL.getScope()); // Tail-recurse through the inlined-at chain. if (const DILocation *IA = DL.getInlinedAt()) - collectLiveScopes(*IA, AliveScopes); + collectLiveScopes(*IA); } // Check if this instruction is a runtime call for value profiling and // if it's instrumenting a constant. -static bool isInstrumentsConstant(Instruction &I) { +bool AgggressiveDeadCodeElimination::isInstrumentsConstant(Instruction &I) { if (CallInst *CI = dyn_cast(&I)) if (Function *Callee = CI->getCalledFunction()) if (Callee->getName().equals(getInstrProfValueProfFuncName())) @@ -73,9 +93,7 @@ return false; } -static bool aggressiveDCE(Function& F) { - SmallPtrSet Alive; - SmallVector Worklist; +bool AgggressiveDeadCodeElimination::aggressiveDCE() { // Collect the set of "root" instructions that are known live. for (Instruction &I : instructions(F)) { @@ -91,13 +109,12 @@ // Propagate liveness backwards to operands. Keep track of live debug info // scopes. - SmallPtrSet AliveScopes; while (!Worklist.empty()) { Instruction *Curr = Worklist.pop_back_val(); // Collect the live debug info scopes attached to this instruction. if (const DILocation *DL = Curr->getDebugLoc()) - collectLiveScopes(*DL, AliveScopes); + collectLiveScopes(*DL); for (Use &OI : Curr->operands()) { if (Instruction *Inst = dyn_cast(OI)) @@ -146,7 +163,7 @@ } PreservedAnalyses ADCEPass::run(Function &F, FunctionAnalysisManager &) { - if (!aggressiveDCE(F)) + if (!AgggressiveDeadCodeElimination(F).aggressiveDCE()) return PreservedAnalyses::all(); // FIXME: This should also 'preserve the CFG'. @@ -162,13 +179,13 @@ initializeADCELegacyPassPass(*PassRegistry::getPassRegistry()); } - bool runOnFunction(Function& F) override { + bool runOnFunction(Function &F) override { if (skipFunction(F)) return false; - return aggressiveDCE(F); + return AgggressiveDeadCodeElimination(F).aggressiveDCE(); } - void getAnalysisUsage(AnalysisUsage& AU) const override { + void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesCFG(); AU.addPreserved(); }