1009b1c42SEd Schouten //===- MachineDominators.cpp - Machine Dominator Calculation --------------===//
2009b1c42SEd Schouten //
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
6009b1c42SEd Schouten //
7009b1c42SEd Schouten //===----------------------------------------------------------------------===//
8009b1c42SEd Schouten //
9009b1c42SEd Schouten // This file implements simple dominator construction algorithms for finding
10009b1c42SEd Schouten // forward dominators on machine functions.
11009b1c42SEd Schouten //
12009b1c42SEd Schouten //===----------------------------------------------------------------------===//
13009b1c42SEd Schouten
14009b1c42SEd Schouten #include "llvm/CodeGen/MachineDominators.h"
155a5ac124SDimitry Andric #include "llvm/ADT/SmallBitVector.h"
167ab83427SDimitry Andric #include "llvm/CodeGen/Passes.h"
17706b4fc4SDimitry Andric #include "llvm/InitializePasses.h"
18145449b1SDimitry Andric #include "llvm/Pass.h"
19145449b1SDimitry Andric #include "llvm/PassRegistry.h"
2001095a5dSDimitry Andric #include "llvm/Support/CommandLine.h"
21ac9a064cSDimitry Andric #include "llvm/Support/GenericDomTreeConstruction.h"
22009b1c42SEd Schouten
23009b1c42SEd Schouten using namespace llvm;
24009b1c42SEd Schouten
251d5ae102SDimitry Andric namespace llvm {
2601095a5dSDimitry Andric // Always verify dominfo if expensive checking is enabled.
2701095a5dSDimitry Andric #ifdef EXPENSIVE_CHECKS
281d5ae102SDimitry Andric bool VerifyMachineDomInfo = true;
2901095a5dSDimitry Andric #else
301d5ae102SDimitry Andric bool VerifyMachineDomInfo = false;
3101095a5dSDimitry Andric #endif
321d5ae102SDimitry Andric } // namespace llvm
331d5ae102SDimitry Andric
3401095a5dSDimitry Andric static cl::opt<bool, true> VerifyMachineDomInfoX(
35044eb2f6SDimitry Andric "verify-machine-dom-info", cl::location(VerifyMachineDomInfo), cl::Hidden,
3601095a5dSDimitry Andric cl::desc("Verify machine dominator info (time consuming)"));
3701095a5dSDimitry Andric
381e7804dbSRoman Divacky namespace llvm {
39ee8648bdSDimitry Andric template class DomTreeNodeBase<MachineBasicBlock>;
4093c91e39SDimitry Andric template class DominatorTreeBase<MachineBasicBlock, false>; // DomTreeBase
41ac9a064cSDimitry Andric
42ac9a064cSDimitry Andric namespace DomTreeBuilder {
43ac9a064cSDimitry Andric template void Calculate<MBBDomTree>(MBBDomTree &DT);
44ac9a064cSDimitry Andric template void CalculateWithUpdates<MBBDomTree>(MBBDomTree &DT, MBBUpdates U);
45ac9a064cSDimitry Andric
46ac9a064cSDimitry Andric template void InsertEdge<MBBDomTree>(MBBDomTree &DT, MachineBasicBlock *From,
47ac9a064cSDimitry Andric MachineBasicBlock *To);
48ac9a064cSDimitry Andric
49ac9a064cSDimitry Andric template void DeleteEdge<MBBDomTree>(MBBDomTree &DT, MachineBasicBlock *From,
50ac9a064cSDimitry Andric MachineBasicBlock *To);
51ac9a064cSDimitry Andric
52ac9a064cSDimitry Andric template void ApplyUpdates<MBBDomTree>(MBBDomTree &DT, MBBDomTreeGraphDiff &,
53ac9a064cSDimitry Andric MBBDomTreeGraphDiff *);
54ac9a064cSDimitry Andric
55ac9a064cSDimitry Andric template bool Verify<MBBDomTree>(const MBBDomTree &DT,
56ac9a064cSDimitry Andric MBBDomTree::VerificationLevel VL);
57ac9a064cSDimitry Andric } // namespace DomTreeBuilder
581e7804dbSRoman Divacky }
59009b1c42SEd Schouten
invalidate(MachineFunction &,const PreservedAnalyses & PA,MachineFunctionAnalysisManager::Invalidator &)60ac9a064cSDimitry Andric bool MachineDominatorTree::invalidate(
61ac9a064cSDimitry Andric MachineFunction &, const PreservedAnalyses &PA,
62ac9a064cSDimitry Andric MachineFunctionAnalysisManager::Invalidator &) {
63ac9a064cSDimitry Andric // Check whether the analysis, all analyses on machine functions, or the
64ac9a064cSDimitry Andric // machine function's CFG have been preserved.
65ac9a064cSDimitry Andric auto PAC = PA.getChecker<MachineDominatorTreeAnalysis>();
66ac9a064cSDimitry Andric return !PAC.preserved() &&
67ac9a064cSDimitry Andric !PAC.preservedSet<AllAnalysesOn<MachineFunction>>() &&
68ac9a064cSDimitry Andric !PAC.preservedSet<CFGAnalyses>();
69ac9a064cSDimitry Andric }
70009b1c42SEd Schouten
71ac9a064cSDimitry Andric AnalysisKey MachineDominatorTreeAnalysis::Key;
72ac9a064cSDimitry Andric
73ac9a064cSDimitry Andric MachineDominatorTreeAnalysis::Result
run(MachineFunction & MF,MachineFunctionAnalysisManager &)74ac9a064cSDimitry Andric MachineDominatorTreeAnalysis::run(MachineFunction &MF,
75ac9a064cSDimitry Andric MachineFunctionAnalysisManager &) {
76ac9a064cSDimitry Andric return MachineDominatorTree(MF);
77ac9a064cSDimitry Andric }
78ac9a064cSDimitry Andric
79ac9a064cSDimitry Andric PreservedAnalyses
run(MachineFunction & MF,MachineFunctionAnalysisManager & MFAM)80ac9a064cSDimitry Andric MachineDominatorTreePrinterPass::run(MachineFunction &MF,
81ac9a064cSDimitry Andric MachineFunctionAnalysisManager &MFAM) {
82ac9a064cSDimitry Andric OS << "MachineDominatorTree for machine function: " << MF.getName() << '\n';
83ac9a064cSDimitry Andric MFAM.getResult<MachineDominatorTreeAnalysis>(MF).print(OS);
84ac9a064cSDimitry Andric return PreservedAnalyses::all();
85ac9a064cSDimitry Andric }
86ac9a064cSDimitry Andric
87ac9a064cSDimitry Andric char MachineDominatorTreeWrapperPass::ID = 0;
88ac9a064cSDimitry Andric
89ac9a064cSDimitry Andric INITIALIZE_PASS(MachineDominatorTreeWrapperPass, "machinedomtree",
90cf099d11SDimitry Andric "MachineDominator Tree Construction", true, true)
91009b1c42SEd Schouten
MachineDominatorTreeWrapperPass()92ac9a064cSDimitry Andric MachineDominatorTreeWrapperPass::MachineDominatorTreeWrapperPass()
93ac9a064cSDimitry Andric : MachineFunctionPass(ID) {
94ac9a064cSDimitry Andric initializeMachineDominatorTreeWrapperPassPass(
95ac9a064cSDimitry Andric *PassRegistry::getPassRegistry());
96706b4fc4SDimitry Andric }
97706b4fc4SDimitry Andric
calculate(MachineFunction & F)98706b4fc4SDimitry Andric void MachineDominatorTree::calculate(MachineFunction &F) {
9967c32a98SDimitry Andric CriticalEdgesToSplit.clear();
10067c32a98SDimitry Andric NewBBs.clear();
101ac9a064cSDimitry Andric recalculate(F);
102009b1c42SEd Schouten }
103009b1c42SEd Schouten
104ac9a064cSDimitry Andric char &llvm::MachineDominatorsID = MachineDominatorTreeWrapperPass::ID;
105ac9a064cSDimitry Andric
runOnMachineFunction(MachineFunction & F)106ac9a064cSDimitry Andric bool MachineDominatorTreeWrapperPass::runOnMachineFunction(MachineFunction &F) {
107ac9a064cSDimitry Andric DT = MachineDominatorTree(F);
108ac9a064cSDimitry Andric return false;
109009b1c42SEd Schouten }
110009b1c42SEd Schouten
releaseMemory()111ac9a064cSDimitry Andric void MachineDominatorTreeWrapperPass::releaseMemory() { DT.reset(); }
112ac9a064cSDimitry Andric
verifyAnalysis() const113ac9a064cSDimitry Andric void MachineDominatorTreeWrapperPass::verifyAnalysis() const {
114ac9a064cSDimitry Andric if (VerifyMachineDomInfo && DT)
115ac9a064cSDimitry Andric if (!DT->verify(MachineDominatorTree::VerificationLevel::Basic))
116ac9a064cSDimitry Andric report_fatal_error("MachineDominatorTree verification failed!");
117009b1c42SEd Schouten }
11859850d08SRoman Divacky
print(raw_ostream & OS,const Module *) const119ac9a064cSDimitry Andric void MachineDominatorTreeWrapperPass::print(raw_ostream &OS,
120ac9a064cSDimitry Andric const Module *) const {
12171d5a254SDimitry Andric if (DT)
12259850d08SRoman Divacky DT->print(OS);
12359850d08SRoman Divacky }
1245a5ac124SDimitry Andric
applySplitCriticalEdges() const1255a5ac124SDimitry Andric void MachineDominatorTree::applySplitCriticalEdges() const {
1265a5ac124SDimitry Andric // Bail out early if there is nothing to do.
1275a5ac124SDimitry Andric if (CriticalEdgesToSplit.empty())
1285a5ac124SDimitry Andric return;
1295a5ac124SDimitry Andric
1305a5ac124SDimitry Andric // For each element in CriticalEdgesToSplit, remember whether or not element
1315a5ac124SDimitry Andric // is the new immediate domminator of its successor. The mapping is done by
1325a5ac124SDimitry Andric // index, i.e., the information for the ith element of CriticalEdgesToSplit is
1335a5ac124SDimitry Andric // the ith element of IsNewIDom.
1345a5ac124SDimitry Andric SmallBitVector IsNewIDom(CriticalEdgesToSplit.size(), true);
1355a5ac124SDimitry Andric size_t Idx = 0;
1365a5ac124SDimitry Andric
1375a5ac124SDimitry Andric // Collect all the dominance properties info, before invalidating
1385a5ac124SDimitry Andric // the underlying DT.
1395a5ac124SDimitry Andric for (CriticalEdge &Edge : CriticalEdgesToSplit) {
1405a5ac124SDimitry Andric // Update dominator information.
1415a5ac124SDimitry Andric MachineBasicBlock *Succ = Edge.ToBB;
142ac9a064cSDimitry Andric MachineDomTreeNode *SuccDTNode = Base::getNode(Succ);
1435a5ac124SDimitry Andric
1445a5ac124SDimitry Andric for (MachineBasicBlock *PredBB : Succ->predecessors()) {
1455a5ac124SDimitry Andric if (PredBB == Edge.NewBB)
1465a5ac124SDimitry Andric continue;
1475a5ac124SDimitry Andric // If we are in this situation:
1485a5ac124SDimitry Andric // FromBB1 FromBB2
1495a5ac124SDimitry Andric // + +
1505a5ac124SDimitry Andric // + + + +
1515a5ac124SDimitry Andric // + + + +
1525a5ac124SDimitry Andric // ... Split1 Split2 ...
1535a5ac124SDimitry Andric // + +
1545a5ac124SDimitry Andric // + +
1555a5ac124SDimitry Andric // +
1565a5ac124SDimitry Andric // Succ
1575a5ac124SDimitry Andric // Instead of checking the domiance property with Split2, we check it with
1585a5ac124SDimitry Andric // FromBB2 since Split2 is still unknown of the underlying DT structure.
1595a5ac124SDimitry Andric if (NewBBs.count(PredBB)) {
1605a5ac124SDimitry Andric assert(PredBB->pred_size() == 1 && "A basic block resulting from a "
1615a5ac124SDimitry Andric "critical edge split has more "
1625a5ac124SDimitry Andric "than one predecessor!");
1635a5ac124SDimitry Andric PredBB = *PredBB->pred_begin();
1645a5ac124SDimitry Andric }
165ac9a064cSDimitry Andric if (!Base::dominates(SuccDTNode, Base::getNode(PredBB))) {
1665a5ac124SDimitry Andric IsNewIDom[Idx] = false;
1675a5ac124SDimitry Andric break;
1685a5ac124SDimitry Andric }
1695a5ac124SDimitry Andric }
1705a5ac124SDimitry Andric ++Idx;
1715a5ac124SDimitry Andric }
1725a5ac124SDimitry Andric
1735a5ac124SDimitry Andric // Now, update DT with the collected dominance properties info.
1745a5ac124SDimitry Andric Idx = 0;
1755a5ac124SDimitry Andric for (CriticalEdge &Edge : CriticalEdgesToSplit) {
1765a5ac124SDimitry Andric // We know FromBB dominates NewBB.
177ac9a064cSDimitry Andric MachineDomTreeNode *NewDTNode =
178ac9a064cSDimitry Andric const_cast<MachineDominatorTree *>(this)->Base::addNewBlock(
179ac9a064cSDimitry Andric Edge.NewBB, Edge.FromBB);
1805a5ac124SDimitry Andric
1815a5ac124SDimitry Andric // If all the other predecessors of "Succ" are dominated by "Succ" itself
1825a5ac124SDimitry Andric // then the new block is the new immediate dominator of "Succ". Otherwise,
1835a5ac124SDimitry Andric // the new block doesn't dominate anything.
1845a5ac124SDimitry Andric if (IsNewIDom[Idx])
185ac9a064cSDimitry Andric const_cast<MachineDominatorTree *>(this)->Base::changeImmediateDominator(
186ac9a064cSDimitry Andric Base::getNode(Edge.ToBB), NewDTNode);
1875a5ac124SDimitry Andric ++Idx;
1885a5ac124SDimitry Andric }
1895a5ac124SDimitry Andric NewBBs.clear();
1905a5ac124SDimitry Andric CriticalEdgesToSplit.clear();
1915a5ac124SDimitry Andric }
192