1522600a2SDimitry Andric //===- MachinePostDominators.cpp -Machine Post Dominator Calculation ------===//
2522600a2SDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6522600a2SDimitry Andric //
7522600a2SDimitry Andric //===----------------------------------------------------------------------===//
8522600a2SDimitry Andric //
9522600a2SDimitry Andric // This file implements simple dominator construction algorithms for finding
10522600a2SDimitry Andric // post dominators on machine functions.
11522600a2SDimitry Andric //
12522600a2SDimitry Andric //===----------------------------------------------------------------------===//
13522600a2SDimitry Andric
14522600a2SDimitry Andric #include "llvm/CodeGen/MachinePostDominators.h"
15706b4fc4SDimitry Andric #include "llvm/InitializePasses.h"
16ac9a064cSDimitry Andric #include "llvm/Support/GenericDomTreeConstruction.h"
17522600a2SDimitry Andric
18522600a2SDimitry Andric using namespace llvm;
19522600a2SDimitry Andric
2093c91e39SDimitry Andric namespace llvm {
2193c91e39SDimitry Andric template class DominatorTreeBase<MachineBasicBlock, true>; // PostDomTreeBase
221d5ae102SDimitry Andric
23ac9a064cSDimitry Andric namespace DomTreeBuilder {
24ac9a064cSDimitry Andric
25ac9a064cSDimitry Andric template void Calculate<MBBPostDomTree>(MBBPostDomTree &DT);
26ac9a064cSDimitry Andric template void InsertEdge<MBBPostDomTree>(MBBPostDomTree &DT,
27ac9a064cSDimitry Andric MachineBasicBlock *From,
28ac9a064cSDimitry Andric MachineBasicBlock *To);
29ac9a064cSDimitry Andric template void DeleteEdge<MBBPostDomTree>(MBBPostDomTree &DT,
30ac9a064cSDimitry Andric MachineBasicBlock *From,
31ac9a064cSDimitry Andric MachineBasicBlock *To);
32ac9a064cSDimitry Andric template void ApplyUpdates<MBBPostDomTree>(MBBPostDomTree &DT,
33ac9a064cSDimitry Andric MBBPostDomTreeGraphDiff &,
34ac9a064cSDimitry Andric MBBPostDomTreeGraphDiff *);
35ac9a064cSDimitry Andric template bool Verify<MBBPostDomTree>(const MBBPostDomTree &DT,
36ac9a064cSDimitry Andric MBBPostDomTree::VerificationLevel VL);
37ac9a064cSDimitry Andric
38ac9a064cSDimitry Andric } // namespace DomTreeBuilder
391d5ae102SDimitry Andric extern bool VerifyMachineDomInfo;
401d5ae102SDimitry Andric } // namespace llvm
4193c91e39SDimitry Andric
42ac9a064cSDimitry Andric AnalysisKey MachinePostDominatorTreeAnalysis::Key;
43ac9a064cSDimitry Andric
44ac9a064cSDimitry Andric MachinePostDominatorTreeAnalysis::Result
run(MachineFunction & MF,MachineFunctionAnalysisManager &)45ac9a064cSDimitry Andric MachinePostDominatorTreeAnalysis::run(MachineFunction &MF,
46ac9a064cSDimitry Andric MachineFunctionAnalysisManager &) {
47ac9a064cSDimitry Andric return MachinePostDominatorTree(MF);
48ac9a064cSDimitry Andric }
49ac9a064cSDimitry Andric
50ac9a064cSDimitry Andric PreservedAnalyses
run(MachineFunction & MF,MachineFunctionAnalysisManager & MFAM)51ac9a064cSDimitry Andric MachinePostDominatorTreePrinterPass::run(MachineFunction &MF,
52ac9a064cSDimitry Andric MachineFunctionAnalysisManager &MFAM) {
53ac9a064cSDimitry Andric OS << "MachinePostDominatorTree for machine function: " << MF.getName()
54ac9a064cSDimitry Andric << '\n';
55ac9a064cSDimitry Andric MFAM.getResult<MachinePostDominatorTreeAnalysis>(MF).print(OS);
56ac9a064cSDimitry Andric return PreservedAnalyses::all();
57ac9a064cSDimitry Andric }
58ac9a064cSDimitry Andric
59ac9a064cSDimitry Andric char MachinePostDominatorTreeWrapperPass::ID = 0;
60522600a2SDimitry Andric
61522600a2SDimitry Andric //declare initializeMachinePostDominatorTreePass
62ac9a064cSDimitry Andric INITIALIZE_PASS(MachinePostDominatorTreeWrapperPass, "machinepostdomtree",
63522600a2SDimitry Andric "MachinePostDominator Tree Construction", true, true)
64522600a2SDimitry Andric
MachinePostDominatorTreeWrapperPass()65ac9a064cSDimitry Andric MachinePostDominatorTreeWrapperPass::MachinePostDominatorTreeWrapperPass()
66ac9a064cSDimitry Andric : MachineFunctionPass(ID), PDT() {
67ac9a064cSDimitry Andric initializeMachinePostDominatorTreeWrapperPassPass(
68ac9a064cSDimitry Andric *PassRegistry::getPassRegistry());
69522600a2SDimitry Andric }
70522600a2SDimitry Andric
runOnMachineFunction(MachineFunction & F)71ac9a064cSDimitry Andric bool MachinePostDominatorTreeWrapperPass::runOnMachineFunction(
72ac9a064cSDimitry Andric MachineFunction &F) {
73ac9a064cSDimitry Andric PDT = MachinePostDominatorTree();
741d5ae102SDimitry Andric PDT->recalculate(F);
75522600a2SDimitry Andric return false;
76522600a2SDimitry Andric }
77522600a2SDimitry Andric
getAnalysisUsage(AnalysisUsage & AU) const78ac9a064cSDimitry Andric void MachinePostDominatorTreeWrapperPass::getAnalysisUsage(
79ac9a064cSDimitry Andric AnalysisUsage &AU) const {
80522600a2SDimitry Andric AU.setPreservesAll();
81522600a2SDimitry Andric MachineFunctionPass::getAnalysisUsage(AU);
82522600a2SDimitry Andric }
83522600a2SDimitry Andric
invalidate(MachineFunction &,const PreservedAnalyses & PA,MachineFunctionAnalysisManager::Invalidator &)84ac9a064cSDimitry Andric bool MachinePostDominatorTree::invalidate(
85ac9a064cSDimitry Andric MachineFunction &, const PreservedAnalyses &PA,
86ac9a064cSDimitry Andric MachineFunctionAnalysisManager::Invalidator &) {
87ac9a064cSDimitry Andric // Check whether the analysis, all analyses on machine functions, or the
88ac9a064cSDimitry Andric // machine function's CFG have been preserved.
89ac9a064cSDimitry Andric auto PAC = PA.getChecker<MachinePostDominatorTreeAnalysis>();
90ac9a064cSDimitry Andric return !PAC.preserved() &&
91ac9a064cSDimitry Andric !PAC.preservedSet<AllAnalysesOn<MachineFunction>>() &&
92ac9a064cSDimitry Andric !PAC.preservedSet<CFGAnalyses>();
93ac9a064cSDimitry Andric }
94ac9a064cSDimitry Andric
findNearestCommonDominator(ArrayRef<MachineBasicBlock * > Blocks) const951d5ae102SDimitry Andric MachineBasicBlock *MachinePostDominatorTree::findNearestCommonDominator(
961d5ae102SDimitry Andric ArrayRef<MachineBasicBlock *> Blocks) const {
971d5ae102SDimitry Andric assert(!Blocks.empty());
981d5ae102SDimitry Andric
991d5ae102SDimitry Andric MachineBasicBlock *NCD = Blocks.front();
1001d5ae102SDimitry Andric for (MachineBasicBlock *BB : Blocks.drop_front()) {
101ac9a064cSDimitry Andric NCD = Base::findNearestCommonDominator(NCD, BB);
1021d5ae102SDimitry Andric
1031d5ae102SDimitry Andric // Stop when the root is reached.
104ac9a064cSDimitry Andric if (isVirtualRoot(getNode(NCD)))
1051d5ae102SDimitry Andric return nullptr;
1061d5ae102SDimitry Andric }
1071d5ae102SDimitry Andric
1081d5ae102SDimitry Andric return NCD;
1091d5ae102SDimitry Andric }
1101d5ae102SDimitry Andric
verifyAnalysis() const111ac9a064cSDimitry Andric void MachinePostDominatorTreeWrapperPass::verifyAnalysis() const {
112ac9a064cSDimitry Andric if (VerifyMachineDomInfo && PDT &&
113ac9a064cSDimitry Andric !PDT->verify(MachinePostDominatorTree::VerificationLevel::Basic))
114ac9a064cSDimitry Andric report_fatal_error("MachinePostDominatorTree verification failed!");
1151d5ae102SDimitry Andric }
1161d5ae102SDimitry Andric
print(llvm::raw_ostream & OS,const Module * M) const117ac9a064cSDimitry Andric void MachinePostDominatorTreeWrapperPass::print(llvm::raw_ostream &OS,
1181d5ae102SDimitry Andric const Module *M) const {
1191d5ae102SDimitry Andric PDT->print(OS);
120522600a2SDimitry Andric }
121