Example #1
0
/// 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;
}