[llvm] r277855 - [ADCE] Refactoring for new functionality (NFC)
David Callahan via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 5 12:38:11 PDT 2016
Author: david2050
Date: Fri Aug 5 14:38:11 2016
New Revision: 277855
URL: http://llvm.org/viewvc/llvm-project?rev=277855&view=rev
Log:
[ADCE] Refactoring for new functionality (NFC)
Summary:
This is another refactoring to break up the one function into three logical components functions.
Another non-functional change before we start added in features.
Reviewers: nadav, mehdi_amini, majnemer
Subscribers: twoh, freik, llvm-commits
Differential Revision: https://reviews.llvm.org/D23102
Modified:
llvm/trunk/lib/Transforms/Scalar/ADCE.cpp
Modified: llvm/trunk/lib/Transforms/Scalar/ADCE.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ADCE.cpp?rev=277855&r1=277854&r2=277855&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/ADCE.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/ADCE.cpp Fri Aug 5 14:38:11 2016
@@ -37,54 +37,71 @@ using namespace llvm;
STATISTIC(NumRemoved, "Number of instructions removed");
namespace {
-class AgggressiveDeadCodeElimination {
+class AggressiveDeadCodeElimination {
Function &F;
- // Instructions known to be live
+ /// Instructions known to be live.
SmallPtrSet<Instruction *, 32> Alive;
- // Instructions known to be live where we need to mark
- // reaching definitions as live
+ /// Instructions known to be live where we need to mark
+ /// reaching definitions as live.
SmallVector<Instruction *, 128> Worklist;
- // Debug info scopes around a live instruction
+ /// Debug info scopes around a live instruction.
SmallPtrSet<const Metadata *, 32> AliveScopes;
+
+ void initialize();
+ /// True for operations which are always treated as live.
+ bool isAlwaysLive(Instruction &I);
+ /// 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();
+ AggressiveDeadCodeElimination(Function &F) : F(F) {}
+ bool performDeadCodeElimination();
};
}
-void AgggressiveDeadCodeElimination::collectLiveScopes(
- const DILocalScope &LS) {
- if (!AliveScopes.insert(&LS).second)
- return;
-
- if (isa<DISubprogram>(LS))
- return;
-
- // Tail-recurse through the scope chain.
- collectLiveScopes(cast<DILocalScope>(*LS.getScope()));
+bool AggressiveDeadCodeElimination::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 AggressiveDeadCodeElimination::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 AggressiveDeadCodeElimination::isAlwaysLive(Instruction &I) {
+
+ // TODO -- use llvm::isInstructionTriviallyDead
+ if (isa<TerminatorInst>(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
// if it's instrumenting a constant.
-bool AgggressiveDeadCodeElimination::isInstrumentsConstant(Instruction &I) {
+bool AggressiveDeadCodeElimination::isInstrumentsConstant(Instruction &I) {
+ // TODO -- move this test into llvm::isInstructionTriviallyDead
if (CallInst *CI = dyn_cast<CallInst>(&I))
if (Function *Callee = CI->getCalledFunction())
if (Callee->getName().equals(getInstrProfValueProfFuncName()))
@@ -93,19 +110,7 @@ bool AgggressiveDeadCodeElimination::isI
return false;
}
-bool AgggressiveDeadCodeElimination::aggressiveDCE() {
-
- // Collect the set of "root" instructions that are known live.
- for (Instruction &I : instructions(F)) {
- if (isa<TerminatorInst>(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 AggressiveDeadCodeElimination::markLiveInstructions() {
// Propagate liveness backwards to operands. Keep track of live debug info
// scopes.
@@ -118,10 +123,43 @@ bool AgggressiveDeadCodeElimination::agg
for (Use &OI : Curr->operands()) {
if (Instruction *Inst = dyn_cast<Instruction>(OI))
- if (Alive.insert(Inst).second)
- Worklist.push_back(Inst);
+ markLive(*Inst);
}
}
+}
+
+void AggressiveDeadCodeElimination::collectLiveScopes(const DILocalScope &LS) {
+ if (!AliveScopes.insert(&LS).second)
+ return;
+
+ if (isa<DISubprogram>(LS))
+ return;
+
+ // Tail-recurse through the scope chain.
+ collectLiveScopes(cast<DILocalScope>(*LS.getScope()));
+}
+
+void AggressiveDeadCodeElimination::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 AggressiveDeadCodeElimination::markLive(Instruction &I) {
+ if (!Alive.insert(&I).second)
+ return;
+ Worklist.push_back(&I);
+}
+
+bool AggressiveDeadCodeElimination::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 +201,7 @@ bool AgggressiveDeadCodeElimination::agg
}
PreservedAnalyses ADCEPass::run(Function &F, FunctionAnalysisManager &) {
- if (!AgggressiveDeadCodeElimination(F).aggressiveDCE())
+ if (!AggressiveDeadCodeElimination(F).performDeadCodeElimination())
return PreservedAnalyses::all();
// FIXME: This should also 'preserve the CFG'.
@@ -182,7 +220,7 @@ struct ADCELegacyPass : public FunctionP
bool runOnFunction(Function &F) override {
if (skipFunction(F))
return false;
- return AgggressiveDeadCodeElimination(F).aggressiveDCE();
+ return AggressiveDeadCodeElimination(F).performDeadCodeElimination();
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
More information about the llvm-commits
mailing list