[NFC] OptPassGate extracted from OptBisect

Summary:
This is an NFC refactoring of the OptBisect class to split it into an optional pass gate interface used by LLVMContext and the Optional Pass Bisector (OptBisect) used for debugging of optional passes.

This refactoring is needed for D44464, which introduces setOptPassGate() method to allow implementations other than OptBisect.

Patch by Yevgeny Rouban.

Reviewers: andrew.w.kaylor, fedor.sergeev, vsk, dberlin, Eugene.Zelenko, reames, skatkov
Reviewed By: fedor.sergeev
Differential Revision: https://reviews.llvm.org/D44821

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@328637 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Fedor Sergeev 2018-03-27 16:57:20 +00:00
parent 9273bb3570
commit 558f76fb1d
10 changed files with 73 additions and 37 deletions

View File

@ -31,7 +31,7 @@ class Function;
class Instruction;
class LLVMContextImpl;
class Module;
class OptBisect;
class OptPassGate;
template <typename T> class SmallVectorImpl;
class SMDiagnostic;
class StringRef;
@ -317,7 +317,8 @@ public:
/// \brief Access the object which manages optimization bisection for failure
/// analysis.
OptBisect &getOptBisect();
OptPassGate &getOptPassGate();
private:
// Module needs access to the add/removeModule methods.
friend class Module;

View File

