#include "llvm/CodeGen/MachineRegionInfo.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/RegionInfoImpl.h" #include "llvm/CodeGen/MachinePostDominators.h" #define DEBUG_TYPE "region" using namespace llvm; STATISTIC(numMachineRegions, "The # of machine regions"); STATISTIC(numMachineSimpleRegions, "The # of simple machine regions"); namespace llvm { template class RegionBase<RegionTraits<MachineFunction>>; template class RegionNodeBase<RegionTraits<MachineFunction>>; template class RegionInfoBase<RegionTraits<MachineFunction>>; } //===----------------------------------------------------------------------===// // MachineRegion implementation // MachineRegion::MachineRegion(MachineBasicBlock *Entry, MachineBasicBlock *Exit, MachineRegionInfo* RI, MachineDominatorTree *DT, MachineRegion *Parent) : RegionBase<RegionTraits<MachineFunction>>(Entry, Exit, RI, DT, Parent) { } MachineRegion::~MachineRegion() { } //===----------------------------------------------------------------------===// // MachineRegionInfo implementation // MachineRegionInfo::MachineRegionInfo() : RegionInfoBase<RegionTraits<MachineFunction>>() { } MachineRegionInfo::~MachineRegionInfo() { } void MachineRegionInfo::updateStatistics(MachineRegion *R) { ++numMachineRegions; // TODO: Slow. Should only be enabled if -stats is used. if (R->isSimple()) ++numMachineSimpleRegions; } void MachineRegionInfo::recalculate(MachineFunction &F, MachineDominatorTree *DT_, MachinePostDominatorTree *PDT_, MachineDominanceFrontier *DF_) { DT = DT_; PDT = PDT_; DF = DF_; MachineBasicBlock *Entry = GraphTraits<MachineFunction*>::getEntryNode(&F); TopLevelRegion = new MachineRegion(Entry, nullptr, this, DT, nullptr); updateStatistics(TopLevelRegion); calculate(F); } //===----------------------------------------------------------------------===// // MachineRegionInfoPass implementation // MachineRegionInfoPass::MachineRegionInfoPass() : MachineFunctionPass(ID) { initializeMachineRegionInfoPassPass(*PassRegistry::getPassRegistry()); } MachineRegionInfoPass::~MachineRegionInfoPass() { } bool MachineRegionInfoPass::runOnMachineFunction(MachineFunction &F) { releaseMemory(); auto DT = &getAnalysis<MachineDominatorTree>(); auto PDT = &getAnalysis<MachinePostDominatorTree>(); auto DF = &getAnalysis<MachineDominanceFrontier>(); RI.recalculate(F, DT, PDT, DF); return false; } void MachineRegionInfoPass::releaseMemory() { RI.releaseMemory(); } void MachineRegionInfoPass::verifyAnalysis() const { // Only do verification when user wants to, otherwise this expensive check // will be invoked by PMDataManager::verifyPreservedAnalysis when // a regionpass (marked PreservedAll) finish. if (MachineRegionInfo::VerifyRegionInfo) RI.verifyAnalysis(); } void MachineRegionInfoPass::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); AU.addRequiredTransitive<DominatorTreeWrapperPass>(); AU.addRequired<PostDominatorTreeWrapperPass>(); AU.addRequired<DominanceFrontierWrapperPass>(); } void MachineRegionInfoPass::print(raw_ostream &OS, const Module *) const { RI.print(OS); } #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) LLVM_DUMP_METHOD void MachineRegionInfoPass::dump() const { RI.dump(); } #endif char MachineRegionInfoPass::ID = 0; INITIALIZE_PASS_BEGIN(MachineRegionInfoPass, "regions", "Detect single entry single exit regions", true, true) INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTree) INITIALIZE_PASS_DEPENDENCY(MachineDominanceFrontier) INITIALIZE_PASS_END(MachineRegionInfoPass, "regions", "Detect single entry single exit regions", true, true) // Create methods available outside of this file, to use them // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by // the link time optimization. namespace llvm { FunctionPass *createMachineRegionInfoPass() { return new MachineRegionInfoPass(); } }