/// Checks whether there are checks in the preheader's predecessor that ensure /// that "Start < End". static bool isRangeChecked(SILValue Start, SILValue End, SILBasicBlock *Preheader, DominanceInfo *DT) { // Check two constants. if (isLessThan(Start, End)) return true; // Look for a branch on EQ around the Preheader. auto *PreheaderPred = Preheader->getSinglePredecessor(); if (!PreheaderPred) return false; auto *CondBr = dyn_cast<CondBranchInst>(PreheaderPred->getTerminator()); if (!CondBr) return false; if (isLessThanCheck(Start, End, CondBr, Preheader)) return true; // Walk up the dominator tree looking for a range check ("SLE Start, End"). DominanceInfoNode *CurDTNode = DT->getNode(PreheaderPred); while (CurDTNode) { if (isSignedLessEqual(Start, End, *CurDTNode->getBlock())) return true; CurDTNode = CurDTNode->getIDom(); } return false; }
/// Update the SSA form after all changes. void CheckedCastBrJumpThreading::updateDominatorTree() { // Update the dominator tree. // If BB was IDom of something, then PredCBBI becomes the IDOM // of this after jump-threading. auto *BBDomNode = DT->getNode(BB); auto &Children = BBDomNode->getChildren(); if (Children.size() > 1) { SmallVector<DominanceInfoNode *, 16> ChildrenCopy; std::copy(Children.begin(), Children.end(), std::back_inserter(ChildrenCopy)); for (auto *Child : ChildrenCopy) { DT->changeImmediateDominator(Child, Node); } } DominanceInfoNode *CommonDom; // Find a common dominator for all unknown preds. if (!UnknownPreds.empty()) { // Find a new IDom for FailureBB CommonDom = findCommonDominator(FailureBB, DT); if (CommonDom) DT->changeImmediateDominator(FailureBB, CommonDom->getBlock()); CommonDom = findCommonDominator(UnknownPreds, DT); // This common dominator dominates the BB now. if (CommonDom) { DT->changeImmediateDominator(BB, CommonDom->getBlock()); } } // Find a common dominator for all failure preds. CommonDom = findCommonDominator(FailurePreds, DT); // This common dominator dominates the TargetFailureBB now. if (CommonDom) { DT->addNewBlock(TargetFailureBB, CommonDom->getBlock()); // Find a new IDom for FailureBB CommonDom = findCommonDominator(FailureBB, DT); if (CommonDom) DT->changeImmediateDominator(FailureBB, CommonDom->getBlock()); } // Find a common dominator for all success preds. CommonDom = findCommonDominator(SuccessPreds, DT); // This common dominator of all success preds dominates the BB now. if (CommonDom) { if (TargetSuccessBB) { DT->addNewBlock(TargetSuccessBB, CommonDom->getBlock()); } else { DT->changeImmediateDominator(BB, CommonDom->getBlock()); } CommonDom = findCommonDominator(SuccessBB, DT); if (CommonDom) DT->changeImmediateDominator(SuccessBB, CommonDom->getBlock()); } // End of dominator tree update. }
/// Find a nearest common dominator for a given set of basic blocks. static DominanceInfoNode *findCommonDominator(ArrayRef<SILBasicBlock *> BBs, DominanceInfo *DT) { DominanceInfoNode *CommonDom = nullptr; for (auto *BB : BBs) { if (!CommonDom) { CommonDom = DT->getNode(BB); } else { CommonDom = DT->getNode( DT->findNearestCommonDominator(CommonDom->getBlock(), BB)); } } return CommonDom; }