17d523365SDimitry Andric //===- CallGraphSCCPass.cpp - Pass that operates BU on call graph ---------===//
27d523365SDimitry Andric //
37d523365SDimitry Andric //                     The LLVM Compiler Infrastructure
47d523365SDimitry Andric //
57d523365SDimitry Andric // This file is distributed under the University of Illinois Open Source
67d523365SDimitry Andric // License. See LICENSE.TXT for details.
77d523365SDimitry Andric //
87d523365SDimitry Andric //===----------------------------------------------------------------------===//
97d523365SDimitry Andric //
107d523365SDimitry Andric // This file implements the CallGraphSCCPass class, which is used for passes
117d523365SDimitry Andric // which are implemented as bottom-up traversals on the call graph.  Because
127d523365SDimitry Andric // there may be cycles in the call graph, passes of this type operate on the
137d523365SDimitry Andric // call-graph in SCC order: that is, they process function bottom-up, except for
147d523365SDimitry Andric // recursive functions, which they process all at once.
157d523365SDimitry Andric //
167d523365SDimitry Andric //===----------------------------------------------------------------------===//
177d523365SDimitry Andric 
187d523365SDimitry Andric #include "llvm/Analysis/CallGraphSCCPass.h"
192cab237bSDimitry Andric #include "llvm/ADT/DenseMap.h"
207d523365SDimitry Andric #include "llvm/ADT/SCCIterator.h"
217d523365SDimitry Andric #include "llvm/ADT/Statistic.h"
227d523365SDimitry Andric #include "llvm/Analysis/CallGraph.h"
232cab237bSDimitry Andric #include "llvm/IR/CallSite.h"
247d523365SDimitry Andric #include "llvm/IR/Function.h"
25*b5893f02SDimitry Andric #include "llvm/IR/IRPrintingPasses.h"
262cab237bSDimitry Andric #include "llvm/IR/Intrinsics.h"
277d523365SDimitry Andric #include "llvm/IR/LLVMContext.h"
287d523365SDimitry Andric #include "llvm/IR/LegacyPassManagers.h"
292cab237bSDimitry Andric #include "llvm/IR/Module.h"
303ca95b02SDimitry Andric #include "llvm/IR/OptBisect.h"
31*b5893f02SDimitry Andric #include "llvm/IR/PassTimingInfo.h"
322cab237bSDimitry Andric #include "llvm/Pass.h"
337d523365SDimitry Andric #include "llvm/Support/CommandLine.h"
347d523365SDimitry Andric #include "llvm/Support/Debug.h"
357d523365SDimitry Andric #include "llvm/Support/Timer.h"
367d523365SDimitry Andric #include "llvm/Support/raw_ostream.h"
372cab237bSDimitry Andric #include <cassert>
382cab237bSDimitry Andric #include <string>
392cab237bSDimitry Andric #include <utility>
402cab237bSDimitry Andric #include <vector>
412cab237bSDimitry Andric 
427d523365SDimitry Andric using namespace llvm;
437d523365SDimitry Andric 
447d523365SDimitry Andric #define DEBUG_TYPE "cgscc-passmgr"
457d523365SDimitry Andric 
467d523365SDimitry Andric static cl::opt<unsigned>
477d523365SDimitry Andric MaxIterations("max-cg-scc-iterations", cl::ReallyHidden, cl::init(4));
487d523365SDimitry Andric 
497d523365SDimitry Andric STATISTIC(MaxSCCIterations, "Maximum CGSCCPassMgr iterations on one SCC");
507d523365SDimitry Andric 
517d523365SDimitry Andric //===----------------------------------------------------------------------===//
527d523365SDimitry Andric // CGPassManager
537d523365SDimitry Andric //
547d523365SDimitry Andric /// CGPassManager manages FPPassManagers and CallGraphSCCPasses.
557d523365SDimitry Andric 
567d523365SDimitry Andric namespace {
577d523365SDimitry Andric 
587d523365SDimitry Andric class CGPassManager : public ModulePass, public PMDataManager {
597d523365SDimitry Andric public:
607d523365SDimitry Andric   static char ID;
612cab237bSDimitry Andric 
CGPassManager()622cab237bSDimitry Andric   explicit CGPassManager() : ModulePass(ID), PMDataManager() {}
637d523365SDimitry Andric 
647d523365SDimitry Andric   /// Execute all of the passes scheduled for execution.  Keep track of
657d523365SDimitry Andric   /// whether any of the passes modifies the module, and if so, return true.
667d523365SDimitry Andric   bool runOnModule(Module &M) override;
677d523365SDimitry Andric 
687d523365SDimitry Andric   using ModulePass::doInitialization;
697d523365SDimitry Andric   using ModulePass::doFinalization;
707d523365SDimitry Andric 
717d523365SDimitry Andric   bool doInitialization(CallGraph &CG);
727d523365SDimitry Andric   bool doFinalization(CallGraph &CG);
737d523365SDimitry Andric 
747d523365SDimitry Andric   /// Pass Manager itself does not invalidate any analysis info.
getAnalysisUsage(AnalysisUsage & Info) const757d523365SDimitry Andric   void getAnalysisUsage(AnalysisUsage &Info) const override {
767d523365SDimitry Andric     // CGPassManager walks SCC and it needs CallGraph.
777d523365SDimitry Andric     Info.addRequired<CallGraphWrapperPass>();
787d523365SDimitry Andric     Info.setPreservesAll();
797d523365SDimitry Andric   }
807d523365SDimitry Andric 
getPassName() const81d88c1a5aSDimitry Andric   StringRef getPassName() const override { return "CallGraph Pass Manager"; }
827d523365SDimitry Andric 
getAsPMDataManager()837d523365SDimitry Andric   PMDataManager *getAsPMDataManager() override { return this; }
getAsPass()847d523365SDimitry Andric   Pass *getAsPass() override { return this; }
857d523365SDimitry Andric 
867d523365SDimitry Andric   // Print passes managed by this manager
dumpPassStructure(unsigned Offset)877d523365SDimitry Andric   void dumpPassStructure(unsigned Offset) override {
887d523365SDimitry Andric     errs().indent(Offset*2) << "Call Graph SCC Pass Manager\n";
897d523365SDimitry Andric     for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
907d523365SDimitry Andric       Pass *P = getContainedPass(Index);
917d523365SDimitry Andric       P->dumpPassStructure(Offset + 1);
927d523365SDimitry Andric       dumpLastUses(P, Offset+1);
937d523365SDimitry Andric     }
947d523365SDimitry Andric   }
957d523365SDimitry Andric 
getContainedPass(unsigned N)967d523365SDimitry Andric   Pass *getContainedPass(unsigned N) {
977d523365SDimitry Andric     assert(N < PassVector.size() && "Pass number out of range!");
987d523365SDimitry Andric     return static_cast<Pass *>(PassVector[N]);
997d523365SDimitry Andric   }
1007d523365SDimitry Andric 
getPassManagerType() const1017d523365SDimitry Andric   PassManagerType getPassManagerType() const override {
1027d523365SDimitry Andric     return PMT_CallGraphPassManager;
1037d523365SDimitry Andric   }
1047d523365SDimitry Andric 
1057d523365SDimitry Andric private:
1067d523365SDimitry Andric   bool RunAllPassesOnSCC(CallGraphSCC &CurSCC, CallGraph &CG,
1077d523365SDimitry Andric                          bool &DevirtualizedCall);
1087d523365SDimitry Andric 
1097d523365SDimitry Andric   bool RunPassOnSCC(Pass *P, CallGraphSCC &CurSCC,
1107d523365SDimitry Andric                     CallGraph &CG, bool &CallGraphUpToDate,
1117d523365SDimitry Andric                     bool &DevirtualizedCall);
112d88c1a5aSDimitry Andric   bool RefreshCallGraph(const CallGraphSCC &CurSCC, CallGraph &CG,
1137d523365SDimitry Andric                         bool IsCheckingMode);
1147d523365SDimitry Andric };
1157d523365SDimitry Andric 
1167d523365SDimitry Andric } // end anonymous namespace.
1177d523365SDimitry Andric 
1187d523365SDimitry Andric char CGPassManager::ID = 0;
1197d523365SDimitry Andric 
RunPassOnSCC(Pass * P,CallGraphSCC & CurSCC,CallGraph & CG,bool & CallGraphUpToDate,bool & DevirtualizedCall)1207d523365SDimitry Andric bool CGPassManager::RunPassOnSCC(Pass *P, CallGraphSCC &CurSCC,
1217d523365SDimitry Andric                                  CallGraph &CG, bool &CallGraphUpToDate,
1227d523365SDimitry Andric                                  bool &DevirtualizedCall) {
1237d523365SDimitry Andric   bool Changed = false;
1247d523365SDimitry Andric   PMDataManager *PM = P->getAsPMDataManager();
1254ba319b5SDimitry Andric   Module &M = CG.getModule();
1267d523365SDimitry Andric 
1277d523365SDimitry Andric   if (!PM) {
1287d523365SDimitry Andric     CallGraphSCCPass *CGSP = (CallGraphSCCPass *)P;
1297d523365SDimitry Andric     if (!CallGraphUpToDate) {
1307d523365SDimitry Andric       DevirtualizedCall |= RefreshCallGraph(CurSCC, CG, false);
1317d523365SDimitry Andric       CallGraphUpToDate = true;
1327d523365SDimitry Andric     }
1337d523365SDimitry Andric 
1347d523365SDimitry Andric     {
135*b5893f02SDimitry Andric       unsigned InstrCount, SCCCount = 0;
136*b5893f02SDimitry Andric       StringMap<std::pair<unsigned, unsigned>> FunctionToInstrCount;
1374ba319b5SDimitry Andric       bool EmitICRemark = M.shouldEmitInstrCountChangedRemark();
1387d523365SDimitry Andric       TimeRegion PassTimer(getPassTimer(CGSP));
1394ba319b5SDimitry Andric       if (EmitICRemark)
140*b5893f02SDimitry Andric         InstrCount = initSizeRemarkInfo(M, FunctionToInstrCount);
1417d523365SDimitry Andric       Changed = CGSP->runOnSCC(CurSCC);
1424ba319b5SDimitry Andric 
143*b5893f02SDimitry Andric       if (EmitICRemark) {
144*b5893f02SDimitry Andric         // FIXME: Add getInstructionCount to CallGraphSCC.
145*b5893f02SDimitry Andric         SCCCount = M.getInstructionCount();
146*b5893f02SDimitry Andric         // Is there a difference in the number of instructions in the module?
147*b5893f02SDimitry Andric         if (SCCCount != InstrCount) {
148*b5893f02SDimitry Andric           // Yep. Emit a remark and update InstrCount.
149*b5893f02SDimitry Andric           int64_t Delta =
150*b5893f02SDimitry Andric               static_cast<int64_t>(SCCCount) - static_cast<int64_t>(InstrCount);
151*b5893f02SDimitry Andric           emitInstrCountChangedRemark(P, M, Delta, InstrCount,
152*b5893f02SDimitry Andric                                       FunctionToInstrCount);
153*b5893f02SDimitry Andric           InstrCount = SCCCount;
154*b5893f02SDimitry Andric         }
155*b5893f02SDimitry Andric       }
1567d523365SDimitry Andric     }
1577d523365SDimitry Andric 
1587d523365SDimitry Andric     // After the CGSCCPass is done, when assertions are enabled, use
1597d523365SDimitry Andric     // RefreshCallGraph to verify that the callgraph was correctly updated.
1607d523365SDimitry Andric #ifndef NDEBUG
1617d523365SDimitry Andric     if (Changed)
1627d523365SDimitry Andric       RefreshCallGraph(CurSCC, CG, true);
1637d523365SDimitry Andric #endif
1647d523365SDimitry Andric 
1657d523365SDimitry Andric     return Changed;
1667d523365SDimitry Andric   }
1677d523365SDimitry Andric 
1687d523365SDimitry Andric   assert(PM->getPassManagerType() == PMT_FunctionPassManager &&
1697d523365SDimitry Andric          "Invalid CGPassManager member");
1707d523365SDimitry Andric   FPPassManager *FPP = (FPPassManager*)P;
1717d523365SDimitry Andric 
1727d523365SDimitry Andric   // Run pass P on all functions in the current SCC.
1737d523365SDimitry Andric   for (CallGraphNode *CGN : CurSCC) {
1747d523365SDimitry Andric     if (Function *F = CGN->getFunction()) {
1757d523365SDimitry Andric       dumpPassInfo(P, EXECUTION_MSG, ON_FUNCTION_MSG, F->getName());
1767d523365SDimitry Andric       {
1777d523365SDimitry Andric         TimeRegion PassTimer(getPassTimer(FPP));
1787d523365SDimitry Andric         Changed |= FPP->runOnFunction(*F);
1797d523365SDimitry Andric       }
1807d523365SDimitry Andric       F->getContext().yield();
1817d523365SDimitry Andric     }
1827d523365SDimitry Andric   }
1837d523365SDimitry Andric 
1847d523365SDimitry Andric   // The function pass(es) modified the IR, they may have clobbered the
1857d523365SDimitry Andric   // callgraph.
1867d523365SDimitry Andric   if (Changed && CallGraphUpToDate) {
1874ba319b5SDimitry Andric     LLVM_DEBUG(dbgs() << "CGSCCPASSMGR: Pass Dirtied SCC: " << P->getPassName()
1884ba319b5SDimitry Andric                       << '\n');
1897d523365SDimitry Andric     CallGraphUpToDate = false;
1907d523365SDimitry Andric   }
1917d523365SDimitry Andric   return Changed;
1927d523365SDimitry Andric }
1937d523365SDimitry Andric 
1947d523365SDimitry Andric /// Scan the functions in the specified CFG and resync the
1957d523365SDimitry Andric /// callgraph with the call sites found in it.  This is used after
1967d523365SDimitry Andric /// FunctionPasses have potentially munged the callgraph, and can be used after
1977d523365SDimitry Andric /// CallGraphSCC passes to verify that they correctly updated the callgraph.
1987d523365SDimitry Andric ///
1997d523365SDimitry Andric /// This function returns true if it devirtualized an existing function call,
2007d523365SDimitry Andric /// meaning it turned an indirect call into a direct call.  This happens when
2017d523365SDimitry Andric /// a function pass like GVN optimizes away stuff feeding the indirect call.
2027d523365SDimitry Andric /// This never happens in checking mode.
RefreshCallGraph(const CallGraphSCC & CurSCC,CallGraph & CG,bool CheckingMode)203d88c1a5aSDimitry Andric bool CGPassManager::RefreshCallGraph(const CallGraphSCC &CurSCC, CallGraph &CG,
204d88c1a5aSDimitry Andric                                      bool CheckingMode) {
2057d523365SDimitry Andric   DenseMap<Value*, CallGraphNode*> CallSites;
2067d523365SDimitry Andric 
2074ba319b5SDimitry Andric   LLVM_DEBUG(dbgs() << "CGSCCPASSMGR: Refreshing SCC with " << CurSCC.size()
2087d523365SDimitry Andric                     << " nodes:\n";
2094ba319b5SDimitry Andric              for (CallGraphNode *CGN
2104ba319b5SDimitry Andric                   : CurSCC) CGN->dump(););
2117d523365SDimitry Andric 
2127d523365SDimitry Andric   bool MadeChange = false;
2137d523365SDimitry Andric   bool DevirtualizedCall = false;
2147d523365SDimitry Andric 
2157d523365SDimitry Andric   // Scan all functions in the SCC.
2167d523365SDimitry Andric   unsigned FunctionNo = 0;
2177d523365SDimitry Andric   for (CallGraphSCC::iterator SCCIdx = CurSCC.begin(), E = CurSCC.end();
2187d523365SDimitry Andric        SCCIdx != E; ++SCCIdx, ++FunctionNo) {
2197d523365SDimitry Andric     CallGraphNode *CGN = *SCCIdx;
2207d523365SDimitry Andric     Function *F = CGN->getFunction();
2217d523365SDimitry Andric     if (!F || F->isDeclaration()) continue;
2227d523365SDimitry Andric 
2237d523365SDimitry Andric     // Walk the function body looking for call sites.  Sync up the call sites in
2247d523365SDimitry Andric     // CGN with those actually in the function.
2257d523365SDimitry Andric 
2267d523365SDimitry Andric     // Keep track of the number of direct and indirect calls that were
2277d523365SDimitry Andric     // invalidated and removed.
2287d523365SDimitry Andric     unsigned NumDirectRemoved = 0, NumIndirectRemoved = 0;
2297d523365SDimitry Andric 
2307d523365SDimitry Andric     // Get the set of call sites currently in the function.
2317d523365SDimitry Andric     for (CallGraphNode::iterator I = CGN->begin(), E = CGN->end(); I != E; ) {
2327d523365SDimitry Andric       // If this call site is null, then the function pass deleted the call
233f37b6182SDimitry Andric       // entirely and the WeakTrackingVH nulled it out.
2347d523365SDimitry Andric       if (!I->first ||
2357d523365SDimitry Andric           // If we've already seen this call site, then the FunctionPass RAUW'd
2367d523365SDimitry Andric           // one call with another, which resulted in two "uses" in the edge
2377d523365SDimitry Andric           // list of the same call.
2387d523365SDimitry Andric           CallSites.count(I->first) ||
2397d523365SDimitry Andric 
2407d523365SDimitry Andric           // If the call edge is not from a call or invoke, or it is a
2417d523365SDimitry Andric           // instrinsic call, then the function pass RAUW'd a call with
2427d523365SDimitry Andric           // another value. This can happen when constant folding happens
2437d523365SDimitry Andric           // of well known functions etc.
2447d523365SDimitry Andric           !CallSite(I->first) ||
2457d523365SDimitry Andric           (CallSite(I->first).getCalledFunction() &&
2467d523365SDimitry Andric            CallSite(I->first).getCalledFunction()->isIntrinsic() &&
2477d523365SDimitry Andric            Intrinsic::isLeaf(
2487d523365SDimitry Andric                CallSite(I->first).getCalledFunction()->getIntrinsicID()))) {
2497d523365SDimitry Andric         assert(!CheckingMode &&
2507d523365SDimitry Andric                "CallGraphSCCPass did not update the CallGraph correctly!");
2517d523365SDimitry Andric 
2527d523365SDimitry Andric         // If this was an indirect call site, count it.
2537d523365SDimitry Andric         if (!I->second->getFunction())
2547d523365SDimitry Andric           ++NumIndirectRemoved;
2557d523365SDimitry Andric         else
2567d523365SDimitry Andric           ++NumDirectRemoved;
2577d523365SDimitry Andric 
2587d523365SDimitry Andric         // Just remove the edge from the set of callees, keep track of whether
2597d523365SDimitry Andric         // I points to the last element of the vector.
2607d523365SDimitry Andric         bool WasLast = I + 1 == E;
2617d523365SDimitry Andric         CGN->removeCallEdge(I);
2627d523365SDimitry Andric 
2637d523365SDimitry Andric         // If I pointed to the last element of the vector, we have to bail out:
2647d523365SDimitry Andric         // iterator checking rejects comparisons of the resultant pointer with
2657d523365SDimitry Andric         // end.
2667d523365SDimitry Andric         if (WasLast)
2677d523365SDimitry Andric           break;
2687d523365SDimitry Andric         E = CGN->end();
2697d523365SDimitry Andric         continue;
2707d523365SDimitry Andric       }
2717d523365SDimitry Andric 
2727d523365SDimitry Andric       assert(!CallSites.count(I->first) &&
2737d523365SDimitry Andric              "Call site occurs in node multiple times");
2747d523365SDimitry Andric 
2757d523365SDimitry Andric       CallSite CS(I->first);
2767d523365SDimitry Andric       if (CS) {
2777d523365SDimitry Andric         Function *Callee = CS.getCalledFunction();
2787d523365SDimitry Andric         // Ignore intrinsics because they're not really function calls.
2797d523365SDimitry Andric         if (!Callee || !(Callee->isIntrinsic()))
2807d523365SDimitry Andric           CallSites.insert(std::make_pair(I->first, I->second));
2817d523365SDimitry Andric       }
2827d523365SDimitry Andric       ++I;
2837d523365SDimitry Andric     }
2847d523365SDimitry Andric 
2857d523365SDimitry Andric     // Loop over all of the instructions in the function, getting the callsites.
2867d523365SDimitry Andric     // Keep track of the number of direct/indirect calls added.
2877d523365SDimitry Andric     unsigned NumDirectAdded = 0, NumIndirectAdded = 0;
2887d523365SDimitry Andric 
2893ca95b02SDimitry Andric     for (BasicBlock &BB : *F)
2903ca95b02SDimitry Andric       for (Instruction &I : BB) {
2913ca95b02SDimitry Andric         CallSite CS(&I);
2927d523365SDimitry Andric         if (!CS) continue;
2937d523365SDimitry Andric         Function *Callee = CS.getCalledFunction();
2947d523365SDimitry Andric         if (Callee && Callee->isIntrinsic()) continue;
2957d523365SDimitry Andric 
2967d523365SDimitry Andric         // If this call site already existed in the callgraph, just verify it
2977d523365SDimitry Andric         // matches up to expectations and remove it from CallSites.
2987d523365SDimitry Andric         DenseMap<Value*, CallGraphNode*>::iterator ExistingIt =
2997d523365SDimitry Andric           CallSites.find(CS.getInstruction());
3007d523365SDimitry Andric         if (ExistingIt != CallSites.end()) {
3017d523365SDimitry Andric           CallGraphNode *ExistingNode = ExistingIt->second;
3027d523365SDimitry Andric 
3037d523365SDimitry Andric           // Remove from CallSites since we have now seen it.
3047d523365SDimitry Andric           CallSites.erase(ExistingIt);
3057d523365SDimitry Andric 
3067d523365SDimitry Andric           // Verify that the callee is right.
3077d523365SDimitry Andric           if (ExistingNode->getFunction() == CS.getCalledFunction())
3087d523365SDimitry Andric             continue;
3097d523365SDimitry Andric 
3107d523365SDimitry Andric           // If we are in checking mode, we are not allowed to actually mutate
3117d523365SDimitry Andric           // the callgraph.  If this is a case where we can infer that the
3127d523365SDimitry Andric           // callgraph is less precise than it could be (e.g. an indirect call
3137d523365SDimitry Andric           // site could be turned direct), don't reject it in checking mode, and
3147d523365SDimitry Andric           // don't tweak it to be more precise.
3157d523365SDimitry Andric           if (CheckingMode && CS.getCalledFunction() &&
3167d523365SDimitry Andric               ExistingNode->getFunction() == nullptr)
3177d523365SDimitry Andric             continue;
3187d523365SDimitry Andric 
3197d523365SDimitry Andric           assert(!CheckingMode &&
3207d523365SDimitry Andric                  "CallGraphSCCPass did not update the CallGraph correctly!");
3217d523365SDimitry Andric 
3227d523365SDimitry Andric           // If not, we either went from a direct call to indirect, indirect to
3237d523365SDimitry Andric           // direct, or direct to different direct.
3247d523365SDimitry Andric           CallGraphNode *CalleeNode;
3257d523365SDimitry Andric           if (Function *Callee = CS.getCalledFunction()) {
3267d523365SDimitry Andric             CalleeNode = CG.getOrInsertFunction(Callee);
3277d523365SDimitry Andric             // Keep track of whether we turned an indirect call into a direct
3287d523365SDimitry Andric             // one.
3297d523365SDimitry Andric             if (!ExistingNode->getFunction()) {
3307d523365SDimitry Andric               DevirtualizedCall = true;
3314ba319b5SDimitry Andric               LLVM_DEBUG(dbgs() << "  CGSCCPASSMGR: Devirtualized call to '"
3327d523365SDimitry Andric                                 << Callee->getName() << "'\n");
3337d523365SDimitry Andric             }
3347d523365SDimitry Andric           } else {
3357d523365SDimitry Andric             CalleeNode = CG.getCallsExternalNode();
3367d523365SDimitry Andric           }
3377d523365SDimitry Andric 
3387d523365SDimitry Andric           // Update the edge target in CGN.
3397d523365SDimitry Andric           CGN->replaceCallEdge(CS, CS, CalleeNode);
3407d523365SDimitry Andric           MadeChange = true;
3417d523365SDimitry Andric           continue;
3427d523365SDimitry Andric         }
3437d523365SDimitry Andric 
3447d523365SDimitry Andric         assert(!CheckingMode &&
3457d523365SDimitry Andric                "CallGraphSCCPass did not update the CallGraph correctly!");
3467d523365SDimitry Andric 
3477d523365SDimitry Andric         // If the call site didn't exist in the CGN yet, add it.
3487d523365SDimitry Andric         CallGraphNode *CalleeNode;
3497d523365SDimitry Andric         if (Function *Callee = CS.getCalledFunction()) {
3507d523365SDimitry Andric           CalleeNode = CG.getOrInsertFunction(Callee);
3517d523365SDimitry Andric           ++NumDirectAdded;
3527d523365SDimitry Andric         } else {
3537d523365SDimitry Andric           CalleeNode = CG.getCallsExternalNode();
3547d523365SDimitry Andric           ++NumIndirectAdded;
3557d523365SDimitry Andric         }
3567d523365SDimitry Andric 
3577d523365SDimitry Andric         CGN->addCalledFunction(CS, CalleeNode);
3587d523365SDimitry Andric         MadeChange = true;
3597d523365SDimitry Andric       }
3607d523365SDimitry Andric 
3617d523365SDimitry Andric     // We scanned the old callgraph node, removing invalidated call sites and
3627d523365SDimitry Andric     // then added back newly found call sites.  One thing that can happen is
3637d523365SDimitry Andric     // that an old indirect call site was deleted and replaced with a new direct
3647d523365SDimitry Andric     // call.  In this case, we have devirtualized a call, and CGSCCPM would like
3657d523365SDimitry Andric     // to iteratively optimize the new code.  Unfortunately, we don't really
3667d523365SDimitry Andric     // have a great way to detect when this happens.  As an approximation, we
3677d523365SDimitry Andric     // just look at whether the number of indirect calls is reduced and the
3687d523365SDimitry Andric     // number of direct calls is increased.  There are tons of ways to fool this
3697d523365SDimitry Andric     // (e.g. DCE'ing an indirect call and duplicating an unrelated block with a
3707d523365SDimitry Andric     // direct call) but this is close enough.
3717d523365SDimitry Andric     if (NumIndirectRemoved > NumIndirectAdded &&
3727d523365SDimitry Andric         NumDirectRemoved < NumDirectAdded)
3737d523365SDimitry Andric       DevirtualizedCall = true;
3747d523365SDimitry Andric 
3757d523365SDimitry Andric     // After scanning this function, if we still have entries in callsites, then
376f37b6182SDimitry Andric     // they are dangling pointers.  WeakTrackingVH should save us for this, so
377f37b6182SDimitry Andric     // abort if
3787d523365SDimitry Andric     // this happens.
3797d523365SDimitry Andric     assert(CallSites.empty() && "Dangling pointers found in call sites map");
3807d523365SDimitry Andric 
3817d523365SDimitry Andric     // Periodically do an explicit clear to remove tombstones when processing
3827d523365SDimitry Andric     // large scc's.
3837d523365SDimitry Andric     if ((FunctionNo & 15) == 15)
3847d523365SDimitry Andric       CallSites.clear();
3857d523365SDimitry Andric   }
3867d523365SDimitry Andric 
3874ba319b5SDimitry Andric   LLVM_DEBUG(if (MadeChange) {
3887d523365SDimitry Andric     dbgs() << "CGSCCPASSMGR: Refreshed SCC is now:\n";
3897d523365SDimitry Andric     for (CallGraphNode *CGN : CurSCC)
3907d523365SDimitry Andric       CGN->dump();
3917d523365SDimitry Andric     if (DevirtualizedCall)
3927d523365SDimitry Andric       dbgs() << "CGSCCPASSMGR: Refresh devirtualized a call!\n";
3937d523365SDimitry Andric   } else {
3947d523365SDimitry Andric     dbgs() << "CGSCCPASSMGR: SCC Refresh didn't change call graph.\n";
3954ba319b5SDimitry Andric   });
3967d523365SDimitry Andric   (void)MadeChange;
3977d523365SDimitry Andric 
3987d523365SDimitry Andric   return DevirtualizedCall;
3997d523365SDimitry Andric }
4007d523365SDimitry Andric 
4017d523365SDimitry Andric /// Execute the body of the entire pass manager on the specified SCC.
4027d523365SDimitry Andric /// This keeps track of whether a function pass devirtualizes
4037d523365SDimitry Andric /// any calls and returns it in DevirtualizedCall.
RunAllPassesOnSCC(CallGraphSCC & CurSCC,CallGraph & CG,bool & DevirtualizedCall)4047d523365SDimitry Andric bool CGPassManager::RunAllPassesOnSCC(CallGraphSCC &CurSCC, CallGraph &CG,
4057d523365SDimitry Andric                                       bool &DevirtualizedCall) {
4067d523365SDimitry Andric   bool Changed = false;
4077d523365SDimitry Andric 
4087d523365SDimitry Andric   // Keep track of whether the callgraph is known to be up-to-date or not.
4097d523365SDimitry Andric   // The CGSSC pass manager runs two types of passes:
4107d523365SDimitry Andric   // CallGraphSCC Passes and other random function passes.  Because other
4117d523365SDimitry Andric   // random function passes are not CallGraph aware, they may clobber the
4127d523365SDimitry Andric   // call graph by introducing new calls or deleting other ones.  This flag
4137d523365SDimitry Andric   // is set to false when we run a function pass so that we know to clean up
4147d523365SDimitry Andric   // the callgraph when we need to run a CGSCCPass again.
4157d523365SDimitry Andric   bool CallGraphUpToDate = true;
4167d523365SDimitry Andric 
4177d523365SDimitry Andric   // Run all passes on current SCC.
4187d523365SDimitry Andric   for (unsigned PassNo = 0, e = getNumContainedPasses();
4197d523365SDimitry Andric        PassNo != e; ++PassNo) {
4207d523365SDimitry Andric     Pass *P = getContainedPass(PassNo);
4217d523365SDimitry Andric 
4227d523365SDimitry Andric     // If we're in -debug-pass=Executions mode, construct the SCC node list,
4237d523365SDimitry Andric     // otherwise avoid constructing this string as it is expensive.
4247d523365SDimitry Andric     if (isPassDebuggingExecutionsOrMore()) {
4257d523365SDimitry Andric       std::string Functions;
4267d523365SDimitry Andric   #ifndef NDEBUG
4277d523365SDimitry Andric       raw_string_ostream OS(Functions);
4287d523365SDimitry Andric       for (CallGraphSCC::iterator I = CurSCC.begin(), E = CurSCC.end();
4297d523365SDimitry Andric            I != E; ++I) {
4307d523365SDimitry Andric         if (I != CurSCC.begin()) OS << ", ";
4317d523365SDimitry Andric         (*I)->print(OS);
4327d523365SDimitry Andric       }
4337d523365SDimitry Andric       OS.flush();
4347d523365SDimitry Andric   #endif
4357d523365SDimitry Andric       dumpPassInfo(P, EXECUTION_MSG, ON_CG_MSG, Functions);
4367d523365SDimitry Andric     }
4377d523365SDimitry Andric     dumpRequiredSet(P);
4387d523365SDimitry Andric 
4397d523365SDimitry Andric     initializeAnalysisImpl(P);
4407d523365SDimitry Andric 
4417d523365SDimitry Andric     // Actually run this pass on the current SCC.
4427d523365SDimitry Andric     Changed |= RunPassOnSCC(P, CurSCC, CG,
4437d523365SDimitry Andric                             CallGraphUpToDate, DevirtualizedCall);
4447d523365SDimitry Andric 
4457d523365SDimitry Andric     if (Changed)
4467d523365SDimitry Andric       dumpPassInfo(P, MODIFICATION_MSG, ON_CG_MSG, "");
4477d523365SDimitry Andric     dumpPreservedSet(P);
4487d523365SDimitry Andric 
4497d523365SDimitry Andric     verifyPreservedAnalysis(P);
4507d523365SDimitry Andric     removeNotPreservedAnalysis(P);
4517d523365SDimitry Andric     recordAvailableAnalysis(P);
4527d523365SDimitry Andric     removeDeadPasses(P, "", ON_CG_MSG);
4537d523365SDimitry Andric   }
4547d523365SDimitry Andric 
4557d523365SDimitry Andric   // If the callgraph was left out of date (because the last pass run was a
4567d523365SDimitry Andric   // functionpass), refresh it before we move on to the next SCC.
4577d523365SDimitry Andric   if (!CallGraphUpToDate)
4587d523365SDimitry Andric     DevirtualizedCall |= RefreshCallGraph(CurSCC, CG, false);
4597d523365SDimitry Andric   return Changed;
4607d523365SDimitry Andric }
4617d523365SDimitry Andric 
4627d523365SDimitry Andric /// Execute all of the passes scheduled for execution.  Keep track of
4637d523365SDimitry Andric /// whether any of the passes modifies the module, and if so, return true.
runOnModule(Module & M)4647d523365SDimitry Andric bool CGPassManager::runOnModule(Module &M) {
4657d523365SDimitry Andric   CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph();
4667d523365SDimitry Andric   bool Changed = doInitialization(CG);
4677d523365SDimitry Andric 
4687d523365SDimitry Andric   // Walk the callgraph in bottom-up SCC order.
4697d523365SDimitry Andric   scc_iterator<CallGraph*> CGI = scc_begin(&CG);
4707d523365SDimitry Andric 
4713ca95b02SDimitry Andric   CallGraphSCC CurSCC(CG, &CGI);
4727d523365SDimitry Andric   while (!CGI.isAtEnd()) {
4737d523365SDimitry Andric     // Copy the current SCC and increment past it so that the pass can hack
4747d523365SDimitry Andric     // on the SCC if it wants to without invalidating our iterator.
4757d523365SDimitry Andric     const std::vector<CallGraphNode *> &NodeVec = *CGI;
476d88c1a5aSDimitry Andric     CurSCC.initialize(NodeVec);
4777d523365SDimitry Andric     ++CGI;
4787d523365SDimitry Andric 
4797d523365SDimitry Andric     // At the top level, we run all the passes in this pass manager on the
4807d523365SDimitry Andric     // functions in this SCC.  However, we support iterative compilation in the
4817d523365SDimitry Andric     // case where a function pass devirtualizes a call to a function.  For
4827d523365SDimitry Andric     // example, it is very common for a function pass (often GVN or instcombine)
4837d523365SDimitry Andric     // to eliminate the addressing that feeds into a call.  With that improved
4847d523365SDimitry Andric     // information, we would like the call to be an inline candidate, infer
4857d523365SDimitry Andric     // mod-ref information etc.
4867d523365SDimitry Andric     //
4877d523365SDimitry Andric     // Because of this, we allow iteration up to a specified iteration count.
4887d523365SDimitry Andric     // This only happens in the case of a devirtualized call, so we only burn
4897d523365SDimitry Andric     // compile time in the case that we're making progress.  We also have a hard
4907d523365SDimitry Andric     // iteration count limit in case there is crazy code.
4917d523365SDimitry Andric     unsigned Iteration = 0;
4927d523365SDimitry Andric     bool DevirtualizedCall = false;
4937d523365SDimitry Andric     do {
4944ba319b5SDimitry Andric       LLVM_DEBUG(if (Iteration) dbgs()
4954ba319b5SDimitry Andric                  << "  SCCPASSMGR: Re-visiting SCC, iteration #" << Iteration
4964ba319b5SDimitry Andric                  << '\n');
4977d523365SDimitry Andric       DevirtualizedCall = false;
4987d523365SDimitry Andric       Changed |= RunAllPassesOnSCC(CurSCC, CG, DevirtualizedCall);
4997d523365SDimitry Andric     } while (Iteration++ < MaxIterations && DevirtualizedCall);
5007d523365SDimitry Andric 
5017d523365SDimitry Andric     if (DevirtualizedCall)
5024ba319b5SDimitry Andric       LLVM_DEBUG(dbgs() << "  CGSCCPASSMGR: Stopped iteration after "
5034ba319b5SDimitry Andric                         << Iteration
5047d523365SDimitry Andric                         << " times, due to -max-cg-scc-iterations\n");
5057d523365SDimitry Andric 
506d8866befSDimitry Andric     MaxSCCIterations.updateMax(Iteration);
5077d523365SDimitry Andric   }
5087d523365SDimitry Andric   Changed |= doFinalization(CG);
5097d523365SDimitry Andric   return Changed;
5107d523365SDimitry Andric }
5117d523365SDimitry Andric 
5127d523365SDimitry Andric /// Initialize CG
doInitialization(CallGraph & CG)5137d523365SDimitry Andric bool CGPassManager::doInitialization(CallGraph &CG) {
5147d523365SDimitry Andric   bool Changed = false;
5157d523365SDimitry Andric   for (unsigned i = 0, e = getNumContainedPasses(); i != e; ++i) {
5167d523365SDimitry Andric     if (PMDataManager *PM = getContainedPass(i)->getAsPMDataManager()) {
5177d523365SDimitry Andric       assert(PM->getPassManagerType() == PMT_FunctionPassManager &&
5187d523365SDimitry Andric              "Invalid CGPassManager member");
5197d523365SDimitry Andric       Changed |= ((FPPassManager*)PM)->doInitialization(CG.getModule());
5207d523365SDimitry Andric     } else {
5217d523365SDimitry Andric       Changed |= ((CallGraphSCCPass*)getContainedPass(i))->doInitialization(CG);
5227d523365SDimitry Andric     }
5237d523365SDimitry Andric   }
5247d523365SDimitry Andric   return Changed;
5257d523365SDimitry Andric }
5267d523365SDimitry Andric 
5277d523365SDimitry Andric /// Finalize CG
doFinalization(CallGraph & CG)5287d523365SDimitry Andric bool CGPassManager::doFinalization(CallGraph &CG) {
5297d523365SDimitry Andric   bool Changed = false;
5307d523365SDimitry Andric   for (unsigned i = 0, e = getNumContainedPasses(); i != e; ++i) {
5317d523365SDimitry Andric     if (PMDataManager *PM = getContainedPass(i)->getAsPMDataManager()) {
5327d523365SDimitry Andric       assert(PM->getPassManagerType() == PMT_FunctionPassManager &&
5337d523365SDimitry Andric              "Invalid CGPassManager member");
5347d523365SDimitry Andric       Changed |= ((FPPassManager*)PM)->doFinalization(CG.getModule());
5357d523365SDimitry Andric     } else {
5367d523365SDimitry Andric       Changed |= ((CallGraphSCCPass*)getContainedPass(i))->doFinalization(CG);
5377d523365SDimitry Andric     }
5387d523365SDimitry Andric   }
5397d523365SDimitry Andric   return Changed;
5407d523365SDimitry Andric }
5417d523365SDimitry Andric 
5427d523365SDimitry Andric //===----------------------------------------------------------------------===//
5437d523365SDimitry Andric // CallGraphSCC Implementation
5447d523365SDimitry Andric //===----------------------------------------------------------------------===//
5457d523365SDimitry Andric 
5467d523365SDimitry Andric /// This informs the SCC and the pass manager that the specified
5477d523365SDimitry Andric /// Old node has been deleted, and New is to be used in its place.
ReplaceNode(CallGraphNode * Old,CallGraphNode * New)5487d523365SDimitry Andric void CallGraphSCC::ReplaceNode(CallGraphNode *Old, CallGraphNode *New) {
5497d523365SDimitry Andric   assert(Old != New && "Should not replace node with self");
5507d523365SDimitry Andric   for (unsigned i = 0; ; ++i) {
5517d523365SDimitry Andric     assert(i != Nodes.size() && "Node not in SCC");
5527d523365SDimitry Andric     if (Nodes[i] != Old) continue;
5537d523365SDimitry Andric     Nodes[i] = New;
5547d523365SDimitry Andric     break;
5557d523365SDimitry Andric   }
5567d523365SDimitry Andric 
5577d523365SDimitry Andric   // Update the active scc_iterator so that it doesn't contain dangling
5587d523365SDimitry Andric   // pointers to the old CallGraphNode.
5597d523365SDimitry Andric   scc_iterator<CallGraph*> *CGI = (scc_iterator<CallGraph*>*)Context;
5607d523365SDimitry Andric   CGI->ReplaceNode(Old, New);
5617d523365SDimitry Andric }
5627d523365SDimitry Andric 
5637d523365SDimitry Andric //===----------------------------------------------------------------------===//
5647d523365SDimitry Andric // CallGraphSCCPass Implementation
5657d523365SDimitry Andric //===----------------------------------------------------------------------===//
5667d523365SDimitry Andric 
5677d523365SDimitry Andric /// Assign pass manager to manage this pass.
assignPassManager(PMStack & PMS,PassManagerType PreferredType)5687d523365SDimitry Andric void CallGraphSCCPass::assignPassManager(PMStack &PMS,
5697d523365SDimitry Andric                                          PassManagerType PreferredType) {
5707d523365SDimitry Andric   // Find CGPassManager
5717d523365SDimitry Andric   while (!PMS.empty() &&
5727d523365SDimitry Andric          PMS.top()->getPassManagerType() > PMT_CallGraphPassManager)
5737d523365SDimitry Andric     PMS.pop();
5747d523365SDimitry Andric 
5757d523365SDimitry Andric   assert(!PMS.empty() && "Unable to handle Call Graph Pass");
5767d523365SDimitry Andric   CGPassManager *CGP;
5777d523365SDimitry Andric 
5787d523365SDimitry Andric   if (PMS.top()->getPassManagerType() == PMT_CallGraphPassManager)
5797d523365SDimitry Andric     CGP = (CGPassManager*)PMS.top();
5807d523365SDimitry Andric   else {
5817d523365SDimitry Andric     // Create new Call Graph SCC Pass Manager if it does not exist.
5827d523365SDimitry Andric     assert(!PMS.empty() && "Unable to create Call Graph Pass Manager");
5837d523365SDimitry Andric     PMDataManager *PMD = PMS.top();
5847d523365SDimitry Andric 
5857d523365SDimitry Andric     // [1] Create new Call Graph Pass Manager
5867d523365SDimitry Andric     CGP = new CGPassManager();
5877d523365SDimitry Andric 
5887d523365SDimitry Andric     // [2] Set up new manager's top level manager
5897d523365SDimitry Andric     PMTopLevelManager *TPM = PMD->getTopLevelManager();
5907d523365SDimitry Andric     TPM->addIndirectPassManager(CGP);
5917d523365SDimitry Andric 
5927d523365SDimitry Andric     // [3] Assign manager to manage this new manager. This may create
5937d523365SDimitry Andric     // and push new managers into PMS
5947d523365SDimitry Andric     Pass *P = CGP;
5957d523365SDimitry Andric     TPM->schedulePass(P);
5967d523365SDimitry Andric 
5977d523365SDimitry Andric     // [4] Push new manager into PMS
5987d523365SDimitry Andric     PMS.push(CGP);
5997d523365SDimitry Andric   }
6007d523365SDimitry Andric 
6017d523365SDimitry Andric   CGP->add(this);
6027d523365SDimitry Andric }
6037d523365SDimitry Andric 
6047d523365SDimitry Andric /// For this class, we declare that we require and preserve the call graph.
6057d523365SDimitry Andric /// If the derived class implements this method, it should
6067d523365SDimitry Andric /// always explicitly call the implementation here.
getAnalysisUsage(AnalysisUsage & AU) const6077d523365SDimitry Andric void CallGraphSCCPass::getAnalysisUsage(AnalysisUsage &AU) const {
6087d523365SDimitry Andric   AU.addRequired<CallGraphWrapperPass>();
6097d523365SDimitry Andric   AU.addPreserved<CallGraphWrapperPass>();
6107d523365SDimitry Andric }
6117d523365SDimitry Andric 
6127d523365SDimitry Andric //===----------------------------------------------------------------------===//
6137d523365SDimitry Andric // PrintCallGraphPass Implementation
6147d523365SDimitry Andric //===----------------------------------------------------------------------===//
6157d523365SDimitry Andric 
6167d523365SDimitry Andric namespace {
6172cab237bSDimitry Andric 
6187d523365SDimitry Andric   /// PrintCallGraphPass - Print a Module corresponding to a call graph.
6197d523365SDimitry Andric   ///
6207d523365SDimitry Andric   class PrintCallGraphPass : public CallGraphSCCPass {
6217d523365SDimitry Andric     std::string Banner;
6222cab237bSDimitry Andric     raw_ostream &OS;       // raw_ostream to print on.
6237d523365SDimitry Andric 
6247d523365SDimitry Andric   public:
6257d523365SDimitry Andric     static char ID;
6262cab237bSDimitry Andric 
PrintCallGraphPass(const std::string & B,raw_ostream & OS)6272cab237bSDimitry Andric     PrintCallGraphPass(const std::string &B, raw_ostream &OS)
6282cab237bSDimitry Andric       : CallGraphSCCPass(ID), Banner(B), OS(OS) {}
6297d523365SDimitry Andric 
getAnalysisUsage(AnalysisUsage & AU) const6307d523365SDimitry Andric     void getAnalysisUsage(AnalysisUsage &AU) const override {
6317d523365SDimitry Andric       AU.setPreservesAll();
6327d523365SDimitry Andric     }
6337d523365SDimitry Andric 
runOnSCC(CallGraphSCC & SCC)6347d523365SDimitry Andric     bool runOnSCC(CallGraphSCC &SCC) override {
63524d58133SDimitry Andric       bool BannerPrinted = false;
6367a7e6055SDimitry Andric       auto PrintBannerOnce = [&]() {
6377a7e6055SDimitry Andric         if (BannerPrinted)
6387a7e6055SDimitry Andric           return;
6392cab237bSDimitry Andric         OS << Banner;
6407a7e6055SDimitry Andric         BannerPrinted = true;
6417a7e6055SDimitry Andric       };
642*b5893f02SDimitry Andric 
643*b5893f02SDimitry Andric       bool NeedModule = llvm::forcePrintModuleIR();
644*b5893f02SDimitry Andric       if (isFunctionInPrintList("*") && NeedModule) {
645*b5893f02SDimitry Andric         PrintBannerOnce();
646*b5893f02SDimitry Andric         OS << "\n";
647*b5893f02SDimitry Andric         SCC.getCallGraph().getModule().print(OS, nullptr);
648*b5893f02SDimitry Andric         return false;
649*b5893f02SDimitry Andric       }
650*b5893f02SDimitry Andric       bool FoundFunction = false;
6517d523365SDimitry Andric       for (CallGraphNode *CGN : SCC) {
65224d58133SDimitry Andric         if (Function *F = CGN->getFunction()) {
65324d58133SDimitry Andric           if (!F->isDeclaration() && isFunctionInPrintList(F->getName())) {
654*b5893f02SDimitry Andric             FoundFunction = true;
655*b5893f02SDimitry Andric             if (!NeedModule) {
6567a7e6055SDimitry Andric               PrintBannerOnce();
6572cab237bSDimitry Andric               F->print(OS);
6587a7e6055SDimitry Andric             }
659*b5893f02SDimitry Andric           }
6602cab237bSDimitry Andric         } else if (isFunctionInPrintList("*")) {
6617a7e6055SDimitry Andric           PrintBannerOnce();
6622cab237bSDimitry Andric           OS << "\nPrinting <null> Function\n";
6637d523365SDimitry Andric         }
6647a7e6055SDimitry Andric       }
665*b5893f02SDimitry Andric       if (NeedModule && FoundFunction) {
666*b5893f02SDimitry Andric         PrintBannerOnce();
667*b5893f02SDimitry Andric         OS << "\n";
668*b5893f02SDimitry Andric         SCC.getCallGraph().getModule().print(OS, nullptr);
669*b5893f02SDimitry Andric       }
6707d523365SDimitry Andric       return false;
6717d523365SDimitry Andric     }
6727a7e6055SDimitry Andric 
getPassName() const6737a7e6055SDimitry Andric     StringRef getPassName() const override { return "Print CallGraph IR"; }
6747d523365SDimitry Andric   };
6757d523365SDimitry Andric 
6767d523365SDimitry Andric } // end anonymous namespace.
6777d523365SDimitry Andric 
6787d523365SDimitry Andric char PrintCallGraphPass::ID = 0;
6797d523365SDimitry Andric 
createPrinterPass(raw_ostream & OS,const std::string & Banner) const6802cab237bSDimitry Andric Pass *CallGraphSCCPass::createPrinterPass(raw_ostream &OS,
6817d523365SDimitry Andric                                           const std::string &Banner) const {
6822cab237bSDimitry Andric   return new PrintCallGraphPass(Banner, OS);
6837d523365SDimitry Andric }
6847d523365SDimitry Andric 
skipSCC(CallGraphSCC & SCC) const6853ca95b02SDimitry Andric bool CallGraphSCCPass::skipSCC(CallGraphSCC &SCC) const {
6863ca95b02SDimitry Andric   return !SCC.getCallGraph().getModule()
6873ca95b02SDimitry Andric               .getContext()
6884ba319b5SDimitry Andric               .getOptPassGate()
6893ca95b02SDimitry Andric               .shouldRunPass(this, SCC);
6903ca95b02SDimitry Andric }
6913ca95b02SDimitry Andric 
6923ca95b02SDimitry Andric char DummyCGSCCPass::ID = 0;
6932cab237bSDimitry Andric 
6943ca95b02SDimitry Andric INITIALIZE_PASS(DummyCGSCCPass, "DummyCGSCCPass", "DummyCGSCCPass", false,
6953ca95b02SDimitry Andric                 false)
696