10b57cec5SDimitry Andric //===- PostDominators.cpp - Post-Dominator Calculation --------------------===//
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 // This file implements the post-dominator construction algorithms.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric #include "llvm/Analysis/PostDominators.h"
140b57cec5SDimitry Andric #include "llvm/IR/Function.h"
15*480093f4SDimitry Andric #include "llvm/IR/Instructions.h"
160b57cec5SDimitry Andric #include "llvm/IR/PassManager.h"
17*480093f4SDimitry Andric #include "llvm/InitializePasses.h"
180b57cec5SDimitry Andric #include "llvm/Pass.h"
190b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
200b57cec5SDimitry Andric
210b57cec5SDimitry Andric using namespace llvm;
220b57cec5SDimitry Andric
230b57cec5SDimitry Andric #define DEBUG_TYPE "postdomtree"
240b57cec5SDimitry Andric
250b57cec5SDimitry Andric #ifdef EXPENSIVE_CHECKS
260b57cec5SDimitry Andric static constexpr bool ExpensiveChecksEnabled = true;
270b57cec5SDimitry Andric #else
280b57cec5SDimitry Andric static constexpr bool ExpensiveChecksEnabled = false;
290b57cec5SDimitry Andric #endif
300b57cec5SDimitry Andric
310b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
320b57cec5SDimitry Andric // PostDominatorTree Implementation
330b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
340b57cec5SDimitry Andric
350b57cec5SDimitry Andric char PostDominatorTreeWrapperPass::ID = 0;
360b57cec5SDimitry Andric
PostDominatorTreeWrapperPass()37*480093f4SDimitry Andric PostDominatorTreeWrapperPass::PostDominatorTreeWrapperPass()
38*480093f4SDimitry Andric : FunctionPass(ID) {
39*480093f4SDimitry Andric initializePostDominatorTreeWrapperPassPass(*PassRegistry::getPassRegistry());
40*480093f4SDimitry Andric }
41*480093f4SDimitry Andric
420b57cec5SDimitry Andric INITIALIZE_PASS(PostDominatorTreeWrapperPass, "postdomtree",
430b57cec5SDimitry Andric "Post-Dominator Tree Construction", true, true)
440b57cec5SDimitry Andric
invalidate(Function & F,const PreservedAnalyses & PA,FunctionAnalysisManager::Invalidator &)450b57cec5SDimitry Andric bool PostDominatorTree::invalidate(Function &F, const PreservedAnalyses &PA,
460b57cec5SDimitry Andric FunctionAnalysisManager::Invalidator &) {
470b57cec5SDimitry Andric // Check whether the analysis, all analyses on functions, or the function's
480b57cec5SDimitry Andric // CFG have been preserved.
490b57cec5SDimitry Andric auto PAC = PA.getChecker<PostDominatorTreeAnalysis>();
500b57cec5SDimitry Andric return !(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>() ||
510b57cec5SDimitry Andric PAC.preservedSet<CFGAnalyses>());
520b57cec5SDimitry Andric }
530b57cec5SDimitry Andric
dominates(const Instruction * I1,const Instruction * I2) const54*480093f4SDimitry Andric bool PostDominatorTree::dominates(const Instruction *I1,
55*480093f4SDimitry Andric const Instruction *I2) const {
56*480093f4SDimitry Andric assert(I1 && I2 && "Expecting valid I1 and I2");
57*480093f4SDimitry Andric
58*480093f4SDimitry Andric const BasicBlock *BB1 = I1->getParent();
59*480093f4SDimitry Andric const BasicBlock *BB2 = I2->getParent();
60*480093f4SDimitry Andric
61*480093f4SDimitry Andric if (BB1 != BB2)
62*480093f4SDimitry Andric return Base::dominates(BB1, BB2);
63*480093f4SDimitry Andric
64*480093f4SDimitry Andric // PHINodes in a block are unordered.
65*480093f4SDimitry Andric if (isa<PHINode>(I1) && isa<PHINode>(I2))
66*480093f4SDimitry Andric return false;
67*480093f4SDimitry Andric
68*480093f4SDimitry Andric // Loop through the basic block until we find I1 or I2.
69*480093f4SDimitry Andric BasicBlock::const_iterator I = BB1->begin();
70*480093f4SDimitry Andric for (; &*I != I1 && &*I != I2; ++I)
71*480093f4SDimitry Andric /*empty*/;
72*480093f4SDimitry Andric
73*480093f4SDimitry Andric return &*I == I2;
74*480093f4SDimitry Andric }
75*480093f4SDimitry Andric
runOnFunction(Function & F)760b57cec5SDimitry Andric bool PostDominatorTreeWrapperPass::runOnFunction(Function &F) {
770b57cec5SDimitry Andric DT.recalculate(F);
780b57cec5SDimitry Andric return false;
790b57cec5SDimitry Andric }
800b57cec5SDimitry Andric
verifyAnalysis() const810b57cec5SDimitry Andric void PostDominatorTreeWrapperPass::verifyAnalysis() const {
820b57cec5SDimitry Andric if (VerifyDomInfo)
830b57cec5SDimitry Andric assert(DT.verify(PostDominatorTree::VerificationLevel::Full));
840b57cec5SDimitry Andric else if (ExpensiveChecksEnabled)
850b57cec5SDimitry Andric assert(DT.verify(PostDominatorTree::VerificationLevel::Basic));
860b57cec5SDimitry Andric }
870b57cec5SDimitry Andric
print(raw_ostream & OS,const Module *) const880b57cec5SDimitry Andric void PostDominatorTreeWrapperPass::print(raw_ostream &OS, const Module *) const {
890b57cec5SDimitry Andric DT.print(OS);
900b57cec5SDimitry Andric }
910b57cec5SDimitry Andric
createPostDomTree()920b57cec5SDimitry Andric FunctionPass* llvm::createPostDomTree() {
930b57cec5SDimitry Andric return new PostDominatorTreeWrapperPass();
940b57cec5SDimitry Andric }
950b57cec5SDimitry Andric
960b57cec5SDimitry Andric AnalysisKey PostDominatorTreeAnalysis::Key;
970b57cec5SDimitry Andric
run(Function & F,FunctionAnalysisManager &)980b57cec5SDimitry Andric PostDominatorTree PostDominatorTreeAnalysis::run(Function &F,
990b57cec5SDimitry Andric FunctionAnalysisManager &) {
1000b57cec5SDimitry Andric PostDominatorTree PDT(F);
1010b57cec5SDimitry Andric return PDT;
1020b57cec5SDimitry Andric }
1030b57cec5SDimitry Andric
PostDominatorTreePrinterPass(raw_ostream & OS)1040b57cec5SDimitry Andric PostDominatorTreePrinterPass::PostDominatorTreePrinterPass(raw_ostream &OS)
1050b57cec5SDimitry Andric : OS(OS) {}
1060b57cec5SDimitry Andric
1070b57cec5SDimitry Andric PreservedAnalyses
run(Function & F,FunctionAnalysisManager & AM)1080b57cec5SDimitry Andric PostDominatorTreePrinterPass::run(Function &F, FunctionAnalysisManager &AM) {
1090b57cec5SDimitry Andric OS << "PostDominatorTree for function: " << F.getName() << "\n";
1100b57cec5SDimitry Andric AM.getResult<PostDominatorTreeAnalysis>(F).print(OS);
1110b57cec5SDimitry Andric
1120b57cec5SDimitry Andric return PreservedAnalyses::all();
1130b57cec5SDimitry Andric }
114