Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit 1e455c5

Browse files
author
Andrew Kaylor
committed
Re-commit optimization bisect support (r267022) without new pass manager 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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@267231 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 2057e74 commit 1e455c5

File tree

96 files changed

+657
-79
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+657
-79
lines changed

include/llvm/Analysis/CallGraphSCCPass.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,15 +77,21 @@ class CallGraphSCCPass : public Pass {
7777
/// the call graph. If the derived class implements this method, it should
7878
/// always explicitly call the implementation here.
7979
void getAnalysisUsage(AnalysisUsage &Info) const override;
80+
81+
protected:
82+
/// Optional passes call this function to check whether the pass should be
83+
/// skipped. This is the case when optimization bisect is over the limit.
84+
bool skipSCC(CallGraphSCC &SCC) const;
8085
};
8186

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

8793
public:
88-
CallGraphSCC(void *context) : Context(context) {}
94+
CallGraphSCC(CallGraph &cg, void *context) : CG(cg), Context(context) {}
8995

9096
void initialize(CallGraphNode *const *I, CallGraphNode *const *E) {
9197
Nodes.assign(I, E);
@@ -101,6 +107,8 @@ class CallGraphSCC {
101107
typedef std::vector<CallGraphNode *>::const_iterator iterator;
102108
iterator begin() const { return Nodes.begin(); }
103109
iterator end() const { return Nodes.end(); }
110+
111+
const CallGraph &getCallGraph() { return CG; }
104112
};
105113

106114
} // End llvm namespace

include/llvm/Analysis/LoopPass.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,10 @@ class LoopPass : public Pass {
8888
virtual void deleteAnalysisLoop(Loop *L) {}
8989

9090
protected:
91-
/// skipOptnoneFunction - Containing function has Attribute::OptimizeNone
92-
/// and most transformation passes should skip it.
93-
bool skipOptnoneFunction(const Loop *L) const;
91+
/// Optional passes call this function to check whether the pass should be
92+
/// skipped. This is the case when Attribute::OptimizeNone is set or when
93+
/// optimization bisect is over the limit.
94+
bool skipLoop(const Loop *L) const;
9495
};
9596

