10b57cec5SDimitry Andric //===- MachinePostDominators.cpp -Machine 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 simple dominator construction algorithms for finding
100b57cec5SDimitry Andric // post dominators on machine functions.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric
140b57cec5SDimitry Andric #include "llvm/CodeGen/MachinePostDominators.h"
15480093f4SDimitry Andric #include "llvm/InitializePasses.h"
16*0fca6ea1SDimitry Andric #include "llvm/Support/GenericDomTreeConstruction.h"
170b57cec5SDimitry Andric
180b57cec5SDimitry Andric using namespace llvm;
190b57cec5SDimitry Andric
200b57cec5SDimitry Andric namespace llvm {
210b57cec5SDimitry Andric template class DominatorTreeBase<MachineBasicBlock, true>; // PostDomTreeBase
228bcb0991SDimitry Andric
23*0fca6ea1SDimitry Andric namespace DomTreeBuilder {
24*0fca6ea1SDimitry Andric
25*0fca6ea1SDimitry Andric template void Calculate<MBBPostDomTree>(MBBPostDomTree &DT);
26*0fca6ea1SDimitry Andric template void InsertEdge<MBBPostDomTree>(MBBPostDomTree &DT,
27*0fca6ea1SDimitry Andric MachineBasicBlock *From,
28*0fca6ea1SDimitry Andric MachineBasicBlock *To);
29*0fca6ea1SDimitry Andric template void DeleteEdge<MBBPostDomTree>(MBBPostDomTree &DT,
30*0fca6ea1SDimitry Andric MachineBasicBlock *From,
31*0fca6ea1SDimitry Andric MachineBasicBlock *To);
32*0fca6ea1SDimitry Andric template void ApplyUpdates<MBBPostDomTree>(MBBPostDomTree &DT,
33*0fca6ea1SDimitry Andric MBBPostDomTreeGraphDiff &,
34*0fca6ea1SDimitry Andric MBBPostDomTreeGraphDiff *);
35*0fca6ea1SDimitry Andric template bool Verify<MBBPostDomTree>(const MBBPostDomTree &DT,
36*0fca6ea1SDimitry Andric MBBPostDomTree::VerificationLevel VL);
37*0fca6ea1SDimitry Andric
38*0fca6ea1SDimitry Andric } // namespace DomTreeBuilder
398bcb0991SDimitry Andric extern bool VerifyMachineDomInfo;
408bcb0991SDimitry Andric } // namespace llvm
410b57cec5SDimitry Andric
42*0fca6ea1SDimitry Andric AnalysisKey MachinePostDominatorTreeAnalysis::Key;
43*0fca6ea1SDimitry Andric
44*0fca6ea1SDimitry Andric MachinePostDominatorTreeAnalysis::Result
run(MachineFunction & MF,MachineFunctionAnalysisManager &)45*0fca6ea1SDimitry Andric MachinePostDominatorTreeAnalysis::run(MachineFunction &MF,
46*0fca6ea1SDimitry Andric MachineFunctionAnalysisManager &) {
47*0fca6ea1SDimitry Andric return MachinePostDominatorTree(MF);
48*0fca6ea1SDimitry Andric }
49*0fca6ea1SDimitry Andric
50*0fca6ea1SDimitry Andric PreservedAnalyses
run(MachineFunction & MF,MachineFunctionAnalysisManager & MFAM)51*0fca6ea1SDimitry Andric MachinePostDominatorTreePrinterPass::run(MachineFunction &MF,
52*0fca6ea1SDimitry Andric MachineFunctionAnalysisManager &MFAM) {
53*0fca6ea1SDimitry Andric OS << "MachinePostDominatorTree for machine function: " << MF.getName()
54*0fca6ea1SDimitry Andric << '\n';
55*0fca6ea1SDimitry Andric MFAM.getResult<MachinePostDominatorTreeAnalysis>(MF).print(OS);
56*0fca6ea1SDimitry Andric return PreservedAnalyses::all();
57*0fca6ea1SDimitry Andric }
58*0fca6ea1SDimitry Andric
59*0fca6ea1SDimitry Andric char MachinePostDominatorTreeWrapperPass::ID = 0;
600b57cec5SDimitry Andric
610b57cec5SDimitry Andric //declare initializeMachinePostDominatorTreePass
62*0fca6ea1SDimitry Andric INITIALIZE_PASS(MachinePostDominatorTreeWrapperPass, "machinepostdomtree",
630b57cec5SDimitry Andric "MachinePostDominator Tree Construction", true, true)
640b57cec5SDimitry Andric
MachinePostDominatorTreeWrapperPass()65*0fca6ea1SDimitry Andric MachinePostDominatorTreeWrapperPass::MachinePostDominatorTreeWrapperPass()
66*0fca6ea1SDimitry Andric : MachineFunctionPass(ID), PDT() {
67*0fca6ea1SDimitry Andric initializeMachinePostDominatorTreeWrapperPassPass(
68*0fca6ea1SDimitry Andric *PassRegistry::getPassRegistry());
690b57cec5SDimitry Andric }
700b57cec5SDimitry Andric
runOnMachineFunction(MachineFunction & F)71*0fca6ea1SDimitry Andric bool MachinePostDominatorTreeWrapperPass::runOnMachineFunction(
72*0fca6ea1SDimitry Andric MachineFunction &F) {
73*0fca6ea1SDimitry Andric PDT = MachinePostDominatorTree();
748bcb0991SDimitry Andric PDT->recalculate(F);
750b57cec5SDimitry Andric return false;
760b57cec5SDimitry Andric }
770b57cec5SDimitry Andric
getAnalysisUsage(AnalysisUsage & AU) const78*0fca6ea1SDimitry Andric void MachinePostDominatorTreeWrapperPass::getAnalysisUsage(
79*0fca6ea1SDimitry Andric AnalysisUsage &AU) const {
800b57cec5SDimitry Andric AU.setPreservesAll();
810b57cec5SDimitry Andric MachineFunctionPass::getAnalysisUsage(AU);
820b57cec5SDimitry Andric }
830b57cec5SDimitry Andric
invalidate(MachineFunction &,const PreservedAnalyses & PA,MachineFunctionAnalysisManager::Invalidator &)84*0fca6ea1SDimitry Andric bool MachinePostDominatorTree::invalidate(
85*0fca6ea1SDimitry Andric MachineFunction &, const PreservedAnalyses &PA,
86*0fca6ea1SDimitry Andric MachineFunctionAnalysisManager::Invalidator &) {
87*0fca6ea1SDimitry Andric // Check whether the analysis, all analyses on machine functions, or the
88*0fca6ea1SDimitry Andric // machine function's CFG have been preserved.
89*0fca6ea1SDimitry Andric auto PAC = PA.getChecker<MachinePostDominatorTreeAnalysis>();
90*0fca6ea1SDimitry Andric return !PAC.preserved() &&
91*0fca6ea1SDimitry Andric !PAC.preservedSet<AllAnalysesOn<MachineFunction>>() &&
92*0fca6ea1SDimitry Andric !PAC.preservedSet<CFGAnalyses>();
93*0fca6ea1SDimitry Andric }
94*0fca6ea1SDimitry Andric
findNearestCommonDominator(ArrayRef<MachineBasicBlock * > Blocks) const958bcb0991SDimitry Andric MachineBasicBlock *MachinePostDominatorTree::findNearestCommonDominator(
968bcb0991SDimitry Andric ArrayRef<MachineBasicBlock *> Blocks) const {
978bcb0991SDimitry Andric assert(!Blocks.empty());
988bcb0991SDimitry Andric
998bcb0991SDimitry Andric MachineBasicBlock *NCD = Blocks.front();
1008bcb0991SDimitry Andric for (MachineBasicBlock *BB : Blocks.drop_front()) {
101*0fca6ea1SDimitry Andric NCD = Base::findNearestCommonDominator(NCD, BB);
1028bcb0991SDimitry Andric
1038bcb0991SDimitry Andric // Stop when the root is reached.
104*0fca6ea1SDimitry Andric if (isVirtualRoot(getNode(NCD)))
1058bcb0991SDimitry Andric return nullptr;
1068bcb0991SDimitry Andric }
1078bcb0991SDimitry Andric
1088bcb0991SDimitry Andric return NCD;
1098bcb0991SDimitry Andric }
1108bcb0991SDimitry Andric
verifyAnalysis() const111*0fca6ea1SDimitry Andric void MachinePostDominatorTreeWrapperPass::verifyAnalysis() const {
112*0fca6ea1SDimitry Andric if (VerifyMachineDomInfo && PDT &&
113*0fca6ea1SDimitry Andric !PDT->verify(MachinePostDominatorTree::VerificationLevel::Basic))
114*0fca6ea1SDimitry Andric report_fatal_error("MachinePostDominatorTree verification failed!");
1158bcb0991SDimitry Andric }
1168bcb0991SDimitry Andric
print(llvm::raw_ostream & OS,const Module * M) const117*0fca6ea1SDimitry Andric void MachinePostDominatorTreeWrapperPass::print(llvm::raw_ostream &OS,
1188bcb0991SDimitry Andric const Module *M) const {
1198bcb0991SDimitry Andric PDT->print(OS);
1200b57cec5SDimitry Andric }
121