xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/MachinePostDominators.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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
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
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 
65*0fca6ea1SDimitry Andric MachinePostDominatorTreeWrapperPass::MachinePostDominatorTreeWrapperPass()
66*0fca6ea1SDimitry Andric     : MachineFunctionPass(ID), PDT() {
67*0fca6ea1SDimitry Andric   initializeMachinePostDominatorTreeWrapperPassPass(
68*0fca6ea1SDimitry Andric       *PassRegistry::getPassRegistry());
690b57cec5SDimitry Andric }
700b57cec5SDimitry Andric 
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 
78*0fca6ea1SDimitry Andric void MachinePostDominatorTreeWrapperPass::getAnalysisUsage(
79*0fca6ea1SDimitry Andric     AnalysisUsage &AU) const {
800b57cec5SDimitry Andric   AU.setPreservesAll();
810b57cec5SDimitry Andric   MachineFunctionPass::getAnalysisUsage(AU);
820b57cec5SDimitry Andric }
830b57cec5SDimitry Andric 
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 
958bcb0991SDimitry 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 
111*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 
117*0fca6ea1SDimitry Andric void MachinePostDominatorTreeWrapperPass::print(llvm::raw_ostream &OS,
1188bcb0991SDimitry Andric                                                 const Module *M) const {
1198bcb0991SDimitry Andric   PDT->print(OS);
1200b57cec5SDimitry Andric }
121