예제 #1
0
bool CGPassManager::RunPassOnSCC(Pass *P, CallGraphSCC &CurSCC,
                                 CallGraph &CG, bool &CallGraphUpToDate,
                                 bool &DevirtualizedCall) {
  bool Changed = false;
  PMDataManager *PM = P->getAsPMDataManager();

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

    {
      TimeRegion PassTimer(getPassTimer(CGSP));
      Changed = CGSP->runOnSCC(CurSCC);
    }

    // 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 (CallGraphSCC::iterator I = CurSCC.begin(), E = CurSCC.end();
       I != E; ++I) {
    if (Function *F = (*I)->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) {
    DEBUG(dbgs() << "CGSCCPASSMGR: Pass Dirtied SCC: "
                 << P->getPassName() << '\n');
    CallGraphUpToDate = false;
  }
  return Changed;
}
예제 #2
0
/// run - 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<CallGraph>();
  bool Changed = doInitialization(CG);

  // Walk SCC
  for (scc_iterator<CallGraph*> I = scc_begin(&CG), E = scc_end(&CG);
       I != E; ++I) {

    // Run all passes on current SCC
    for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
      Pass *P = getContainedPass(Index);
      AnalysisUsage AnUsage;
      P->getAnalysisUsage(AnUsage);

      dumpPassInfo(P, EXECUTION_MSG, ON_CG_MSG, "");
      dumpAnalysisSetInfo("Required", P, AnUsage.getRequiredSet());

      initializeAnalysisImpl(P);

      StartPassTimer(P);
      if (CallGraphSCCPass *CGSP = dynamic_cast<CallGraphSCCPass *>(P))
        Changed |= CGSP->runOnSCC(*I);   // TODO : What if CG is changed ?
      else {
        FPPassManager *FPP = dynamic_cast<FPPassManager *>(P);
        assert (FPP && "Invalid CGPassManager member");

        // Run pass P on all functions current SCC
        std::vector<CallGraphNode*> &SCC = *I;
        for (unsigned i = 0, e = SCC.size(); i != e; ++i) {
          Function *F = SCC[i]->getFunction();
          if (F) {
            dumpPassInfo(P, EXECUTION_MSG, ON_FUNCTION_MSG, F->getNameStart());
            Changed |= FPP->runOnFunction(*F);
          }
        }
      }
      StopPassTimer(P);

      if (Changed)
        dumpPassInfo(P, MODIFICATION_MSG, ON_CG_MSG, "");
      dumpAnalysisSetInfo("Preserved", P, AnUsage.getPreservedSet());

      verifyPreservedAnalysis(P);      
      removeNotPreservedAnalysis(P);
      recordAvailableAnalysis(P);
      removeDeadPasses(P, "", ON_CG_MSG);
    }
  }
  Changed |= doFinalization(CG);
  return Changed;
}
예제 #3
0
/// Finalize CG
bool CGPassManager::doFinalization(CallGraph &CG) {
  bool Changed = false;
  for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {  
    Pass *P = getContainedPass(Index);
    if (CallGraphSCCPass *CGSP = dynamic_cast<CallGraphSCCPass *>(P)) {
      Changed |= CGSP->doFinalization(CG);
    } else {
      FPPassManager *FP = dynamic_cast<FPPassManager *>(P);
      assert (FP && "Invalid CGPassManager member");
      Changed |= FP->doFinalization(CG.getModule());
    }
  }
  return Changed;
}
예제 #4
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;
      bool EmitICRemark = M.shouldEmitInstrCountChangedRemark();
      TimeRegion PassTimer(getPassTimer(CGSP));
      if (EmitICRemark)
        InstrCount = initSizeRemarkInfo(M);
      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);
          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;
}