17ea69237SEugene Zelenko //===- lib/Codegen/MachineRegionInfo.cpp ----------------------------------===//
27ea69237SEugene Zelenko //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67ea69237SEugene Zelenko //
77ea69237SEugene Zelenko //===----------------------------------------------------------------------===//
87ea69237SEugene Zelenko 
96bda14b3SChandler Carruth #include "llvm/CodeGen/MachineRegionInfo.h"
101b8d8379SMatt Arsenault #include "llvm/ADT/Statistic.h"
111b8d8379SMatt Arsenault #include "llvm/Analysis/RegionInfoImpl.h"
12d9903888SChandler Carruth #include "llvm/CodeGen/MachinePostDominators.h"
13432a3883SNico Weber #include "llvm/Config/llvm-config.h"
1405da2fe5SReid Kleckner #include "llvm/InitializePasses.h"
157ea69237SEugene Zelenko #include "llvm/Pass.h"
167ea69237SEugene Zelenko #include "llvm/Support/Compiler.h"
177ea69237SEugene Zelenko #include "llvm/Support/Debug.h"
181b8d8379SMatt Arsenault 
1943130592SMatthias Braun #define DEBUG_TYPE "machine-region-info"
205e23fb86SRichard Smith 
211b8d8379SMatt Arsenault using namespace llvm;
221b8d8379SMatt Arsenault 
231b8d8379SMatt Arsenault STATISTIC(numMachineRegions,       "The # of machine regions");
241b8d8379SMatt Arsenault STATISTIC(numMachineSimpleRegions, "The # of simple machine regions");
251b8d8379SMatt Arsenault 
261b8d8379SMatt Arsenault namespace llvm {
277ea69237SEugene Zelenko 
281b8d8379SMatt Arsenault template class RegionBase<RegionTraits<MachineFunction>>;
291b8d8379SMatt Arsenault template class RegionNodeBase<RegionTraits<MachineFunction>>;
301b8d8379SMatt Arsenault template class RegionInfoBase<RegionTraits<MachineFunction>>;
317ea69237SEugene Zelenko 
327ea69237SEugene Zelenko } // end namespace llvm
331b8d8379SMatt Arsenault 
341b8d8379SMatt Arsenault //===----------------------------------------------------------------------===//
351b8d8379SMatt Arsenault // MachineRegion implementation
361b8d8379SMatt Arsenault 
MachineRegion(MachineBasicBlock * Entry,MachineBasicBlock * Exit,MachineRegionInfo * RI,MachineDominatorTree * DT,MachineRegion * Parent)371b8d8379SMatt Arsenault MachineRegion::MachineRegion(MachineBasicBlock *Entry, MachineBasicBlock *Exit,
381b8d8379SMatt Arsenault                              MachineRegionInfo* RI,
391b8d8379SMatt Arsenault                              MachineDominatorTree *DT, MachineRegion *Parent) :
407ea69237SEugene Zelenko   RegionBase<RegionTraits<MachineFunction>>(Entry, Exit, RI, DT, Parent) {}
411b8d8379SMatt Arsenault 
427ea69237SEugene Zelenko MachineRegion::~MachineRegion() = default;
431b8d8379SMatt Arsenault 
441b8d8379SMatt Arsenault //===----------------------------------------------------------------------===//
451b8d8379SMatt Arsenault // MachineRegionInfo implementation
461b8d8379SMatt Arsenault 
477ea69237SEugene Zelenko MachineRegionInfo::MachineRegionInfo() = default;
481b8d8379SMatt Arsenault 
497ea69237SEugene Zelenko MachineRegionInfo::~MachineRegionInfo() = default;
501b8d8379SMatt Arsenault 
updateStatistics(MachineRegion * R)511b8d8379SMatt Arsenault void MachineRegionInfo::updateStatistics(MachineRegion *R) {
521b8d8379SMatt Arsenault   ++numMachineRegions;
531b8d8379SMatt Arsenault 
541b8d8379SMatt Arsenault   // TODO: Slow. Should only be enabled if -stats is used.
551b8d8379SMatt Arsenault   if (R->isSimple())
561b8d8379SMatt Arsenault     ++numMachineSimpleRegions;
571b8d8379SMatt Arsenault }
581b8d8379SMatt Arsenault 
recalculate(MachineFunction & F,MachineDominatorTree * DT_,MachinePostDominatorTree * PDT_,MachineDominanceFrontier * DF_)5974a53322SNAKAMURA Takumi void MachineRegionInfo::recalculate(MachineFunction &F,
601b8d8379SMatt Arsenault                                     MachineDominatorTree *DT_,
611b8d8379SMatt Arsenault                                     MachinePostDominatorTree *PDT_,
621b8d8379SMatt Arsenault                                     MachineDominanceFrontier *DF_) {
631b8d8379SMatt Arsenault   DT = DT_;
641b8d8379SMatt Arsenault   PDT = PDT_;
651b8d8379SMatt Arsenault   DF = DF_;
661b8d8379SMatt Arsenault 
671b8d8379SMatt Arsenault   MachineBasicBlock *Entry = GraphTraits<MachineFunction*>::getEntryNode(&F);
681b8d8379SMatt Arsenault 
691b8d8379SMatt Arsenault   TopLevelRegion = new MachineRegion(Entry, nullptr, this, DT, nullptr);
701b8d8379SMatt Arsenault   updateStatistics(TopLevelRegion);
711b8d8379SMatt Arsenault   calculate(F);
721b8d8379SMatt Arsenault }
731b8d8379SMatt Arsenault 
741b8d8379SMatt Arsenault //===----------------------------------------------------------------------===//
751b8d8379SMatt Arsenault // MachineRegionInfoPass implementation
761b8d8379SMatt Arsenault //
771b8d8379SMatt Arsenault 
MachineRegionInfoPass()781b8d8379SMatt Arsenault MachineRegionInfoPass::MachineRegionInfoPass() : MachineFunctionPass(ID) {
791b8d8379SMatt Arsenault   initializeMachineRegionInfoPassPass(*PassRegistry::getPassRegistry());
801b8d8379SMatt Arsenault }
811b8d8379SMatt Arsenault 
827ea69237SEugene Zelenko MachineRegionInfoPass::~MachineRegionInfoPass() = default;
831b8d8379SMatt Arsenault 
runOnMachineFunction(MachineFunction & F)841b8d8379SMatt Arsenault bool MachineRegionInfoPass::runOnMachineFunction(MachineFunction &F) {
851b8d8379SMatt Arsenault   releaseMemory();
861b8d8379SMatt Arsenault 
871b8d8379SMatt Arsenault   auto DT = &getAnalysis<MachineDominatorTree>();
881b8d8379SMatt Arsenault   auto PDT = &getAnalysis<MachinePostDominatorTree>();
891b8d8379SMatt Arsenault   auto DF = &getAnalysis<MachineDominanceFrontier>();
901b8d8379SMatt Arsenault 
911b8d8379SMatt Arsenault   RI.recalculate(F, DT, PDT, DF);
9243130592SMatthias Braun 
93d34e60caSNicola Zaghen   LLVM_DEBUG(RI.dump());
9443130592SMatthias Braun 
951b8d8379SMatt Arsenault   return false;
961b8d8379SMatt Arsenault }
971b8d8379SMatt Arsenault 
releaseMemory()981b8d8379SMatt Arsenault void MachineRegionInfoPass::releaseMemory() {
991b8d8379SMatt Arsenault   RI.releaseMemory();
1001b8d8379SMatt Arsenault }
1011b8d8379SMatt Arsenault 
verifyAnalysis() const1021b8d8379SMatt Arsenault void MachineRegionInfoPass::verifyAnalysis() const {
1031b8d8379SMatt Arsenault   // Only do verification when user wants to, otherwise this expensive check
1041b8d8379SMatt Arsenault   // will be invoked by PMDataManager::verifyPreservedAnalysis when
1051b8d8379SMatt Arsenault   // a regionpass (marked PreservedAll) finish.
1061b8d8379SMatt Arsenault   if (MachineRegionInfo::VerifyRegionInfo)
1071b8d8379SMatt Arsenault     RI.verifyAnalysis();
1081b8d8379SMatt Arsenault }
1091b8d8379SMatt Arsenault 
getAnalysisUsage(AnalysisUsage & AU) const1101b8d8379SMatt Arsenault void MachineRegionInfoPass::getAnalysisUsage(AnalysisUsage &AU) const {
1111b8d8379SMatt Arsenault   AU.setPreservesAll();
11243130592SMatthias Braun   AU.addRequired<MachineDominatorTree>();
11343130592SMatthias Braun   AU.addRequired<MachinePostDominatorTree>();
11443130592SMatthias Braun   AU.addRequired<MachineDominanceFrontier>();
11543130592SMatthias Braun   MachineFunctionPass::getAnalysisUsage(AU);
1161b8d8379SMatt Arsenault }
1171b8d8379SMatt Arsenault 
print(raw_ostream & OS,const Module *) const1181b8d8379SMatt Arsenault void MachineRegionInfoPass::print(raw_ostream &OS, const Module *) const {
1191b8d8379SMatt Arsenault   RI.print(OS);
1201b8d8379SMatt Arsenault }
1211b8d8379SMatt Arsenault 
122615eb470SAaron Ballman #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const123eb2a2546SYaron Keren LLVM_DUMP_METHOD void MachineRegionInfoPass::dump() const {
1241b8d8379SMatt Arsenault   RI.dump();
1251b8d8379SMatt Arsenault }
126118b0c78SNAKAMURA Takumi #endif
1271b8d8379SMatt Arsenault 
1281b8d8379SMatt Arsenault char MachineRegionInfoPass::ID = 0;
129695e4374SJan Sjodin char &MachineRegionInfoPassID = MachineRegionInfoPass::ID;
1301b8d8379SMatt Arsenault 
13143130592SMatthias Braun INITIALIZE_PASS_BEGIN(MachineRegionInfoPass, DEBUG_TYPE,
1321b8d8379SMatt Arsenault                       "Detect single entry single exit regions", true, true)
1331b8d8379SMatt Arsenault INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
1341b8d8379SMatt Arsenault INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTree)
1351b8d8379SMatt Arsenault INITIALIZE_PASS_DEPENDENCY(MachineDominanceFrontier)
13643130592SMatthias Braun INITIALIZE_PASS_END(MachineRegionInfoPass, DEBUG_TYPE,
1371b8d8379SMatt Arsenault                     "Detect single entry single exit regions", true, true)
1381b8d8379SMatt Arsenault 
139*e2024d72SArthur Eubanks // Create methods available outside of this file, to use them
140*e2024d72SArthur Eubanks // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
141*e2024d72SArthur Eubanks // the link time optimization.
142*e2024d72SArthur Eubanks 
1431b8d8379SMatt Arsenault namespace llvm {
1447ea69237SEugene Zelenko 
createMachineRegionInfoPass()1451b8d8379SMatt Arsenault FunctionPass *createMachineRegionInfoPass() {
1461b8d8379SMatt Arsenault   return new MachineRegionInfoPass();
1471b8d8379SMatt Arsenault }
1481b8d8379SMatt Arsenault 
1497ea69237SEugene Zelenko } // end namespace llvm
150