//===- CallGraphSCCPass.cpp - Pass that operates BU on call graph ---------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the CallGraphSCCPass class, which is used for passes
// which are implemented as bottom-up traversals on the call graph.  Because
// there may be cycles in the call graph, passes of this type operate on the
// call-graph in SCC order: that is, they process function bottom-up, except for
// recursive functions, which they process all at once.
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/CallGraphSCCPass.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SCCIterator.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/CallGraph.h"
#include "llvm/IR/AbstractCallSite.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManagers.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/OptBisect.h"
#include "llvm/IR/PassTimingInfo.h"
#include "llvm/IR/PrintPasses.h"
#include "llvm/IR/StructuralHash.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <string>
#include <utility>
#include <vector>

using namespace llvm;

#define DEBUG_TYPE "cgscc-passmgr"

cl::opt<unsigned> MaxDevirtIterations("max-devirt-iterations", cl::ReallyHidden,
                                      cl::init(4));

STATISTIC(MaxSCCIterations, "Maximum CGSCCPassMgr iterations on one SCC");

//===----------------------------------------------------------------------===//
// CGPassManager
//
/// CGPassManager manages FPPassManagers and CallGraphSCCPasses.

namespace {

class CGPassManager : public ModulePass, public PMDataManager {
public:
  static char ID;

  explicit CGPassManager() : ModulePass(ID), PMDataManager() {}

  /// Execute all of the passes scheduled for execution.  Keep track of
  /// whether any of the passes modifies the module, and if so, return true.
  bool runOnModule(Module &M) override;

  using ModulePass::doInitialization;
  using ModulePass::doFinalization;

  bool doInitialization(CallGraph &CG);
  bool doFinalization(CallGraph &CG);

  /// Pass Manager itself does not invalidate any analysis info.
  void getAnalysisUsage(AnalysisUsage &Info) const override {
    // CGPassManager walks SCC and it needs CallGraph.
    Info.addRequired<CallGraphWrapperPass>();
    Info.setPreservesAll();
  }

  StringRef getPassName() const override { return "CallGraph Pass Manager"; }

  PMDataManager *getAsPMDataManager() override { return this; }
  Pass *getAsPass() override { return this; }

  // Print passes managed by this manager
  void dumpPassStructure(unsigned Offset) override {
    errs().indent(Offset*2) << "Call Graph SCC Pass Manager\n";
    for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
      Pass *P = getContainedPass(Index);
      P->dumpPassStructure(Offset + 1);
      dumpLastUses(P, Offset+1);
    }
  }

  Pass *getContainedPass(unsigned N) {
    assert(N < PassVector.size() && "Pass number out of range!");
    return static_cast<Pass *>(PassVector[N]);
  }

  PassManagerType getPassManagerType() const override {
    return PMT_CallGraphPassManager;
  }

private:
  bool RunAllPassesOnSCC(CallGraphSCC &CurSCC, CallGraph &CG,
                         bool &DevirtualizedCall);

  bool RunPassOnSCC(Pass *P, CallGraphSCC &CurSCC,
                    CallGraph &CG, bool &CallGraphUpToDate,
                    bool &DevirtualizedCall);
  bool RefreshCallGraph(const CallGraphSCC &CurSCC, CallGraph &CG,
                        bool IsCheckingMode);
};

} // end anonymous namespace.

char CGPassManager::ID = 0;

