106f32e7eSjoerg //===- RegionInfo.cpp - SESE region detection analysis --------------------===//
206f32e7eSjoerg //
306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information.
506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606f32e7eSjoerg //
706f32e7eSjoerg //===----------------------------------------------------------------------===//
806f32e7eSjoerg // Detects single entry single exit regions in the control flow graph.
906f32e7eSjoerg //===----------------------------------------------------------------------===//
1006f32e7eSjoerg 
1106f32e7eSjoerg #include "llvm/Analysis/RegionInfo.h"
1206f32e7eSjoerg #include "llvm/ADT/Statistic.h"
13*da58b97aSjoerg #include "llvm/InitializePasses.h"
1406f32e7eSjoerg #ifndef NDEBUG
1506f32e7eSjoerg #include "llvm/Analysis/RegionPrinter.h"
1606f32e7eSjoerg #endif
1706f32e7eSjoerg #include "llvm/Analysis/RegionInfoImpl.h"
1806f32e7eSjoerg #include "llvm/Config/llvm-config.h"
1906f32e7eSjoerg #include "llvm/IR/Function.h"
2006f32e7eSjoerg #include "llvm/Support/CommandLine.h"
2106f32e7eSjoerg #include "llvm/Support/Compiler.h"
2206f32e7eSjoerg 
2306f32e7eSjoerg using namespace llvm;
2406f32e7eSjoerg 
2506f32e7eSjoerg #define DEBUG_TYPE "region"
2606f32e7eSjoerg 
2706f32e7eSjoerg namespace llvm {
2806f32e7eSjoerg 
2906f32e7eSjoerg template class RegionBase<RegionTraits<Function>>;
3006f32e7eSjoerg template class RegionNodeBase<RegionTraits<Function>>;
3106f32e7eSjoerg template class RegionInfoBase<RegionTraits<Function>>;
3206f32e7eSjoerg 
3306f32e7eSjoerg } // end namespace llvm
3406f32e7eSjoerg 
3506f32e7eSjoerg STATISTIC(numRegions,       "The # of regions");
3606f32e7eSjoerg STATISTIC(numSimpleRegions, "The # of simple regions");
3706f32e7eSjoerg 
3806f32e7eSjoerg // Always verify if expensive checking is enabled.
3906f32e7eSjoerg 
4006f32e7eSjoerg static cl::opt<bool,true>
4106f32e7eSjoerg VerifyRegionInfoX(
4206f32e7eSjoerg   "verify-region-info",
4306f32e7eSjoerg   cl::location(RegionInfoBase<RegionTraits<Function>>::VerifyRegionInfo),
4406f32e7eSjoerg   cl::desc("Verify region info (time consuming)"));
4506f32e7eSjoerg 
4606f32e7eSjoerg static cl::opt<Region::PrintStyle, true> printStyleX("print-region-style",
4706f32e7eSjoerg   cl::location(RegionInfo::printStyle),
4806f32e7eSjoerg   cl::Hidden,
4906f32e7eSjoerg   cl::desc("style of printing regions"),
5006f32e7eSjoerg   cl::values(
5106f32e7eSjoerg     clEnumValN(Region::PrintNone, "none",  "print no details"),
5206f32e7eSjoerg     clEnumValN(Region::PrintBB, "bb",
5306f32e7eSjoerg                "print regions in detail with block_iterator"),
5406f32e7eSjoerg     clEnumValN(Region::PrintRN, "rn",
5506f32e7eSjoerg                "print regions in detail with element_iterator")));
5606f32e7eSjoerg 
5706f32e7eSjoerg //===----------------------------------------------------------------------===//
5806f32e7eSjoerg // Region implementation
5906f32e7eSjoerg //
6006f32e7eSjoerg 
Region(BasicBlock * Entry,BasicBlock * Exit,RegionInfo * RI,DominatorTree * DT,Region * Parent)6106f32e7eSjoerg Region::Region(BasicBlock *Entry, BasicBlock *Exit,
6206f32e7eSjoerg                RegionInfo* RI,
6306f32e7eSjoerg                DominatorTree *DT, Region *Parent) :
6406f32e7eSjoerg   RegionBase<RegionTraits<Function>>(Entry, Exit, RI, DT, Parent) {
6506f32e7eSjoerg 
6606f32e7eSjoerg }
6706f32e7eSjoerg 
6806f32e7eSjoerg Region::~Region() = default;
6906f32e7eSjoerg 
7006f32e7eSjoerg //===----------------------------------------------------------------------===//
7106f32e7eSjoerg // RegionInfo implementation
7206f32e7eSjoerg //
7306f32e7eSjoerg 
7406f32e7eSjoerg RegionInfo::RegionInfo() = default;
7506f32e7eSjoerg 
7606f32e7eSjoerg RegionInfo::~RegionInfo() = default;
7706f32e7eSjoerg 
invalidate(Function & F,const PreservedAnalyses & PA,FunctionAnalysisManager::Invalidator &)7806f32e7eSjoerg bool RegionInfo::invalidate(Function &F, const PreservedAnalyses &PA,
7906f32e7eSjoerg                             FunctionAnalysisManager::Invalidator &) {
8006f32e7eSjoerg   // Check whether the analysis, all analyses on functions, or the function's
8106f32e7eSjoerg   // CFG has been preserved.
8206f32e7eSjoerg   auto PAC = PA.getChecker<RegionInfoAnalysis>();
8306f32e7eSjoerg   return !(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>() ||
8406f32e7eSjoerg            PAC.preservedSet<CFGAnalyses>());
8506f32e7eSjoerg }
8606f32e7eSjoerg 
updateStatistics(Region * R)8706f32e7eSjoerg void RegionInfo::updateStatistics(Region *R) {
8806f32e7eSjoerg   ++numRegions;
8906f32e7eSjoerg 
9006f32e7eSjoerg   // TODO: Slow. Should only be enabled if -stats is used.
9106f32e7eSjoerg   if (R->isSimple())
9206f32e7eSjoerg     ++numSimpleRegions;
9306f32e7eSjoerg }
9406f32e7eSjoerg 
recalculate(Function & F,DominatorTree * DT_,PostDominatorTree * PDT_,DominanceFrontier * DF_)9506f32e7eSjoerg void RegionInfo::recalculate(Function &F, DominatorTree *DT_,
9606f32e7eSjoerg                              PostDominatorTree *PDT_, DominanceFrontier *DF_) {
9706f32e7eSjoerg   DT = DT_;
9806f32e7eSjoerg   PDT = PDT_;
9906f32e7eSjoerg   DF = DF_;
10006f32e7eSjoerg 
10106f32e7eSjoerg   TopLevelRegion = new Region(&F.getEntryBlock(), nullptr,
10206f32e7eSjoerg                               this, DT, nullptr);
10306f32e7eSjoerg   updateStatistics(TopLevelRegion);
10406f32e7eSjoerg   calculate(F);
10506f32e7eSjoerg }
10606f32e7eSjoerg 
10706f32e7eSjoerg #ifndef NDEBUG
view()10806f32e7eSjoerg void RegionInfo::view() { viewRegion(this); }
10906f32e7eSjoerg 
viewOnly()11006f32e7eSjoerg void RegionInfo::viewOnly() { viewRegionOnly(this); }
11106f32e7eSjoerg #endif
11206f32e7eSjoerg 
11306f32e7eSjoerg //===----------------------------------------------------------------------===//
11406f32e7eSjoerg // RegionInfoPass implementation
11506f32e7eSjoerg //
11606f32e7eSjoerg 
RegionInfoPass()11706f32e7eSjoerg RegionInfoPass::RegionInfoPass() : FunctionPass(ID) {
11806f32e7eSjoerg   initializeRegionInfoPassPass(*PassRegistry::getPassRegistry());
11906f32e7eSjoerg }
12006f32e7eSjoerg 
12106f32e7eSjoerg RegionInfoPass::~RegionInfoPass() = default;
12206f32e7eSjoerg 
runOnFunction(Function & F)12306f32e7eSjoerg bool RegionInfoPass::runOnFunction(Function &F) {
12406f32e7eSjoerg   releaseMemory();
12506f32e7eSjoerg 
12606f32e7eSjoerg   auto DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
12706f32e7eSjoerg   auto PDT = &getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree();
12806f32e7eSjoerg   auto DF = &getAnalysis<DominanceFrontierWrapperPass>().getDominanceFrontier();
12906f32e7eSjoerg 
13006f32e7eSjoerg   RI.recalculate(F, DT, PDT, DF);
13106f32e7eSjoerg   return false;
13206f32e7eSjoerg }
13306f32e7eSjoerg 
releaseMemory()13406f32e7eSjoerg void RegionInfoPass::releaseMemory() {
13506f32e7eSjoerg   RI.releaseMemory();
13606f32e7eSjoerg }
13706f32e7eSjoerg 
verifyAnalysis() const13806f32e7eSjoerg void RegionInfoPass::verifyAnalysis() const {
13906f32e7eSjoerg     RI.verifyAnalysis();
14006f32e7eSjoerg }
14106f32e7eSjoerg 
getAnalysisUsage(AnalysisUsage & AU) const14206f32e7eSjoerg void RegionInfoPass::getAnalysisUsage(AnalysisUsage &AU) const {
14306f32e7eSjoerg   AU.setPreservesAll();
14406f32e7eSjoerg   AU.addRequiredTransitive<DominatorTreeWrapperPass>();
14506f32e7eSjoerg   AU.addRequired<PostDominatorTreeWrapperPass>();
14606f32e7eSjoerg   AU.addRequired<DominanceFrontierWrapperPass>();
14706f32e7eSjoerg }
14806f32e7eSjoerg 
print(raw_ostream & OS,const Module *) const14906f32e7eSjoerg void RegionInfoPass::print(raw_ostream &OS, const Module *) const {
15006f32e7eSjoerg   RI.print(OS);
15106f32e7eSjoerg }
15206f32e7eSjoerg 
15306f32e7eSjoerg #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const15406f32e7eSjoerg LLVM_DUMP_METHOD void RegionInfoPass::dump() const {
15506f32e7eSjoerg   RI.dump();
15606f32e7eSjoerg }
15706f32e7eSjoerg #endif
15806f32e7eSjoerg 
15906f32e7eSjoerg char RegionInfoPass::ID = 0;
16006f32e7eSjoerg 
16106f32e7eSjoerg INITIALIZE_PASS_BEGIN(RegionInfoPass, "regions",
16206f32e7eSjoerg                 "Detect single entry single exit regions", true, true)
16306f32e7eSjoerg INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
16406f32e7eSjoerg INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass)
16506f32e7eSjoerg INITIALIZE_PASS_DEPENDENCY(DominanceFrontierWrapperPass)
16606f32e7eSjoerg INITIALIZE_PASS_END(RegionInfoPass, "regions",
16706f32e7eSjoerg                 "Detect single entry single exit regions", true, true)
16806f32e7eSjoerg 
16906f32e7eSjoerg // Create methods available outside of this file, to use them
17006f32e7eSjoerg // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
17106f32e7eSjoerg // the link time optimization.
17206f32e7eSjoerg 
17306f32e7eSjoerg namespace llvm {
17406f32e7eSjoerg 
createRegionInfoPass()17506f32e7eSjoerg   FunctionPass *createRegionInfoPass() {
17606f32e7eSjoerg     return new RegionInfoPass();
17706f32e7eSjoerg   }
17806f32e7eSjoerg 
17906f32e7eSjoerg } // end namespace llvm
18006f32e7eSjoerg 
18106f32e7eSjoerg //===----------------------------------------------------------------------===//
18206f32e7eSjoerg // RegionInfoAnalysis implementation
18306f32e7eSjoerg //
18406f32e7eSjoerg 
18506f32e7eSjoerg AnalysisKey RegionInfoAnalysis::Key;
18606f32e7eSjoerg 
run(Function & F,FunctionAnalysisManager & AM)18706f32e7eSjoerg RegionInfo RegionInfoAnalysis::run(Function &F, FunctionAnalysisManager &AM) {
18806f32e7eSjoerg   RegionInfo RI;
18906f32e7eSjoerg   auto *DT = &AM.getResult<DominatorTreeAnalysis>(F);
19006f32e7eSjoerg   auto *PDT = &AM.getResult<PostDominatorTreeAnalysis>(F);
19106f32e7eSjoerg   auto *DF = &AM.getResult<DominanceFrontierAnalysis>(F);
19206f32e7eSjoerg 
19306f32e7eSjoerg   RI.recalculate(F, DT, PDT, DF);
19406f32e7eSjoerg   return RI;
19506f32e7eSjoerg }
19606f32e7eSjoerg 
RegionInfoPrinterPass(raw_ostream & OS)19706f32e7eSjoerg RegionInfoPrinterPass::RegionInfoPrinterPass(raw_ostream &OS)
19806f32e7eSjoerg   : OS(OS) {}
19906f32e7eSjoerg 
run(Function & F,FunctionAnalysisManager & AM)20006f32e7eSjoerg PreservedAnalyses RegionInfoPrinterPass::run(Function &F,
20106f32e7eSjoerg                                              FunctionAnalysisManager &AM) {
20206f32e7eSjoerg   OS << "Region Tree for function: " << F.getName() << "\n";
20306f32e7eSjoerg   AM.getResult<RegionInfoAnalysis>(F).print(OS);
20406f32e7eSjoerg 
20506f32e7eSjoerg   return PreservedAnalyses::all();
20606f32e7eSjoerg }
20706f32e7eSjoerg 
run(Function & F,FunctionAnalysisManager & AM)20806f32e7eSjoerg PreservedAnalyses RegionInfoVerifierPass::run(Function &F,
20906f32e7eSjoerg                                               FunctionAnalysisManager &AM) {
21006f32e7eSjoerg   AM.getResult<RegionInfoAnalysis>(F).verifyAnalysis();
21106f32e7eSjoerg 
21206f32e7eSjoerg   return PreservedAnalyses::all();
21306f32e7eSjoerg }
214