1d288ef4cSDimitry Andric //===- lib/Codegen/MachineRegionInfo.cpp ----------------------------------===//
2d288ef4cSDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6d288ef4cSDimitry Andric //
7d288ef4cSDimitry Andric //===----------------------------------------------------------------------===//
8d288ef4cSDimitry Andric
97ab83427SDimitry Andric #include "llvm/CodeGen/MachineRegionInfo.h"
105ca98fd9SDimitry Andric #include "llvm/ADT/Statistic.h"
115ca98fd9SDimitry Andric #include "llvm/Analysis/RegionInfoImpl.h"
1267c32a98SDimitry Andric #include "llvm/CodeGen/MachinePostDominators.h"
13eb11fae6SDimitry Andric #include "llvm/Config/llvm-config.h"
14706b4fc4SDimitry Andric #include "llvm/InitializePasses.h"
15d288ef4cSDimitry Andric #include "llvm/Pass.h"
16d288ef4cSDimitry Andric #include "llvm/Support/Compiler.h"
17d288ef4cSDimitry Andric #include "llvm/Support/Debug.h"
1867c32a98SDimitry Andric
1971d5a254SDimitry Andric #define DEBUG_TYPE "machine-region-info"
205ca98fd9SDimitry Andric
215ca98fd9SDimitry Andric using namespace llvm;
225ca98fd9SDimitry Andric
235ca98fd9SDimitry Andric STATISTIC(numMachineRegions, "The # of machine regions");
245ca98fd9SDimitry Andric STATISTIC(numMachineSimpleRegions, "The # of simple machine regions");
255ca98fd9SDimitry Andric
265ca98fd9SDimitry Andric namespace llvm {
27d288ef4cSDimitry Andric
285ca98fd9SDimitry Andric template class RegionBase<RegionTraits<MachineFunction>>;
295ca98fd9SDimitry Andric template class RegionNodeBase<RegionTraits<MachineFunction>>;
305ca98fd9SDimitry Andric template class RegionInfoBase<RegionTraits<MachineFunction>>;
31d288ef4cSDimitry Andric
32d288ef4cSDimitry Andric } // end namespace llvm
335ca98fd9SDimitry Andric
345ca98fd9SDimitry Andric //===----------------------------------------------------------------------===//
355ca98fd9SDimitry Andric // MachineRegion implementation
365ca98fd9SDimitry Andric
MachineRegion(MachineBasicBlock * Entry,MachineBasicBlock * Exit,MachineRegionInfo * RI,MachineDominatorTree * DT,MachineRegion * Parent)375ca98fd9SDimitry Andric MachineRegion::MachineRegion(MachineBasicBlock *Entry, MachineBasicBlock *Exit,
385ca98fd9SDimitry Andric MachineRegionInfo* RI,
395ca98fd9SDimitry Andric MachineDominatorTree *DT, MachineRegion *Parent) :
40d288ef4cSDimitry Andric RegionBase<RegionTraits<MachineFunction>>(Entry, Exit, RI, DT, Parent) {}
415ca98fd9SDimitry Andric
42d288ef4cSDimitry Andric MachineRegion::~MachineRegion() = default;
435ca98fd9SDimitry Andric
445ca98fd9SDimitry Andric //===----------------------------------------------------------------------===//
455ca98fd9SDimitry Andric // MachineRegionInfo implementation
465ca98fd9SDimitry Andric
47d288ef4cSDimitry Andric MachineRegionInfo::MachineRegionInfo() = default;
485ca98fd9SDimitry Andric
49d288ef4cSDimitry Andric MachineRegionInfo::~MachineRegionInfo() = default;
505ca98fd9SDimitry Andric
updateStatistics(MachineRegion * R)515ca98fd9SDimitry Andric void MachineRegionInfo::updateStatistics(MachineRegion *R) {
525ca98fd9SDimitry Andric ++numMachineRegions;
535ca98fd9SDimitry Andric
545ca98fd9SDimitry Andric // TODO: Slow. Should only be enabled if -stats is used.
555ca98fd9SDimitry Andric if (R->isSimple())
565ca98fd9SDimitry Andric ++numMachineSimpleRegions;
575ca98fd9SDimitry Andric }
585ca98fd9SDimitry Andric
recalculate(MachineFunction & F,MachineDominatorTree * DT_,MachinePostDominatorTree * PDT_,MachineDominanceFrontier * DF_)595ca98fd9SDimitry Andric void MachineRegionInfo::recalculate(MachineFunction &F,
605ca98fd9SDimitry Andric MachineDominatorTree *DT_,
615ca98fd9SDimitry Andric MachinePostDominatorTree *PDT_,
625ca98fd9SDimitry Andric MachineDominanceFrontier *DF_) {
635ca98fd9SDimitry Andric DT = DT_;
645ca98fd9SDimitry Andric PDT = PDT_;
655ca98fd9SDimitry Andric DF = DF_;
665ca98fd9SDimitry Andric
675ca98fd9SDimitry Andric MachineBasicBlock *Entry = GraphTraits<MachineFunction*>::getEntryNode(&F);
685ca98fd9SDimitry Andric
695ca98fd9SDimitry Andric TopLevelRegion = new MachineRegion(Entry, nullptr, this, DT, nullptr);
705ca98fd9SDimitry Andric updateStatistics(TopLevelRegion);
715ca98fd9SDimitry Andric calculate(F);
725ca98fd9SDimitry Andric }
735ca98fd9SDimitry Andric
745ca98fd9SDimitry Andric //===----------------------------------------------------------------------===//
755ca98fd9SDimitry Andric // MachineRegionInfoPass implementation
765ca98fd9SDimitry Andric //
775ca98fd9SDimitry Andric
MachineRegionInfoPass()785ca98fd9SDimitry Andric MachineRegionInfoPass::MachineRegionInfoPass() : MachineFunctionPass(ID) {
795ca98fd9SDimitry Andric initializeMachineRegionInfoPassPass(*PassRegistry::getPassRegistry());
805ca98fd9SDimitry Andric }
815ca98fd9SDimitry Andric
82d288ef4cSDimitry Andric MachineRegionInfoPass::~MachineRegionInfoPass() = default;
835ca98fd9SDimitry Andric
runOnMachineFunction(MachineFunction & F)845ca98fd9SDimitry Andric bool MachineRegionInfoPass::runOnMachineFunction(MachineFunction &F) {
855ca98fd9SDimitry Andric releaseMemory();
865ca98fd9SDimitry Andric
87ac9a064cSDimitry Andric auto DT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
88ac9a064cSDimitry Andric auto PDT =
89ac9a064cSDimitry Andric &getAnalysis<MachinePostDominatorTreeWrapperPass>().getPostDomTree();
905ca98fd9SDimitry Andric auto DF = &getAnalysis<MachineDominanceFrontier>();
915ca98fd9SDimitry Andric
925ca98fd9SDimitry Andric RI.recalculate(F, DT, PDT, DF);
9371d5a254SDimitry Andric
94eb11fae6SDimitry Andric LLVM_DEBUG(RI.dump());
9571d5a254SDimitry Andric
965ca98fd9SDimitry Andric return false;
975ca98fd9SDimitry Andric }
985ca98fd9SDimitry Andric
releaseMemory()995ca98fd9SDimitry Andric void MachineRegionInfoPass::releaseMemory() {
1005ca98fd9SDimitry Andric RI.releaseMemory();
1015ca98fd9SDimitry Andric }
1025ca98fd9SDimitry Andric
verifyAnalysis() const1035ca98fd9SDimitry Andric void MachineRegionInfoPass::verifyAnalysis() const {
1045ca98fd9SDimitry Andric // Only do verification when user wants to, otherwise this expensive check
1055ca98fd9SDimitry Andric // will be invoked by PMDataManager::verifyPreservedAnalysis when
1065ca98fd9SDimitry Andric // a regionpass (marked PreservedAll) finish.
1075ca98fd9SDimitry Andric if (MachineRegionInfo::VerifyRegionInfo)
1085ca98fd9SDimitry Andric RI.verifyAnalysis();
1095ca98fd9SDimitry Andric }
1105ca98fd9SDimitry Andric
getAnalysisUsage(AnalysisUsage & AU) const1115ca98fd9SDimitry Andric void MachineRegionInfoPass::getAnalysisUsage(AnalysisUsage &AU) const {
1125ca98fd9SDimitry Andric AU.setPreservesAll();
113ac9a064cSDimitry Andric AU.addRequired<MachineDominatorTreeWrapperPass>();
114ac9a064cSDimitry Andric AU.addRequired<MachinePostDominatorTreeWrapperPass>();
11571d5a254SDimitry Andric AU.addRequired<MachineDominanceFrontier>();
11671d5a254SDimitry Andric MachineFunctionPass::getAnalysisUsage(AU);
1175ca98fd9SDimitry Andric }
1185ca98fd9SDimitry Andric
print(raw_ostream & OS,const Module *) const1195ca98fd9SDimitry Andric void MachineRegionInfoPass::print(raw_ostream &OS, const Module *) const {
1205ca98fd9SDimitry Andric RI.print(OS);
1215ca98fd9SDimitry Andric }
1225ca98fd9SDimitry Andric
1235ca98fd9SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const12401095a5dSDimitry Andric LLVM_DUMP_METHOD void MachineRegionInfoPass::dump() const {
1255ca98fd9SDimitry Andric RI.dump();
1265ca98fd9SDimitry Andric }
1275ca98fd9SDimitry Andric #endif
1285ca98fd9SDimitry Andric
1295ca98fd9SDimitry Andric char MachineRegionInfoPass::ID = 0;
13071d5a254SDimitry Andric char &MachineRegionInfoPassID = MachineRegionInfoPass::ID;
1315ca98fd9SDimitry Andric
13271d5a254SDimitry Andric INITIALIZE_PASS_BEGIN(MachineRegionInfoPass, DEBUG_TYPE,
1335ca98fd9SDimitry Andric "Detect single entry single exit regions", true, true)
134ac9a064cSDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
135ac9a064cSDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTreeWrapperPass)
1365ca98fd9SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineDominanceFrontier)
13771d5a254SDimitry Andric INITIALIZE_PASS_END(MachineRegionInfoPass, DEBUG_TYPE,
1385ca98fd9SDimitry Andric "Detect single entry single exit regions", true, true)
1395ca98fd9SDimitry Andric
1405ca98fd9SDimitry Andric // Create methods available outside of this file, to use them
1415ca98fd9SDimitry Andric // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
1425ca98fd9SDimitry Andric // the link time optimization.
1435ca98fd9SDimitry Andric
1445ca98fd9SDimitry Andric namespace llvm {
145d288ef4cSDimitry Andric
createMachineRegionInfoPass()1465ca98fd9SDimitry Andric FunctionPass *createMachineRegionInfoPass() {
1475ca98fd9SDimitry Andric return new MachineRegionInfoPass();
1485ca98fd9SDimitry Andric }
1495ca98fd9SDimitry Andric
150d288ef4cSDimitry Andric } // end namespace llvm
151