43#define DEBUG_TYPE "cgscc-passmgr"
50STATISTIC(MaxSCCIterations,
"Maximum CGSCCPassMgr iterations on one SCC");
69 using ModulePass::doInitialization;
70 using ModulePass::doFinalization;
79 Info.setPreservesAll();
91 Pass *
P = getContainedPass(Index);
92 P->dumpPassStructure(
Offset + 1);
97 Pass *getContainedPass(
unsigned N) {
98 assert(
N < PassVector.size() &&
"Pass number out of range!");
99 return static_cast<Pass *
>(PassVector[
N]);
108 bool &DevirtualizedCall);
112 bool &DevirtualizedCall);
114 bool IsCheckingMode);
119char CGPassManager::ID = 0;
123 bool &DevirtualizedCall) {
124 bool Changed =
false;
130 if (!CallGraphUpToDate) {
131 DevirtualizedCall |= RefreshCallGraph(CurSCC, CG,
false);
132 CallGraphUpToDate =
true;
138 bool EmitICRemark =
M.shouldEmitInstrCountChangedRemark();
141 InstrCount = initSizeRemarkInfo(M, FunctionToInstrCount);
146 SCCCount =
M.getInstructionCount();
151 static_cast<int64_t
>(SCCCount) -
static_cast<int64_t
>(
InstrCount);
152 emitInstrCountChangedRemark(
P, M, Delta,
InstrCount,
153 FunctionToInstrCount);
163 RefreshCallGraph(CurSCC, CG,
true);
170 "Invalid CGPassManager member");
181 F->getContext().yield();
187 if (Changed && CallGraphUpToDate) {
188 LLVM_DEBUG(
dbgs() <<
"CGSCCPASSMGR: Pass Dirtied SCC: " <<
P->getPassName()
190 CallGraphUpToDate =
false;
211 : CurSCC) CGN->dump(););
213 bool MadeChange =
false;
214 bool DevirtualizedCall =
false;
217 unsigned FunctionNo = 0;
219 SCCIdx != E; ++SCCIdx, ++FunctionNo) {
222 if (!
F ||
F->isDeclaration())
continue;
229 unsigned NumDirectRemoved = 0, NumIndirectRemoved = 0;
236 bool WasLast =
I + 1 == CGNEnd;
258 if (RemoveAndCheckForDone(
I))
265 auto *
Call = dyn_cast_or_null<CallBase>(*
I->first);
272 "CallGraphSCCPass did not update the CallGraph correctly!");
275 if (!
I->second->getFunction())
276 ++NumIndirectRemoved;
280 if (RemoveAndCheckForDone(
I))
285 assert(!Calls.
count(Call) &&
"Call site occurs in node multiple times");
290 if (!Callee || !(
Callee->isIntrinsic()))
291 Calls.
insert(std::make_pair(Call,
I->second));
298 unsigned NumDirectAdded = 0, NumIndirectAdded = 0;
302 auto *
Call = dyn_cast<CallBase>(&
I);
306 if (Callee &&
Callee->isIntrinsic())
322 if (ExistingIt != Calls.
end()) {
326 Calls.
erase(ExistingIt);
337 if (CheckingMode &&
Call->getCalledFunction() &&
342 "CallGraphSCCPass did not update the CallGraph correctly!");
352 DevirtualizedCall =
true;
354 <<
Callee->getName() <<
"'\n");
367 "CallGraphSCCPass did not update the CallGraph correctly!");
393 if (NumIndirectRemoved > NumIndirectAdded &&
394 NumDirectRemoved < NumDirectAdded)
395 DevirtualizedCall =
true;
401 assert(Calls.
empty() &&
"Dangling pointers found in call sites map");
405 if ((FunctionNo & 15) == 15)
410 dbgs() <<
"CGSCCPASSMGR: Refreshed SCC is now:\n";
413 if (DevirtualizedCall)
414 dbgs() <<
"CGSCCPASSMGR: Refresh devirtualized a call!\n";
416 dbgs() <<
"CGSCCPASSMGR: SCC Refresh didn't change call graph.\n";
420 return DevirtualizedCall;
427 bool &DevirtualizedCall) {
428 bool Changed =
false;
437 bool CallGraphUpToDate =
true;
440 for (
unsigned PassNo = 0, e = getNumContainedPasses();
441 PassNo !=
e; ++PassNo) {
442 Pass *
P = getContainedPass(PassNo);
446 if (isPassDebuggingExecutionsOrMore()) {
447 std::string Functions;
460 initializeAnalysisImpl(
P);
462#ifdef EXPENSIVE_CHECKS
468 RunPassOnSCC(
P, CurSCC, CG, CallGraphUpToDate, DevirtualizedCall);
470 Changed |= LocalChanged;
472#ifdef EXPENSIVE_CHECKS
473 if (!LocalChanged && (RefHash !=
P->structuralHash(CG.
getModule()))) {
474 llvm::errs() <<
"Pass modifies its input and doesn't report it: "
475 <<
P->getPassName() <<
"\n";
483 verifyPreservedAnalysis(
P);
485 removeNotPreservedAnalysis(
P);
486 recordAvailableAnalysis(
P);
492 if (!CallGraphUpToDate)
493 DevirtualizedCall |= RefreshCallGraph(CurSCC, CG,
false);
499bool CGPassManager::runOnModule(
Module &M) {
500 CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph();
501 bool Changed = doInitialization(CG);
510 const std::vector<CallGraphNode *> &NodeVec = *CGI;
511 CurSCC.initialize(NodeVec);
526 unsigned Iteration = 0;
527 bool DevirtualizedCall =
false;
530 <<
" SCCPASSMGR: Re-visiting SCC, iteration #" << Iteration
532 DevirtualizedCall =
false;
533 Changed |= RunAllPassesOnSCC(CurSCC, CG, DevirtualizedCall);
536 if (DevirtualizedCall)
539 <<
" times, due to -max-devirt-iterations\n");
541 MaxSCCIterations.updateMax(Iteration);
543 Changed |= doFinalization(CG);
548bool CGPassManager::doInitialization(
CallGraph &CG) {
549 bool Changed =
false;
550 for (
unsigned i = 0, e = getNumContainedPasses(); i !=
e; ++i) {
551 if (
PMDataManager *PM = getContainedPass(i)->getAsPMDataManager()) {
553 "Invalid CGPassManager member");
563bool CGPassManager::doFinalization(
CallGraph &CG) {
564 bool Changed =
false;
565 for (
unsigned i = 0, e = getNumContainedPasses(); i !=
e; ++i) {
566 if (
PMDataManager *PM = getContainedPass(i)->getAsPMDataManager()) {
568 "Invalid CGPassManager member");
584 assert(Old != New &&
"Should not replace node with self");
585 for (
unsigned i = 0; ; ++i) {
586 assert(i != Nodes.size() &&
"Node not in SCC");
587 if (Nodes[i] != Old)
continue;
591 Nodes.erase(Nodes.begin() + i);
613 while (!PMS.
empty() &&
617 assert(!PMS.
empty() &&
"Unable to handle Call Graph Pass");
621 CGP = (CGPassManager*)PMS.
top();
624 assert(!PMS.
empty() &&
"Unable to create Call Graph Pass Manager");
628 CGP =
new CGPassManager();
677 bool BannerPrinted =
false;
678 auto PrintBannerOnce = [&]() {
682 BannerPrinted =
true;
689 SCC.getCallGraph().getModule().print(
OS,
nullptr);
692 bool FoundFunction =
false;
696 FoundFunction =
true;
704 OS <<
"\nPrinting <null> Function\n";
707 if (NeedModule && FoundFunction) {
710 SCC.getCallGraph().getModule().print(
OS,
nullptr);
715 StringRef getPassName()
const override {
return "Print CallGraph IR"; }
720char PrintCallGraphPass::ID = 0;
723 const std::string &Banner)
const {
724 return new PrintCallGraphPass(Banner,
OS);
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Analysis containing CSE Info
This file provides interfaces used to build and manipulate a call graph, which is a very useful tool ...
static unsigned InstrCount
This file defines the DenseMap class.
Module.h This file contains the declarations for the Module class.
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This header defines classes/functions to handle pass execution timing information with interfaces for...
This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected components (SCCs) of a ...
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
void setPreservesAll()
Set by analyses that do not transform their input at all.
LLVM Basic Block Representation.
A node in the call graph for a module.
LLVM_ABI void print(raw_ostream &OS) const
void addCalledFunction(CallBase *Call, CallGraphNode *M)
Adds a function to the list of functions called by this one.
LLVM_ABI void replaceCallEdge(CallBase &Call, CallBase &NewCall, CallGraphNode *NewNode)
Replaces the edge in the node for the specified call site with a new one.
LLVM_ABI void dump() const
Print out this call graph node.
Function * getFunction() const
Returns the function that this call graph node represents.
std::vector< CallRecord >::iterator iterator
void removeCallEdge(iterator I)
Pass * createPrinterPass(raw_ostream &OS, const std::string &Banner) const override
createPrinterPass - Get a pass that prints the Module corresponding to a CallGraph.
virtual bool runOnSCC(CallGraphSCC &SCC)=0
runOnSCC - This method should be implemented by the subclass to perform whatever action is necessary ...
void getAnalysisUsage(AnalysisUsage &Info) const override
getAnalysisUsage - For this class, we declare that we require and preserve the call graph.
void assignPassManager(PMStack &PMS, PassManagerType PMT) override
Assign pass manager to manager this pass.
CallGraphSCC - This is a single SCC that a CallGraphSCCPass is run on.
std::vector< CallGraphNode * >::const_iterator iterator
LLVM_ABI void ReplaceNode(CallGraphNode *Old, CallGraphNode *New)
ReplaceNode - This informs the SCC and the pass manager that the specified Old node has been deleted,...
LLVM_ABI void DeleteNode(CallGraphNode *Old)
DeleteNode - This informs the SCC and the pass manager that the specified Old node has been deleted.
The ModulePass which wraps up a CallGraph and the logic to build it.
The basic data container for the call graph of a Module of IR.
LLVM_ABI CallGraphNode * getOrInsertFunction(const Function *F)
Similar to operator[], but this will insert a new CallGraphNode for F if one does not already exist.
CallGraphNode * getCallsExternalNode() const
Module & getModule() const
Returns the module the call graph corresponds to.
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
This pass is required by interprocedural register allocation.
FPPassManager manages BBPassManagers and FunctionPasses.
bool runOnFunction(Function &F)
run - Execute all of the passes scheduled for execution.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
virtual bool runOnModule(Module &M)=0
runOnModule - Virtual method overriden by subclasses to process the module being operated on.
A Module instance is used to store all the information related to an LLVM module.
PMDataManager provides the common place to manage the analysis data used by pass managers.
void dumpLastUses(Pass *P, unsigned Offset) const
virtual Pass * getAsPass()=0
PMTopLevelManager * getTopLevelManager()
unsigned getNumContainedPasses() const
virtual PassManagerType getPassManagerType() const
PMStack - This class implements a stack data structure of PMDataManager pointers.
PMDataManager * top() const
LLVM_ABI void push(PMDataManager *PM)
PMTopLevelManager manages LastUser info and collects common APIs used by top level pass managers.
void addIndirectPassManager(PMDataManager *Manager)
void schedulePass(Pass *P)
Schedule pass P for execution.
Pass interface - Implemented by all 'passes'.
virtual PMDataManager * getAsPMDataManager()
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
virtual bool doInitialization(Module &)
doInitialization - Virtual method overridden by subclasses to do any necessary initialization before ...
virtual bool doFinalization(Module &)
doFinalization - Virtual method overriden by subclasses to do any necessary clean up after all passes...
virtual void dumpPassStructure(unsigned Offset=0)
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
StringRef - Represent a constant reference to a string, i.e.
The TimeRegion class is used as a helper class to call the startTimer() and stopTimer() methods of th...
This class implements an extremely fast bulk output stream that can only output to a stream.
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
A raw_ostream that writes to an std::string.
Enumerate the SCCs of a directed graph in reverse topological order of the SCC DAG.
bool isAtEnd() const
Direct loop termination test which is more efficient than comparison with end().
void ReplaceNode(NodeRef Old, NodeRef New)
This informs the scc_iterator that the specified Old node has been deleted, and New is to be used in ...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
bool forcePrintModuleIR()
PassManagerType
Different types of internal pass managers.
@ PMT_CallGraphPassManager
CGPassManager.
@ PMT_FunctionPassManager
FPPassManager.
scc_iterator< T > scc_begin(const T &G)
Construct the begin iterator for a deduced graph type T.
LLVM_ABI Timer * getPassTimer(Pass *)
Request the timer for this legacy-pass-manager's pass instance.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isFunctionInPrintList(StringRef FunctionName)
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
void forEachCallbackFunction(const CallBase &CB, UnaryFunction Func)
Apply function Func to each CB's callback function.
cl::opt< unsigned > MaxDevirtIterations("max-devirt-iterations", cl::ReallyHidden, cl::init(4))