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