152 lines · cpp
1//===- lib/Codegen/MachineRegionInfo.cpp ----------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/CodeGen/MachineRegionInfo.h"10#include "llvm/ADT/Statistic.h"11#include "llvm/Analysis/RegionInfoImpl.h"12#include "llvm/CodeGen/MachinePostDominators.h"13#include "llvm/CodeGen/Passes.h"14#include "llvm/Config/llvm-config.h"15#include "llvm/InitializePasses.h"16#include "llvm/Pass.h"17#include "llvm/Support/Compiler.h"18#include "llvm/Support/Debug.h"19 20#define DEBUG_TYPE "machine-region-info"21 22using namespace llvm;23 24STATISTIC(numMachineRegions, "The # of machine regions");25STATISTIC(numMachineSimpleRegions, "The # of simple machine regions");26 27namespace llvm {28 29template class RegionBase<RegionTraits<MachineFunction>>;30template class RegionNodeBase<RegionTraits<MachineFunction>>;31template class RegionInfoBase<RegionTraits<MachineFunction>>;32 33} // end namespace llvm34 35//===----------------------------------------------------------------------===//36// MachineRegion implementation37 38MachineRegion::MachineRegion(MachineBasicBlock *Entry, MachineBasicBlock *Exit,39 MachineRegionInfo* RI,40 MachineDominatorTree *DT, MachineRegion *Parent) :41 RegionBase<RegionTraits<MachineFunction>>(Entry, Exit, RI, DT, Parent) {}42 43MachineRegion::~MachineRegion() = default;44 45//===----------------------------------------------------------------------===//46// MachineRegionInfo implementation47 48MachineRegionInfo::MachineRegionInfo() = default;49 50MachineRegionInfo::~MachineRegionInfo() = default;51 52void MachineRegionInfo::updateStatistics(MachineRegion *R) {53 ++numMachineRegions;54 55 // TODO: Slow. Should only be enabled if -stats is used.56 if (R->isSimple())57 ++numMachineSimpleRegions;58}59 60void MachineRegionInfo::recalculate(MachineFunction &F,61 MachineDominatorTree *DT_,62 MachinePostDominatorTree *PDT_,63 MachineDominanceFrontier *DF_) {64 DT = DT_;65 PDT = PDT_;66 DF = DF_;67 68 MachineBasicBlock *Entry = GraphTraits<MachineFunction*>::getEntryNode(&F);69 70 TopLevelRegion = new MachineRegion(Entry, nullptr, this, DT, nullptr);71 updateStatistics(TopLevelRegion);72 calculate(F);73}74 75//===----------------------------------------------------------------------===//76// MachineRegionInfoPass implementation77//78 79MachineRegionInfoPass::MachineRegionInfoPass() : MachineFunctionPass(ID) {80 initializeMachineRegionInfoPassPass(*PassRegistry::getPassRegistry());81}82 83MachineRegionInfoPass::~MachineRegionInfoPass() = default;84 85bool MachineRegionInfoPass::runOnMachineFunction(MachineFunction &F) {86 releaseMemory();87 88 auto DT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();89 auto PDT =90 &getAnalysis<MachinePostDominatorTreeWrapperPass>().getPostDomTree();91 auto DF = &getAnalysis<MachineDominanceFrontier>();92 93 RI.recalculate(F, DT, PDT, DF);94 95 LLVM_DEBUG(RI.dump());96 97 return false;98}99 100void MachineRegionInfoPass::releaseMemory() {101 RI.releaseMemory();102}103 104void MachineRegionInfoPass::verifyAnalysis() const {105 // Only do verification when user wants to, otherwise this expensive check106 // will be invoked by PMDataManager::verifyPreservedAnalysis when107 // a regionpass (marked PreservedAll) finish.108 if (MachineRegionInfo::VerifyRegionInfo)109 RI.verifyAnalysis();110}111 112void MachineRegionInfoPass::getAnalysisUsage(AnalysisUsage &AU) const {113 AU.setPreservesAll();114 AU.addRequired<MachineDominatorTreeWrapperPass>();115 AU.addRequired<MachinePostDominatorTreeWrapperPass>();116 AU.addRequired<MachineDominanceFrontier>();117 MachineFunctionPass::getAnalysisUsage(AU);118}119 120void MachineRegionInfoPass::print(raw_ostream &OS, const Module *) const {121 RI.print(OS);122}123 124#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)125LLVM_DUMP_METHOD void MachineRegionInfoPass::dump() const {126 RI.dump();127}128#endif129 130char MachineRegionInfoPass::ID = 0;131char &llvm::MachineRegionInfoPassID = MachineRegionInfoPass::ID;132 133INITIALIZE_PASS_BEGIN(MachineRegionInfoPass, DEBUG_TYPE,134 "Detect single entry single exit regions", true, true)135INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)136INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTreeWrapperPass)137INITIALIZE_PASS_DEPENDENCY(MachineDominanceFrontier)138INITIALIZE_PASS_END(MachineRegionInfoPass, DEBUG_TYPE,139 "Detect single entry single exit regions", true, true)140 141// Create methods available outside of this file, to use them142// "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by143// the link time optimization.144 145namespace llvm {146 147FunctionPass *createMachineRegionInfoPass() {148 return new MachineRegionInfoPass();149}150 151} // end namespace llvm152