bool CGPassManager::RunPassOnSCC(Pass *P, CallGraphSCC &CurSCC,
                                 CallGraph &CG, bool &CallGraphUpToDate,
                                 bool &DevirtualizedCall) {
  bool Changed = false;
  PMDataManager *PM = P->getAsPMDataManager();
  Module &M = CG.getModule();

  if (!PM) {
    CallGraphSCCPass *CGSP = (CallGraphSCCPass *)P;
    if (!CallGraphUpToDate) {
      DevirtualizedCall |= RefreshCallGraph(CurSCC, CG, false);
      CallGraphUpToDate = true;
    }

    {
      unsigned InstrCount, SCCCount = 0;
      StringMap<std::pair<unsigned, unsigned>> FunctionToInstrCount;
      bool EmitICRemark = M.shouldEmitInstrCountChangedRemark();
      TimeRegion PassTimer(getPassTimer(CGSP));
      if (EmitICRemark)
        InstrCount = initSizeRemarkInfo(M, FunctionToInstrCount);
      Changed = CGSP->runOnSCC(CurSCC);

      if (EmitICRemark) {
        // FIXME: Add getInstructionCount to CallGraphSCC.
        SCCCount = M.getInstructionCount();
        // Is there a difference in the number of instructions in the module?
        if (SCCCount != InstrCount) {
          // Yep. Emit a remark and update InstrCount.
          int64_t Delta =
              static_cast<int64_t>(SCCCount) - static_cast<int64_t>(InstrCount);
          emitInstrCountChangedRemark(P, M, Delta, InstrCount,
                                      FunctionToInstrCount);
          InstrCount = SCCCount;
        }
      }
    }

    // After the CGSCCPass is done, when assertions are enabled, use
    // RefreshCallGraph to verify that the callgraph was correctly updated.
#ifndef NDEBUG
    if (Changed)
      RefreshCallGraph(CurSCC, CG, true);
#endif

    return Changed;
  }

  assert(PM->getPassManagerType() == PMT_FunctionPassManager &&
         "Invalid CGPassManager member");
  FPPassManager *FPP = (FPPassManager*)P;

  // Run pass P on all functions in the current SCC.
  for (CallGraphNode *CGN : CurSCC) {
    if (Function *F = CGN->getFunction()) {
      dumpPassInfo(P, EXECUTION_MSG, ON_FUNCTION_MSG, F->getName());
      {
        TimeRegion PassTimer(getPassTimer(FPP));
        Changed |= FPP->runOnFunction(*F);
      }
      F->getContext().yield();
    }
  }

  // The function pass(es) modified the IR, they may have clobbered the
  // callgraph.
  if (Changed && CallGraphUpToDate) {
    LLVM_DEBUG(dbgs() << "CGSCCPASSMGR: Pass Dirtied SCC: " << P->getPassName()
                      << '\n');
    CallGraphUpToDate = false;
  }
  return Changed;
}

