Exemplo n.º 1
0
/// Subtract a constant from a builtin integer value.
static SILValue getSub(SILLocation Loc, SILValue Val, unsigned SubVal,
                       SILBuilder &B) {
  SmallVector<SILValue, 4> Args(1, Val);
  Args.push_back(B.createIntegerLiteral(Loc, Val->getType(), SubVal));
  Args.push_back(B.createIntegerLiteral(
      Loc, SILType::getBuiltinIntegerType(1, B.getASTContext()), -1));

  auto *AI = B.createBuiltinBinaryFunctionWithOverflow(
      Loc, "ssub_with_overflow", Args);
  return B.createTupleExtract(Loc, AI, 0);
}
Exemplo n.º 2
0
  /// If necessary insert an overflow for this induction variable.
  /// If we compare for equality we need to make sure that the range does wrap.
  /// We would have trapped either when overflowing or when accessing an array
  /// out of bounds in the original loop.
  void checkOverflow(SILBuilder &Builder) {
    if (IsOverflowCheckInserted || Cmp != BuiltinValueKind::ICMP_EQ)
      return;

    auto Loc = Inc->getLoc();
    auto ResultTy = SILType::getBuiltinIntegerType(1, Builder.getASTContext());
    auto *CmpSGE = Builder.createBuiltinBinaryFunction(
        Loc, "cmp_sge", Start->getType(), ResultTy, {Start, End});
    Builder.createCondFail(Loc, CmpSGE);
    IsOverflowCheckInserted = true;

    // We can now remove the cond fail on the increment the above comparison
    // guarantees that the addition won't overflow.
    auto *CondFail = isOverflowChecked(cast<BuiltinInst>(Inc));
    if (CondFail)
      CondFail->eraseFromParent();
  }
Exemplo n.º 3
0
NullablePtr<SILInstruction>
Projection::
createAddrProjection(SILBuilder &B, SILLocation Loc, SILValue Base) const {
    // Grab Base's type.
    SILType BaseTy = Base.getType();

    // If BaseTy is not an address type, bail.
    if (!BaseTy.isAddress())
        return nullptr;

    // If this projection is associated with an object type, convert its type to
    // an address type.
    //
    // *NOTE* We purposely do not handle local storage types here since we want to
    // always fail in such a case. That is handled by checking that Ty is an
    // address.
    SILType Ty = Type.isObject()? Type.getAddressType() : Type;

    if (!Ty.isAddress())
        return nullptr;

    // Ok, we now know that the type of Base and the type represented by the base
    // of this projection match and that this projection can be represented as
    // value. Create the instruction if we can. Otherwise, return nullptr.
    switch (getKind()) {
    case ProjectionKind::Struct:
        return B.createStructElementAddr(Loc, Base, cast<VarDecl>(getDecl()));
    case ProjectionKind::Tuple:
        return B.createTupleElementAddr(Loc, Base, getIndex());
    case ProjectionKind::Index: {
        auto Ty = SILType::getBuiltinIntegerType(32, B.getASTContext());
        auto *IntLiteral = B.createIntegerLiteral(Loc, Ty, getIndex());
        return B.createIndexAddr(Loc, Base, IntLiteral);
    }
    case ProjectionKind::Enum:
        return B.createUncheckedTakeEnumDataAddr(Loc, Base,
                cast<EnumElementDecl>(getDecl()));
    case ProjectionKind::Class:
        return B.createRefElementAddr(Loc, Base, cast<VarDecl>(getDecl()));
    }
}