//===- lib/Codegen/MachineRegionInfo.cpp ----------------------------------===// // // 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 // //===----------------------------------------------------------------------===// #include "llvm/CodeGen/MachineRegionInfo.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/RegionInfoImpl.h" #include "llvm/CodeGen/MachinePostDominators.h" #include "llvm/CodeGen/Passes.h" #include "llvm/Config/llvm-config.h" #include "llvm/InitializePasses.h" #include "llvm/Pass.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #define DEBUG_TYPE "machine-region-info" using namespace llvm; STATISTIC(numMachineRegions, "The # of machine regions"); STATISTIC(numMachineSimpleRegions, "The # of simple machine regions"); namespace llvm { template class LLVM_EXPORT_TEMPLATE RegionBase>; template class LLVM_EXPORT_TEMPLATE RegionNodeBase>; template class LLVM_EXPORT_TEMPLATE RegionInfoBase>; } // end namespace llvm //===----------------------------------------------------------------------===// // RegionTraits implementation // void RegionTraits::updateStatistics(MachineRegion *R) { ++numMachineRegions; // TODO: Slow. Should only be enabled if -stats is used. if (R->isSimple()) ++numMachineSimpleRegions; } //===----------------------------------------------------------------------===// // MachineRegion implementation MachineRegion::MachineRegion(MachineBasicBlock *Entry, MachineBasicBlock *Exit, MachineRegionInfo* RI, MachineDominatorTree *DT, MachineRegion *Parent) : RegionBase>(Entry, Exit, RI, DT, Parent) {} MachineRegion::~MachineRegion() = default; //===----------------------------------------------------------------------===// // MachineRegionInfo implementation MachineRegionInfo::MachineRegionInfo() = default; MachineRegionInfo::~MachineRegionInfo() = default; void MachineRegionInfo::recalculate(MachineFunction &F, MachineDominatorTree *DT_, MachinePostDominatorTree *PDT_, MachineDominanceFrontier *DF_) { DT = DT_; PDT = PDT_; DF = DF_; MachineBasicBlock *Entry = GraphTraits::getEntryNode(&F); TopLevelRegion = new MachineRegion(Entry, nullptr, this, DT, nullptr); RegionTraits::updateStatistics(TopLevelRegion); calculate(F); } bool MachineRegionInfo::invalidate( MachineFunction &F, const PreservedAnalyses &PA, MachineFunctionAnalysisManager::Invalidator &) { // Check whether the analysis, all analyses on functions, or the function's // CFG has been preserved. auto PAC = PA.getChecker(); return !(PAC.preserved() || PAC.preservedSet>() || PAC.preservedSet()); } //===----------------------------------------------------------------------===// // MachineRegionAnalysis implementation // AnalysisKey MachineRegionInfoAnalysis::Key; MachineRegionInfo MachineRegionInfoAnalysis::run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM) { MachineRegionInfo MRI; MRI.recalculate(MF, &MFAM.getResult(MF), &MFAM.getResult(MF), &MFAM.getResult(MF)); return MRI; } PreservedAnalyses MachineRegionInfoPrinterPass::run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM) { MachineRegionInfo &MRI = MFAM.getResult(MF); MRI.print(OS); return PreservedAnalyses::all(); } //===----------------------------------------------------------------------===// // MachineRegionInfoPass implementation // MachineRegionInfoPass::MachineRegionInfoPass() : MachineFunctionPass(ID) {} MachineRegionInfoPass::~MachineRegionInfoPass() = default; bool MachineRegionInfoPass::runOnMachineFunction(MachineFunction &F) { releaseMemory(); auto DT = &getAnalysis().getDomTree(); auto PDT = &getAnalysis().getPostDomTree(); auto DF = &getAnalysis().getMDF(); RI.recalculate(F, DT, PDT, DF); LLVM_DEBUG(RI.dump()); return false; } void MachineRegionInfoPass::releaseMemory() { RI.releaseMemory(); } void MachineRegionInfoPass::verifyAnalysis() const { // Only do verification when user wants to. if (MachineRegionInfo::VerifyRegionInfo) RI.verifyAnalysis(); } void MachineRegionInfoPass::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); AU.addRequired(); AU.addRequired(); AU.addRequired(); MachineFunctionPass::getAnalysisUsage(AU); } 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; char &llvm::MachineRegionInfoPassID = MachineRegionInfoPass::ID; INITIALIZE_PASS_BEGIN(MachineRegionInfoPass, DEBUG_TYPE, "Detect single entry single exit regions", true, true) INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(MachineDominanceFrontierWrapperPass) INITIALIZE_PASS_END(MachineRegionInfoPass, DEBUG_TYPE, "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(); } } // end namespace llvm