summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/Pass.h36
-rw-r--r--llvm/include/llvm/PassAnalysisSupport.h5
-rw-r--r--llvm/lib/Analysis/CallGraphSCCPass.cpp1
-rw-r--r--llvm/lib/Analysis/LoopInfo.cpp6
-rw-r--r--llvm/lib/Analysis/LoopPass.cpp1
-rw-r--r--llvm/lib/CodeGen/MachineDominators.cpp2
-rw-r--r--llvm/lib/CodeGen/MachineFunctionPass.cpp4
-rw-r--r--llvm/lib/IR/LegacyPassManager.cpp18
-rw-r--r--llvm/lib/IR/Pass.cpp7
-rw-r--r--llvm/test/CodeGen/Generic/externally_available.ll2
-rw-r--r--llvm/test/CodeGen/Mips/mul.ll2
11 files changed, 67 insertions, 17 deletions
diff --git a/llvm/include/llvm/Pass.h b/llvm/include/llvm/Pass.h
index e9c8ca3072c..105da67cbb3 100644
--- a/llvm/include/llvm/Pass.h
+++ b/llvm/include/llvm/Pass.h
@@ -29,6 +29,7 @@
#ifndef LLVM_PASS_H
#define LLVM_PASS_H
+#include <assert.h>
#include <string>
namespace llvm {
@@ -82,17 +83,40 @@ class Pass {
AnalysisResolver *Resolver; // Used to resolve analysis
const void *PassID;
PassKind Kind;
+ bool Executed;
+
void operator=(const Pass&) = delete;
Pass(const Pass &) = delete;
public:
explicit Pass(PassKind K, char &pid)
- : Resolver(nullptr), PassID(&pid), Kind(K) { }
+ : Resolver(nullptr), PassID(&pid), Kind(K), Executed(false) { }
virtual ~Pass();
-
PassKind getPassKind() const { return Kind; }
+ /// Returns true if the pass has already executed.
+ ///
+ /// For an analysis pass it means the result is available. If the function
+ /// returns false, the pass was not run, was skipped or freed.
+ ///
+ bool isExecuted() const { return Executed; }
+
+ /// Marks the pass as executed or not.
+ ///
+ /// A pass should be marked as executed, if its 'runOn*' method successfully
+ /// finished. When the pass is not needed anymore, it is marked as
+ /// 'non-executed', it takes place in \c freePass. It also occurs when the
+ /// pass is skipped for some reason.
+ ///
+ /// The flag should be set prior to call to 'runOn*' method. If it decides
+ /// that the pass should be skipped, it will reset the flag.
+ ///
+ void setExecuted(bool x) {
+ assert(x || !getAsImmutablePass()); // Immutable pass cannot be invalidated.
+ Executed = x;
+ }
+
/// getPassName - Return a nice clean name for a pass. This usually
/// implemented in terms of the name that is registered by one of the
/// Registration templates, but can be overloaded directly.
@@ -279,8 +303,7 @@ public:
///
bool runOnModule(Module &) override { return false; }
- explicit ImmutablePass(char &pid)
- : ModulePass(pid) {}
+ explicit ImmutablePass(char &pid) : ModulePass(pid) { setExecuted(true); }
// Force out-of-line virtual method.
~ImmutablePass() override;
@@ -316,8 +339,9 @@ public:
protected:
/// Optional passes call this function to check whether the pass should be
/// skipped. This is the case when Attribute::OptimizeNone is set or when
- /// optimization bisect is over the limit.
- bool skipFunction(const Function &F) const;
+ /// optimization bisect is over the limit. It also resets flag Executed on
+ /// the pass.
+ bool skipFunction(const Function &F);
};
diff --git a/llvm/include/llvm/PassAnalysisSupport.h b/llvm/include/llvm/PassAnalysisSupport.h
index abd99293805..d7091fc4fe4 100644
--- a/llvm/include/llvm/PassAnalysisSupport.h
+++ b/llvm/include/llvm/PassAnalysisSupport.h
@@ -206,6 +206,9 @@ AnalysisType *Pass::getAnalysisIfAvailable() const {
Pass *ResultPass = Resolver->getAnalysisIfAvailable(PI, true);
if (!ResultPass) return nullptr;
+ if (!ResultPass->isExecuted())
+ return nullptr;
+
// Because the AnalysisType may not be a subclass of pass (for
// AnalysisGroups), we use getAdjustedAnalysisPointer here to potentially
// adjust the return pointer (because the class may multiply inherit, once
@@ -234,6 +237,8 @@ AnalysisType &Pass::getAnalysisID(AnalysisID PI) const {
assert (ResultPass &&
"getAnalysis*() called on an analysis that was not "
"'required' by pass!");
+ assert(ResultPass->isExecuted() &&
+ "getAnalysis*() called on an analysis that was freed");
// Because the AnalysisType may not be a subclass of pass (for
// AnalysisGroups), we use getAdjustedAnalysisPointer here to potentially
diff --git a/llvm/lib/Analysis/CallGraphSCCPass.cpp b/llvm/lib/Analysis/CallGraphSCCPass.cpp
index 9cef7814415..290fd34cff5 100644
--- a/llvm/lib/Analysis/CallGraphSCCPass.cpp
+++ b/llvm/lib/Analysis/CallGraphSCCPass.cpp
@@ -414,6 +414,7 @@ bool CGPassManager::RunAllPassesOnSCC(CallGraphSCC &CurSCC, CallGraph &CG,
initializeAnalysisImpl(P);
// Actually run this pass on the current SCC.
+ P->setExecuted(true);
Changed |= RunPassOnSCC(P, CurSCC, CG,
CallGraphUpToDate, DevirtualizedCall);
diff --git a/llvm/lib/Analysis/LoopInfo.cpp b/llvm/lib/Analysis/LoopInfo.cpp
index f449ce94d57..1b5d6e5d1b7 100644
--- a/llvm/lib/Analysis/LoopInfo.cpp
+++ b/llvm/lib/Analysis/LoopInfo.cpp
@@ -722,8 +722,10 @@ void LoopInfoWrapperPass::verifyAnalysis() const {
// checking by default, LoopPass has been taught to call verifyLoop manually
// during loop pass sequences.
if (VerifyLoopInfo) {
- auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
- LI.verify(DT);
+ if (auto *Analysis = getAnalysisIfAvailable<DominatorTreeWrapperPass>()) {
+ auto &DT = Analysis->getDomTree();
+ LI.verify(DT);
+ }
}
}
diff --git a/llvm/lib/Analysis/LoopPass.cpp b/llvm/lib/Analysis/LoopPass.cpp
index 3f4a0794215..d3e697e5c61 100644
--- a/llvm/lib/Analysis/LoopPass.cpp
+++ b/llvm/lib/Analysis/LoopPass.cpp
@@ -198,6 +198,7 @@ bool LPPassManager::runOnFunction(Function &F) {
PassManagerPrettyStackEntry X(P, *CurrentLoop->getHeader());
TimeRegion PassTimer(getPassTimer(P));
+ P->setExecuted(true);
Changed |= P->runOnLoop(CurrentLoop, *this);
}
LoopWasDeleted = CurrentLoop->isInvalid();
diff --git a/llvm/lib/CodeGen/MachineDominators.cpp b/llvm/lib/CodeGen/MachineDominators.cpp
index 303a6a9263b..a548480044e 100644
--- a/llvm/lib/CodeGen/MachineDominators.cpp
+++ b/llvm/lib/CodeGen/MachineDominators.cpp
@@ -69,7 +69,7 @@ void MachineDominatorTree::releaseMemory() {
}
void MachineDominatorTree::verifyAnalysis() const {
- if (VerifyMachineDomInfo)
+ if (VerifyMachineDomInfo && isExecuted())
verifyDomTree();
}
diff --git a/llvm/lib/CodeGen/MachineFunctionPass.cpp b/llvm/lib/CodeGen/MachineFunctionPass.cpp
index 2265676ff8b..a7ece36a1e5 100644
--- a/llvm/lib/CodeGen/MachineFunctionPass.cpp
+++ b/llvm/lib/CodeGen/MachineFunctionPass.cpp
@@ -38,8 +38,10 @@ Pass *MachineFunctionPass::createPrinterPass(raw_ostream &O,
bool MachineFunctionPass::runOnFunction(Function &F) {
// Do not codegen any 'available_externally' functions at all, they have
// definitions outside the translation unit.
- if (F.hasAvailableExternallyLinkage())
+ if (F.hasAvailableExternallyLinkage()) {
+ setExecuted(false);
return false;
+ }
MachineModuleInfo &MMI = getAnalysis<MachineModuleInfo>();
MachineFunction &MF = MMI.getMachineFunction(F);
diff --git a/llvm/lib/IR/LegacyPassManager.cpp b/llvm/lib/IR/LegacyPassManager.cpp
index 628a67bd639..0b2c40b742a 100644
--- a/llvm/lib/IR/LegacyPassManager.cpp
+++ b/llvm/lib/IR/LegacyPassManager.cpp
@@ -955,6 +955,9 @@ void PMDataManager::freePass(Pass *P, StringRef Msg,
AvailableAnalysis.erase(Pos);
}
}
+
+ if (!P->getAsImmutablePass())
+ P->setExecuted(false);
}
/// Add pass P into the PassVector. Update
@@ -1293,6 +1296,7 @@ bool BBPassManager::runOnFunction(Function &F) {
PassManagerPrettyStackEntry X(BP, *I);
TimeRegion PassTimer(getPassTimer(BP));
+ BP->setExecuted(true);
LocalChanged |= BP->runOnBasicBlock(*I);
}
@@ -1459,7 +1463,9 @@ bool FunctionPassManagerImpl::run(Function &F) {
initializeAllAnalysisInfo();
for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) {
- Changed |= getContainedManager(Index)->runOnFunction(F);
+ FPPassManager *P = getContainedManager(Index);
+ P->setExecuted(true);
+ Changed |= P->runOnFunction(F);
F.getContext().yield();
}
@@ -1510,6 +1516,7 @@ bool FPPassManager::runOnFunction(Function &F) {
PassManagerPrettyStackEntry X(FP, F);
TimeRegion PassTimer(getPassTimer(FP));
+ FP->setExecuted(true);
LocalChanged |= FP->runOnFunction(F);
}
@@ -1530,8 +1537,10 @@ bool FPPassManager::runOnFunction(Function &F) {
bool FPPassManager::runOnModule(Module &M) {
bool Changed = false;
- for (Function &F : M)
+ for (Function &F : M) {
+ setExecuted(true);
Changed |= runOnFunction(F);
+ }
return Changed;
}
@@ -1587,6 +1596,7 @@ MPPassManager::runOnModule(Module &M) {
PassManagerPrettyStackEntry X(MP, M);
TimeRegion PassTimer(getPassTimer(MP));
+ MP->setExecuted(true);
LocalChanged |= MP->runOnModule(M);
}
@@ -1690,7 +1700,9 @@ bool PassManagerImpl::run(Module &M) {
initializeAllAnalysisInfo();
for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) {
- Changed |= getContainedManager(Index)->runOnModule(M);
+ MPPassManager *P = getContainedManager(Index);
+ P->setExecuted(true);
+ Changed |= P->runOnModule(M);
M.getContext().yield();
}
diff --git a/llvm/lib/IR/Pass.cpp b/llvm/lib/IR/Pass.cpp
index a42945ef3ff..6e22c1d4641 100644
--- a/llvm/lib/IR/Pass.cpp
+++ b/llvm/lib/IR/Pass.cpp
@@ -146,13 +146,16 @@ PassManagerType FunctionPass::getPotentialPassManagerType() const {
return PMT_FunctionPassManager;
}
-bool FunctionPass::skipFunction(const Function &F) const {
- if (!F.getContext().getOptBisect().shouldRunPass(this, F))
+bool FunctionPass::skipFunction(const Function &F) {
+ if (!F.getContext().getOptBisect().shouldRunPass(this, F)) {
+ setExecuted(false);
return true;
+ }
if (F.hasFnAttribute(Attribute::OptimizeNone)) {
DEBUG(dbgs() << "Skipping pass '" << getPassName() << "' on function "
<< F.getName() << "\n");
+ setExecuted(false);
return true;
}
return false;
diff --git a/llvm/test/CodeGen/Generic/externally_available.ll b/llvm/test/CodeGen/Generic/externally_available.ll
index 7976cc97188..2376bc73992 100644
--- a/llvm/test/CodeGen/Generic/externally_available.ll
+++ b/llvm/test/CodeGen/Generic/externally_available.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s | not grep test_
+; RUN: llc -verify-machine-dom-info < %s | not grep test_
; test_function should not be emitted to the .s file.
define available_externally i32 @test_function() {
diff --git a/llvm/test/CodeGen/Mips/mul.ll b/llvm/test/CodeGen/Mips/mul.ll
index 9e053fc2e7d..fa147b08ff2 100644
--- a/llvm/test/CodeGen/Mips/mul.ll
+++ b/llvm/test/CodeGen/Mips/mul.ll
@@ -1,4 +1,4 @@
-; RUN: llc -march=mipsel -mattr=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16
+; RUN: llc -march=mipsel -mattr=mips16 -relocation-model=pic -O3 -verify-loop-info < %s | FileCheck %s -check-prefix=16
@iiii = global i32 5, align 4
@jjjj = global i32 -6, align 4
OpenPOWER on IntegriCloud