示例#1
0
SILInstruction *SILCombiner::visitSwitchValueInst(SwitchValueInst *SVI) {
  SILValue Cond = SVI->getOperand();
  BuiltinIntegerType *CondTy = Cond->getType().getAs<BuiltinIntegerType>();
  if (!CondTy || !CondTy->isFixedWidth(1))
    return nullptr;

  SILBasicBlock *FalseBB = nullptr;
  SILBasicBlock *TrueBB = nullptr;
  for (unsigned Idx = 0, Num = SVI->getNumCases(); Idx < Num; ++Idx) {
    auto Case = SVI->getCase(Idx);
    auto *CaseVal = dyn_cast<IntegerLiteralInst>(Case.first);
    if (!CaseVal)
      return nullptr;
    SILBasicBlock *DestBB = Case.second;
    assert(DestBB->args_empty() &&
           "switch_value case destination cannot take arguments");
    if (CaseVal->getValue() == 0) {
      assert(!FalseBB && "double case value 0 in switch_value");
      FalseBB = DestBB;
    } else {
      assert(!TrueBB && "double case value 1 in switch_value");
      TrueBB = DestBB;
    }
  }
  if (SVI->hasDefault()) {
    assert(SVI->getDefaultBB()->args_empty() &&
           "switch_value default destination cannot take arguments");
    if (!FalseBB) {
      FalseBB = SVI->getDefaultBB();
    } else if (!TrueBB) {
      TrueBB = SVI->getDefaultBB();
    }
  }
  if (!FalseBB || !TrueBB)
    return nullptr;

  Builder.setCurrentDebugScope(SVI->getDebugScope());
  return Builder.createCondBranch(SVI->getLoc(), Cond, TrueBB, FalseBB);
}