@ -20,12 +20,32 @@
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.
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; }
};
/// This class implements a mechanism to disable passes and individual
/// optimizations at compile time based on a command line option
/// (-opt-bisect-limit) in order to perform a bisecting search for
/// optimization-related problems.
class OptBisect {
class OptBisect : public OptPassGate {
public:
/// \brief Default constructor, initializes the OptBisect state based on the
/// -opt-bisect-limit command line argument.
@ -36,20 +56,26 @@ public:
/// through LLVMContext.
OptBisect();
virtual ~OptBisect() = default;
/// Checks the bisect limit to determine if the specified pass should run.
///
/// This function will immediate return true if bisection is disabled. If the
/// bisect limit is set to -1, the function will print a message describing
/// These functions immediately return true if bisection is disabled. If the
/// bisect limit is set to -1, the functions print a message describing
/// the pass and the bisect number assigned to it and return true. Otherwise,
/// the function will print a message with the bisect number assigned to the
/// the functions print 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 exceded or false if it has.
/// the bisect limit has not yet been exceeded or false if it has.
///
/// Most passes should not call this routine directly. Instead, it is called
/// through a helper routine provided by the pass base class. For instance,
/// function passes should call FunctionPass::skipFunction().
template <class UnitT>
bool shouldRunPass(const Pass *P, const UnitT &U);
/// Most passes should not call these routines 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;
private:
bool checkPass(const StringRef PassName, const StringRef TargetDesc);

View File

@ -648,7 +648,7 @@ Pass *CallGraphSCCPass::createPrinterPass(raw_ostream &OS,
bool CallGraphSCCPass::skipSCC(CallGraphSCC &SCC) const {
return !SCC.getCallGraph().getModule()
.getContext()
.getOptBisect()
.getOptPassGate()
.shouldRunPass(this, SCC);
}

View File

@ -357,7 +357,7 @@ bool LoopPass::skipLoop(const Loop *L) const {
return false;
// Check the opt bisect limit.
LLVMContext &Context = F->getContext();
if (!Context.getOptBisect().shouldRunPass(this, *L))
if (!Context.getOptPassGate().shouldRunPass(this, *L))
return true;
// Check for the OptimizeNone attribute.
if (F->hasFnAttribute(Attribute::OptimizeNone)) {

View File

@ -283,7 +283,7 @@ Pass *RegionPass::createPrinterPass(raw_ostream &O,
bool RegionPass::skipRegion(Region &R) const {
Function &F = *R.getEntry()->getParent();
if (!F.getContext().getOptBisect().shouldRunPass(this, R))
if (!F.getContext().getOptPassGate().shouldRunPass(this, R))
return true;
if (F.hasFnAttribute(Attribute::OptimizeNone)) {

View File

@ -332,8 +332,8 @@ void LLVMContext::setDiscardValueNames(bool Discard) {
pImpl->DiscardValueNames = Discard;
}
OptBisect &LLVMContext::getOptBisect() {
return pImpl->getOptBisect();
OptPassGate &LLVMContext::getOptPassGate() {
return pImpl->getOptPassGate();
}
const DiagnosticHandler *LLVMContext::getDiagHandlerPtr() const {

View File

@ -222,8 +222,8 @@ void LLVMContextImpl::getSyncScopeNames(
/// Singleton instance of the OptBisect class.
///
/// This singleton is accessed via the LLVMContext::getOptBisect() function. It
/// provides a mechanism to disable passes and individual optimizations at
/// This singleton is accessed via the LLVMContext::getOptPassGate() function.
/// It provides a mechanism to disable passes and individual optimizations at
/// compile time based on a command line option (-opt-bisect-limit) in order to
/// perform a bisecting search for optimization-related problems.
///
@ -233,6 +233,6 @@ void LLVMContextImpl::getSyncScopeNames(
/// enabled in order to enable a consistent bisect count.
static ManagedStatic<OptBisect> OptBisector;
OptBisect &LLVMContextImpl::getOptBisect() {
OptPassGate &LLVMContextImpl::getOptPassGate() {
return *OptBisector;
}

View File

@ -1357,7 +1357,7 @@ public:
/// \brief Access the object which manages optimization bisection for failure
/// analysis.
OptBisect &getOptBisect();
OptPassGate &getOptPassGate();
};
} // end namespace llvm

View File

@ -36,7 +36,7 @@ static cl::opt<int> OptBisectLimit("opt-bisect-limit", cl::Hidden,
cl::Optional,
cl::desc("Maximum optimization to perform"));
OptBisect::OptBisect() {
OptBisect::OptBisect() : OptPassGate() {
BisectEnabled = OptBisectLimit != std::numeric_limits<int>::max();
}
@ -92,19 +92,28 @@ static std::string getDescription(const CallGraphSCC &SCC) {
return Desc;
}
// Force instantiations.
template bool OptBisect::shouldRunPass(const Pass *, const Module &);
template bool OptBisect::shouldRunPass(const Pass *, const Function &);
template bool OptBisect::shouldRunPass(const Pass *, const BasicBlock &);
template bool OptBisect::shouldRunPass(const Pass *, const Loop &);
template bool OptBisect::shouldRunPass(const Pass *, const CallGraphSCC &);
template bool OptBisect::shouldRunPass(const Pass *, const Region &);
bool OptBisect::shouldRunPass(const Pass *P, const Module &U) {
return !BisectEnabled || checkPass(P->getPassName(), getDescription(U));
}
template <class UnitT>
bool OptBisect::shouldRunPass(const Pass *P, const UnitT &U) {
if (!BisectEnabled)
return true;
return 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, const CallGraphSCC &U) {
return !BisectEnabled || checkPass(P->getPassName(), getDescription(U));
}
bool OptBisect::checkPass(const StringRef PassName,

View File

@ -56,7 +56,7 @@ PassManagerType ModulePass::getPotentialPassManagerType() const {
}
bool ModulePass::skipModule(Module &M) const {
return !M.getContext().getOptBisect().shouldRunPass(this, M);
return !M.getContext().getOptPassGate().shouldRunPass(this, M);
}
bool Pass::mustPreserveAnalysisID(char &AID) const {
@ -155,7 +155,7 @@ PassManagerType FunctionPass::getPotentialPassManagerType() const {
}
bool FunctionPass::skipFunction(const Function &F) const {
if (!F.getContext().getOptBisect().shouldRunPass(this, F))
if (!F.getContext().getOptPassGate().shouldRunPass(this, F))
return true;
if (F.hasFnAttribute(Attribute::OptimizeNone)) {
@ -189,7 +189,7 @@ bool BasicBlockPass::skipBasicBlock(const BasicBlock &BB) const {
const Function *F = BB.getParent();
if (!F)
return false;
if (!F->getContext().getOptBisect().shouldRunPass(this, BB))
if (!F->getContext().getOptPassGate().shouldRunPass(this, BB))
return true;
if (F->hasFnAttribute(Attribute::OptimizeNone)) {
// Report this only once per function.