/// Scan the functions in the specified CFG and resync the
/// callgraph with the call sites found in it.  This is used after
/// FunctionPasses have potentially munged the callgraph, and can be used after
/// CallGraphSCC passes to verify that they correctly updated the callgraph.
///
/// This function returns true if it devirtualized an existing function call,
/// meaning it turned an indirect call into a direct call.  This happens when
/// a function pass like GVN optimizes away stuff feeding the indirect call.
/// This never happens in checking mode.
bool CGPassManager::RefreshCallGraph(const CallGraphSCC &CurSCC, CallGraph &CG,
                                     bool CheckingMode) {
  DenseMap<Value *, CallGraphNode *> Calls;

  LLVM_DEBUG(dbgs() << "CGSCCPASSMGR: Refreshing SCC with " << CurSCC.size()
                    << " nodes:\n";
             for (CallGraphNode *CGN
                  : CurSCC) CGN->dump(););

  bool MadeChange = false;
  bool DevirtualizedCall = false;

  // Scan all functions in the SCC.
  unsigned FunctionNo = 0;
  for (CallGraphSCC::iterator SCCIdx = CurSCC.begin(), E = CurSCC.end();
       SCCIdx != E; ++SCCIdx, ++FunctionNo) {
    CallGraphNode *CGN = *SCCIdx;
    Function *F = CGN->getFunction();
    if (!F || F->isDeclaration()) continue;

    // Walk the function body looking for call sites.  Sync up the call sites in
    // CGN with those actually in the function.

    // Keep track of the number of direct and indirect calls that were
    // invalidated and removed.
    unsigned NumDirectRemoved = 0, NumIndirectRemoved = 0;

    CallGraphNode::iterator CGNEnd = CGN->end();

    auto RemoveAndCheckForDone = [&](CallGraphNode::iterator I) {
      // Just remove the edge from the set of callees, keep track of whether
      // I points to the last element of the vector.
      bool WasLast = I + 1 == CGNEnd;
      CGN->removeCallEdge(I);

      // If I pointed to the last element of the vector, we have to bail out:
      // iterator checking rejects comparisons of the resultant pointer with
      // end.
      if (WasLast)
        return true;

      CGNEnd = CGN->end();
      return false;
    };

    // Get the set of call sites currently in the function.
    for (CallGraphNode::iterator I = CGN->begin(); I != CGNEnd;) {
      // Delete "reference" call records that do not have call instruction. We
      // reinsert them as needed later. However, keep them in checking mode.
      if (!I->first) {
        if (CheckingMode) {
          ++I;
          continue;
        }
        if (RemoveAndCheckForDone(I))
          break;
        continue;
      }

      // If this call site is null, then the function pass deleted the call
      // entirely and the WeakTrackingVH nulled it out.
      auto *Call = dyn_cast_or_null<CallBase>(*I->first);
      if (!Call ||
          // If we've already seen this call site, then the FunctionPass RAUW'd
          // one call with another, which resulted in two "uses" in the edge
          // list of the same call.
          Calls.count(Call) ||

          // If the call edge is not from a call or invoke, or it is a
          // instrinsic call, then the function pass RAUW'd a call with
          // another value. This can happen when constant folding happens
          // of well known functions etc.
          (Call->getCalledFunction() &&
           Call->getCalledFunction()->isIntrinsic() &&
           Intrinsic::isLeaf(Call->getCalledFunction()->getIntrinsicID()))) {
        assert(!CheckingMode &&
               "CallGraphSCCPass did not update the CallGraph correctly!");

        // If this was an indirect call site, count it.
        if (!I->second->getFunction())
          ++NumIndirectRemoved;
        else
          ++NumDirectRemoved;

        if (RemoveAndCheckForDone(I))
          break;
        continue;
      }

      assert(!Calls.count(Call) && "Call site occurs in node multiple times");

      if (Call) {
        Function *Callee = Call->getCalledFunction();
        // Ignore intrinsics because they're not really function calls.
        if (!Callee || !(Callee->isIntrinsic()))
          Calls.insert(std::make_pair(Call, I->second));
      }
      ++I;
    }

    // Loop over all of the instructions in the function, getting the callsites.
    // Keep track of the number of direct/indirect calls added.
    unsigned NumDirectAdded = 0, NumIndirectAdded = 0;

    for (BasicBlock &BB : *F)
      for (Instruction &I : BB) {
        auto *Call = dyn_cast<CallBase>(&I);
        if (!Call)
          continue;
        Function *Callee = Call->getCalledFunction();
        if (Callee && Callee->isIntrinsic())
          continue;

        // If we are not in checking mode, insert potential callback calls as
        // references. This is not a requirement but helps to iterate over the
        // functions in the right order.
        if (!CheckingMode) {
          forEachCallbackFunction(*Call, [&](Function *CB) {
            CGN->addCalledFunction(nullptr, CG.getOrInsertFunction(CB));
          });
        }

        // If this call site already existed in the callgraph, just verify it
        // matches up to expectations and remove it from Calls.
        DenseMap<Value *, CallGraphNode *>::iterator ExistingIt =
            Calls.find(Call);
        if (ExistingIt != Calls.end()) {
          CallGraphNode *ExistingNode = ExistingIt->second;

          // Remove from Calls since we have now seen it.
          Calls.erase(ExistingIt);

          // Verify that the callee is right.
          if (ExistingNode->getFunction() == Call->getCalledFunction())
            continue;

          // If we are in checking mode, we are not allowed to actually mutate
          // the callgraph.  If this is a case where we can infer that the
          // callgraph is less precise than it could be (e.g. an indirect call
          // site could be turned direct), don't reject it in checking mode, and
          // don't tweak it to be more precise.
          if (CheckingMode && Call->getCalledFunction() &&
              ExistingNode->getFunction() == nullptr)
            continue;

          assert(!CheckingMode &&
                 "CallGraphSCCPass did not update the CallGraph correctly!");

          // If not, we either went from a direct call to indirect, indirect to
          // direct, or direct to different direct.
          CallGraphNode *CalleeNode;
          if (Function *Callee = Call->getCalledFunction()) {
            CalleeNode = CG.getOrInsertFunction(Callee);
            // Keep track of whether we turned an indirect call into a direct
            // one.
            if (!ExistingNode->getFunction()) {
              DevirtualizedCall = true;
              LLVM_DEBUG(dbgs() << "  CGSCCPASSMGR: Devirtualized call to '"
                                << Callee->getName() << "'\n");
            }
          } else {
            CalleeNode = CG.getCallsExternalNode();
          }

          // Update the edge target in CGN.
          CGN->replaceCallEdge(*Call, *Call, CalleeNode);
          MadeChange = true;
          continue;
        }

        assert(!CheckingMode &&
               "CallGraphSCCPass did not update the CallGraph correctly!");

        // If the call site didn't exist in the CGN yet, add it.
        CallGraphNode *CalleeNode;
        if (Function *Callee = Call->getCalledFunction()) {
          CalleeNode = CG.getOrInsertFunction(Callee);
          ++NumDirectAdded;
        } else {
          CalleeNode = CG.getCallsExternalNode();
          ++NumIndirectAdded;
        }

        CGN->addCalledFunction(Call, CalleeNode);
        MadeChange = true;
      }

    // We scanned the old callgraph node, removing invalidated call sites and
    // then added back newly found call sites.  One thing that can happen is
    // that an old indirect call site was deleted and replaced with a new direct
    // call.  In this case, we have devirtualized a call, and CGSCCPM would like
    // to iteratively optimize the new code.  Unfortunately, we don't really
    // have a great way to detect when this happens.  As an approximation, we
    // just look at whether the number of indirect calls is reduced and the
    // number of direct calls is increased.  There are tons of ways to fool this
    // (e.g. DCE'ing an indirect call and duplicating an unrelated block with a
    // direct call) but this is close enough.
    if (NumIndirectRemoved > NumIndirectAdded &&
        NumDirectRemoved < NumDirectAdded)
      DevirtualizedCall = true;

    // After scanning this function, if we still have entries in callsites, then
    // they are dangling pointers.  WeakTrackingVH should save us for this, so
    // abort if
    // this happens.
    assert(Calls.empty() && "Dangling pointers found in call sites map");

    // Periodically do an explicit clear to remove tombstones when processing
    // large scc's.
    if ((FunctionNo & 15) == 15)
      Calls.clear();
  }

  LLVM_DEBUG(if (MadeChange) {
    dbgs() << "CGSCCPASSMGR: Refreshed SCC is now:\n";
    for (CallGraphNode *CGN : CurSCC)
      CGN->dump();
    if (DevirtualizedCall)
      dbgs() << "CGSCCPASSMGR: Refresh devirtualized a call!\n";
  } else {
    dbgs() << "CGSCCPASSMGR: SCC Refresh didn't change call graph.\n";
  });
  (void)MadeChange;

  return DevirtualizedCall;
}

