44#define DEBUG_TYPE "cgscc-passmgr"
49 .max_devirt_iterations;
52STATISTIC(MaxSCCIterations,
"Maximum CGSCCPassMgr iterations on one SCC");
69 bool runOnModule(
Module &M)
override;
71 using ModulePass::doInitialization;
72 using ModulePass::doFinalization;
74 bool doInitialization(CallGraph &CG);
75 bool doFinalization(CallGraph &CG);
78 void getAnalysisUsage(AnalysisUsage &Info)
const override {
80 Info.addRequired<CallGraphWrapperPass>();
81 Info.setPreservesAll();
84 StringRef getPassName()
const override {
return "CallGraph Pass Manager"; }
86 PMDataManager *getAsPMDataManager()
override {
return this; }
87 Pass *getAsPass()
override {
return this; }
90 void dumpPassStructure(
unsigned Offset)
override {
92 for (
unsigned Index = 0;
Index < getNumContainedPasses(); ++
Index) {
93 Pass *
P = getContainedPass(Index);
94 P->dumpPassStructure(
Offset + 1);
99 Pass *getContainedPass(
unsigned N) {
100 assert(
N < PassVector.size() &&
"Pass number out of range!");
101 return static_cast<Pass *
>(PassVector[
N]);
109 bool RunAllPassesOnSCC(CallGraphSCC &CurSCC, CallGraph &CG,
110 bool &DevirtualizedCall);
112 bool RunPassOnSCC(
Pass *
P, CallGraphSCC &CurSCC,
113 CallGraph &CG,
bool &CallGraphUpToDate,
114 bool &DevirtualizedCall);
115 bool RefreshCallGraph(
const CallGraphSCC &CurSCC, CallGraph &CG,
116 bool IsCheckingMode);
121char CGPassManager::ID = 0;
125 bool &DevirtualizedCall) {
127 PMDataManager *PM =
P->getAsPMDataManager();
131 CallGraphSCCPass *CGSP = (CallGraphSCCPass *)
P;
132 if (!CallGraphUpToDate) {
133 DevirtualizedCall |= RefreshCallGraph(CurSCC, CG,
false);
134 CallGraphUpToDate =
true;
139 StringMap<std::pair<unsigned, unsigned>> FunctionToInstrCount;
140 bool EmitICRemark =
M.shouldEmitInstrCountChangedRemark();
143 InstrCount = initSizeRemarkInfo(M, FunctionToInstrCount);
148 SCCCount =
M.getInstructionCount();
153 static_cast<int64_t
>(SCCCount) -
static_cast<int64_t
>(
InstrCount);
154 emitInstrCountChangedRemark(
P, M, Delta,
InstrCount,
155 FunctionToInstrCount);
165 RefreshCallGraph(CurSCC, CG,
true);
172 "Invalid CGPassManager member");
173 FPPassManager *FPP = (FPPassManager*)
P;
176 for (CallGraphNode *CGN : CurSCC) {
183 F->getContext().yield();
189 if (
Changed && CallGraphUpToDate) {
190 LLVM_DEBUG(
dbgs() <<
"CGSCCPASSMGR: Pass Dirtied SCC: " <<
P->getPassName()
192 CallGraphUpToDate =
false;
206bool CGPassManager::RefreshCallGraph(
const CallGraphSCC &CurSCC, CallGraph &CG,
208 DenseMap<Value *, CallGraphNode *> Calls;
212 for (CallGraphNode *CGN
213 : CurSCC) CGN->dump(););
215 bool MadeChange =
false;
216 bool DevirtualizedCall =
false;
219 unsigned FunctionNo = 0;
221 SCCIdx !=
E; ++SCCIdx, ++FunctionNo) {
222 CallGraphNode *CGN = *SCCIdx;
224 if (!
F ||
F->isDeclaration())
continue;
231 unsigned NumDirectRemoved = 0, NumIndirectRemoved = 0;
238 bool WasLast =
I + 1 == CGNEnd;
260 if (RemoveAndCheckForDone(
I))
274 "CallGraphSCCPass did not update the CallGraph correctly!");
277 if (!
I->second->getFunction())
278 ++NumIndirectRemoved;
282 if (RemoveAndCheckForDone(
I))
287 assert(!Calls.
count(
Call) &&
"Call site occurs in node multiple times");
292 if (!Callee || !(
Callee->isIntrinsic()))
300 unsigned NumDirectAdded = 0, NumIndirectAdded = 0;
302 for (BasicBlock &BB : *
F)
303 for (Instruction &
I : BB) {
308 if (Callee &&
Callee->isIntrinsic())
323 if (ExistingIt != Calls.
end()) {
324 CallGraphNode *ExistingNode = ExistingIt->second;
327 Calls.
erase(ExistingIt);
343 "CallGraphSCCPass did not update the CallGraph correctly!");
347 CallGraphNode *CalleeNode;
353 DevirtualizedCall =
true;
355 <<
Callee->getName() <<
"'\n");
368 "CallGraphSCCPass did not update the CallGraph correctly!");
371 CallGraphNode *CalleeNode;
394 if (NumIndirectRemoved > NumIndirectAdded &&
395 NumDirectRemoved < NumDirectAdded)
396 DevirtualizedCall =
true;
402 assert(Calls.
empty() &&
"Dangling pointers found in call sites map");
406 if ((FunctionNo & 15) == 15)
411 dbgs() <<
"CGSCCPASSMGR: Refreshed SCC is now:\n";
412 for (CallGraphNode *CGN : CurSCC)
414 if (DevirtualizedCall)
415 dbgs() <<
"CGSCCPASSMGR: Refresh devirtualized a call!\n";
417 dbgs() <<
"CGSCCPASSMGR: SCC Refresh didn't change call graph.\n";
421 return DevirtualizedCall;
427bool CGPassManager::RunAllPassesOnSCC(CallGraphSCC &CurSCC, CallGraph &CG,
428 bool &DevirtualizedCall) {
438 bool CallGraphUpToDate =
true;
441 for (
unsigned PassNo = 0, e = getNumContainedPasses();
442 PassNo !=
e; ++PassNo) {
443 Pass *
P = getContainedPass(PassNo);
447 if (isPassDebuggingExecutionsOrMore()) {
448 std::string Functions;
450 raw_string_ostream OS(Functions);
452 for (
const CallGraphNode *CGN : CurSCC) {
461 initializeAnalysisImpl(
P);
463#ifdef EXPENSIVE_CHECKS
469 RunPassOnSCC(
P, CurSCC, CG, CallGraphUpToDate, DevirtualizedCall);
473#ifdef EXPENSIVE_CHECKS
474 if (!LocalChanged && (RefHash !=
P->structuralHash(CG.
getModule()))) {
475 llvm::errs() <<
"Pass modifies its input and doesn't report it: "
476 <<
P->getPassName() <<
"\n";
484 verifyPreservedAnalysis(
P);
486 removeNotPreservedAnalysis(
P);
487 recordAvailableAnalysis(
P);
493 if (!CallGraphUpToDate)
494 DevirtualizedCall |= RefreshCallGraph(CurSCC, CG,
false);
500bool CGPassManager::runOnModule(
Module &M) {
501 const unsigned MaxDevirtIterations =
503 CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph();
504 bool Changed = doInitialization(CG);
507 scc_iterator<CallGraph*> CGI =
scc_begin(&CG);
509 CallGraphSCC CurSCC(CG);
513 const std::vector<CallGraphNode *> &NodeVec = *CGI;
514 CurSCC.initialize(NodeVec);
529 unsigned Iteration = 0;
530 bool DevirtualizedCall =
false;
533 <<
" SCCPASSMGR: Re-visiting SCC, iteration #" << Iteration
535 DevirtualizedCall =
false;
536 Changed |= RunAllPassesOnSCC(CurSCC, CG, DevirtualizedCall);
537 }
while (Iteration++ < MaxDevirtIterations && DevirtualizedCall);
539 if (DevirtualizedCall)
542 <<
" times, due to -max-devirt-iterations\n");
544 MaxSCCIterations.updateMax(Iteration);
551bool CGPassManager::doInitialization(CallGraph &CG) {
553 for (
unsigned i = 0, e = getNumContainedPasses(); i !=
e; ++i) {
554 if (PMDataManager *PM = getContainedPass(i)->getAsPMDataManager()) {
556 "Invalid CGPassManager member");
559 Changed |= ((CallGraphSCCPass*)getContainedPass(i))->doInitialization(CG);
566bool CGPassManager::doFinalization(CallGraph &CG) {
568 for (
unsigned i = 0, e = getNumContainedPasses(); i !=
e; ++i) {
569 if (PMDataManager *PM = getContainedPass(i)->getAsPMDataManager()) {
571 "Invalid CGPassManager member");
574 Changed |= ((CallGraphSCCPass*)getContainedPass(i))->doFinalization(CG);
588 while (!PMS.
empty() &&
592 assert(!PMS.
empty() &&
"Unable to handle Call Graph Pass");
596 CGP = (CGPassManager*)PMS.
top();
599 assert(!PMS.
empty() &&
"Unable to create Call Graph Pass Manager");
603 CGP =
new CGPassManager();
644 PrintCallGraphPass(
const std::string &
B,
raw_ostream &OS)
651 bool runOnSCC(CallGraphSCC &SCC)
override {
652 bool BannerPrinted =
false;
653 auto PrintBannerOnce = [&]() {
656 OS << Banner <<
"\n";
657 BannerPrinted =
true;
664 SCC.getCallGraph().getModule().print(OS,
nullptr);
667 bool FoundFunction =
false;
668 for (CallGraphNode *CGN : SCC) {
671 FoundFunction =
true;
679 OS <<
"\nPrinting <null> Function\n";
682 if (NeedModule && FoundFunction) {
685 SCC.getCallGraph().getModule().print(OS,
nullptr);
690 StringRef getPassName()
const override {
return "Print CallGraph IR"; }
695char PrintCallGraphPass::ID = 0;
698 const std::string &Banner)
const {
699 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< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
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.
print mir2vec MIR2Vec Vocabulary Printer Pass
Machine Check Debug Module
#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.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
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
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.
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
This pass is required by interprocedural register allocation.
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...
PMDataManager provides the common place to manage the analysis data used by pass managers.
PMTopLevelManager * getTopLevelManager()
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'.
Pass(PassKind K, char &pid)
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.
bool isAtEnd() const
Direct loop termination test which is more efficient than comparison with end().
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI unsigned getMaxDevirtIterations(const cl::LibraryOptionsContext *)
LLVM_ABI bool forcePrintModuleIR()
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
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.
const AnalysisOptions & getAnalysisOptions(const LLVMContext &C)
auto dyn_cast_or_null(const Y &Val)
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.
LLVM_ABI bool shouldPrintFunction(const Function &F)
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.
LLVM_ABI bool shouldPrintAllFunctions()