Index: lib/Transforms/Scalar/ADCE.cpp =================================================================== --- lib/Transforms/Scalar/ADCE.cpp +++ lib/Transforms/Scalar/ADCE.cpp @@ -46,40 +46,54 @@ SmallVector Worklist; // Debug info scopes around a live instruction SmallPtrSet AliveScopes; + + void initialize(); + // True for operations which are always treated as live + bool isAlwaysLive(Instruction &); + // True for instrumentation instructions for value profiling + bool isInstrumentsConstant(Instruction &I); + + + // Propagate liveness to reaching definitions + void markLiveInstructions(); + // Mark an instruction as live + void markLive(Instruction &I); void collectLiveScopes(const DILocalScope &LS); void collectLiveScopes(const DILocation &DL); - bool isInstrumentsConstant(Instruction &I); + + + // Remove instructions not marked live, return if any any instruction + // was removed + bool removeDeadInstructions(); + public: AgggressiveDeadCodeElimination(Function &F) : F(F) {} - bool aggressiveDCE(); + bool performDeadCodeElimination(); }; } -void AgggressiveDeadCodeElimination::collectLiveScopes( - const DILocalScope &LS) { - if (!AliveScopes.insert(&LS).second) - return; - - if (isa(LS)) - return; - - // Tail-recurse through the scope chain. - collectLiveScopes(cast(*LS.getScope())); +bool AgggressiveDeadCodeElimination::performDeadCodeElimination() { + initialize(); + markLiveInstructions(); + return removeDeadInstructions(); } -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()); +void AgggressiveDeadCodeElimination::initialize() { + // Collect the set of "root" instructions that are known live. + for (Instruction &I : instructions(F)) + if (isAlwaysLive(I)) + markLive(I); +} - // Tail-recurse through the inlined-at chain. - if (const DILocation *IA = DL.getInlinedAt()) - collectLiveScopes(*IA); +bool AgggressiveDeadCodeElimination::isAlwaysLive(Instruction &I) { + if (isa(I) || I.isEHPad() || I.mayHaveSideEffects()) { + // Skip any value profile instrumentation calls if they are + // instrumenting constants. + if (!isInstrumentsConstant(I)) + return true; + } + return false; } // Check if this instruction is a runtime call for value profiling and @@ -93,19 +107,7 @@ return false; } -bool AgggressiveDeadCodeElimination::aggressiveDCE() { - - // Collect the set of "root" instructions that are known live. - for (Instruction &I : instructions(F)) { - if (isa(I) || I.isEHPad() || I.mayHaveSideEffects()) { - // Skip any value profile instrumentation calls if they are - // instrumenting constants. - if (isInstrumentsConstant(I)) - continue; - Alive.insert(&I); - Worklist.push_back(&I); - } - } +void AgggressiveDeadCodeElimination::markLiveInstructions() { // Propagate liveness backwards to operands. Keep track of live debug info // scopes. @@ -118,10 +120,43 @@ for (Use &OI : Curr->operands()) { if (Instruction *Inst = dyn_cast(OI)) - if (Alive.insert(Inst).second) - Worklist.push_back(Inst); + markLive(*Inst); } } +} + +void AgggressiveDeadCodeElimination::collectLiveScopes(const DILocalScope &LS) { + if (!AliveScopes.insert(&LS).second) + return; + + if (isa(LS)) + return; + + // Tail-recurse through the scope chain. + collectLiveScopes(cast(*LS.getScope())); +} + +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()); + + // Tail-recurse through the inlined-at chain. + if (const DILocation *IA = DL.getInlinedAt()) + collectLiveScopes(*IA); +} + +void AgggressiveDeadCodeElimination::markLive(Instruction &I) { + if (!Alive.insert(&I).second) + return; + Worklist.push_back(&I); +} + +bool AgggressiveDeadCodeElimination::removeDeadInstructions() { // The inverse of the live set is the dead set. These are those instructions // which have no side effects and do not influence the control flow or return @@ -163,7 +198,7 @@ } PreservedAnalyses ADCEPass::run(Function &F, FunctionAnalysisManager &) { - if (!AgggressiveDeadCodeElimination(F).aggressiveDCE()) + if (!AgggressiveDeadCodeElimination(F).performDeadCodeElimination()) return PreservedAnalyses::all(); // FIXME: This should also 'preserve the CFG'. @@ -182,7 +217,7 @@ bool runOnFunction(Function &F) override { if (skipFunction(F)) return false; - return AgggressiveDeadCodeElimination(F).aggressiveDCE(); + return AgggressiveDeadCodeElimination(F).performDeadCodeElimination(); } void getAnalysisUsage(AnalysisUsage &AU) const override {