/// Execute the body of the entire pass manager on the specified SCC.
/// This keeps track of whether a function pass devirtualizes
/// any calls and returns it in DevirtualizedCall.
bool CGPassManager::RunAllPassesOnSCC(CallGraphSCC &CurSCC, CallGraph &CG,
                                      bool &DevirtualizedCall) {
  bool Changed = false;

  // Keep track of whether the callgraph is known to be up-to-date or not.
  // The CGSSC pass manager runs two types of passes:
  // CallGraphSCC Passes and other random function passes.  Because other
  // random function passes are not CallGraph aware, they may clobber the
  // call graph by introducing new calls or deleting other ones.  This flag
  // is set to false when we run a function pass so that we know to clean up
  // the callgraph when we need to run a CGSCCPass again.
  bool CallGraphUpToDate = true;

  // Run all passes on current SCC.
  for (unsigned PassNo = 0, e = getNumContainedPasses();
       PassNo != e; ++PassNo) {
    Pass *P = getContainedPass(PassNo);

    // If we're in -debug-pass=Executions mode, construct the SCC node list,
    // otherwise avoid constructing this string as it is expensive.
    if (isPassDebuggingExecutionsOrMore()) {
      std::string Functions;
  #ifndef NDEBUG
      raw_string_ostream OS(Functions);
      for (CallGraphSCC::iterator I = CurSCC.begin(), E = CurSCC.end();
           I != E; ++I) {
        if (I != CurSCC.begin()) OS << ", ";
        (*I)->print(OS);
      }
      OS.flush();
  #endif
      dumpPassInfo(P, EXECUTION_MSG, ON_CG_MSG, Functions);
    }
    dumpRequiredSet(P);

    initializeAnalysisImpl(P);

#ifdef EXPENSIVE_CHECKS
    uint64_t RefHash = StructuralHash(CG.getModule());
#endif

    // Actually run this pass on the current SCC.
    bool LocalChanged =
        RunPassOnSCC(P, CurSCC, CG, CallGraphUpToDate, DevirtualizedCall);

    Changed |= LocalChanged;

#ifdef EXPENSIVE_CHECKS
    if (!LocalChanged && (RefHash != StructuralHash(CG.getModule()))) {
      llvm::errs() << "Pass modifies its input and doesn't report it: "
                   << P->getPassName() << "\n";
      llvm_unreachable("Pass modifies its input and doesn't report it");
    }
#endif
    if (LocalChanged)
      dumpPassInfo(P, MODIFICATION_MSG, ON_CG_MSG, "");
    dumpPreservedSet(P);

    verifyPreservedAnalysis(P);
    if (LocalChanged)
      removeNotPreservedAnalysis(P);
    recordAvailableAnalysis(P);
    removeDeadPasses(P, "", ON_CG_MSG);
  }

  // If the callgraph was left out of date (because the last pass run was a
  // functionpass), refresh it before we move on to the next SCC.
  if (!CallGraphUpToDate)
    DevirtualizedCall |= RefreshCallGraph(CurSCC, CG, false);
  return Changed;
}

