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;
}
/// 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;
}
/// 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.
}
Example #4
0
bool CSE::processFunction(SILFunction &Fm, DominanceInfo *DT) {
  std::vector<StackNode *> nodesToProcess;

  // Tables that the pass uses when walking the domtree.
  ScopedHTType AVTable;
  AvailableValues = &AVTable;

  bool Changed = false;

  // Process the root node.
  nodesToProcess.push_back(new StackNode(AvailableValues, DT->getRootNode(),
                  DT->getRootNode()->begin(),
                  DT->getRootNode()->end()));

  // Process the stack.
  while (!nodesToProcess.empty()) {
    // Grab the first item off the stack. Set the current generation, remove
    // the node from the stack, and process it.
    StackNode *NodeToProcess = nodesToProcess.back();

    // Check if the node needs to be processed.
    if (!NodeToProcess->isProcessed()) {
      // Process the node.
      Changed |= processNode(NodeToProcess->node());
      NodeToProcess->process();

    } else if (NodeToProcess->childIter() != NodeToProcess->end()) {
      // Push the next child onto the stack.
      DominanceInfoNode *child = NodeToProcess->nextChild();
      nodesToProcess.push_back(
          new StackNode(AvailableValues, child, child->begin(), child->end()));
    } else {
      // It has been processed, and there are no more children to process,
      // so delete it and pop it off the stack.
      delete NodeToProcess;
      nodesToProcess.pop_back();
    }
  } // while (!nodes...)

  return Changed;
}