9697
class LPPassManager : public FunctionPass, public PMDataManager {

include/llvm/IR/LLVMContext.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class DiagnosticInfo;
3232
template <typename T> class SmallVectorImpl;
3333
class Function;
3434
class DebugLoc;
35+
class OptBisect;
3536

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

230+
/// \brief Access the object which manages optimization bisection for failure
231+
/// analysis.
232+
OptBisect &getOptBisect();
229233
private:
230234
LLVMContext(LLVMContext&) = delete;
231235
void operator=(LLVMContext&) = delete;

include/llvm/IR/OptBisect.h

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
//===----------- llvm/IR/OptBisect.h - LLVM Bisect support -------------===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
///
10+
/// \file
11+
/// This file declares the interface for bisecting optimizations.
12+
///
13+
//===----------------------------------------------------------------------===//
14+
15+
#ifndef LLVM_IR_OPTBISECT_H
16+
#define LLVM_IR_OPTBISECT_H
17+
18+
namespace llvm {
19+
20+
class Pass;
21+
class StringRef;
22+
class Twine;
23+
24+
/// This class implements a mechanism to disable passes and individual
25+
/// optimizations at compile time based on a command line option
26+
/// (-opt-bisect-limit) in order to perform a bisecting search for
27+
/// optimization-related problems.
28+
class OptBisect {
29+
public:
30+
/// \brief Default constructor, initializes the OptBisect state based on the
31+
/// -opt-bisect-limit command line argument.
32+
///
33+
/// By default, bisection is disabled.
34+
///
35+
/// Clients should not instantiate this class directly. All access should go
36+
/// through LLVMContext.
37+
OptBisect();
38+
39+
/// Checks the bisect limit to determine if the specified pass should run.
40+
///
41+
/// This function will immediate return true if bisection is disabled. If the
42+
/// bisect limit is set to -1, the function will print a message describing
43+
/// the pass and the bisect number assigned to it and return true. Otherwise,
44+
/// the function will print a message with the bisect number assigned to the
45+
/// pass and indicating whether or not the pass will be run and return true if
46+
/// the bisect limit has not yet been exceded or false if it has.
47+
///
48+
/// Most passes should not call this routine directly. Instead, it is called
49+
/// through a helper routine provided by the pass base class. For instance,
50+
/// function passes should call FunctionPass::skipFunction().
51+
template <class UnitT>
52+
bool shouldRunPass(const Pass *P, const UnitT &U);
53+
54+
/// Checks the bisect limit to determine if the optimization described by the
55+
/// /p Desc argument should run.
56+
///
57+
/// This function will immediate return true if bisection is disabled. If the
58+
/// bisect limit is set to -1, the function will print a message with the
59+
/// bisect number assigned to the optimization along with the /p Desc
60+
/// description and return true. Otherwise, the function will print a message
61+
/// with the bisect number assigned to the optimization and indicating whether
62+
/// or not the pass will be run and return true if the bisect limit has not
63+
/// yet been exceded or false if it has.
64+
///
65+
/// Passes may call this function to provide more fine grained control over
66+
/// individual optimizations performed by the pass. Passes which cannot be
67+
/// skipped entirely (such as non-optional code generation passes) may still
68+
/// call this function to control whether or not individual optional
69+
/// transformations are performed.
70+
bool shouldRunCase(const Twine &Desc);
71+
72+
private:
73+
bool checkPass(const StringRef PassName, const StringRef TargetDesc);
74+
75+
bool BisectEnabled = false;
76+
unsigned LastBisectNum = 0;
77+
};
78+
79+
} // end namespace llvm
80+
81+
#endif // LLVM_IR_OPTBISECT_H

include/llvm/Pass.h

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,11 @@ class ModulePass : public Pass {
251251
explicit ModulePass(char &pid) : Pass(PT_Module, pid) {}
252252
// Force out-of-line virtual method.
253253
~ModulePass() override;
254+
255+
protected:
256+
/// Optional passes call this function to check whether the pass should be
257+
/// skipped. This is the case when optimization bisect is over the limit.
258+
bool skipModule(Module &M) const;
254259
};
255260

256261

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

312317
protected:
313-
/// skipOptnoneFunction - This function has Attribute::OptimizeNone
314-
/// and most transformation passes should skip it.
315-
bool skipOptnoneFunction(const Function &F) const;
318+
/// Optional passes call this function to check whether the pass should be
319+
/// skipped. This is the case when Attribute::OptimizeNone is set or when
320+
/// optimization bisect is over the limit.
321+
bool skipFunction(const Function &F) const;
316322
};
317323

318324

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

361367
protected:
362-
/// skipOptnoneFunction - Containing function has Attribute::OptimizeNone
363-
/// and most transformation passes should skip it.
364-
bool skipOptnoneFunction(const BasicBlock &BB) const;
368+
/// Optional passes call this function to check whether the pass should be
369+
/// skipped. This is the case when Attribute::OptimizeNone is set or when
370+
/// optimization bisect is over the limit.
371+
bool skipBasicBlock(const BasicBlock &BB) const;
365372
};
366373

367374
/// If the user specifies the -time-passes argument on an LLVM tool command line