/// Execute all of the passes scheduled for execution.  Keep track of
/// whether any of the passes modifies the module, and if so, return true.
bool CGPassManager::runOnModule(Module &M) {
  CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph();
  bool Changed = doInitialization(CG);

  // Walk the callgraph in bottom-up SCC order.
  scc_iterator<CallGraph*> CGI = scc_begin(&CG);

  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.
    const std::vector<CallGraphNode *> &NodeVec = *CGI;
    CurSCC.initialize(NodeVec);
    ++CGI;

    // At the top level, we run all the passes in this pass manager on the
    // functions in this SCC.  However, we support iterative compilation in the
    // case where a function pass devirtualizes a call to a function.  For
    // example, it is very common for a function pass (often GVN or instcombine)
    // to eliminate the addressing that feeds into a call.  With that improved
    // information, we would like the call to be an inline candidate, infer
    // mod-ref information etc.
    //
    // Because of this, we allow iteration up to a specified iteration count.
    // This only happens in the case of a devirtualized call, so we only burn
    // compile time in the case that we're making progress.  We also have a hard
    // iteration count limit in case there is crazy code.
    unsigned Iteration = 0;
    bool DevirtualizedCall = false;
    do {
      LLVM_DEBUG(if (Iteration) dbgs()
                 << "  SCCPASSMGR: Re-visiting SCC, iteration #" << Iteration
                 << '\n');
      DevirtualizedCall = false;
      Changed |= RunAllPassesOnSCC(CurSCC, CG, DevirtualizedCall);
    } while (Iteration++ < MaxDevirtIterations && DevirtualizedCall);

    if (DevirtualizedCall)
      LLVM_DEBUG(dbgs() << "  CGSCCPASSMGR: Stopped iteration after "
                        << Iteration
                        << " times, due to -max-devirt-iterations\n");

    MaxSCCIterations.updateMax(Iteration);
  }
  Changed |= doFinalization(CG);
  return Changed;
}

