xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/MachineRegionInfo.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- lib/Codegen/MachineRegionInfo.cpp ----------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegionInfo.h"
100b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
110b57cec5SDimitry Andric #include "llvm/Analysis/RegionInfoImpl.h"
120b57cec5SDimitry Andric #include "llvm/CodeGen/MachinePostDominators.h"
130b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h"
14480093f4SDimitry Andric #include "llvm/InitializePasses.h"
150b57cec5SDimitry Andric #include "llvm/Pass.h"
160b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
170b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric #define DEBUG_TYPE "machine-region-info"
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric using namespace llvm;
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric STATISTIC(numMachineRegions,       "The # of machine regions");
240b57cec5SDimitry Andric STATISTIC(numMachineSimpleRegions, "The # of simple machine regions");
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric namespace llvm {
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric template class RegionBase<RegionTraits<MachineFunction>>;
290b57cec5SDimitry Andric template class RegionNodeBase<RegionTraits<MachineFunction>>;
300b57cec5SDimitry Andric template class RegionInfoBase<RegionTraits<MachineFunction>>;
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric } // end namespace llvm
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
350b57cec5SDimitry Andric // MachineRegion implementation
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric MachineRegion::MachineRegion(MachineBasicBlock *Entry, MachineBasicBlock *Exit,
380b57cec5SDimitry Andric                              MachineRegionInfo* RI,
390b57cec5SDimitry Andric                              MachineDominatorTree *DT, MachineRegion *Parent) :
400b57cec5SDimitry Andric   RegionBase<RegionTraits<MachineFunction>>(Entry, Exit, RI, DT, Parent) {}
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric MachineRegion::~MachineRegion() = default;
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
450b57cec5SDimitry Andric // MachineRegionInfo implementation
460b57cec5SDimitry Andric 
470b57cec5SDimitry Andric MachineRegionInfo::MachineRegionInfo() = default;
480b57cec5SDimitry Andric 
490b57cec5SDimitry Andric MachineRegionInfo::~MachineRegionInfo() = default;
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric void MachineRegionInfo::updateStatistics(MachineRegion *R) {
520b57cec5SDimitry Andric   ++numMachineRegions;
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric   // TODO: Slow. Should only be enabled if -stats is used.
550b57cec5SDimitry Andric   if (R->isSimple())
560b57cec5SDimitry Andric     ++numMachineSimpleRegions;
570b57cec5SDimitry Andric }
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric void MachineRegionInfo::recalculate(MachineFunction &F,
600b57cec5SDimitry Andric                                     MachineDominatorTree *DT_,
610b57cec5SDimitry Andric                                     MachinePostDominatorTree *PDT_,
620b57cec5SDimitry Andric                                     MachineDominanceFrontier *DF_) {
630b57cec5SDimitry Andric   DT = DT_;
640b57cec5SDimitry Andric   PDT = PDT_;
650b57cec5SDimitry Andric   DF = DF_;
660b57cec5SDimitry Andric 
670b57cec5SDimitry Andric   MachineBasicBlock *Entry = GraphTraits<MachineFunction*>::getEntryNode(&F);
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric   TopLevelRegion = new MachineRegion(Entry, nullptr, this, DT, nullptr);
700b57cec5SDimitry Andric   updateStatistics(TopLevelRegion);
710b57cec5SDimitry Andric   calculate(F);
720b57cec5SDimitry Andric }
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
750b57cec5SDimitry Andric // MachineRegionInfoPass implementation
760b57cec5SDimitry Andric //
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric MachineRegionInfoPass::MachineRegionInfoPass() : MachineFunctionPass(ID) {
790b57cec5SDimitry Andric   initializeMachineRegionInfoPassPass(*PassRegistry::getPassRegistry());
800b57cec5SDimitry Andric }
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric MachineRegionInfoPass::~MachineRegionInfoPass() = default;
830b57cec5SDimitry Andric 
840b57cec5SDimitry Andric bool MachineRegionInfoPass::runOnMachineFunction(MachineFunction &F) {
850b57cec5SDimitry Andric   releaseMemory();
860b57cec5SDimitry Andric 
87*0fca6ea1SDimitry Andric   auto DT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
88*0fca6ea1SDimitry Andric   auto PDT =
89*0fca6ea1SDimitry Andric       &getAnalysis<MachinePostDominatorTreeWrapperPass>().getPostDomTree();
900b57cec5SDimitry Andric   auto DF = &getAnalysis<MachineDominanceFrontier>();
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric   RI.recalculate(F, DT, PDT, DF);
930b57cec5SDimitry Andric 
940b57cec5SDimitry Andric   LLVM_DEBUG(RI.dump());
950b57cec5SDimitry Andric 
960b57cec5SDimitry Andric   return false;
970b57cec5SDimitry Andric }
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric void MachineRegionInfoPass::releaseMemory() {
1000b57cec5SDimitry Andric   RI.releaseMemory();
1010b57cec5SDimitry Andric }
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric void MachineRegionInfoPass::verifyAnalysis() const {
1040b57cec5SDimitry Andric   // Only do verification when user wants to, otherwise this expensive check
1050b57cec5SDimitry Andric   // will be invoked by PMDataManager::verifyPreservedAnalysis when
1060b57cec5SDimitry Andric   // a regionpass (marked PreservedAll) finish.
1070b57cec5SDimitry Andric   if (MachineRegionInfo::VerifyRegionInfo)
1080b57cec5SDimitry Andric     RI.verifyAnalysis();
1090b57cec5SDimitry Andric }
1100b57cec5SDimitry Andric 
1110b57cec5SDimitry Andric void MachineRegionInfoPass::getAnalysisUsage(AnalysisUsage &AU) const {
1120b57cec5SDimitry Andric   AU.setPreservesAll();
113*0fca6ea1SDimitry Andric   AU.addRequired<MachineDominatorTreeWrapperPass>();
114*0fca6ea1SDimitry Andric   AU.addRequired<MachinePostDominatorTreeWrapperPass>();
1150b57cec5SDimitry Andric   AU.addRequired<MachineDominanceFrontier>();
1160b57cec5SDimitry Andric   MachineFunctionPass::getAnalysisUsage(AU);
1170b57cec5SDimitry Andric }
1180b57cec5SDimitry Andric 
1190b57cec5SDimitry Andric void MachineRegionInfoPass::print(raw_ostream &OS, const Module *) const {
1200b57cec5SDimitry Andric   RI.print(OS);
1210b57cec5SDimitry Andric }
1220b57cec5SDimitry Andric 
1230b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1240b57cec5SDimitry Andric LLVM_DUMP_METHOD void MachineRegionInfoPass::dump() const {
1250b57cec5SDimitry Andric   RI.dump();
1260b57cec5SDimitry Andric }
1270b57cec5SDimitry Andric #endif
1280b57cec5SDimitry Andric 
1290b57cec5SDimitry Andric char MachineRegionInfoPass::ID = 0;
1300b57cec5SDimitry Andric char &MachineRegionInfoPassID = MachineRegionInfoPass::ID;
1310b57cec5SDimitry Andric 
1320b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(MachineRegionInfoPass, DEBUG_TYPE,
1330b57cec5SDimitry Andric                       "Detect single entry single exit regions", true, true)
134*0fca6ea1SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
135*0fca6ea1SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTreeWrapperPass)
1360b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineDominanceFrontier)
1370b57cec5SDimitry Andric INITIALIZE_PASS_END(MachineRegionInfoPass, DEBUG_TYPE,
1380b57cec5SDimitry Andric                     "Detect single entry single exit regions", true, true)
1390b57cec5SDimitry Andric 
1400b57cec5SDimitry Andric // Create methods available outside of this file, to use them
1410b57cec5SDimitry Andric // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
1420b57cec5SDimitry Andric // the link time optimization.
1430b57cec5SDimitry Andric 
1440b57cec5SDimitry Andric namespace llvm {
1450b57cec5SDimitry Andric 
1460b57cec5SDimitry Andric FunctionPass *createMachineRegionInfoPass() {
1470b57cec5SDimitry Andric   return new MachineRegionInfoPass();
1480b57cec5SDimitry Andric }
1490b57cec5SDimitry Andric 
1500b57cec5SDimitry Andric } // end namespace llvm
151