lib/Analysis/CallGraphSCCPass.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "llvm/IR/IntrinsicInst.h"
2424
#include "llvm/IR/LLVMContext.h"
2525
#include "llvm/IR/LegacyPassManagers.h"
26+
#include "llvm/IR/OptBisect.h"
2627
#include "llvm/Support/CommandLine.h"
2728
#include "llvm/Support/Debug.h"
2829
#include "llvm/Support/Timer.h"
@@ -444,7 +445,7 @@ bool CGPassManager::runOnModule(Module &M) {
444445
// Walk the callgraph in bottom-up SCC order.
445446
scc_iterator<CallGraph*> CGI = scc_begin(&CG);
446447

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

635+
bool CallGraphSCCPass::skipSCC(CallGraphSCC &SCC) const {
636+
return !SCC.getCallGraph().getModule()
637+
.getContext()
638+
.getOptBisect()
639+
.shouldRunPass(this, SCC);
640+
}

lib/Analysis/LoopPass.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "llvm/Analysis/LoopPass.h"
1717
#include "llvm/IR/IRPrintingPasses.h"
1818
#include "llvm/IR/LLVMContext.h"
19+
#include "llvm/IR/OptBisect.h"
1920
#include "llvm/IR/PassManager.h"
2021
#include "llvm/Support/Debug.h"
2122
#include "llvm/Support/Timer.h"
@@ -335,11 +336,16 @@ void LoopPass::assignPassManager(PMStack &PMS,
335336
LPPM->add(this);
336337
}
337338

338-
// Containing function has Attribute::OptimizeNone and transformation
339-
// passes should skip it.
340-
bool LoopPass::skipOptnoneFunction(const Loop *L) const {
339+
bool LoopPass::skipLoop(const Loop *L) const {
341340
const Function *F = L->getHeader()->getParent();
342-
if (F && F->hasFnAttribute(Attribute::OptimizeNone)) {
341+
if (!F)
342+
return false;
343+
// Check the opt bisect limit.
344+
LLVMContext &Context = F->getContext();
345+
if (!Context.getOptBisect().shouldRunPass(this, *L))
346+
return true;
347+
// Check for the OptimizeNone attribute.
348+
if (F->hasFnAttribute(Attribute::OptimizeNone)) {
343349
// FIXME: Report this to dbgs() only once per function.
344350
DEBUG(dbgs() << "Skipping pass '" << getPassName()
345351
<< "' in function " << F->getName() << "\n");

lib/CodeGen/BranchFolding.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ INITIALIZE_PASS(BranchFolderPass, "branch-folder",
9090
"Control Flow Optimizer", false, false)
9191

9292
bool BranchFolderPass::runOnMachineFunction(MachineFunction &MF) {
93-
if (skipOptnoneFunction(*MF.getFunction()))
93+
if (skipFunction(*MF.getFunction()))
9494
return false;
9595

9696
TargetPassConfig *PassConfig = &getAnalysis<TargetPassConfig>();

lib/CodeGen/CodeGenPrepare.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ FunctionPass *llvm::createCodeGenPreparePass(const TargetMachine *TM) {
211211
}
212212

213213
bool CodeGenPrepare::runOnFunction(Function &F) {
214-
if (skipOptnoneFunction(F))
214+
if (skipFunction(F))
215215
return false;
216216

217217
DL = &F.getParent()->getDataLayout();

lib/CodeGen/DeadMachineInstructionElim.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ bool DeadMachineInstructionElim::isDead(const MachineInstr *MI) const {
9090
}
9191

9292
bool DeadMachineInstructionElim::runOnMachineFunction(MachineFunction &MF) {
93-
if (skipOptnoneFunction(*MF.getFunction()))
93+
if (skipFunction(*MF.getFunction()))
9494
return false;
9595

9696
bool AnyChanges = false;

lib/CodeGen/LowerEmuTLS.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ ModulePass *llvm::createLowerEmuTLSPass(const TargetMachine *TM) {
6363
}
6464

6565
bool LowerEmuTLS::runOnModule(Module &M) {
66+
if (skipModule(M))
67+
return false;
68+
6669
if (!TM || !TM->Options.EmulatedTLS)
6770
return false;
6871

lib/CodeGen/MachineBlockPlacement.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1430,7 +1430,7 @@ bool MachineBlockPlacement::runOnMachineFunction(MachineFunction &F) {
14301430
if (std::next(F.begin()) == F.end())
14311431
return false;
14321432

1433-
if (skipOptnoneFunction(*F.getFunction()))
1433+
if (skipFunction(*F.getFunction()))
14341434
return false;
14351435

14361436
MBPI = &getAnalysis<MachineBranchProbabilityInfo>();

lib/CodeGen/MachineCSE.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -704,7 +704,7 @@ bool MachineCSE::PerformCSE(MachineDomTreeNode *Node) {
704704
}
705705

706706
bool MachineCSE::runOnMachineFunction(MachineFunction &MF) {
707-
if (skipOptnoneFunction(*MF.getFunction()))
707+
if (skipFunction(*MF.getFunction()))
708708
return false;
709709

710710
TII = MF.getSubtarget().getInstrInfo();

lib/CodeGen/MachineCopyPropagation.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ void MachineCopyPropagation::CopyPropagateBlock(MachineBasicBlock &MBB) {
349349
}
350350

351351
bool MachineCopyPropagation::runOnMachineFunction(MachineFunction &MF) {
352-
if (skipOptnoneFunction(*MF.getFunction()))
352+
if (skipFunction(*MF.getFunction()))
353353
return false;
354354

355355
Changed = false;

lib/CodeGen/MachineLICM.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ static bool LoopIsOuterMostWithPredecessor(MachineLoop *CurLoop) {
260260
}
261261

262262
bool MachineLICM::runOnMachineFunction(MachineFunction &MF) {
263-
if (skipOptnoneFunction(*MF.getFunction()))
263+
if (skipFunction(*MF.getFunction()))
264264
return false;
265265

266266
Changed = FirstInLoop = false;

lib/CodeGen/MachineScheduler.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ ScheduleDAGInstrs *PostMachineScheduler::createPostMachineScheduler() {
324324
/// design would be to split blocks at scheduling boundaries, but LLVM has a
325325
/// general bias against block splitting purely for implementation simplicity.
326326
bool MachineScheduler::runOnMachineFunction(MachineFunction &mf) {
327-
if (skipOptnoneFunction(*mf.getFunction()))
327+
if (skipFunction(*mf.getFunction()))
328328
return false;
329329

330330
if (EnableMachineSched.getNumOccurrences()) {
@@ -362,7 +362,7 @@ bool MachineScheduler::runOnMachineFunction(MachineFunction &mf) {
362362
}
363363

364364
bool PostMachineScheduler::runOnMachineFunction(MachineFunction &mf) {
365-
if (skipOptnoneFunction(*mf.getFunction()))
365+
if (skipFunction(*mf.getFunction()))
366366
return false;
367367

368368
if (EnablePostRAMachineSched.getNumOccurrences()) {

lib/CodeGen/MachineSink.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ MachineSinking::AllUsesDominatedByBlock(unsigned Reg,
257257
}
258258

259259
bool MachineSinking::runOnMachineFunction(MachineFunction &MF) {
260-
if (skipOptnoneFunction(*MF.getFunction()))
260+
if (skipFunction(*MF.getFunction()))
261261
return false;
262262

263263
DEBUG(dbgs() << "******** Machine Sinking ********\n");

lib/CodeGen/OptimizePHIs.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ INITIALIZE_PASS(OptimizePHIs, "opt-phis",
6363
"Optimize machine instruction PHIs", false, false)
6464

6565
bool OptimizePHIs::runOnMachineFunction(MachineFunction &Fn) {
66-
if (skipOptnoneFunction(*Fn.getFunction()))
66+
if (skipFunction(*Fn.getFunction()))
6767
return false;
6868

6969
MRI = &Fn.getRegInfo();

lib/CodeGen/PeepholeOptimizer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1471,7 +1471,7 @@ bool PeepholeOptimizer::foldRedundantNAPhysCopy(
14711471
}
14721472

14731473
bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) {
1474-
if (skipOptnoneFunction(*MF.getFunction()))
1474+
if (skipFunction(*MF.getFunction()))
14751475
return false;
14761476

14771477
DEBUG(dbgs() << "********** PEEPHOLE OPTIMIZER **********\n");

lib/CodeGen/PostRASchedulerList.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ bool PostRAScheduler::enablePostRAScheduler(
273273
}
274274

275275
bool PostRAScheduler::runOnMachineFunction(MachineFunction &Fn) {
276-
if (skipOptnoneFunction(*Fn.getFunction()))
276+
if (skipFunction(*Fn.getFunction()))
277277
return false;
278278

279279
TII = Fn.getSubtarget().getInstrInfo();

lib/CodeGen/StackColoring.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -657,7 +657,7 @@ void StackColoring::expungeSlotMap(DenseMap<int, int> &SlotRemap,
657657
}
658658

659659
bool StackColoring::runOnMachineFunction(MachineFunction &Func) {
660-
if (skipOptnoneFunction(*Func.getFunction()))
660+
if (skipFunction(*Func.getFunction()))
661661
return false;
662662

663663
DEBUG(dbgs() << "********** Stack Coloring **********\n"

lib/CodeGen/TailDuplication.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ INITIALIZE_PASS(TailDuplicatePass, "tailduplication", "Tail Duplication", false,
4444
false)
4545

4646
bool TailDuplicatePass::runOnMachineFunction(MachineFunction &MF) {
47-
if (skipOptnoneFunction(*MF.getFunction()))
47+
if (skipFunction(*MF.getFunction()))
4848
return false;
4949

5050
auto MMI = getAnalysisIfAvailable<MachineModuleInfo>();

lib/IR/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ add_llvm_library(LLVMCore
3939
Module.cpp
4040
ModuleSummaryIndex.cpp
4141
Operator.cpp
42+
OptBisect.cpp
4243
Pass.cpp
4344
PassManager.cpp
4445
PassRegistry.cpp

0 commit comments

Comments
 (0)