/// Initialize CG
bool CGPassManager::doInitialization(CallGraph &CG) {
  bool Changed = false;
  for (unsigned i = 0, e = getNumContainedPasses(); i != e; ++i) {
    if (PMDataManager *PM = getContainedPass(i)->getAsPMDataManager()) {
      assert(PM->getPassManagerType() == PMT_FunctionPassManager &&
             "Invalid CGPassManager member");
      Changed |= ((FPPassManager*)PM)->doInitialization(CG.getModule());
    } else {
      Changed |= ((CallGraphSCCPass*)getContainedPass(i))->doInitialization(CG);
    }
  }
  return Changed;
}

/// Finalize CG
bool CGPassManager::doFinalization(CallGraph &CG) {
  bool Changed = false;
  for (unsigned i = 0, e = getNumContainedPasses(); i != e; ++i) {
    if (PMDataManager *PM = getContainedPass(i)->getAsPMDataManager()) {
      assert(PM->getPassManagerType() == PMT_FunctionPassManager &&
             "Invalid CGPassManager member");
      Changed |= ((FPPassManager*)PM)->doFinalization(CG.getModule());
    } else {
      Changed |= ((CallGraphSCCPass*)getContainedPass(i))->doFinalization(CG);
    }
  }
  return Changed;
}

//===----------------------------------------------------------------------===//
// CallGraphSCC Implementation
//===----------------------------------------------------------------------===//

/// This informs the SCC and the pass manager that the specified
/// Old node has been deleted, and New is to be used in its place.
void CallGraphSCC::ReplaceNode(CallGraphNode *Old, CallGraphNode *New) {
  assert(Old != New && "Should not replace node with self");
  for (unsigned i = 0; ; ++i) {
    assert(i != Nodes.size() && "Node not in SCC");
    if (Nodes[i] != Old) continue;
    if (New)
      Nodes[i] = New;
    else
      Nodes.erase(Nodes.begin() + i);
    break;
  }

  // Update the active scc_iterator so that it doesn't contain dangling
  // pointers to the old CallGraphNode.
  scc_iterator<CallGraph*> *CGI = (scc_iterator<CallGraph*>*)Context;
  CGI->ReplaceNode(Old, New);
}

void CallGraphSCC::DeleteNode(CallGraphNode *Old) {
  ReplaceNode(Old, /*New=*/nullptr);
}

//===----------------------------------------------------------------------===//
// CallGraphSCCPass Implementation
//===----------------------------------------------------------------------===//

/// Assign pass manager to manage this pass.
void CallGraphSCCPass::assignPassManager(PMStack &PMS,
                                         PassManagerType PreferredType) {
  // Find CGPassManager
  while (!PMS.empty() &&
         PMS.top()->getPassManagerType() > PMT_CallGraphPassManager)
    PMS.pop();

  assert(!PMS.empty() && "Unable to handle Call Graph Pass");
  CGPassManager *CGP;

  if (PMS.top()->getPassManagerType() == PMT_CallGraphPassManager)
    CGP = (CGPassManager*)PMS.top();
  else {
    // Create new Call Graph SCC Pass Manager if it does not exist.
    assert(!PMS.empty() && "Unable to create Call Graph Pass Manager");
    PMDataManager *PMD = PMS.top();

    // [1] Create new Call Graph Pass Manager
    CGP = new CGPassManager();

    // [2] Set up new manager's top level manager
    PMTopLevelManager *TPM = PMD->getTopLevelManager();
    TPM->addIndirectPassManager(CGP);

    // [3] Assign manager to manage this new manager. This may create
    // and push new managers into PMS
    Pass *P = CGP;
    TPM->schedulePass(P);

    // [4] Push new manager into PMS
    PMS.push(CGP);
  }

  CGP->add(this);
}

