/////////////////////////////////////////////////////////////////////////////// // // // ControlDependence.cpp // // Copyright (C) Microsoft Corporation. All rights reserved. // // This file is distributed under the University of Illinois Open Source // // License. See LICENSE.TXT for details. // // // // Control dependence is computed using algorithm in Figure 7.9 from [AK]. // // // // References // // [AK] Optimizing Compilers for Modern Architectures by Allen and Kennedy. // /////////////////////////////////////////////////////////////////////////////// #include "dxc/HLSL/ControlDependence.h" #include "dxc/Support/Global.h" #include "llvm/Support/Debug.h" using namespace llvm; using namespace hlsl; const BasicBlockSet &ControlDependence::GetCDBlocks(BasicBlock *pBB) const { auto it = m_ControlDependence.find(pBB); if (it != m_ControlDependence.end()) return it->second; else return m_EmptyBBSet; } void ControlDependence::print(raw_ostream &OS) { OS << "Control dependence for function '" << m_pFunc->getName() << "'\n"; for (auto &it : m_ControlDependence) { BasicBlock *pBB = it.first; OS << "Block " << pBB->getName() << ": { "; bool bFirst = true; for (BasicBlock *pBB2 : it.second) { if (!bFirst) OS << ", "; OS << pBB2->getName(); bFirst = false; } OS << " }\n"; } OS << "\n"; } void ControlDependence::dump() { print(dbgs()); } void ControlDependence::Compute(Function *F, PostDomRelationType &PostDomRel) { m_pFunc = F; // Compute reverse topological order of PDT. BasicBlockVector RevTopOrder; BasicBlockSet VisitedBBs; for (BasicBlock *pBB : PostDomRel.getRoots()) { ComputeRevTopOrderRec(PostDomRel, pBB, RevTopOrder, VisitedBBs); } DXASSERT_NOMSG(RevTopOrder.size() == VisitedBBs.size()); // Compute control dependence relation. for (size_t iBB = 0; iBB < RevTopOrder.size(); iBB++) { BasicBlock *x = RevTopOrder[iBB]; // For each y = pred(x): if ipostdom(y) != x then add "x is control dependent on y" for (auto itPred = pred_begin(x), endPred = pred_end(x); itPred != endPred; ++itPred) { BasicBlock *y = *itPred; // predecessor of x BasicBlock *pPredIDomBB = GetIPostDom(PostDomRel, y); if (pPredIDomBB != x) { m_ControlDependence[x].insert(y); } } // For all z such that ipostdom(z) = x for (DomTreeNode *child : PostDomRel.getNode(x)->getChildren()) { BasicBlock *z = child->getBlock(); auto it = m_ControlDependence.find(z); if (it == m_ControlDependence.end()) continue; // For all y in CDG(z) for (BasicBlock *y : it->second) { // if ipostdom(y) != x then add "x is control dependent on y" BasicBlock *pPredIDomBB = GetIPostDom(PostDomRel, y); if (pPredIDomBB != x) { m_ControlDependence[x].insert(y); } } } } } void ControlDependence::Clear() { m_pFunc = nullptr; m_ControlDependence.clear(); m_EmptyBBSet.clear(); } BasicBlock *ControlDependence::GetIPostDom(PostDomRelationType &PostDomRel, BasicBlock *pBB) { auto *pPDTNode = PostDomRel.getNode(pBB); auto *pIDomNode = pPDTNode->getIDom(); BasicBlock *pIDomBB = pIDomNode != nullptr ? pIDomNode->getBlock() : nullptr; return pIDomBB; } void ControlDependence::ComputeRevTopOrderRec(PostDomRelationType &PostDomRel, BasicBlock *pBB, BasicBlockVector &RevTopOrder, BasicBlockSet &VisitedBBs) { if (VisitedBBs.find(pBB) != VisitedBBs.end()) { return; } VisitedBBs.insert(pBB); SmallVector Descendants; PostDomRel.getDescendants(pBB, Descendants); for (BasicBlock *pDescBB : Descendants) { if (pDescBB != pBB) ComputeRevTopOrderRec(PostDomRel, pDescBB, RevTopOrder, VisitedBBs); } RevTopOrder.emplace_back(pBB); }