1d43023a8SChris Lattner //===- PostDominators.cpp - Post-Dominator Calculation --------------------===//
2081aabc3SChris Lattner //
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
6482202a6SJohn Criswell //
7482202a6SJohn Criswell //===----------------------------------------------------------------------===//
8482202a6SJohn Criswell //
9d43023a8SChris Lattner // This file implements the post-dominator construction algorithms.
10081aabc3SChris Lattner //
11081aabc3SChris Lattner //===----------------------------------------------------------------------===//
12081aabc3SChris Lattner
13c86203acSChris Lattner #include "llvm/Analysis/PostDominators.h"
14bb1b2d09SEugene Zelenko #include "llvm/IR/Function.h"
15*ae8a8c2dSTsang Whitney W.H #include "llvm/IR/Instructions.h"
163f978407SHongbin Zheng #include "llvm/IR/PassManager.h"
1705da2fe5SReid Kleckner #include "llvm/InitializePasses.h"
18bb1b2d09SEugene Zelenko #include "llvm/Pass.h"
19bb1b2d09SEugene Zelenko #include "llvm/Support/raw_ostream.h"
20bb1b2d09SEugene Zelenko
21f9f7c2d3SChris Lattner using namespace llvm;
22960707c3SBrian Gaeke
23f1221bd0SChandler Carruth #define DEBUG_TYPE "postdomtree"
24f1221bd0SChandler Carruth
257c35de12SDavid Green #ifdef EXPENSIVE_CHECKS
267c35de12SDavid Green static constexpr bool ExpensiveChecksEnabled = true;
277c35de12SDavid Green #else
287c35de12SDavid Green static constexpr bool ExpensiveChecksEnabled = false;
297c35de12SDavid Green #endif
307c35de12SDavid Green
31c385bebcSChris Lattner //===----------------------------------------------------------------------===//
32f35a1dbcSOwen Anderson // PostDominatorTree Implementation
33d5811b96SNate Begeman //===----------------------------------------------------------------------===//
34d5811b96SNate Begeman
353f978407SHongbin Zheng char PostDominatorTreeWrapperPass::ID = 0;
36bb1b2d09SEugene Zelenko
PostDominatorTreeWrapperPass()3705da2fe5SReid Kleckner PostDominatorTreeWrapperPass::PostDominatorTreeWrapperPass()
3805da2fe5SReid Kleckner : FunctionPass(ID) {
3905da2fe5SReid Kleckner initializePostDominatorTreeWrapperPassPass(*PassRegistry::getPassRegistry());
4005da2fe5SReid Kleckner }
4105da2fe5SReid Kleckner
423f978407SHongbin Zheng INITIALIZE_PASS(PostDominatorTreeWrapperPass, "postdomtree",
43df7a4f25SOwen Anderson "Post-Dominator Tree Construction", true, true)
44d5811b96SNate Begeman
invalidate(Function & F,const PreservedAnalyses & PA,FunctionAnalysisManager::Invalidator &)45ca68a3ecSChandler Carruth bool PostDominatorTree::invalidate(Function &F, const PreservedAnalyses &PA,
46ca68a3ecSChandler Carruth FunctionAnalysisManager::Invalidator &) {
47ca68a3ecSChandler Carruth // Check whether the analysis, all analyses on functions, or the function's
48ca68a3ecSChandler Carruth // CFG have been preserved.
49ca68a3ecSChandler Carruth auto PAC = PA.getChecker<PostDominatorTreeAnalysis>();
50ca68a3ecSChandler Carruth return !(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>() ||
51ca68a3ecSChandler Carruth PAC.preservedSet<CFGAnalyses>());
52ca68a3ecSChandler Carruth }
53ca68a3ecSChandler Carruth
dominates(const Instruction * I1,const Instruction * I2) const54*ae8a8c2dSTsang Whitney W.H bool PostDominatorTree::dominates(const Instruction *I1,
55*ae8a8c2dSTsang Whitney W.H const Instruction *I2) const {
56*ae8a8c2dSTsang Whitney W.H assert(I1 && I2 && "Expecting valid I1 and I2");
57*ae8a8c2dSTsang Whitney W.H
58*ae8a8c2dSTsang Whitney W.H const BasicBlock *BB1 = I1->getParent();
59*ae8a8c2dSTsang Whitney W.H const BasicBlock *BB2 = I2->getParent();
60*ae8a8c2dSTsang Whitney W.H
61*ae8a8c2dSTsang Whitney W.H if (BB1 != BB2)
62*ae8a8c2dSTsang Whitney W.H return Base::dominates(BB1, BB2);
63*ae8a8c2dSTsang Whitney W.H
64*ae8a8c2dSTsang Whitney W.H // PHINodes in a block are unordered.
65*ae8a8c2dSTsang Whitney W.H if (isa<PHINode>(I1) && isa<PHINode>(I2))
66*ae8a8c2dSTsang Whitney W.H return false;
67*ae8a8c2dSTsang Whitney W.H
68*ae8a8c2dSTsang Whitney W.H // Loop through the basic block until we find I1 or I2.
69*ae8a8c2dSTsang Whitney W.H BasicBlock::const_iterator I = BB1->begin();
70*ae8a8c2dSTsang Whitney W.H for (; &*I != I1 && &*I != I2; ++I)
71*ae8a8c2dSTsang Whitney W.H /*empty*/;
72*ae8a8c2dSTsang Whitney W.H
73*ae8a8c2dSTsang Whitney W.H return &*I == I2;
74*ae8a8c2dSTsang Whitney W.H }
75*ae8a8c2dSTsang Whitney W.H
runOnFunction(Function & F)763f978407SHongbin Zheng bool PostDominatorTreeWrapperPass::runOnFunction(Function &F) {
773f978407SHongbin Zheng DT.recalculate(F);
78b60f2549SOwen Anderson return false;
79b60f2549SOwen Anderson }
80b60f2549SOwen Anderson
verifyAnalysis() const817c35de12SDavid Green void PostDominatorTreeWrapperPass::verifyAnalysis() const {
827c35de12SDavid Green if (VerifyDomInfo)
837c35de12SDavid Green assert(DT.verify(PostDominatorTree::VerificationLevel::Full));
847c35de12SDavid Green else if (ExpensiveChecksEnabled)
857c35de12SDavid Green assert(DT.verify(PostDominatorTree::VerificationLevel::Basic));
867c35de12SDavid Green }
877c35de12SDavid Green
print(raw_ostream & OS,const Module *) const883f978407SHongbin Zheng void PostDominatorTreeWrapperPass::print(raw_ostream &OS, const Module *) const {
893f978407SHongbin Zheng DT.print(OS);
902a45575cSTorok Edwin }
912a45575cSTorok Edwin
createPostDomTree()92b1ba352eSOwen Anderson FunctionPass* llvm::createPostDomTree() {
933f978407SHongbin Zheng return new PostDominatorTreeWrapperPass();
94b1ba352eSOwen Anderson }
95b1ba352eSOwen Anderson
96dab4eae2SChandler Carruth AnalysisKey PostDominatorTreeAnalysis::Key;
97df0cd726SNAKAMURA Takumi
run(Function & F,FunctionAnalysisManager &)98164a2aa6SChandler Carruth PostDominatorTree PostDominatorTreeAnalysis::run(Function &F,
99164a2aa6SChandler Carruth FunctionAnalysisManager &) {
100ef33edd9SJakub Kuderski PostDominatorTree PDT(F);
1013f978407SHongbin Zheng return PDT;
1023f978407SHongbin Zheng }
1033f978407SHongbin Zheng
PostDominatorTreePrinterPass(raw_ostream & OS)1043f978407SHongbin Zheng PostDominatorTreePrinterPass::PostDominatorTreePrinterPass(raw_ostream &OS)
1053f978407SHongbin Zheng : OS(OS) {}
1063f978407SHongbin Zheng
1073f978407SHongbin Zheng PreservedAnalyses
run(Function & F,FunctionAnalysisManager & AM)108b47f8010SChandler Carruth PostDominatorTreePrinterPass::run(Function &F, FunctionAnalysisManager &AM) {
1093f978407SHongbin Zheng OS << "PostDominatorTree for function: " << F.getName() << "\n";
110b47f8010SChandler Carruth AM.getResult<PostDominatorTreeAnalysis>(F).print(OS);
1113f978407SHongbin Zheng
1123f978407SHongbin Zheng return PreservedAnalyses::all();
1133f978407SHongbin Zheng }
114