Skip to content

Commit

Permalink
Re-commit optimization bisect support (r267022) without new pass mana…
Browse files Browse the repository at this point in the history
…ger support.

The original commit was reverted because of a buildbot problem with LazyCallGraph::SCC handling (not related to the OptBisect handling).

Differential Revision: http://reviews.llvm.org/D19172

llvm-svn: 267231
  • Loading branch information
andykaylor committed Apr 22, 2016
1 parent 1e9e615 commit aa641a5
Show file tree
Hide file tree
Showing 96 changed files with 657 additions and 79 deletions.
10 changes: 9 additions & 1 deletion llvm/include/llvm/Analysis/CallGraphSCCPass.h
Expand Up @@ -77,15 +77,21 @@ class CallGraphSCCPass : public Pass {
/// the call graph. If the derived class implements this method, it should
/// always explicitly call the implementation here.
void getAnalysisUsage(AnalysisUsage &Info) const override;

protected:
/// Optional passes call this function to check whether the pass should be
/// skipped. This is the case when optimization bisect is over the limit.
bool skipSCC(CallGraphSCC &SCC) const;
};

/// CallGraphSCC - This is a single SCC that a CallGraphSCCPass is run on.
class CallGraphSCC {
const CallGraph &CG; // The call graph for this SCC.
void *Context; // The CGPassManager object that is vending this.
std::vector<CallGraphNode*> Nodes;

public:
CallGraphSCC(void *context) : Context(context) {}
CallGraphSCC(CallGraph &cg, void *context) : CG(cg), Context(context) {}

void initialize(CallGraphNode *const *I, CallGraphNode *const *E) {
Nodes.assign(I, E);
Expand All @@ -101,6 +107,8 @@ class CallGraphSCC {
typedef std::vector<CallGraphNode *>::const_iterator iterator;
iterator begin() const { return Nodes.begin(); }
iterator end() const { return Nodes.end(); }

const CallGraph &getCallGraph() { return CG; }
};

} // End llvm namespace
Expand Down
7 changes: 4 additions & 3 deletions llvm/include/llvm/Analysis/LoopPass.h
Expand Up @@ -88,9 +88,10 @@ class LoopPass : public Pass {
virtual void deleteAnalysisLoop(Loop *L) {}

protected:
/// skipOptnoneFunction - Containing function has Attribute::OptimizeNone
/// and most transformation passes should skip it.
bool skipOptnoneFunction(const Loop *L) const;
/// 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 skipLoop(const Loop *L) const;
};

class LPPassManager : public FunctionPass, public PMDataManager {
Expand Down
4 changes: 4 additions & 0 deletions llvm/include/llvm/IR/LLVMContext.h
Expand Up @@ -32,6 +32,7 @@ class DiagnosticInfo;
template <typename T> class SmallVectorImpl;
class Function;
class DebugLoc;
class OptBisect;

/// This is an important class for using LLVM in a threaded context. It
/// (opaquely) owns and manages the core "global" data of LLVM's core
Expand Down Expand Up @@ -226,6 +227,9 @@ class LLVMContext {
return OptionRegistry::instance().template get<ValT, Base, Mem>();
}

/// \brief Access the object which manages optimization bisection for failure
/// analysis.
OptBisect &getOptBisect();
private:
LLVMContext(LLVMContext&) = delete;
void operator=(LLVMContext&) = delete;
Expand Down
81 changes: 81 additions & 0 deletions llvm/include/llvm/IR/OptBisect.h
@@ -0,0 +1,81 @@
//===----------- llvm/IR/OptBisect.h - LLVM Bisect support -------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file declares the interface for bisecting optimizations.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_IR_OPTBISECT_H
#define LLVM_IR_OPTBISECT_H

namespace llvm {

class Pass;
class StringRef;
class Twine;

/// 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 {
public:
/// \brief Default constructor, initializes the OptBisect state based on the
/// -opt-bisect-limit command line argument.
///
/// By default, bisection is disabled.
///
/// Clients should not instantiate this class directly. All access should go
/// through LLVMContext.
OptBisect();

/// 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
/// 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
/// 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.
///
/// 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);

/// Checks the bisect limit to determine if the optimization described by the
/// /p Desc argument 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 with the
/// bisect number assigned to the optimization along with the /p Desc
/// description and return true. Otherwise, the function will print a message
/// with the bisect number assigned to the optimization 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.
///
/// Passes may call this function to provide more fine grained control over
/// individual optimizations performed by the pass. Passes which cannot be
/// skipped entirely (such as non-optional code generation passes) may still
/// call this function to control whether or not individual optional
/// transformations are performed.
bool shouldRunCase(const Twine &Desc);

private:
bool checkPass(const StringRef PassName, const StringRef TargetDesc);

bool BisectEnabled = false;
unsigned LastBisectNum = 0;
};

} // end namespace llvm

#endif // LLVM_IR_OPTBISECT_H
19 changes: 13 additions & 6 deletions llvm/include/llvm/Pass.h
Expand Up @@ -251,6 +251,11 @@ class ModulePass : public Pass {
explicit ModulePass(char &pid) : Pass(PT_Module, pid) {}
// Force out-of-line virtual method.
~ModulePass() override;

protected:
/// Optional passes call this function to check whether the pass should be
/// skipped. This is the case when optimization bisect is over the limit.
bool skipModule(Module &M) const;
};


Expand Down Expand Up @@ -310,9 +315,10 @@ class FunctionPass : public Pass {
PassManagerType getPotentialPassManagerType() const override;

protected:
/// skipOptnoneFunction - This function has Attribute::OptimizeNone
/// and most transformation passes should skip it.
bool skipOptnoneFunction(const Function &F) const;
/// 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;
};


Expand Down Expand Up @@ -359,9 +365,10 @@ class BasicBlockPass : public Pass {
PassManagerType getPotentialPassManagerType() const override;

protected:
/// skipOptnoneFunction - Containing function has Attribute::OptimizeNone
/// and most transformation passes should skip it.
bool skipOptnoneFunction(const BasicBlock &BB) const;
/// 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 skipBasicBlock(const BasicBlock &BB) const;
};

/// If the user specifies the -time-passes argument on an LLVM tool command line
Expand Down
9 changes: 8 additions & 1 deletion llvm/lib/Analysis/CallGraphSCCPass.cpp
Expand Up @@ -23,6 +23,7 @@
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManagers.h"
#include "llvm/IR/OptBisect.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Timer.h"
Expand Down Expand Up @@ -444,7 +445,7 @@ bool CGPassManager::runOnModule(Module &M) {
// Walk the callgraph in bottom-up SCC order.
scc_iterator<CallGraph*> CGI = scc_begin(&CG);

CallGraphSCC CurSCC(&CGI);
CallGraphSCC CurSCC(CG, &CGI);
while (!CGI.isAtEnd()) {
// Copy the current SCC and increment past it so that the pass can hack
// on the SCC if it wants to without invalidating our iterator.
Expand Down Expand Up @@ -631,3 +632,9 @@ Pass *CallGraphSCCPass::createPrinterPass(raw_ostream &O,
return new PrintCallGraphPass(Banner, O);
}

bool CallGraphSCCPass::skipSCC(CallGraphSCC &SCC) const {
return !SCC.getCallGraph().getModule()
.getContext()
.getOptBisect()
.shouldRunPass(this, SCC);
}
14 changes: 10 additions & 4 deletions llvm/lib/Analysis/LoopPass.cpp
Expand Up @@ -16,6 +16,7 @@
#include "llvm/Analysis/LoopPass.h"
#include "llvm/IR/IRPrintingPasses.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/OptBisect.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Timer.h"
Expand Down Expand Up @@ -335,11 +336,16 @@ void LoopPass::assignPassManager(PMStack &PMS,
LPPM->add(this);
}

// Containing function has Attribute::OptimizeNone and transformation
// passes should skip it.
bool LoopPass::skipOptnoneFunction(const Loop *L) const {
bool LoopPass::skipLoop(const Loop *L) const {
const Function *F = L->getHeader()->getParent();
if (F && F->hasFnAttribute(Attribute::OptimizeNone)) {
if (!F)
return false;
// Check the opt bisect limit.
LLVMContext &Context = F->getContext();
if (!Context.getOptBisect().shouldRunPass(this, *L))
return true;
// Check for the OptimizeNone attribute.
if (F->hasFnAttribute(Attribute::OptimizeNone)) {
// FIXME: Report this to dbgs() only once per function.
DEBUG(dbgs() << "Skipping pass '" << getPassName()
<< "' in function " << F->getName() << "\n");
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/BranchFolding.cpp
Expand Up @@ -90,7 +90,7 @@ INITIALIZE_PASS(BranchFolderPass, "branch-folder",
"Control Flow Optimizer", false, false)

bool BranchFolderPass::runOnMachineFunction(MachineFunction &MF) {
if (skipOptnoneFunction(*MF.getFunction()))
if (skipFunction(*MF.getFunction()))
return false;

TargetPassConfig *PassConfig = &getAnalysis<TargetPassConfig>();
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/CodeGenPrepare.cpp
Expand Up @@ -211,7 +211,7 @@ FunctionPass *llvm::createCodeGenPreparePass(const TargetMachine *TM) {
}

bool CodeGenPrepare::runOnFunction(Function &F) {
if (skipOptnoneFunction(F))
if (skipFunction(F))
return false;

DL = &F.getParent()->getDataLayout();
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/DeadMachineInstructionElim.cpp
Expand Up @@ -90,7 +90,7 @@ bool DeadMachineInstructionElim::isDead(const MachineInstr *MI) const {
}

bool DeadMachineInstructionElim::runOnMachineFunction(MachineFunction &MF) {
if (skipOptnoneFunction(*MF.getFunction()))
if (skipFunction(*MF.getFunction()))
return false;

bool AnyChanges = false;
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/CodeGen/LowerEmuTLS.cpp
Expand Up @@ -63,6 +63,9 @@ ModulePass *llvm::createLowerEmuTLSPass(const TargetMachine *TM) {
}

bool LowerEmuTLS::runOnModule(Module &M) {
if (skipModule(M))
return false;

if (!TM || !TM->Options.EmulatedTLS)
return false;

Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/MachineBlockPlacement.cpp
Expand Up @@ -1430,7 +1430,7 @@ bool MachineBlockPlacement::runOnMachineFunction(MachineFunction &F) {
if (std::next(F.begin()) == F.end())
return false;

if (skipOptnoneFunction(*F.getFunction()))
if (skipFunction(*F.getFunction()))
return false;

MBPI = &getAnalysis<MachineBranchProbabilityInfo>();
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/MachineCSE.cpp
Expand Up @@ -704,7 +704,7 @@ bool MachineCSE::PerformCSE(MachineDomTreeNode *Node) {
}

bool MachineCSE::runOnMachineFunction(MachineFunction &MF) {
if (skipOptnoneFunction(*MF.getFunction()))
if (skipFunction(*MF.getFunction()))
return false;

TII = MF.getSubtarget().getInstrInfo();
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/MachineCopyPropagation.cpp
Expand Up @@ -349,7 +349,7 @@ void MachineCopyPropagation::CopyPropagateBlock(MachineBasicBlock &MBB) {
}

bool MachineCopyPropagation::runOnMachineFunction(MachineFunction &MF) {
if (skipOptnoneFunction(*MF.getFunction()))
if (skipFunction(*MF.getFunction()))
return false;

Changed = false;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/MachineLICM.cpp
Expand Up @@ -260,7 +260,7 @@ static bool LoopIsOuterMostWithPredecessor(MachineLoop *CurLoop) {
}

bool MachineLICM::runOnMachineFunction(MachineFunction &MF) {
if (skipOptnoneFunction(*MF.getFunction()))
if (skipFunction(*MF.getFunction()))
return false;

Changed = FirstInLoop = false;
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/CodeGen/MachineScheduler.cpp
Expand Up @@ -324,7 +324,7 @@ ScheduleDAGInstrs *PostMachineScheduler::createPostMachineScheduler() {
/// design would be to split blocks at scheduling boundaries, but LLVM has a
/// general bias against block splitting purely for implementation simplicity.
bool MachineScheduler::runOnMachineFunction(MachineFunction &mf) {
if (skipOptnoneFunction(*mf.getFunction()))
if (skipFunction(*mf.getFunction()))
return false;

if (EnableMachineSched.getNumOccurrences()) {
Expand Down Expand Up @@ -362,7 +362,7 @@ bool MachineScheduler::runOnMachineFunction(MachineFunction &mf) {
}

bool PostMachineScheduler::runOnMachineFunction(MachineFunction &mf) {
if (skipOptnoneFunction(*mf.getFunction()))
if (skipFunction(*mf.getFunction()))
return false;

if (EnablePostRAMachineSched.getNumOccurrences()) {
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/MachineSink.cpp
Expand Up @@ -257,7 +257,7 @@ MachineSinking::AllUsesDominatedByBlock(unsigned Reg,
}

bool MachineSinking::runOnMachineFunction(MachineFunction &MF) {
if (skipOptnoneFunction(*MF.getFunction()))
if (skipFunction(*MF.getFunction()))
return false;

DEBUG(dbgs() << "******** Machine Sinking ********\n");
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/OptimizePHIs.cpp
Expand Up @@ -63,7 +63,7 @@ INITIALIZE_PASS(OptimizePHIs, "opt-phis",
"Optimize machine instruction PHIs", false, false)

bool OptimizePHIs::runOnMachineFunction(MachineFunction &Fn) {
if (skipOptnoneFunction(*Fn.getFunction()))
if (skipFunction(*Fn.getFunction()))
return false;

MRI = &Fn.getRegInfo();
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/PeepholeOptimizer.cpp
Expand Up @@ -1471,7 +1471,7 @@ bool PeepholeOptimizer::foldRedundantNAPhysCopy(
}

bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) {
if (skipOptnoneFunction(*MF.getFunction()))
if (skipFunction(*MF.getFunction()))
return false;

DEBUG(dbgs() << "********** PEEPHOLE OPTIMIZER **********\n");
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/PostRASchedulerList.cpp
Expand Up @@ -273,7 +273,7 @@ bool PostRAScheduler::enablePostRAScheduler(
}

bool PostRAScheduler::runOnMachineFunction(MachineFunction &Fn) {
if (skipOptnoneFunction(*Fn.getFunction()))
if (skipFunction(*Fn.getFunction()))
return false;

TII = Fn.getSubtarget().getInstrInfo();
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/StackColoring.cpp
Expand Up @@ -657,7 +657,7 @@ void StackColoring::expungeSlotMap(DenseMap<int, int> &SlotRemap,
}

bool StackColoring::runOnMachineFunction(MachineFunction &Func) {
if (skipOptnoneFunction(*Func.getFunction()))
if (skipFunction(*Func.getFunction()))
return false;

DEBUG(dbgs() << "********** Stack Coloring **********\n"
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/TailDuplication.cpp
Expand Up @@ -44,7 +44,7 @@ INITIALIZE_PASS(TailDuplicatePass, "tailduplication", "Tail Duplication", false,
false)

bool TailDuplicatePass::runOnMachineFunction(MachineFunction &MF) {
if (skipOptnoneFunction(*MF.getFunction()))
if (skipFunction(*MF.getFunction()))
return false;

auto MMI = getAnalysisIfAvailable<MachineModuleInfo>();
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/IR/CMakeLists.txt
Expand Up @@ -39,6 +39,7 @@ add_llvm_library(LLVMCore
Module.cpp
ModuleSummaryIndex.cpp
Operator.cpp
OptBisect.cpp
Pass.cpp
PassManager.cpp
PassRegistry.cpp
Expand Down

0 comments on commit aa641a5

Please sign in to comment.