summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/IR/OptBisect.h36
-rw-r--r--llvm/lib/Analysis/CallGraphSCCPass.cpp25
-rw-r--r--llvm/lib/Analysis/LoopPass.cpp8
-rw-r--r--llvm/lib/Analysis/RegionPass.cpp7
-rw-r--r--llvm/lib/IR/OptBisect.cpp76
-rw-r--r--llvm/lib/IR/Pass.cpp22
-rw-r--r--llvm/unittests/IR/LegacyPassManagerTest.cpp7
7 files changed, 75 insertions, 106 deletions
diff --git a/llvm/include/llvm/IR/OptBisect.h b/llvm/include/llvm/IR/OptBisect.h
index 8d51b6856dd..1b2b0bd7aca 100644
--- a/llvm/include/llvm/IR/OptBisect.h
+++ b/llvm/include/llvm/IR/OptBisect.h
@@ -19,12 +19,6 @@
namespace llvm {
class Pass;
-class Module;
-class Function;
-class BasicBlock;
-class Region;
-class Loop;
-class CallGraphSCC;
/// Extensions to this class implement mechanisms to disable passes and
/// individual optimizations at compile time.
@@ -32,12 +26,14 @@ class OptPassGate {
public:
virtual ~OptPassGate() = default;
- virtual bool shouldRunPass(const Pass *P, const Module &U) { return true; }
- virtual bool shouldRunPass(const Pass *P, const Function &U) {return true; }
- virtual bool shouldRunPass(const Pass *P, const BasicBlock &U) { return true; }
- virtual bool shouldRunPass(const Pass *P, const Region &U) { return true; }
- virtual bool shouldRunPass(const Pass *P, const Loop &U) { return true; }
- virtual bool shouldRunPass(const Pass *P, const CallGraphSCC &U) { return true; }
+ /// IRDescription is a textual description of the IR unit the pass is running
+ /// over.
+ virtual bool shouldRunPass(const Pass *P, StringRef IRDescription) {
+ return true;
+ }
+
+ /// isEnabled should return true before calling shouldRunPass
+ virtual bool isEnabled() const { return false; }
};
/// This class implements a mechanism to disable passes and individual
@@ -59,23 +55,19 @@ public:
/// Checks the bisect limit to determine if the specified pass should run.
///
- /// These functions immediately return true if bisection is disabled. If the
- /// bisect limit is set to -1, the functions print a message describing
+ /// If the bisect limit is set to -1, the function prints a message describing
/// the pass and the bisect number assigned to it and return true. Otherwise,
- /// the functions print a message with the bisect number assigned to the
+ /// the function prints a message with the bisect number assigned to the
/// pass and indicating whether or not the pass will be run and return true if
/// the bisect limit has not yet been exceeded or false if it has.
///
- /// Most passes should not call these routines directly. Instead, they are
+ /// Most passes should not call this routine directly. Instead, they are
/// called through helper routines provided by the pass base classes. For
/// instance, function passes should call FunctionPass::skipFunction().
- bool shouldRunPass(const Pass *P, const Module &U) override;
- bool shouldRunPass(const Pass *P, const Function &U) override;
- bool shouldRunPass(const Pass *P, const BasicBlock &U) override;
- bool shouldRunPass(const Pass *P, const Region &U) override;
- bool shouldRunPass(const Pass *P, const Loop &U) override;
- bool shouldRunPass(const Pass *P, const CallGraphSCC &U) override;
+ bool shouldRunPass(const Pass *P, StringRef IRDescription) override;
+ /// isEnabled should return true before calling shouldRunPass
+ bool isEnabled() const override { return BisectEnabled; }
private:
bool checkPass(const StringRef PassName, const StringRef TargetDesc);
diff --git a/llvm/lib/Analysis/CallGraphSCCPass.cpp b/llvm/lib/Analysis/CallGraphSCCPass.cpp
index ee01f2536fb..eb02042c111 100644
--- a/llvm/lib/Analysis/CallGraphSCCPass.cpp
+++ b/llvm/lib/Analysis/CallGraphSCCPass.cpp
@@ -681,11 +681,28 @@ Pass *CallGraphSCCPass::createPrinterPass(raw_ostream &OS,
return new PrintCallGraphPass(Banner, OS);
}
+static std::string getDescription(const CallGraphSCC &SCC) {
+ std::string Desc = "SCC (";
+ bool First = true;
+ for (CallGraphNode *CGN : SCC) {
+ if (First)
+ First = false;
+ else
+ Desc += ", ";
+ Function *F = CGN->getFunction();
+ if (F)
+ Desc += F->getName();
+ else
+ Desc += "<<null function>>";
+ }
+ Desc += ")";
+ return Desc;
+}
+
bool CallGraphSCCPass::skipSCC(CallGraphSCC &SCC) const {
- return !SCC.getCallGraph().getModule()
- .getContext()
- .getOptPassGate()
- .shouldRunPass(this, SCC);
+ OptPassGate &Gate =
+ SCC.getCallGraph().getModule().getContext().getOptPassGate();
+ return Gate.isEnabled() && !Gate.shouldRunPass(this, getDescription(SCC));
}
char DummyCGSCCPass::ID = 0;
diff --git a/llvm/lib/Analysis/LoopPass.cpp b/llvm/lib/Analysis/LoopPass.cpp
index e36370be3ce..c801b9a2d1a 100644
--- a/llvm/lib/Analysis/LoopPass.cpp
+++ b/llvm/lib/Analysis/LoopPass.cpp
@@ -383,13 +383,17 @@ void LoopPass::assignPassManager(PMStack &PMS,
LPPM->add(this);
}
+static std::string getDescription(const Loop &L) {
+ return "loop";
+}
+
bool LoopPass::skipLoop(const Loop *L) const {
const Function *F = L->getHeader()->getParent();
if (!F)
return false;
// Check the opt bisect limit.
- LLVMContext &Context = F->getContext();
- if (!Context.getOptPassGate().shouldRunPass(this, *L))
+ OptPassGate &Gate = F->getContext().getOptPassGate();
+ if (Gate.isEnabled() && !Gate.shouldRunPass(this, getDescription(*L)))
return true;
// Check for the OptimizeNone attribute.
if (F->hasFnAttribute(Attribute::OptimizeNone)) {
diff --git a/llvm/lib/Analysis/RegionPass.cpp b/llvm/lib/Analysis/RegionPass.cpp
index 0e43af65e6c..901adbf27d9 100644
--- a/llvm/lib/Analysis/RegionPass.cpp
+++ b/llvm/lib/Analysis/RegionPass.cpp
@@ -278,9 +278,14 @@ Pass *RegionPass::createPrinterPass(raw_ostream &O,
return new PrintRegionPass(Banner, O);
}
+static std::string getDescription(const Region &R) {
+ return "region";
+}
+
bool RegionPass::skipRegion(Region &R) const {
Function &F = *R.getEntry()->getParent();
- if (!F.getContext().getOptPassGate().shouldRunPass(this, R))
+ OptPassGate &Gate = F.getContext().getOptPassGate();
+ if (Gate.isEnabled() && Gate.shouldRunPass(this, getDescription(R)))
return true;
if (F.hasFnAttribute(Attribute::OptimizeNone)) {
diff --git a/llvm/lib/IR/OptBisect.cpp b/llvm/lib/IR/OptBisect.cpp
index 6f4d954d822..3104b90f307 100644
--- a/llvm/lib/IR/OptBisect.cpp
+++ b/llvm/lib/IR/OptBisect.cpp
@@ -14,13 +14,6 @@
#include "llvm/IR/OptBisect.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/Analysis/CallGraph.h"
-#include "llvm/Analysis/CallGraphSCCPass.h"
-#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/RegionInfo.h"
-#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/Module.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/raw_ostream.h"
@@ -46,73 +39,10 @@ static void printPassMessage(const StringRef &Name, int PassNum,
<< "(" << PassNum << ") " << Name << " on " << TargetDesc << "\n";
}
-static std::string getDescription(const Module &M) {
- return "module (" + M.getName().str() + ")";
-}
-
-static std::string getDescription(const Function &F) {
- return "function (" + F.getName().str() + ")";
-}
-
-static std::string getDescription(const BasicBlock &BB) {
- return "basic block (" + BB.getName().str() + ") in function (" +
- BB.getParent()->getName().str() + ")";
-}
-
-static std::string getDescription(const Loop &L) {
- // FIXME: Move into LoopInfo so we can get a better description
- // (and avoid a circular dependency between IR and Analysis).
- return "loop";
-}
-
-static std::string getDescription(const Region &R) {
- // FIXME: Move into RegionInfo so we can get a better description
- // (and avoid a circular dependency between IR and Analysis).
- return "region";
-}
-
-static std::string getDescription(const CallGraphSCC &SCC) {
- // FIXME: Move into CallGraphSCCPass to avoid circular dependency between
- // IR and Analysis.
- std::string Desc = "SCC (";
- bool First = true;
- for (CallGraphNode *CGN : SCC) {
- if (First)
- First = false;
- else
- Desc += ", ";
- Function *F = CGN->getFunction();
- if (F)
- Desc += F->getName();
- else
- Desc += "<<null function>>";
- }
- Desc += ")";
- return Desc;
-}
-
-bool OptBisect::shouldRunPass(const Pass *P, const Module &U) {
- return !BisectEnabled || checkPass(P->getPassName(), getDescription(U));
-}
-
-bool OptBisect::shouldRunPass(const Pass *P, const Function &U) {
- return !BisectEnabled || checkPass(P->getPassName(), getDescription(U));
-}
-
-bool OptBisect::shouldRunPass(const Pass *P, const BasicBlock &U) {
- return !BisectEnabled || checkPass(P->getPassName(), getDescription(U));
-}
-
-bool OptBisect::shouldRunPass(const Pass *P, const Region &U) {
- return !BisectEnabled || checkPass(P->getPassName(), getDescription(U));
-}
-
-bool OptBisect::shouldRunPass(const Pass *P, const Loop &U) {
- return !BisectEnabled || checkPass(P->getPassName(), getDescription(U));
-}
+bool OptBisect::shouldRunPass(const Pass *P, StringRef IRDescription) {
+ assert(BisectEnabled);
-bool OptBisect::shouldRunPass(const Pass *P, const CallGraphSCC &U) {
- return !BisectEnabled || checkPass(P->getPassName(), getDescription(U));
+ return checkPass(P->getPassName(), IRDescription);
}
bool OptBisect::checkPass(const StringRef PassName,
diff --git a/llvm/lib/IR/Pass.cpp b/llvm/lib/IR/Pass.cpp
index e9a0c68495b..4038205e044 100644
--- a/llvm/lib/IR/Pass.cpp
+++ b/llvm/lib/IR/Pass.cpp
@@ -55,8 +55,13 @@ PassManagerType ModulePass::getPotentialPassManagerType() const {
return PMT_ModulePassManager;
}
+static std::string getDescription(const Module &M) {
+ return "module (" + M.getName().str() + ")";
+}
+
bool ModulePass::skipModule(Module &M) const {
- return !M.getContext().getOptPassGate().shouldRunPass(this, M);
+ OptPassGate &Gate = M.getContext().getOptPassGate();
+ return Gate.isEnabled() && !Gate.shouldRunPass(this, getDescription(M));
}
bool Pass::mustPreserveAnalysisID(char &AID) const {
@@ -154,8 +159,13 @@ PassManagerType FunctionPass::getPotentialPassManagerType() const {
return PMT_FunctionPassManager;
}
+static std::string getDescription(const Function &F) {
+ return "function (" + F.getName().str() + ")";
+}
+
bool FunctionPass::skipFunction(const Function &F) const {
- if (!F.getContext().getOptPassGate().shouldRunPass(this, F))
+ OptPassGate &Gate = F.getContext().getOptPassGate();
+ if (Gate.isEnabled() && !Gate.shouldRunPass(this, getDescription(F)))
return true;
if (F.hasFnAttribute(Attribute::OptimizeNone)) {
@@ -185,11 +195,17 @@ bool BasicBlockPass::doFinalization(Function &) {
return false;
}
+static std::string getDescription(const BasicBlock &BB) {
+ return "basic block (" + BB.getName().str() + ") in function (" +
+ BB.getParent()->getName().str() + ")";
+}
+
bool BasicBlockPass::skipBasicBlock(const BasicBlock &BB) const {
const Function *F = BB.getParent();
if (!F)
return false;
- if (!F->getContext().getOptPassGate().shouldRunPass(this, BB))
+ OptPassGate &Gate = F->getContext().getOptPassGate();
+ if (Gate.isEnabled() && !Gate.shouldRunPass(this, getDescription(BB)))
return true;
if (F->hasFnAttribute(Attribute::OptimizeNone)) {
// Report this only once per function.
diff --git a/llvm/unittests/IR/LegacyPassManagerTest.cpp b/llvm/unittests/IR/LegacyPassManagerTest.cpp
index ea3b112f2a5..6c0c251aff9 100644
--- a/llvm/unittests/IR/LegacyPassManagerTest.cpp
+++ b/llvm/unittests/IR/LegacyPassManagerTest.cpp
@@ -400,7 +400,12 @@ namespace llvm {
struct CustomOptPassGate : public OptPassGate {
bool Skip;
CustomOptPassGate(bool Skip) : Skip(Skip) { }
- bool shouldRunPass(const Pass *P, const Module &U) { return !Skip; }
+ bool shouldRunPass(const Pass *P, StringRef IRDescription) {
+ if (P->getPassKind() == PT_Module)
+ return !Skip;
+ return OptPassGate::shouldRunPass(P, IRDescription);
+ }
+ bool isEnabled() const { return true; }
};
// Optional module pass.
OpenPOWER on IntegriCloud