/// For this class, we declare that we require and preserve the call graph.
/// If the derived class implements this method, it should
/// always explicitly call the implementation here.
void CallGraphSCCPass::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.addRequired<CallGraphWrapperPass>();
  AU.addPreserved<CallGraphWrapperPass>();
}

//===----------------------------------------------------------------------===//
// PrintCallGraphPass Implementation
//===----------------------------------------------------------------------===//

namespace {

  /// PrintCallGraphPass - Print a Module corresponding to a call graph.
  ///
  class PrintCallGraphPass : public CallGraphSCCPass {
    std::string Banner;
    raw_ostream &OS;       // raw_ostream to print on.

  public:
    static char ID;

    PrintCallGraphPass(const std::string &B, raw_ostream &OS)
      : CallGraphSCCPass(ID), Banner(B), OS(OS) {}

    void getAnalysisUsage(AnalysisUsage &AU) const override {
      AU.setPreservesAll();
    }

    bool runOnSCC(CallGraphSCC &SCC) override {
      bool BannerPrinted = false;
      auto PrintBannerOnce = [&]() {
        if (BannerPrinted)
          return;
        OS << Banner;
        BannerPrinted = true;
      };

      bool NeedModule = llvm::forcePrintModuleIR();
      if (isFunctionInPrintList("*") && NeedModule) {
        PrintBannerOnce();
        OS << "\n";
        SCC.getCallGraph().getModule().print(OS, nullptr);
        return false;
      }
      bool FoundFunction = false;
      for (CallGraphNode *CGN : SCC) {
        if (Function *F = CGN->getFunction()) {
          if (!F->isDeclaration() && isFunctionInPrintList(F->getName())) {
            FoundFunction = true;
            if (!NeedModule) {
              PrintBannerOnce();
              F->print(OS);
            }
          }
        } else if (isFunctionInPrintList("*")) {
          PrintBannerOnce();
          OS << "\nPrinting <null> Function\n";
        }
      }
      if (NeedModule && FoundFunction) {
        PrintBannerOnce();
        OS << "\n";
        SCC.getCallGraph().getModule().print(OS, nullptr);
      }
      return false;
    }

    StringRef getPassName() const override { return "Print CallGraph IR"; }
  };

} // end anonymous namespace.

char PrintCallGraphPass::ID = 0;

Pass *CallGraphSCCPass::createPrinterPass(raw_ostream &OS,
                                          const std::string &Banner) const {
  return new PrintCallGraphPass(Banner, OS);
}

static std::string getDescription(const CallGraphSCC &SCC) {
  std::string Desc = "SCC (";
  bool First = true;
  for (CallGraphNode *CGN : SCC) {
    if (First)
      First = false;
    else
      Desc += ", ";
    Function *F = CGN->getFunction();
    if (F)
      Desc += F->getName();
    else
      Desc += "<<null function>>";
  }
  Desc += ")";
  return Desc;
}

bool CallGraphSCCPass::skipSCC(CallGraphSCC &SCC) const {
  OptPassGate &Gate =
      SCC.getCallGraph().getModule().getContext().getOptPassGate();
  return Gate.isEnabled() && !Gate.shouldRunPass(this, getDescription(SCC));
}

char DummyCGSCCPass::ID = 0;

INITIALIZE_PASS(DummyCGSCCPass, "DummyCGSCCPass", "DummyCGSCCPass", false,
                false)
