xref: /freebsd-src/contrib/llvm-project/llvm/lib/Analysis/RegionInfo.cpp (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
10b57cec5SDimitry Andric //===- RegionInfo.cpp - SESE region detection analysis --------------------===//
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 // Detects single entry single exit regions in the control flow graph.
90b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
100b57cec5SDimitry Andric 
110b57cec5SDimitry Andric #include "llvm/Analysis/RegionInfo.h"
120b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
13*81ad6265SDimitry Andric #include "llvm/Analysis/DominanceFrontier.h"
14480093f4SDimitry Andric #include "llvm/InitializePasses.h"
150b57cec5SDimitry Andric #ifndef NDEBUG
160b57cec5SDimitry Andric #include "llvm/Analysis/RegionPrinter.h"
170b57cec5SDimitry Andric #endif
180b57cec5SDimitry Andric #include "llvm/Analysis/RegionInfoImpl.h"
190b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h"
200b57cec5SDimitry Andric #include "llvm/IR/Function.h"
210b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
220b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric using namespace llvm;
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric #define DEBUG_TYPE "region"
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric namespace llvm {
290b57cec5SDimitry Andric 
300b57cec5SDimitry Andric template class RegionBase<RegionTraits<Function>>;
310b57cec5SDimitry Andric template class RegionNodeBase<RegionTraits<Function>>;
320b57cec5SDimitry Andric template class RegionInfoBase<RegionTraits<Function>>;
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric } // end namespace llvm
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric STATISTIC(numRegions,       "The # of regions");
370b57cec5SDimitry Andric STATISTIC(numSimpleRegions, "The # of simple regions");
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric // Always verify if expensive checking is enabled.
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric static cl::opt<bool,true>
420b57cec5SDimitry Andric VerifyRegionInfoX(
430b57cec5SDimitry Andric   "verify-region-info",
440b57cec5SDimitry Andric   cl::location(RegionInfoBase<RegionTraits<Function>>::VerifyRegionInfo),
450b57cec5SDimitry Andric   cl::desc("Verify region info (time consuming)"));
460b57cec5SDimitry Andric 
470b57cec5SDimitry Andric static cl::opt<Region::PrintStyle, true> printStyleX("print-region-style",
480b57cec5SDimitry Andric   cl::location(RegionInfo::printStyle),
490b57cec5SDimitry Andric   cl::Hidden,
500b57cec5SDimitry Andric   cl::desc("style of printing regions"),
510b57cec5SDimitry Andric   cl::values(
520b57cec5SDimitry Andric     clEnumValN(Region::PrintNone, "none",  "print no details"),
530b57cec5SDimitry Andric     clEnumValN(Region::PrintBB, "bb",
540b57cec5SDimitry Andric                "print regions in detail with block_iterator"),
550b57cec5SDimitry Andric     clEnumValN(Region::PrintRN, "rn",
560b57cec5SDimitry Andric                "print regions in detail with element_iterator")));
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
590b57cec5SDimitry Andric // Region implementation
600b57cec5SDimitry Andric //
610b57cec5SDimitry Andric 
Region(BasicBlock * Entry,BasicBlock * Exit,RegionInfo * RI,DominatorTree * DT,Region * Parent)620b57cec5SDimitry Andric Region::Region(BasicBlock *Entry, BasicBlock *Exit,
630b57cec5SDimitry Andric                RegionInfo* RI,
640b57cec5SDimitry Andric                DominatorTree *DT, Region *Parent) :
650b57cec5SDimitry Andric   RegionBase<RegionTraits<Function>>(Entry, Exit, RI, DT, Parent) {
660b57cec5SDimitry Andric 
670b57cec5SDimitry Andric }
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric Region::~Region() = default;
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
720b57cec5SDimitry Andric // RegionInfo implementation
730b57cec5SDimitry Andric //
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric RegionInfo::RegionInfo() = default;
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric RegionInfo::~RegionInfo() = default;
780b57cec5SDimitry Andric 
invalidate(Function & F,const PreservedAnalyses & PA,FunctionAnalysisManager::Invalidator &)790b57cec5SDimitry Andric bool RegionInfo::invalidate(Function &F, const PreservedAnalyses &PA,
800b57cec5SDimitry Andric                             FunctionAnalysisManager::Invalidator &) {
810b57cec5SDimitry Andric   // Check whether the analysis, all analyses on functions, or the function's
820b57cec5SDimitry Andric   // CFG has been preserved.
830b57cec5SDimitry Andric   auto PAC = PA.getChecker<RegionInfoAnalysis>();
840b57cec5SDimitry Andric   return !(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>() ||
850b57cec5SDimitry Andric            PAC.preservedSet<CFGAnalyses>());
860b57cec5SDimitry Andric }
870b57cec5SDimitry Andric 
updateStatistics(Region * R)880b57cec5SDimitry Andric void RegionInfo::updateStatistics(Region *R) {
890b57cec5SDimitry Andric   ++numRegions;
900b57cec5SDimitry Andric 
910b57cec5SDimitry Andric   // TODO: Slow. Should only be enabled if -stats is used.
920b57cec5SDimitry Andric   if (R->isSimple())
930b57cec5SDimitry Andric     ++numSimpleRegions;
940b57cec5SDimitry Andric }
950b57cec5SDimitry Andric 
recalculate(Function & F,DominatorTree * DT_,PostDominatorTree * PDT_,DominanceFrontier * DF_)960b57cec5SDimitry Andric void RegionInfo::recalculate(Function &F, DominatorTree *DT_,
970b57cec5SDimitry Andric                              PostDominatorTree *PDT_, DominanceFrontier *DF_) {
980b57cec5SDimitry Andric   DT = DT_;
990b57cec5SDimitry Andric   PDT = PDT_;
1000b57cec5SDimitry Andric   DF = DF_;
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric   TopLevelRegion = new Region(&F.getEntryBlock(), nullptr,
1030b57cec5SDimitry Andric                               this, DT, nullptr);
1040b57cec5SDimitry Andric   updateStatistics(TopLevelRegion);
1050b57cec5SDimitry Andric   calculate(F);
1060b57cec5SDimitry Andric }
1070b57cec5SDimitry Andric 
1080b57cec5SDimitry Andric #ifndef NDEBUG
view()1090b57cec5SDimitry Andric void RegionInfo::view() { viewRegion(this); }
1100b57cec5SDimitry Andric 
viewOnly()1110b57cec5SDimitry Andric void RegionInfo::viewOnly() { viewRegionOnly(this); }
1120b57cec5SDimitry Andric #endif
1130b57cec5SDimitry Andric 
1140b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1150b57cec5SDimitry Andric // RegionInfoPass implementation
1160b57cec5SDimitry Andric //
1170b57cec5SDimitry Andric 
RegionInfoPass()1180b57cec5SDimitry Andric RegionInfoPass::RegionInfoPass() : FunctionPass(ID) {
1190b57cec5SDimitry Andric   initializeRegionInfoPassPass(*PassRegistry::getPassRegistry());
1200b57cec5SDimitry Andric }
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric RegionInfoPass::~RegionInfoPass() = default;
1230b57cec5SDimitry Andric 
runOnFunction(Function & F)1240b57cec5SDimitry Andric bool RegionInfoPass::runOnFunction(Function &F) {
1250b57cec5SDimitry Andric   releaseMemory();
1260b57cec5SDimitry Andric 
1270b57cec5SDimitry Andric   auto DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
1280b57cec5SDimitry Andric   auto PDT = &getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree();
1290b57cec5SDimitry Andric   auto DF = &getAnalysis<DominanceFrontierWrapperPass>().getDominanceFrontier();
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric   RI.recalculate(F, DT, PDT, DF);
1320b57cec5SDimitry Andric   return false;
1330b57cec5SDimitry Andric }
1340b57cec5SDimitry Andric 
releaseMemory()1350b57cec5SDimitry Andric void RegionInfoPass::releaseMemory() {
1360b57cec5SDimitry Andric   RI.releaseMemory();
1370b57cec5SDimitry Andric }
1380b57cec5SDimitry Andric 
verifyAnalysis() const1390b57cec5SDimitry Andric void RegionInfoPass::verifyAnalysis() const {
1400b57cec5SDimitry Andric     RI.verifyAnalysis();
1410b57cec5SDimitry Andric }
1420b57cec5SDimitry Andric 
getAnalysisUsage(AnalysisUsage & AU) const1430b57cec5SDimitry Andric void RegionInfoPass::getAnalysisUsage(AnalysisUsage &AU) const {
1440b57cec5SDimitry Andric   AU.setPreservesAll();
1450b57cec5SDimitry Andric   AU.addRequiredTransitive<DominatorTreeWrapperPass>();
1460b57cec5SDimitry Andric   AU.addRequired<PostDominatorTreeWrapperPass>();
1470b57cec5SDimitry Andric   AU.addRequired<DominanceFrontierWrapperPass>();
1480b57cec5SDimitry Andric }
1490b57cec5SDimitry Andric 
print(raw_ostream & OS,const Module *) const1500b57cec5SDimitry Andric void RegionInfoPass::print(raw_ostream &OS, const Module *) const {
1510b57cec5SDimitry Andric   RI.print(OS);
1520b57cec5SDimitry Andric }
1530b57cec5SDimitry Andric 
1540b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const1550b57cec5SDimitry Andric LLVM_DUMP_METHOD void RegionInfoPass::dump() const {
1560b57cec5SDimitry Andric   RI.dump();
1570b57cec5SDimitry Andric }
1580b57cec5SDimitry Andric #endif
1590b57cec5SDimitry Andric 
1600b57cec5SDimitry Andric char RegionInfoPass::ID = 0;
1610b57cec5SDimitry Andric 
1620b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(RegionInfoPass, "regions",
1630b57cec5SDimitry Andric                 "Detect single entry single exit regions", true, true)
1640b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
1650b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass)
1660b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(DominanceFrontierWrapperPass)
1670b57cec5SDimitry Andric INITIALIZE_PASS_END(RegionInfoPass, "regions",
1680b57cec5SDimitry Andric                 "Detect single entry single exit regions", true, true)
1690b57cec5SDimitry Andric 
1700b57cec5SDimitry Andric // Create methods available outside of this file, to use them
1710b57cec5SDimitry Andric // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
1720b57cec5SDimitry Andric // the link time optimization.
1730b57cec5SDimitry Andric 
1740b57cec5SDimitry Andric namespace llvm {
1750b57cec5SDimitry Andric 
createRegionInfoPass()1760b57cec5SDimitry Andric   FunctionPass *createRegionInfoPass() {
1770b57cec5SDimitry Andric     return new RegionInfoPass();
1780b57cec5SDimitry Andric   }
1790b57cec5SDimitry Andric 
1800b57cec5SDimitry Andric } // end namespace llvm
1810b57cec5SDimitry Andric 
1820b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1830b57cec5SDimitry Andric // RegionInfoAnalysis implementation
1840b57cec5SDimitry Andric //
1850b57cec5SDimitry Andric 
1860b57cec5SDimitry Andric AnalysisKey RegionInfoAnalysis::Key;
1870b57cec5SDimitry Andric 
run(Function & F,FunctionAnalysisManager & AM)1880b57cec5SDimitry Andric RegionInfo RegionInfoAnalysis::run(Function &F, FunctionAnalysisManager &AM) {
1890b57cec5SDimitry Andric   RegionInfo RI;
1900b57cec5SDimitry Andric   auto *DT = &AM.getResult<DominatorTreeAnalysis>(F);
1910b57cec5SDimitry Andric   auto *PDT = &AM.getResult<PostDominatorTreeAnalysis>(F);
1920b57cec5SDimitry Andric   auto *DF = &AM.getResult<DominanceFrontierAnalysis>(F);
1930b57cec5SDimitry Andric 
1940b57cec5SDimitry Andric   RI.recalculate(F, DT, PDT, DF);
1950b57cec5SDimitry Andric   return RI;
1960b57cec5SDimitry Andric }
1970b57cec5SDimitry Andric 
RegionInfoPrinterPass(raw_ostream & OS)1980b57cec5SDimitry Andric RegionInfoPrinterPass::RegionInfoPrinterPass(raw_ostream &OS)
1990b57cec5SDimitry Andric   : OS(OS) {}
2000b57cec5SDimitry Andric 
run(Function & F,FunctionAnalysisManager & AM)2010b57cec5SDimitry Andric PreservedAnalyses RegionInfoPrinterPass::run(Function &F,
2020b57cec5SDimitry Andric                                              FunctionAnalysisManager &AM) {
2030b57cec5SDimitry Andric   OS << "Region Tree for function: " << F.getName() << "\n";
2040b57cec5SDimitry Andric   AM.getResult<RegionInfoAnalysis>(F).print(OS);
2050b57cec5SDimitry Andric 
2060b57cec5SDimitry Andric   return PreservedAnalyses::all();
2070b57cec5SDimitry Andric }
2080b57cec5SDimitry Andric 
run(Function & F,FunctionAnalysisManager & AM)2090b57cec5SDimitry Andric PreservedAnalyses RegionInfoVerifierPass::run(Function &F,
2100b57cec5SDimitry Andric                                               FunctionAnalysisManager &AM) {
2110b57cec5SDimitry Andric   AM.getResult<RegionInfoAnalysis>(F).verifyAnalysis();
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric   return PreservedAnalyses::all();
2140b57cec5SDimitry Andric }
215