in lib/Serialization/DeserializeSIL.cpp [1082:2896]
bool SILDeserializer::readSILInstruction(SILFunction *Fn,
SILBuilder &Builder,
unsigned RecordKind,
SmallVectorImpl<uint64_t> &scratch) {
if (Fn)
Builder.setCurrentDebugScope(Fn->getDebugScope());
unsigned RawOpCode = 0, TyCategory = 0, TyCategory2 = 0, TyCategory3 = 0,
Attr = 0, Attr2 = 0, Attr3 = 0, Attr4 = 0, NumSubs = 0,
NumConformances = 0;
ValueID ValID, ValID2, ValID3;
TypeID TyID, TyID2, TyID3;
TypeID ConcreteTyID;
SourceLoc SLoc;
ApplyOptions ApplyOpts;
ArrayRef<uint64_t> ListOfValues;
SILLocation Loc = RegularLocation(SLoc);
ValueOwnershipKind forwardingOwnership(OwnershipKind::Any);
auto decodeValueOwnership = [](unsigned field){
// Invalid/Any ownership is never encoded.
return ValueOwnershipKind(field+1);
};
switch (RecordKind) {
default:
llvm_unreachable("Record kind for a SIL instruction is not supported.");
case SIL_ONE_VALUE_ONE_OPERAND:
SILOneValueOneOperandLayout::readRecord(scratch, RawOpCode, Attr,
ValID, TyID, TyCategory,
ValID2);
break;
case SIL_ONE_TYPE:
SILOneTypeLayout::readRecord(scratch, RawOpCode, Attr, TyID, TyCategory);
break;
case SIL_ONE_OPERAND:
SILOneOperandLayout::readRecord(scratch, RawOpCode, Attr,
TyID, TyCategory, ValID);
break;
case SIL_ONE_OPERAND_EXTRA_ATTR:
SILOneOperandExtraAttributeLayout::readRecord(scratch, RawOpCode, Attr,
TyID, TyCategory, ValID);
break;
case SIL_ONE_TYPE_ONE_OPERAND:
SILOneTypeOneOperandLayout::readRecord(scratch, RawOpCode, Attr,
TyID, TyCategory,
TyID2, TyCategory2,
ValID);
break;
case SIL_ONE_TYPE_ONE_OPERAND_EXTRA_ATTR:
SILOneTypeOneOperandExtraAttributeLayout::readRecord(scratch, RawOpCode,
Attr, TyID, TyCategory,
TyID2, TyCategory2,
ValID);
break;
case SIL_INIT_EXISTENTIAL:
SILInitExistentialLayout::readRecord(scratch, RawOpCode,
TyID, TyCategory,
TyID2, TyCategory2,
ValID,
ConcreteTyID,
NumConformances);
break;
case SIL_ONE_TYPE_VALUES:
SILOneTypeValuesLayout::readRecord(scratch, RawOpCode, TyID, TyCategory,
ListOfValues);
break;
case SIL_ONE_TYPE_OWNERSHIP_VALUES: {
unsigned ownershipField;
SILOneTypeOwnershipValuesLayout::readRecord(scratch, RawOpCode,
ownershipField, TyID,
TyCategory, ListOfValues);
forwardingOwnership = decodeValueOwnership(ownershipField);
break;
}
case SIL_TWO_OPERANDS:
SILTwoOperandsLayout::readRecord(scratch, RawOpCode, Attr,
TyID, TyCategory, ValID,
TyID2, TyCategory2, ValID2);
break;
case SIL_TWO_OPERANDS_EXTRA_ATTR:
SILTwoOperandsExtraAttributeLayout::readRecord(scratch, RawOpCode, Attr,
TyID, TyCategory, ValID,
TyID2, TyCategory2, ValID2);
break;
case SIL_TAIL_ADDR:
SILTailAddrLayout::readRecord(scratch, RawOpCode,
TyID, ValID,
TyID2, ValID2,
TyID3);
break;
case SIL_INST_APPLY: {
unsigned Kind, RawApplyOpts;
SILInstApplyLayout::readRecord(scratch, Kind, RawApplyOpts, NumSubs, TyID, TyID2,
ValID, ListOfValues);
switch (Kind) {
case SIL_APPLY:
RawOpCode = (unsigned)SILInstructionKind::ApplyInst;
break;
case SIL_PARTIAL_APPLY:
RawOpCode = (unsigned)SILInstructionKind::PartialApplyInst;
break;
case SIL_BUILTIN:
RawOpCode = (unsigned)SILInstructionKind::BuiltinInst;
break;
case SIL_TRY_APPLY:
RawOpCode = (unsigned)SILInstructionKind::TryApplyInst;
break;
case SIL_BEGIN_APPLY:
RawOpCode = (unsigned)SILInstructionKind::BeginApplyInst;
break;
default:
llvm_unreachable("unexpected apply inst kind");
}
ApplyOpts = ApplyOptions(ApplyFlags(RawApplyOpts));
break;
}
case SIL_INST_NO_OPERAND:
SILInstNoOperandLayout::readRecord(scratch, RawOpCode);
break;
case SIL_INST_WITNESS_METHOD:
SILInstWitnessMethodLayout::readRecord(
scratch, TyID, TyCategory, Attr, TyID2, TyCategory2, TyID3,
TyCategory3, ValID3, ListOfValues);
RawOpCode = (unsigned)SILInstructionKind::WitnessMethodInst;
break;
case SIL_INST_DIFFERENTIABLE_FUNCTION:
SILInstDifferentiableFunctionLayout::readRecord(
scratch, /*numParams*/ Attr, /*numResults*/ Attr2,
/*numDiffParams*/ Attr3,
/*hasDerivativeFunctions*/ Attr4, ListOfValues);
RawOpCode = (unsigned)SILInstructionKind::DifferentiableFunctionInst;
break;
case SIL_INST_LINEAR_FUNCTION:
SILInstLinearFunctionLayout::readRecord(scratch, /*numDiffParams*/ Attr,
/*hasTransposeFunction*/ Attr2,
ListOfValues);
RawOpCode = (unsigned)SILInstructionKind::LinearFunctionInst;
break;
case SIL_INST_DIFFERENTIABLE_FUNCTION_EXTRACT:
SILInstDifferentiableFunctionExtractLayout::readRecord(
scratch, TyID, TyCategory, ValID, /*extractee*/ Attr,
/*hasExplicitExtracteeType*/ Attr2, /*explicitExtracteeType*/ TyID2);
RawOpCode = (unsigned)SILInstructionKind::DifferentiableFunctionExtractInst;
break;
case SIL_INST_LINEAR_FUNCTION_EXTRACT:
SILInstLinearFunctionExtractLayout::readRecord(
scratch, TyID, TyCategory, ValID, /*extractee*/ Attr);
RawOpCode = (unsigned)SILInstructionKind::LinearFunctionExtractInst;
break;
}
// FIXME: validate
SILInstructionKind OpCode = (SILInstructionKind) RawOpCode;
SILInstruction *ResultInst;
switch (OpCode) {
case SILInstructionKind::DebugValueInst:
llvm_unreachable("not supported");
case SILInstructionKind::AllocBoxInst:
assert(RecordKind == SIL_ONE_TYPE && "Layout should be OneType.");
ResultInst = Builder.createAllocBox(
Loc, cast<SILBoxType>(MF->getType(TyID)->getCanonicalType()), None,
/*bool hasDynamicLifetime*/ Attr != 0);
break;
case SILInstructionKind::AllocStackInst: {
assert(RecordKind == SIL_ONE_TYPE && "Layout should be OneType.");
bool hasDynamicLifetime = Attr & 0x1;
bool isLexical = (Attr >> 1) & 0x1;
ResultInst = Builder.createAllocStack(
Loc, getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn),
None, hasDynamicLifetime, isLexical);
break;
}
case SILInstructionKind::MetatypeInst:
assert(RecordKind == SIL_ONE_TYPE && "Layout should be OneType.");
ResultInst = Builder.createMetatype(
Loc, getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn));
break;
case SILInstructionKind::GetAsyncContinuationInst:
assert(RecordKind == SIL_ONE_TYPE && "Layout should be OneType.");
ResultInst = Builder.createGetAsyncContinuation(
Loc, MF->getType(TyID)->getCanonicalType(),
/*throws*/ Attr != 0);
break;
case SILInstructionKind::GetAsyncContinuationAddrInst:
assert(RecordKind == SIL_ONE_TYPE_ONE_OPERAND
&& "Layout should be OneTypeOneOperand.");
ResultInst = Builder.createGetAsyncContinuationAddr(Loc,
getLocalValue(ValID, getSILType(MF->getType(TyID2),
(SILValueCategory)TyCategory2, Fn)),
MF->getType(TyID)->getCanonicalType(),
/*throws*/ Attr != 0);
break;
#define ONETYPE_ONEOPERAND_INST(ID) \
case SILInstructionKind::ID##Inst: \
assert(RecordKind == SIL_ONE_TYPE_ONE_OPERAND && \
"Layout should be OneTypeOneOperand."); \
ResultInst = Builder.create##ID( \
Loc, getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn), \
getLocalValue(ValID, getSILType(MF->getType(TyID2), \
(SILValueCategory)TyCategory2, Fn))); \
break;
ONETYPE_ONEOPERAND_INST(ValueMetatype)
ONETYPE_ONEOPERAND_INST(ExistentialMetatype)
ONETYPE_ONEOPERAND_INST(ProjectExistentialBox)
#undef ONETYPE_ONEOPERAND_INST
case SILInstructionKind::DeallocBoxInst:
assert(RecordKind == SIL_ONE_TYPE_ONE_OPERAND &&
"Layout should be OneTypeOneOperand.");
ResultInst = Builder.createDeallocBox(
Loc,
getLocalValue(ValID, getSILType(MF->getType(TyID2),
(SILValueCategory)TyCategory2, Fn)));
break;
case SILInstructionKind::OpenExistentialAddrInst:
assert(RecordKind == SIL_ONE_TYPE_ONE_OPERAND &&
"Layout should be OneTypeOneOperand.");
ResultInst = Builder.createOpenExistentialAddr(
Loc,
getLocalValue(ValID, getSILType(MF->getType(TyID2),
(SILValueCategory)TyCategory2, Fn)),
getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn),
Attr == 0 ? OpenedExistentialAccess::Immutable
: OpenedExistentialAccess::Mutable);
break;
#define ONEOPERAND_ONETYPE_INST(ID) \
case SILInstructionKind::ID##Inst: \
assert(RecordKind == SIL_ONE_TYPE_ONE_OPERAND && \
"Layout should be OneTypeOneOperand."); \
ResultInst = Builder.create##ID( \
Loc, \
getLocalValue(ValID, getSILType(MF->getType(TyID2), \
(SILValueCategory)TyCategory2, Fn)), \
getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn)); \
break;
ONEOPERAND_ONETYPE_INST(OpenExistentialRef)
ONEOPERAND_ONETYPE_INST(OpenExistentialMetatype)
ONEOPERAND_ONETYPE_INST(OpenExistentialBox)
ONEOPERAND_ONETYPE_INST(OpenExistentialValue)
ONEOPERAND_ONETYPE_INST(OpenExistentialBoxValue)
// Conversion instructions.
#define LOADABLE_REF_STORAGE(Name, ...) \
ONEOPERAND_ONETYPE_INST(RefTo##Name) \
ONEOPERAND_ONETYPE_INST(Name##ToRef)
#include "swift/AST/ReferenceStorage.def"
ONEOPERAND_ONETYPE_INST(UncheckedRefCast)
ONEOPERAND_ONETYPE_INST(UncheckedAddrCast)
ONEOPERAND_ONETYPE_INST(UncheckedTrivialBitCast)
ONEOPERAND_ONETYPE_INST(UncheckedBitwiseCast)
ONEOPERAND_ONETYPE_INST(UncheckedValueCast)
ONEOPERAND_ONETYPE_INST(BridgeObjectToRef)
ONEOPERAND_ONETYPE_INST(BridgeObjectToWord)
ONEOPERAND_ONETYPE_INST(Upcast)
ONEOPERAND_ONETYPE_INST(AddressToPointer)
ONEOPERAND_ONETYPE_INST(RefToRawPointer)
ONEOPERAND_ONETYPE_INST(RawPointerToRef)
ONEOPERAND_ONETYPE_INST(ThinToThickFunction)
ONEOPERAND_ONETYPE_INST(ThickToObjCMetatype)
ONEOPERAND_ONETYPE_INST(ObjCToThickMetatype)
ONEOPERAND_ONETYPE_INST(ObjCMetatypeToObject)
ONEOPERAND_ONETYPE_INST(ObjCExistentialMetatypeToObject)
ONEOPERAND_ONETYPE_INST(ThinFunctionToPointer)
ONEOPERAND_ONETYPE_INST(PointerToThinFunction)
ONEOPERAND_ONETYPE_INST(ProjectBlockStorage)
#undef ONEOPERAND_ONETYPE_INST
case SILInstructionKind::ProjectBoxInst: {
assert(RecordKind == SIL_ONE_TYPE_ONE_OPERAND &&
"Layout should be OneTypeOneOperand.");
ResultInst = Builder.createProjectBox(
Loc,
getLocalValue(ValID, getSILType(MF->getType(TyID2),
(SILValueCategory)TyCategory2, Fn)),
TyID);
break;
}
case SILInstructionKind::ConvertEscapeToNoEscapeInst: {
assert(RecordKind == SIL_ONE_TYPE_ONE_OPERAND &&
"Layout should be OneTypeOneOperand.");
bool isLifetimeGuaranteed = Attr & 0x01;
ResultInst = Builder.createConvertEscapeToNoEscape(
Loc,
getLocalValue(ValID, getSILType(MF->getType(TyID2),
(SILValueCategory)TyCategory2, Fn)),
getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn),
isLifetimeGuaranteed);
break;
}
case SILInstructionKind::ConvertFunctionInst: {
assert(RecordKind == SIL_ONE_TYPE_ONE_OPERAND
&& "Layout should be OneTypeOneOperand.");
bool withoutActuallyEscaping = Attr & 0x01;
ResultInst = Builder.createConvertFunction(
Loc,
getLocalValue(ValID, getSILType(MF->getType(TyID2),
(SILValueCategory)TyCategory2, Fn)),
getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn),
withoutActuallyEscaping);
break;
}
case SILInstructionKind::PointerToAddressInst: {
assert(RecordKind == SIL_ONE_TYPE_ONE_OPERAND_EXTRA_ATTR &&
"Layout should be OneTypeOneOperand.");
auto alignment = llvm::decodeMaybeAlign(Attr & 0xFF);
bool isStrict = Attr & 0x100;
bool isInvariant = Attr & 0x200;
ResultInst = Builder.createPointerToAddress(
Loc,
getLocalValue(ValID, getSILType(MF->getType(TyID2),
(SILValueCategory)TyCategory2, Fn)),
getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn),
isStrict, isInvariant, alignment);
break;
}
case SILInstructionKind::DeallocExistentialBoxInst: {
assert(RecordKind == SIL_ONE_TYPE_ONE_OPERAND &&
"Layout should be OneTypeOneOperand.");
ResultInst = Builder.createDeallocExistentialBox(
Loc, MF->getType(TyID)->getCanonicalType(),
getLocalValue(ValID, getSILType(MF->getType(TyID2),
(SILValueCategory)TyCategory2, Fn)));
break;
}
case SILInstructionKind::RefToBridgeObjectInst: {
auto RefTy =
getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn);
auto Ref = getLocalValue(ValID, RefTy);
auto BitsTy =
getSILType(MF->getType(TyID2), (SILValueCategory)TyCategory2, Fn);
auto Bits = getLocalValue(ValID2, BitsTy);
ResultInst = Builder.createRefToBridgeObject(Loc, Ref, Bits);
break;
}
case SILInstructionKind::ObjCProtocolInst: {
auto Ty = getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn);
auto Proto = MF->getDecl(ValID);
ResultInst = Builder.createObjCProtocol(Loc, cast<ProtocolDecl>(Proto), Ty);
break;
}
case SILInstructionKind::InitExistentialAddrInst:
case SILInstructionKind::InitExistentialValueInst:
case SILInstructionKind::InitExistentialMetatypeInst:
case SILInstructionKind::InitExistentialRefInst:
case SILInstructionKind::AllocExistentialBoxInst: {
auto Ty = getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn);
auto Ty2 = MF->getType(TyID2);
CanType ConcreteTy;
if (OpCode != SILInstructionKind::InitExistentialMetatypeInst)
ConcreteTy = MF->getType(ConcreteTyID)->getCanonicalType();
SILValue operand;
if (OpCode != SILInstructionKind::AllocExistentialBoxInst)
operand = getLocalValue(
ValID, getSILType(Ty2, (SILValueCategory)TyCategory2, Fn));
SmallVector<ProtocolConformanceRef, 2> conformances;
while (NumConformances--) {
auto conformance = MF->readConformance(SILCursor);
conformances.push_back(conformance);
}
auto ctxConformances = MF->getContext().AllocateCopy(conformances);
switch (OpCode) {
default: llvm_unreachable("Out of sync with parent switch");
case SILInstructionKind::InitExistentialAddrInst:
ResultInst = Builder.createInitExistentialAddr(Loc, operand, ConcreteTy,
Ty, ctxConformances);
break;
case SILInstructionKind::InitExistentialValueInst:
ResultInst = Builder.createInitExistentialValue(Loc, Ty, ConcreteTy,
operand, ctxConformances);
break;
case SILInstructionKind::InitExistentialMetatypeInst:
ResultInst = Builder.createInitExistentialMetatype(Loc, operand, Ty,
ctxConformances);
break;
case SILInstructionKind::InitExistentialRefInst:
ResultInst = Builder.createInitExistentialRef(Loc, Ty, ConcreteTy,
operand, ctxConformances);
break;
case SILInstructionKind::AllocExistentialBoxInst:
ResultInst = Builder.createAllocExistentialBox(Loc, Ty, ConcreteTy,
ctxConformances);
break;
}
break;
}
case SILInstructionKind::AllocRefInst:
case SILInstructionKind::AllocRefDynamicInst: {
assert(RecordKind == SIL_ONE_TYPE_VALUES &&
"Layout should be OneTypeValues.");
unsigned NumVals = ListOfValues.size();
assert(NumVals >= 1 && "Not enough values");
unsigned Flags = ListOfValues[0];
bool isObjC = (bool)(Flags & 1);
bool canAllocOnStack = (bool)((Flags >> 1) & 1);
SILType ClassTy =
getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn);
SmallVector<SILValue, 4> Counts;
SmallVector<SILType, 4> TailTypes;
unsigned i = 1;
for (; i + 2 < NumVals; i += 3) {
SILType TailType = getSILType(MF->getType(ListOfValues[i]),
SILValueCategory::Object, Fn);
TailTypes.push_back(TailType);
SILType CountType = getSILType(MF->getType(ListOfValues[i + 2]),
SILValueCategory::Object, Fn);
SILValue CountVal = getLocalValue(ListOfValues[i+1], CountType);
Counts.push_back(CountVal);
}
if (OpCode == SILInstructionKind::AllocRefDynamicInst) {
assert(i + 2 == NumVals);
assert(!canAllocOnStack);
SILType MetadataType = getSILType(MF->getType(ListOfValues[i+1]),
SILValueCategory::Object, Fn);
SILValue MetadataOp = getLocalValue(ListOfValues[i], MetadataType);
ResultInst = Builder.createAllocRefDynamic(Loc, MetadataOp, ClassTy,
isObjC, TailTypes, Counts);
} else {
assert(i == NumVals);
ResultInst = Builder.createAllocRef(Loc, ClassTy, isObjC, canAllocOnStack,
TailTypes, Counts);
}
break;
}
case SILInstructionKind::ApplyInst:
case SILInstructionKind::BeginApplyInst: {
// Format: attributes such as transparent, the callee's type, a value for
// the callee and a list of values for the arguments. Each value in the list
// is represented with 2 IDs: ValueID and ValueResultNumber.
auto Ty = MF->getType(TyID);
auto Ty2 = MF->getType(TyID2);
SILType FnTy = getSILType(Ty, SILValueCategory::Object, Fn);
SILType SubstFnTy = getSILType(Ty2, SILValueCategory::Object, Fn);
SILFunctionConventions substConventions(SubstFnTy.castTo<SILFunctionType>(),
Builder.getModule());
assert(substConventions.getNumSILArguments() == ListOfValues.size()
&& "Argument number mismatch in ApplyInst.");
SmallVector<SILValue, 4> Args;
for (unsigned I = 0, E = ListOfValues.size(); I < E; ++I)
Args.push_back(getLocalValue(ListOfValues[I],
substConventions.getSILArgumentType(
I, Builder.getTypeExpansionContext())));
SubstitutionMap Substitutions = MF->getSubstitutionMap(NumSubs);
if (OpCode == SILInstructionKind::ApplyInst) {
ResultInst =
Builder.createApply(Loc, getLocalValue(ValID, FnTy), Substitutions,
Args, ApplyOpts);
} else {
ResultInst = Builder.createBeginApply(Loc, getLocalValue(ValID, FnTy),
Substitutions, Args, ApplyOpts);
}
break;
}
case SILInstructionKind::TryApplyInst: {
// Format: attributes such as transparent, the callee's type, a value for
// the callee and a list of values for the arguments. Each value in the list
// is represented with 2 IDs: ValueID and ValueResultNumber. The final
// two values in the list are the basic block identifiers.
auto Ty = MF->getType(TyID);
auto Ty2 = MF->getType(TyID2);
SILType FnTy = getSILType(Ty, SILValueCategory::Object, Fn);
SILType SubstFnTy = getSILType(Ty2, SILValueCategory::Object, Fn);
SILBasicBlock *errorBB = getBBForReference(Fn, ListOfValues.back());
ListOfValues = ListOfValues.drop_back();
SILBasicBlock *normalBB = getBBForReference(Fn, ListOfValues.back());
ListOfValues = ListOfValues.drop_back();
SILFunctionConventions substConventions(SubstFnTy.castTo<SILFunctionType>(),
Builder.getModule());
assert(substConventions.getNumSILArguments() == ListOfValues.size()
&& "Argument number mismatch in ApplyInst.");
SmallVector<SILValue, 4> Args;
for (unsigned I = 0, E = ListOfValues.size(); I < E; ++I)
Args.push_back(getLocalValue(ListOfValues[I],
substConventions.getSILArgumentType(
I, Builder.getTypeExpansionContext())));
SubstitutionMap Substitutions = MF->getSubstitutionMap(NumSubs);
ResultInst = Builder.createTryApply(Loc, getLocalValue(ValID, FnTy),
Substitutions, Args, normalBB, errorBB,
ApplyOpts);
break;
}
case SILInstructionKind::PartialApplyInst: {
auto Ty = MF->getType(TyID);
auto Ty2 = MF->getType(TyID2);
SILType FnTy = getSILType(Ty, SILValueCategory::Object, Fn);
SILType closureTy = getSILType(Ty2, SILValueCategory::Object, Fn);
SubstitutionMap Substitutions = MF->getSubstitutionMap(NumSubs);
auto SubstFnTy = SILType::getPrimitiveObjectType(
FnTy.castTo<SILFunctionType>()->substGenericArgs(
Builder.getModule(), Substitutions,
Builder.getTypeExpansionContext()));
SILFunctionConventions fnConv(SubstFnTy.castTo<SILFunctionType>(),
Builder.getModule());
unsigned numArgs = fnConv.getNumSILArguments();
assert(numArgs >= ListOfValues.size()
&& "Argument number mismatch in PartialApplyInst.");
SILValue FnVal = getLocalValue(ValID, FnTy);
SmallVector<SILValue, 4> Args;
unsigned unappliedArgs = numArgs - ListOfValues.size();
for (unsigned I = 0, E = ListOfValues.size(); I < E; ++I)
Args.push_back(getLocalValue(
ListOfValues[I],
fnConv.getSILArgumentType(I + unappliedArgs,
Builder.getTypeExpansionContext())));
auto onStack = closureTy.castTo<SILFunctionType>()->isNoEscape()
? PartialApplyInst::OnStackKind::OnStack
: PartialApplyInst::OnStackKind::NotOnStack;
// FIXME: Why the arbitrary order difference in IRBuilder type argument?
ResultInst = Builder.createPartialApply(
Loc, FnVal, Substitutions, Args,
closureTy.castTo<SILFunctionType>()->getCalleeConvention(), onStack);
break;
}
case SILInstructionKind::BuiltinInst: {
auto ASTTy = MF->getType(TyID);
auto ResultTy = getSILType(ASTTy, (SILValueCategory)(unsigned)TyID2, Fn);
SmallVector<SILValue, 4> Args;
for (unsigned i = 0, e = ListOfValues.size(); i < e; i += 3) {
auto ArgASTTy = MF->getType(ListOfValues[i+1]);
auto ArgTy = getSILType(
ArgASTTy, (SILValueCategory)(unsigned)ListOfValues[i + 2], Fn);
Args.push_back(getLocalValue(ListOfValues[i], ArgTy));
}
SubstitutionMap Substitutions = MF->getSubstitutionMap(NumSubs);
Identifier Name = MF->getIdentifier(ValID);
ResultInst =
Builder.createBuiltin(Loc, Name, ResultTy, Substitutions, Args);
break;
}
case SILInstructionKind::AllocGlobalInst: {
// Format: Name and type. Use SILOneOperandLayout.
StringRef Name = MF->getIdentifierText(ValID);
// Find the global variable.
SILGlobalVariable *g = getGlobalForReference(Name);
assert(g && "Can't deserialize global variable");
ResultInst = Builder.createAllocGlobal(Loc, g);
break;
}
case SILInstructionKind::GlobalAddrInst:
case SILInstructionKind::GlobalValueInst: {
// Format: Name and type. Use SILOneOperandLayout.
auto Ty = MF->getType(TyID);
StringRef Name = MF->getIdentifierText(ValID);
// Find the global variable.
SILGlobalVariable *g = getGlobalForReference(Name);
assert(g && "Can't deserialize global variable");
SILType expectedType =
(OpCode == SILInstructionKind::GlobalAddrInst
? g->getLoweredTypeInContext(TypeExpansionContext(*Fn))
.getAddressType()
: g->getLoweredTypeInContext(TypeExpansionContext(*Fn)));
assert(expectedType == getSILType(Ty, (SILValueCategory)TyCategory, Fn) &&
"Type of a global variable does not match GlobalAddr.");
(void)Ty;
(void)expectedType;
if (OpCode == SILInstructionKind::GlobalAddrInst) {
ResultInst = Builder.createGlobalAddr(Loc, g);
} else {
ResultInst = Builder.createGlobalValue(Loc, g);
}
break;
}
case SILInstructionKind::BaseAddrForOffsetInst:
assert(RecordKind == SIL_ONE_TYPE && "Layout should be OneType.");
ResultInst = Builder.createBaseAddrForOffset(
Loc, getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn));
break;
case SILInstructionKind::DeallocStackInst: {
auto Ty = MF->getType(TyID);
ResultInst = Builder.createDeallocStack(
Loc,
getLocalValue(ValID, getSILType(Ty, (SILValueCategory)TyCategory, Fn)));
break;
}
case SILInstructionKind::DeallocStackRefInst: {
auto Ty = MF->getType(TyID);
ResultInst = Builder.createDeallocStackRef(
Loc,
getLocalValue(ValID, getSILType(Ty, (SILValueCategory)TyCategory, Fn)));
break;
}
case SILInstructionKind::DeallocRefInst: {
auto Ty = MF->getType(TyID);
ResultInst = Builder.createDeallocRef(
Loc,
getLocalValue(ValID, getSILType(Ty, (SILValueCategory)TyCategory, Fn)));
break;
}
case SILInstructionKind::DeallocPartialRefInst: {
auto Ty = MF->getType(TyID);
auto Ty2 = MF->getType(TyID2);
ResultInst = Builder.createDeallocPartialRef(
Loc,
getLocalValue(ValID, getSILType(Ty, (SILValueCategory)TyCategory, Fn)),
getLocalValue(ValID2,
getSILType(Ty2, (SILValueCategory)TyCategory2, Fn)));
break;
}
case SILInstructionKind::FunctionRefInst: {
auto Ty = MF->getType(TyID);
StringRef FuncName = MF->getIdentifierText(ValID);
ResultInst = Builder.createFunctionRef(
Loc,
getFuncForReference(
FuncName, getSILType(Ty, (SILValueCategory)TyCategory, nullptr)));
break;
}
case SILInstructionKind::DynamicFunctionRefInst: {
auto Ty = MF->getType(TyID);
StringRef FuncName = MF->getIdentifierText(ValID);
ResultInst = Builder.createDynamicFunctionRef(
Loc,
getFuncForReference(
FuncName, getSILType(Ty, (SILValueCategory)TyCategory, nullptr)));
break;
}
case SILInstructionKind::PreviousDynamicFunctionRefInst: {
auto Ty = MF->getType(TyID);
StringRef FuncName = MF->getIdentifierText(ValID);
ResultInst = Builder.createPreviousDynamicFunctionRef(
Loc,
getFuncForReference(
FuncName, getSILType(Ty, (SILValueCategory)TyCategory, nullptr)));
break;
}
case SILInstructionKind::MarkDependenceInst: {
auto Ty = MF->getType(TyID);
auto Ty2 = MF->getType(TyID2);
ResultInst = Builder.createMarkDependence(
Loc,
getLocalValue(ValID, getSILType(Ty, (SILValueCategory)TyCategory, Fn)),
getLocalValue(ValID2,
getSILType(Ty2, (SILValueCategory)TyCategory2, Fn)));
break;
}
case SILInstructionKind::CopyBlockWithoutEscapingInst: {
auto Ty = MF->getType(TyID);
auto Ty2 = MF->getType(TyID2);
ResultInst = Builder.createCopyBlockWithoutEscaping(
Loc,
getLocalValue(ValID, getSILType(Ty, (SILValueCategory)TyCategory, Fn)),
getLocalValue(ValID2,
getSILType(Ty2, (SILValueCategory)TyCategory2, Fn)));
break;
}
case SILInstructionKind::IndexAddrInst: {
auto Ty = MF->getType(TyID);
auto Ty2 = MF->getType(TyID2);
ResultInst = Builder.createIndexAddr(
Loc,
getLocalValue(ValID, getSILType(Ty, (SILValueCategory)TyCategory, Fn)),
getLocalValue(ValID2,
getSILType(Ty2, (SILValueCategory)TyCategory2, Fn)));
break;
}
case SILInstructionKind::TailAddrInst: {
auto Ty = MF->getType(TyID);
auto Ty2 = MF->getType(TyID2);
auto ResultTy = MF->getType(TyID3);
ResultInst = Builder.createTailAddr(
Loc,
getLocalValue(ValID, getSILType(Ty, SILValueCategory::Address, Fn)),
getLocalValue(ValID2, getSILType(Ty2, SILValueCategory::Object, Fn)),
getSILType(ResultTy, SILValueCategory::Address, Fn));
break;
}
case SILInstructionKind::IndexRawPointerInst: {
auto Ty = MF->getType(TyID);
auto Ty2 = MF->getType(TyID2);
ResultInst = Builder.createIndexRawPointer(
Loc,
getLocalValue(ValID, getSILType(Ty, (SILValueCategory)TyCategory, Fn)),
getLocalValue(ValID2,
getSILType(Ty2, (SILValueCategory)TyCategory2, Fn)));
break;
}
case SILInstructionKind::IntegerLiteralInst: {
auto Ty = MF->getType(TyID);
auto intTy = Ty->castTo<AnyBuiltinIntegerType>();
StringRef text = MF->getIdentifierText(ValID);
bool negate = text[0] == '-';
if (negate) text = text.drop_front();
APInt value = intTy->getWidth().parse(text, 10, negate);
ResultInst = Builder.createIntegerLiteral(
Loc, getSILType(Ty, (SILValueCategory)TyCategory, Fn), value);
break;
}
case SILInstructionKind::FloatLiteralInst: {
auto Ty = MF->getType(TyID);
auto floatTy = Ty->castTo<BuiltinFloatType>();
StringRef StringVal = MF->getIdentifierText(ValID);
// Build APInt from string.
APInt bits(floatTy->getBitWidth(), StringVal, 16);
if (bits.getBitWidth() != floatTy->getBitWidth())
bits = bits.zextOrTrunc(floatTy->getBitWidth());
APFloat value(floatTy->getAPFloatSemantics(), bits);
ResultInst = Builder.createFloatLiteral(
Loc, getSILType(Ty, (SILValueCategory)TyCategory, Fn), value);
break;
}
case SILInstructionKind::StringLiteralInst: {
StringRef StringVal = MF->getIdentifierText(ValID);
auto encoding = fromStableStringEncoding(Attr);
if (!encoding) return true;
ResultInst =
Builder.createStringLiteral(Loc, StringVal, encoding.getValue());
break;
}
case SILInstructionKind::CondFailInst: {
SILValue Op = getLocalValue(
ValID, getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn));
StringRef StringVal = MF->getIdentifierText(ValID2);
ResultInst = Builder.createCondFail(Loc, Op, StringVal);
break;
}
case SILInstructionKind::MarkFunctionEscapeInst: {
// Format: a list of typed values. A typed value is expressed by 4 IDs:
// TypeID, TypeCategory, ValueID, ValueResultNumber.
SmallVector<SILValue, 4> OpList;
for (unsigned I = 0, E = ListOfValues.size(); I < E; I += 3) {
auto EltTy = MF->getType(ListOfValues[I]);
OpList.push_back(getLocalValue(
ListOfValues[I + 2],
getSILType(EltTy, (SILValueCategory)ListOfValues[I + 1], Fn)));
}
ResultInst = Builder.createMarkFunctionEscape(Loc, OpList);
break;
}
// Checked Conversion instructions.
case SILInstructionKind::UnconditionalCheckedCastInst: {
SILType srcLoweredType = getSILType(MF->getType(ListOfValues[1]),
(SILValueCategory)ListOfValues[2], Fn);
SILValue src = getLocalValue(ListOfValues[0], srcLoweredType);
SILType targetLoweredType =
getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn);
CanType targetFormalType =
MF->getType(ListOfValues[3])->getCanonicalType();
ResultInst = Builder.createUnconditionalCheckedCast(
Loc, src, targetLoweredType, targetFormalType);
break;
}
#define UNARY_INSTRUCTION(ID) \
case SILInstructionKind::ID##Inst: \
assert(RecordKind == SIL_ONE_OPERAND && "Layout should be OneOperand."); \
ResultInst = Builder.create##ID( \
Loc, \
getLocalValue(ValID, getSILType(MF->getType(TyID), \
(SILValueCategory)TyCategory, Fn))); \
break;
#define REFCOUNTING_INSTRUCTION(ID) \
case SILInstructionKind::ID##Inst: \
assert(RecordKind == SIL_ONE_OPERAND && "Layout should be OneOperand."); \
ResultInst = Builder.create##ID( \
Loc, \
getLocalValue(ValID, getSILType(MF->getType(TyID), \
(SILValueCategory)TyCategory, Fn)), \
(Atomicity)Attr); \
break;
#define UNCHECKED_REF_STORAGE(Name, ...) \
UNARY_INSTRUCTION(StrongCopy##Name##Value)
#define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
REFCOUNTING_INSTRUCTION(Name##Retain) \
REFCOUNTING_INSTRUCTION(Name##Release) \
REFCOUNTING_INSTRUCTION(StrongRetain##Name) \
UNARY_INSTRUCTION(StrongCopy##Name##Value)
#include "swift/AST/ReferenceStorage.def"
REFCOUNTING_INSTRUCTION(RetainValue)
REFCOUNTING_INSTRUCTION(RetainValueAddr)
REFCOUNTING_INSTRUCTION(UnmanagedRetainValue)
UNARY_INSTRUCTION(CopyValue)
UNARY_INSTRUCTION(ExplicitCopyValue)
REFCOUNTING_INSTRUCTION(ReleaseValue)
REFCOUNTING_INSTRUCTION(ReleaseValueAddr)
REFCOUNTING_INSTRUCTION(UnmanagedReleaseValue)
REFCOUNTING_INSTRUCTION(AutoreleaseValue)
REFCOUNTING_INSTRUCTION(UnmanagedAutoreleaseValue)
REFCOUNTING_INSTRUCTION(SetDeallocating)
UNARY_INSTRUCTION(DeinitExistentialAddr)
UNARY_INSTRUCTION(DeinitExistentialValue)
UNARY_INSTRUCTION(EndBorrow)
UNARY_INSTRUCTION(DestroyAddr)
UNARY_INSTRUCTION(Return)
UNARY_INSTRUCTION(Throw)
UNARY_INSTRUCTION(ClassifyBridgeObject)
UNARY_INSTRUCTION(ValueToBridgeObject)
UNARY_INSTRUCTION(FixLifetime)
UNARY_INSTRUCTION(EndLifetime)
UNARY_INSTRUCTION(CopyBlock)
UNARY_INSTRUCTION(LoadBorrow)
REFCOUNTING_INSTRUCTION(StrongRetain)
REFCOUNTING_INSTRUCTION(StrongRelease)
UNARY_INSTRUCTION(IsUnique)
UNARY_INSTRUCTION(AbortApply)
UNARY_INSTRUCTION(EndApply)
UNARY_INSTRUCTION(ExtractExecutor)
#undef UNARY_INSTRUCTION
#undef REFCOUNTING_INSTRUCTION
case SILInstructionKind::BeginBorrowInst: {
assert(RecordKind == SIL_ONE_OPERAND && "Layout should be OneOperand.");
bool isLexical = Attr & 0x1;
ResultInst = Builder.createBeginBorrow(
Loc,
getLocalValue(ValID, getSILType(MF->getType(TyID),
(SILValueCategory)TyCategory, Fn)),
isLexical);
break;
}
case SILInstructionKind::IsEscapingClosureInst: {
assert(RecordKind == SIL_ONE_OPERAND && "Layout should be OneOperand.");
unsigned verificationType = Attr;
ResultInst = Builder.createIsEscapingClosure(
Loc,
getLocalValue(ValID, getSILType(MF->getType(TyID),
(SILValueCategory)TyCategory, Fn)),
verificationType);
break;
}
case SILInstructionKind::HopToExecutorInst: {
assert(RecordKind == SIL_ONE_OPERAND && "Layout should be OneOperand.");
unsigned mandatory = Attr;
ResultInst = Builder.createHopToExecutor(
Loc,
getLocalValue(ValID, getSILType(MF->getType(TyID),
(SILValueCategory)TyCategory, Fn)),
mandatory != 0);
break;
}
case SILInstructionKind::DestroyValueInst: {
assert(RecordKind == SIL_ONE_OPERAND && "Layout should be OneOperand.");
unsigned poisonRefs = Attr;
ResultInst = Builder.createDestroyValue(
Loc,
getLocalValue(ValID, getSILType(MF->getType(TyID),
(SILValueCategory)TyCategory, Fn)),
poisonRefs != 0);
break;
}
case SILInstructionKind::BeginCOWMutationInst: {
assert(RecordKind == SIL_ONE_OPERAND && "Layout should be OneOperand.");
unsigned isNative = Attr;
ResultInst = Builder.createBeginCOWMutation(
Loc,
getLocalValue(ValID, getSILType(MF->getType(TyID),
(SILValueCategory)TyCategory, Fn)),
isNative != 0);
break;
}
case SILInstructionKind::EndCOWMutationInst: {
assert(RecordKind == SIL_ONE_OPERAND && "Layout should be OneOperand.");
unsigned keepUnique = Attr;
ResultInst = Builder.createEndCOWMutation(
Loc,
getLocalValue(ValID, getSILType(MF->getType(TyID),
(SILValueCategory)TyCategory, Fn)),
keepUnique != 0);
break;
}
case SILInstructionKind::DestructureTupleInst: {
assert(RecordKind == SIL_ONE_OPERAND && "Layout should be OneOperand.");
SILValue Operand = getLocalValue(
ValID, getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn));
ResultInst = Builder.createDestructureTuple(Loc, Operand);
break;
}
case SILInstructionKind::DestructureStructInst: {
assert(RecordKind == SIL_ONE_OPERAND && "Layout should be OneOperand.");
SILValue Operand = getLocalValue(
ValID, getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn));
ResultInst = Builder.createDestructureStruct(Loc, Operand);
break;
}
case SILInstructionKind::UncheckedOwnershipConversionInst: {
auto Ty = MF->getType(TyID);
auto ResultKind = decodeValueOwnership(Attr);
ResultInst = Builder.createUncheckedOwnershipConversion(
Loc,
getLocalValue(ValID, getSILType(Ty, (SILValueCategory)TyCategory, Fn)),
ResultKind);
break;
}
case SILInstructionKind::MoveValueInst: {
auto Ty = MF->getType(TyID);
bool AllowsDiagnostics = Attr & 0x1;
bool IsLexical = (Attr >> 1) & 0x1;
auto *MVI = Builder.createMoveValue(
Loc,
getLocalValue(ValID, getSILType(Ty, (SILValueCategory)TyCategory, Fn)),
IsLexical);
MVI->setAllowsDiagnostics(AllowsDiagnostics);
ResultInst = MVI;
break;
}
case SILInstructionKind::LoadInst: {
auto Ty = MF->getType(TyID);
auto Qualifier = LoadOwnershipQualifier(Attr);
ResultInst = Builder.createLoad(
Loc,
getLocalValue(ValID, getSILType(Ty, (SILValueCategory)TyCategory, Fn)),
Qualifier);
break;
}
#define NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
case SILInstructionKind::Load##Name##Inst: { \
auto Ty = MF->getType(TyID); \
bool isTake = (Attr > 0); \
auto Val = getLocalValue( \
ValID, getSILType(Ty, SILValueCategory(TyCategory), Fn)); \
ResultInst = Builder.createLoad##Name(Loc, Val, IsTake_t(isTake)); \
break; \
} \
case SILInstructionKind::Store##Name##Inst: { \
auto Ty = MF->getType(TyID); \
SILType addrType = getSILType(Ty, (SILValueCategory)TyCategory, Fn); \
auto refType = addrType.castTo<Name##StorageType>(); \
auto ValType = SILType::getPrimitiveObjectType(refType.getReferentType()); \
bool isInit = (Attr > 0); \
ResultInst = Builder.createStore##Name(Loc, getLocalValue(ValID, ValType), \
getLocalValue(ValID2, addrType), \
IsInitialization_t(isInit)); \
break; \
}
#include "swift/AST/ReferenceStorage.def"
case SILInstructionKind::MarkUninitializedInst: {
auto Ty = getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn);
auto Kind = (MarkUninitializedInst::Kind)Attr;
auto Val = getLocalValue(ValID, Ty);
ResultInst = Builder.createMarkUninitialized(Loc, Val, Kind);
break;
}
case SILInstructionKind::StoreInst: {
auto Ty = MF->getType(TyID);
SILType addrType = getSILType(Ty, (SILValueCategory)TyCategory, Fn);
SILType ValType = addrType.getObjectType();
auto Qualifier = StoreOwnershipQualifier(Attr);
ResultInst =
Builder.createStore(Loc, getLocalValue(ValID, ValType),
getLocalValue(ValID2, addrType), Qualifier);
break;
}
case SILInstructionKind::StoreBorrowInst: {
auto Ty = MF->getType(TyID);
SILType addrType = getSILType(Ty, (SILValueCategory)TyCategory, Fn);
SILType ValType = addrType.getObjectType();
ResultInst = Builder.createStoreBorrow(Loc, getLocalValue(ValID, ValType),
getLocalValue(ValID2, addrType));
break;
}
case SILInstructionKind::BeginAccessInst: {
SILValue op = getLocalValue(
ValID, getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn));
auto accessKind = SILAccessKind(Attr & 0x3);
auto enforcement = SILAccessEnforcement((Attr >> 2) & 0x3);
bool noNestedConflict = (Attr >> 4) & 0x01;
bool fromBuiltin = (Attr >> 5) & 0x01;
ResultInst = Builder.createBeginAccess(Loc, op, accessKind, enforcement,
noNestedConflict, fromBuiltin);
break;
}
case SILInstructionKind::EndAccessInst: {
SILValue op = getLocalValue(
ValID, getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn));
bool aborted = Attr & 0x1;
ResultInst = Builder.createEndAccess(Loc, op, aborted);
break;
}
case SILInstructionKind::BeginUnpairedAccessInst: {
SILValue source = getLocalValue(
ValID, getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn));
SILValue buffer =
getLocalValue(ValID2, getSILType(MF->getType(TyID2),
(SILValueCategory)TyCategory2, Fn));
auto accessKind = SILAccessKind(Attr & 0x3);
auto enforcement = SILAccessEnforcement((Attr >> 2) & 0x03);
bool noNestedConflict = (Attr >> 4) & 0x01;
bool fromBuiltin = (Attr >> 5) & 0x01;
ResultInst = Builder.createBeginUnpairedAccess(
Loc, source, buffer, accessKind, enforcement, noNestedConflict,
fromBuiltin);
break;
}
case SILInstructionKind::EndUnpairedAccessInst: {
SILValue op = getLocalValue(
ValID, getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn));
bool aborted = Attr & 0x1;
auto enforcement = SILAccessEnforcement((Attr >> 1) & 0x03);
bool fromBuiltin = (Attr >> 3) & 0x01;
ResultInst = Builder.createEndUnpairedAccess(Loc, op, enforcement, aborted,
fromBuiltin);
break;
}
case SILInstructionKind::CopyAddrInst: {
auto Ty = MF->getType(TyID);
SILType addrType = getSILType(Ty, (SILValueCategory)TyCategory, Fn);
bool isInit = (Attr & 0x2) > 0;
bool isTake = (Attr & 0x1) > 0;
ResultInst = Builder.createCopyAddr(
Loc, getLocalValue(ValID, addrType), getLocalValue(ValID2, addrType),
IsTake_t(isTake), IsInitialization_t(isInit));
break;
}
case SILInstructionKind::MarkUnresolvedMoveAddrInst: {
auto Ty = MF->getType(TyID);
SILType addrType = getSILType(Ty, (SILValueCategory)TyCategory, Fn);
ResultInst = Builder.createMarkUnresolvedMoveAddr(
Loc, getLocalValue(ValID, addrType), getLocalValue(ValID2, addrType));
break;
}
case SILInstructionKind::AssignInst: {
auto Ty = MF->getType(TyID);
SILType addrType = getSILType(Ty, (SILValueCategory)TyCategory, Fn);
SILType valType = addrType.getObjectType();
auto qualifier = AssignOwnershipQualifier(Attr);
ResultInst =
Builder.createAssign(Loc, getLocalValue(ValID, valType),
getLocalValue(ValID2, addrType), qualifier);
break;
}
case SILInstructionKind::AssignByWrapperInst:
llvm_unreachable("not supported");
case SILInstructionKind::BindMemoryInst: {
assert(RecordKind == SIL_ONE_TYPE_VALUES &&
"Layout should be OneTypeValues.");
auto Ty = MF->getType(TyID); // BoundTy
ResultInst = Builder.createBindMemory(
Loc,
getLocalValue(ListOfValues[2],
getSILType(MF->getType(ListOfValues[0]),
(SILValueCategory)ListOfValues[1], Fn)),
getLocalValue(ListOfValues[5],
getSILType(MF->getType(ListOfValues[3]),
(SILValueCategory)ListOfValues[4], Fn)),
getSILType(Ty, (SILValueCategory)TyCategory, Fn));
break;
}
case SILInstructionKind::RebindMemoryInst: {
assert(RecordKind == SIL_TWO_OPERANDS && "Layout should be TwoOperands.");
auto Ty = MF->getType(TyID);
auto Ty2 = MF->getType(TyID2);
ResultInst = Builder.createRebindMemory(
Loc,
getLocalValue(ValID, getSILType(Ty, (SILValueCategory)TyCategory, Fn)),
getLocalValue(ValID2,
getSILType(Ty2, (SILValueCategory)TyCategory2, Fn)));
break;
}
case SILInstructionKind::StructElementAddrInst:
case SILInstructionKind::StructExtractInst: {
// Use SILOneValueOneOperandLayout.
VarDecl *Field = cast<VarDecl>(MF->getDecl(ValID));
auto Ty = MF->getType(TyID);
auto Val =
getLocalValue(ValID2, getSILType(Ty, (SILValueCategory)TyCategory, Fn));
auto ResultTy = Val->getType().getFieldType(
Field, SILMod, Builder.getTypeExpansionContext());
if (OpCode == SILInstructionKind::StructElementAddrInst)
ResultInst = Builder.createStructElementAddr(Loc, Val, Field,
ResultTy.getAddressType());
else
ResultInst = Builder.createStructExtract(Loc, Val, Field,
ResultTy.getObjectType());
break;
}
case SILInstructionKind::StructInst: {
// Format: a type followed by a list of typed values. A typed value is
// expressed by 4 IDs: TypeID, TypeCategory, ValueID, ValueResultNumber.
auto Ty = MF->getType(TyID);
SmallVector<SILValue, 4> OpList;
for (unsigned I = 0, E = ListOfValues.size(); I < E; I += 3) {
auto EltTy = MF->getType(ListOfValues[I]);
OpList.push_back(getLocalValue(
ListOfValues[I + 2],
getSILType(EltTy, (SILValueCategory)ListOfValues[I + 1], Fn)));
}
ResultInst = Builder.createStruct(
Loc, getSILType(Ty, (SILValueCategory)TyCategory, Fn), OpList);
break;
}
case SILInstructionKind::TupleElementAddrInst:
case SILInstructionKind::TupleExtractInst: {
// Use OneTypeOneOperand layout where the field number is stored in TypeID.
auto Ty2 = MF->getType(TyID2);
SILType ST = getSILType(Ty2, (SILValueCategory)TyCategory2, Fn);
TupleType *TT = ST.castTo<TupleType>();
auto ResultTy = TT->getElement(TyID).getType();
switch (OpCode) {
default: llvm_unreachable("Out of sync with parent switch");
case SILInstructionKind::TupleElementAddrInst:
ResultInst = Builder.createTupleElementAddr(
Loc, getLocalValue(ValID, ST), TyID,
getSILType(ResultTy, SILValueCategory::Address, Fn));
break;
case SILInstructionKind::TupleExtractInst:
ResultInst = Builder.createTupleExtract(
Loc, getLocalValue(ValID, ST), TyID,
getSILType(ResultTy, SILValueCategory::Object, Fn));
break;
}
break;
}
case SILInstructionKind::TupleInst: {
// Format: a type followed by a list of values. A value is expressed by
// 2 IDs: ValueID, ValueResultNumber.
auto Ty = MF->getType(TyID);
TupleType *TT = Ty->castTo<TupleType>();
assert(TT && "Type of a TupleInst should be TupleType");
SmallVector<SILValue, 4> OpList;
for (unsigned I = 0, E = ListOfValues.size(); I < E; ++I) {
Type EltTy = TT->getElement(I).getType();
OpList.push_back(
getLocalValue(ListOfValues[I],
getSILType(EltTy, SILValueCategory::Object, Fn)));
}
ResultInst = Builder.createTuple(
Loc, getSILType(Ty, (SILValueCategory)TyCategory, Fn), OpList);
break;
}
case SILInstructionKind::ObjectInst: {
assert(RecordKind == SIL_ONE_TYPE_VALUES &&
"Layout should be OneTypeValues.");
unsigned NumVals = ListOfValues.size();
assert(NumVals >= 1 && "Not enough values");
unsigned numBaseElements = ListOfValues[0];
SILType ClassTy =
getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn);
SmallVector<SILValue, 4> elements;
for (unsigned i = 1; i < NumVals; i += 2) {
SILType elementType = getSILType(MF->getType(ListOfValues[i + 1]),
SILValueCategory::Object, Fn);
SILValue elementVal = getLocalValue(ListOfValues[i], elementType);
elements.push_back(elementVal);
}
ResultInst = Builder.createObject(Loc, ClassTy, elements, numBaseElements);
break;
}
case SILInstructionKind::BranchInst: {
SmallVector<SILValue, 4> Args;
for (unsigned I = 0, E = ListOfValues.size(); I < E; I += 3)
Args.push_back(
getLocalValue(ListOfValues[I + 2],
getSILType(MF->getType(ListOfValues[I]),
(SILValueCategory)ListOfValues[I + 1], Fn)));
ResultInst = Builder.createBranch(Loc, getBBForReference(Fn, TyID), Args);
break;
}
case SILInstructionKind::CondBranchInst: {
// Format: condition, true basic block ID, a list of arguments, false basic
// block ID, a list of arguments. Use SILOneTypeValuesLayout: the type is
// for condition, the list has value for condition, true basic block ID,
// false basic block ID, number of true arguments, and a list of true|false
// arguments.
SILValue Cond = getLocalValue(
ListOfValues[0],
getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn));
unsigned NumTrueArgs = ListOfValues[3];
unsigned StartOfTrueArg = 4;
unsigned StartOfFalseArg = StartOfTrueArg + 3*NumTrueArgs;
SmallVector<SILValue, 4> TrueArgs;
for (unsigned I = StartOfTrueArg, E = StartOfFalseArg; I < E; I += 3)
TrueArgs.push_back(
getLocalValue(ListOfValues[I + 2],
getSILType(MF->getType(ListOfValues[I]),
(SILValueCategory)ListOfValues[I + 1], Fn)));
SmallVector<SILValue, 4> FalseArgs;
for (unsigned I = StartOfFalseArg, E = ListOfValues.size(); I < E; I += 3)
FalseArgs.push_back(
getLocalValue(ListOfValues[I + 2],
getSILType(MF->getType(ListOfValues[I]),
(SILValueCategory)ListOfValues[I + 1], Fn)));
ResultInst = Builder.createCondBranch(
Loc, Cond, getBBForReference(Fn, ListOfValues[1]), TrueArgs,
getBBForReference(Fn, ListOfValues[2]), FalseArgs);
break;
}
case SILInstructionKind::AwaitAsyncContinuationInst: {
// Format: continuation, resume block ID, error block ID if given
SILValue Cont = getLocalValue(
ListOfValues[0],
getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn));
SILBasicBlock *resultBB = getBBForReference(Fn, ListOfValues[1]);
SILBasicBlock *errorBB = nullptr;
if (ListOfValues.size() >= 3) {
errorBB = getBBForReference(Fn, ListOfValues[2]);
}
ResultInst = Builder.createAwaitAsyncContinuation(Loc, Cont, resultBB, errorBB);
break;
}
case SILInstructionKind::SwitchEnumInst:
case SILInstructionKind::SwitchEnumAddrInst: {
// Format: condition, a list of cases (EnumElementDecl + Basic Block ID),
// default basic block ID. Use SILOneTypeValuesLayout: the type is
// for condition, the list has value for condition, hasDefault, default
// basic block ID, a list of (DeclID, BasicBlock ID).
SILValue Cond = getLocalValue(
ListOfValues[0],
getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn));
SILBasicBlock *DefaultBB = nullptr;
if (ListOfValues[1])
DefaultBB = getBBForReference(Fn, ListOfValues[2]);
SmallVector<std::pair<EnumElementDecl*, SILBasicBlock*>, 4> CaseBBs;
for (unsigned I = 3, E = ListOfValues.size(); I < E; I += 2) {
CaseBBs.push_back( {cast<EnumElementDecl>(MF->getDecl(ListOfValues[I])),
getBBForReference(Fn, ListOfValues[I+1])} );
}
if (OpCode == SILInstructionKind::SwitchEnumInst) {
ResultInst = Builder.createSwitchEnum(Loc, Cond, DefaultBB, CaseBBs,
None, ProfileCounter(),
forwardingOwnership);
} else {
ResultInst = Builder.createSwitchEnumAddr(Loc, Cond, DefaultBB, CaseBBs);
}
break;
}
case SILInstructionKind::SelectEnumInst:
case SILInstructionKind::SelectEnumAddrInst: {
// Format: condition, a list of cases (EnumElementDecl + Value ID),
// default value ID. Use SILOneTypeValuesLayout: the type is
// for condition, the list has value for condition, result type,
// hasDefault, default
// basic block ID, a list of (DeclID, BasicBlock ID).
SILValue Cond = getLocalValue(ListOfValues[0],
getSILType(MF->getType(TyID),
(SILValueCategory)TyCategory, Fn));
Type ResultLoweredTy = MF->getType(ListOfValues[1]);
SILValueCategory ResultCategory = (SILValueCategory)ListOfValues[2];
SILType ResultTy = getSILType(ResultLoweredTy, ResultCategory, Fn);
SILValue DefaultVal = nullptr;
if (ListOfValues[3])
DefaultVal = getLocalValue(ListOfValues[4], ResultTy);
SmallVector<std::pair<EnumElementDecl*, SILValue>, 4> CaseVals;
for (unsigned I = 5, E = ListOfValues.size(); I < E; I += 2) {
auto Value = getLocalValue(ListOfValues[I+1], ResultTy);
CaseVals.push_back({cast<EnumElementDecl>(MF->getDecl(ListOfValues[I])),
Value});
}
if (OpCode == SILInstructionKind::SelectEnumInst)
ResultInst =
Builder.createSelectEnum(Loc, Cond, ResultTy, DefaultVal, CaseVals);
else
ResultInst = Builder.createSelectEnumAddr(Loc, Cond, ResultTy, DefaultVal,
CaseVals);
break;
}
case SILInstructionKind::SwitchValueInst: {
// Format: condition, a list of cases (Value ID + Basic Block ID),
// default basic block ID. Use SILOneTypeValuesLayout: the type is
// for condition, the list contains value for condition, hasDefault, default
// basic block ID, a list of (Value ID, BasicBlock ID).
SILType ResultTy = getSILType(MF->getType(TyID),
(SILValueCategory)TyCategory, Fn);
SILValue Cond = getLocalValue(
ListOfValues[0],
getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn));
SILBasicBlock *DefaultBB = nullptr;
if (ListOfValues[1])
DefaultBB = getBBForReference(Fn, ListOfValues[2]);
SmallVector<std::pair<SILValue, SILBasicBlock*>, 4> CaseBBs;
for (unsigned I = 3, E = ListOfValues.size(); I < E; I += 2) {
auto value = getLocalValue(ListOfValues[I], ResultTy);
CaseBBs.push_back( {value, getBBForReference(Fn, ListOfValues[I+1])} );
}
ResultInst = Builder.createSwitchValue(Loc, Cond, DefaultBB, CaseBBs);
break;
}
case SILInstructionKind::SelectValueInst: {
// Format: condition, a list of cases (ValueID + Value ID),
// default value ID. Use SILOneTypeValuesLayout: the type is
// for condition, the list has value for condition, result type,
// hasDefault, default,
// basic block ID, a list of (Value ID, Value ID).
SILValue Cond = getLocalValue(
ListOfValues[0],
getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn));
Type ResultLoweredTy = MF->getType(ListOfValues[1]);
SILValueCategory ResultCategory = (SILValueCategory)ListOfValues[2];
SILType ResultTy = getSILType(ResultLoweredTy, ResultCategory, Fn);
SILValue DefaultVal = nullptr;
if (ListOfValues[3])
DefaultVal = getLocalValue(ListOfValues[4], ResultTy);
SmallVector<std::pair<SILValue, SILValue>, 4> CaseValuesAndResults;
for (unsigned I = 5, E = ListOfValues.size(); I < E; I += 2) {
auto CaseValue = getLocalValue(ListOfValues[I], Cond->getType());
auto Result = getLocalValue(ListOfValues[I+1], ResultTy);
CaseValuesAndResults.push_back({CaseValue, Result});
}
ResultInst = Builder.createSelectValue(Loc, Cond, ResultTy, DefaultVal,
CaseValuesAndResults);
break;
}
case SILInstructionKind::EnumInst: {
// Format: a type, an operand and a decl ID. Use SILTwoOperandsLayout: type,
// (DeclID + hasOperand), and an operand.
SILValue Operand;
if (Attr)
Operand =
getLocalValue(ValID2, getSILType(MF->getType(TyID2),
(SILValueCategory)TyCategory2, Fn));
ResultInst = Builder.createEnum(
Loc, Operand, cast<EnumElementDecl>(MF->getDecl(ValID)),
getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn));
break;
}
case SILInstructionKind::InitEnumDataAddrInst: {
// Use SILOneValueOneOperandLayout.
EnumElementDecl *Elt = cast<EnumElementDecl>(MF->getDecl(ValID));
SILType OperandTy = getSILType(MF->getType(TyID),
(SILValueCategory) TyCategory, Fn);
SILType ResultTy = OperandTy.getEnumElementType(
Elt, SILMod, Builder.getTypeExpansionContext());
ResultInst = Builder.createInitEnumDataAddr(
Loc, getLocalValue(ValID2, OperandTy), Elt, ResultTy);
break;
}
case SILInstructionKind::UncheckedEnumDataInst: {
// Use SILOneValueOneOperandLayout.
EnumElementDecl *Elt = cast<EnumElementDecl>(MF->getDecl(ValID));
SILType OperandTy =
getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn);
SILType ResultTy = OperandTy.getEnumElementType(
Elt, SILMod, Builder.getTypeExpansionContext());
ResultInst = Builder.createUncheckedEnumData(
Loc, getLocalValue(ValID2, OperandTy), Elt, ResultTy);
break;
}
case SILInstructionKind::UncheckedTakeEnumDataAddrInst: {
// Use SILOneValueOneOperandLayout.
EnumElementDecl *Elt = cast<EnumElementDecl>(MF->getDecl(ValID));
SILType OperandTy =
getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn);
SILType ResultTy = OperandTy.getEnumElementType(
Elt, SILMod, Builder.getTypeExpansionContext());
ResultInst = Builder.createUncheckedTakeEnumDataAddr(
Loc, getLocalValue(ValID2, OperandTy), Elt, ResultTy);
break;
}
case SILInstructionKind::InjectEnumAddrInst: {
// Use SILOneValueOneOperandLayout.
EnumElementDecl *Elt = cast<EnumElementDecl>(MF->getDecl(ValID));
auto Ty = MF->getType(TyID);
ResultInst = Builder.createInjectEnumAddr(
Loc,
getLocalValue(ValID2, getSILType(Ty, (SILValueCategory)TyCategory, Fn)),
Elt);
break;
}
case SILInstructionKind::RefElementAddrInst: {
// Use SILOneValueOneOperandLayout.
VarDecl *Field = cast<VarDecl>(MF->getDecl(ValID));
auto Ty = MF->getType(TyID);
auto Val = getLocalValue(ValID2,
getSILType(Ty, (SILValueCategory)TyCategory, Fn));
auto ResultTy = Val->getType().getFieldType(
Field, SILMod, Builder.getTypeExpansionContext());
ResultInst = Builder.createRefElementAddr(Loc, Val, Field, ResultTy,
/*Immutable*/ Attr & 0x1);
break;
}
case SILInstructionKind::RefTailAddrInst: {
assert(RecordKind == SIL_ONE_TYPE_ONE_OPERAND &&
"Layout should be OneTypeOneOperand.");
assert((SILValueCategory)TyCategory == SILValueCategory::Address);
ResultInst = Builder.createRefTailAddr(
Loc,
getLocalValue(ValID, getSILType(MF->getType(TyID2),
(SILValueCategory)TyCategory2, Fn)),
getSILType(MF->getType(TyID), SILValueCategory::Address, Fn),
/*Immutable*/ Attr & 0x1);
break;
}
case SILInstructionKind::ClassMethodInst:
case SILInstructionKind::SuperMethodInst:
case SILInstructionKind::ObjCMethodInst:
case SILInstructionKind::ObjCSuperMethodInst: {
// Format: a type, an operand and a SILDeclRef. Use SILOneTypeValuesLayout:
// type, Attr, SILDeclRef (DeclID, Kind, uncurryLevel), and an operand.
unsigned NextValueIndex = 0;
SILDeclRef DRef = getSILDeclRef(MF, ListOfValues, NextValueIndex);
SILType Ty =
getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn);
assert(ListOfValues.size() >= NextValueIndex + 2 &&
"Out of entries for MethodInst");
SILType operandTy =
getSILType(MF->getType(ListOfValues[NextValueIndex]),
(SILValueCategory)ListOfValues[NextValueIndex + 1], Fn);
NextValueIndex += 2;
switch (OpCode) {
default: llvm_unreachable("Out of sync with parent switch");
case SILInstructionKind::ClassMethodInst:
ResultInst = Builder.createClassMethod(
Loc, getLocalValue(ListOfValues[NextValueIndex], operandTy), DRef,
Ty);
break;
case SILInstructionKind::SuperMethodInst:
ResultInst = Builder.createSuperMethod(
Loc, getLocalValue(ListOfValues[NextValueIndex], operandTy), DRef,
Ty);
break;
case SILInstructionKind::ObjCMethodInst:
ResultInst = Builder.createObjCMethod(
Loc, getLocalValue(ListOfValues[NextValueIndex], operandTy), DRef,
Ty);
break;
case SILInstructionKind::ObjCSuperMethodInst:
ResultInst = Builder.createObjCSuperMethod(
Loc, getLocalValue(ListOfValues[NextValueIndex], operandTy), DRef,
Ty);
break;
}
break;
}
case SILInstructionKind::WitnessMethodInst: {
unsigned NextValueIndex = 0;
SILDeclRef DRef = getSILDeclRef(MF, ListOfValues, NextValueIndex);
assert(ListOfValues.size() >= NextValueIndex &&
"Out of entries for MethodInst");
CanType Ty = MF->getType(TyID)->getCanonicalType();
SILType OperandTy =
getSILType(MF->getType(TyID2), (SILValueCategory)TyCategory2, Fn);
auto Conformance = MF->readConformance(SILCursor);
// Read the optional opened existential.
SILValue ExistentialOperand;
if (TyID3) {
SILType ExistentialOperandTy =
getSILType(MF->getType(TyID3), (SILValueCategory)TyCategory3, Fn);
if (ValID3)
ExistentialOperand = getLocalValue(ValID3, ExistentialOperandTy);
}
ResultInst =
Builder.createWitnessMethod(Loc, Ty, Conformance, DRef, OperandTy);
break;
}
case SILInstructionKind::DynamicMethodBranchInst: {
// Format: a typed value, a SILDeclRef, a BasicBlock ID for method,
// a BasicBlock ID for no method. Use SILOneTypeValuesLayout.
unsigned NextValueIndex = 1;
SILDeclRef DRef = getSILDeclRef(MF, ListOfValues, NextValueIndex);
assert(ListOfValues.size() == NextValueIndex + 2 &&
"Wrong number of entries for DynamicMethodBranchInst");
ResultInst = Builder.createDynamicMethodBranch(
Loc,
getLocalValue(
ListOfValues[0],
getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn)),
DRef, getBBForReference(Fn, ListOfValues[NextValueIndex]),
getBBForReference(Fn, ListOfValues[NextValueIndex + 1]));
break;
}
case SILInstructionKind::CheckedCastBranchInst: {
// Format: the cast kind, a typed value, a BasicBlock ID for success,
// a BasicBlock ID for failure. Uses SILOneTypeValuesLayout.
bool isExact = ListOfValues[0] != 0;
SILType opTy = getSILType(MF->getType(ListOfValues[2]),
(SILValueCategory)ListOfValues[3], Fn);
SILValue op = getLocalValue(ListOfValues[1], opTy);
SILType targetLoweredType =
getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn);
CanType targetFormalType =
MF->getType(ListOfValues[4])->getCanonicalType();
auto *successBB = getBBForReference(Fn, ListOfValues[5]);
auto *failureBB = getBBForReference(Fn, ListOfValues[6]);
ResultInst =
Builder.createCheckedCastBranch(Loc, isExact, op, targetLoweredType,
targetFormalType, successBB, failureBB,
forwardingOwnership);
break;
}
case SILInstructionKind::CheckedCastValueBranchInst: {
CanType srcFormalType = MF->getType(ListOfValues[0])->getCanonicalType();
SILType srcLoweredType = getSILType(MF->getType(ListOfValues[2]),
(SILValueCategory)ListOfValues[3], Fn);
SILValue op = getLocalValue(ListOfValues[1], srcLoweredType);
SILType targetLoweredType =
getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn);
CanType targetFormalType =
MF->getType(ListOfValues[4])->getCanonicalType();
auto *successBB = getBBForReference(Fn, ListOfValues[5]);
auto *failureBB = getBBForReference(Fn, ListOfValues[6]);
ResultInst = Builder.createCheckedCastValueBranch(
Loc, op, srcFormalType, targetLoweredType, targetFormalType, successBB,
failureBB);
break;
}
case SILInstructionKind::UnconditionalCheckedCastValueInst: {
CanType srcFormalType = MF->getType(ListOfValues[0])->getCanonicalType();
SILType srcLoweredType = getSILType(MF->getType(ListOfValues[2]),
(SILValueCategory)ListOfValues[3], Fn);
SILValue src = getLocalValue(ListOfValues[1], srcLoweredType);
SILType targetLoweredType =
getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn);
CanType targetFormalType = MF->getType(ListOfValues[4])->getCanonicalType();
ResultInst = Builder.createUnconditionalCheckedCastValue(
Loc, src, srcFormalType, targetLoweredType, targetFormalType);
break;
}
case SILInstructionKind::UnconditionalCheckedCastAddrInst: {
// ignore attr.
CanType srcFormalType = MF->getType(ListOfValues[0])->getCanonicalType();
SILType srcLoweredType = getSILType(MF->getType(ListOfValues[2]),
(SILValueCategory)ListOfValues[3], Fn);
SILValue src = getLocalValue(ListOfValues[1], srcLoweredType);
CanType targetFormalType = MF->getType(ListOfValues[4])->getCanonicalType();
SILType targetLoweredType =
getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn);
SILValue dest = getLocalValue(ListOfValues[5], targetLoweredType);
ResultInst = Builder.createUnconditionalCheckedCastAddr(
Loc, src, srcFormalType, dest, targetFormalType);
break;
}
case SILInstructionKind::CheckedCastAddrBranchInst: {
CastConsumptionKind consumption = getCastConsumptionKind(ListOfValues[0]);
CanType srcFormalType = MF->getType(ListOfValues[1])->getCanonicalType();
SILType srcLoweredType = getSILType(MF->getType(ListOfValues[3]),
(SILValueCategory)ListOfValues[4], Fn);
SILValue src = getLocalValue(ListOfValues[2], srcLoweredType);
CanType targetFormalType =
MF->getType(ListOfValues[5])->getCanonicalType();
SILType targetLoweredType =
getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn);
SILValue dest = getLocalValue(ListOfValues[6], targetLoweredType);
auto *successBB = getBBForReference(Fn, ListOfValues[7]);
auto *failureBB = getBBForReference(Fn, ListOfValues[8]);
ResultInst = Builder.createCheckedCastAddrBranch(
Loc, consumption, src, srcFormalType, dest, targetFormalType, successBB,
failureBB);
break;
}
case SILInstructionKind::UncheckedRefCastAddrInst: {
CanType sourceType = MF->getType(ListOfValues[0])->getCanonicalType();
// ignore attr.
SILType srcAddrTy = getSILType(MF->getType(ListOfValues[2]),
(SILValueCategory)ListOfValues[3], Fn);
SILValue src = getLocalValue(ListOfValues[1], srcAddrTy);
CanType targetType = MF->getType(ListOfValues[4])->getCanonicalType();
SILType destAddrTy =
getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn);
SILValue dest = getLocalValue(ListOfValues[5], destAddrTy);
ResultInst = Builder.createUncheckedRefCastAddr(Loc, src, sourceType, dest,
targetType);
break;
}
case SILInstructionKind::InitBlockStorageHeaderInst: {
assert(ListOfValues.size() == 5 &&
"expected 5 values for InitBlockStorageHeader");
SILType blockTy =
getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn);
SILType storageTy = getSILType(MF->getType(ListOfValues[1]),
SILValueCategory::Address, Fn);
SILValue storage
= getLocalValue(ListOfValues[0], storageTy);
SILType invokeTy =
getSILType(MF->getType(ListOfValues[3]), SILValueCategory::Object, Fn);
SILValue invoke
= getLocalValue(ListOfValues[2], invokeTy);
auto SubMap = MF->getSubstitutionMap(ListOfValues[4]);
ResultInst = Builder.createInitBlockStorageHeader(Loc, storage, invoke,
blockTy, SubMap);
break;
}
case SILInstructionKind::UnreachableInst: {
ResultInst = Builder.createUnreachable(Loc);
break;
}
case SILInstructionKind::UnwindInst: {
ResultInst = Builder.createUnwind(Loc);
break;
}
case SILInstructionKind::YieldInst: {
SILBasicBlock *unwindBB = getBBForReference(Fn, ListOfValues.back());
ListOfValues = ListOfValues.drop_back();
SILBasicBlock *resumeBB = getBBForReference(Fn, ListOfValues.back());
ListOfValues = ListOfValues.drop_back();
SmallVector<SILValue, 4> yieldedValues;
for (unsigned I = 0, E = ListOfValues.size(); I < E; I += 3) {
auto valueTy = MF->getType(ListOfValues[I]);
auto valueCategory = (SILValueCategory) ListOfValues[I+1];
yieldedValues.push_back(getLocalValue(
ListOfValues[I + 2], getSILType(valueTy, valueCategory, Fn)));
}
ResultInst = Builder.createYield(Loc, yieldedValues, resumeBB, unwindBB);
break;
}
case SILInstructionKind::KeyPathInst: {
unsigned nextValue = 0;
SILType kpTy =
getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn);
auto rootTy = MF->getType(ListOfValues[nextValue++]);
auto valueTy = MF->getType(ListOfValues[nextValue++]);
auto numComponents = ListOfValues[nextValue++];
auto numOperands = ListOfValues[nextValue++];
auto subMap = MF->getSubstitutionMap(ListOfValues[nextValue++]);
auto objcString = MF->getIdentifierText(ListOfValues[nextValue++]);
auto numGenericParams = ListOfValues[nextValue++];
SmallVector<GenericTypeParamType *, 4> genericParams;
while (numGenericParams-- > 0) {
genericParams.push_back(MF->getType(ListOfValues[nextValue++])
->castTo<GenericTypeParamType>());
}
SmallVector<KeyPathPatternComponent, 4> components;
components.reserve(numComponents);
while (numComponents-- > 0) {
components.push_back(*readKeyPathComponent(ListOfValues, nextValue));
}
SmallVector<Requirement, 4> requirements;
MF->readGenericRequirements(requirements, SILCursor);
CanGenericSignature sig = CanGenericSignature();
if (!genericParams.empty() || !requirements.empty())
sig = GenericSignature::get(genericParams, requirements)
.getCanonicalSignature();
auto pattern = KeyPathPattern::get(SILMod, sig,
rootTy->getCanonicalType(),
valueTy->getCanonicalType(),
components,
objcString);
SmallVector<SILValue, 4> operands;
operands.reserve(numOperands);
while (numOperands-- > 0) {
auto opValue = ListOfValues[nextValue++];
auto opTy = MF->getType(ListOfValues[nextValue++]);
auto opCat = (SILValueCategory)ListOfValues[nextValue++];
operands.push_back(getLocalValue(opValue, getSILType(opTy, opCat, Fn)));
}
ResultInst = Builder.createKeyPath(Loc, pattern, subMap, operands, kpTy);
break;
}
case SILInstructionKind::DifferentiableFunctionInst: {
auto numParams = Attr;
auto numResults = Attr2;
auto numParamIndices = Attr3;
bool hasDerivativeFunctions = (bool)Attr4;
unsigned numOperands = hasDerivativeFunctions ? 3 : 1;
auto numResultIndices =
ListOfValues.size() - numOperands * 3 - numParamIndices;
assert(ListOfValues.size() ==
numParamIndices + numResultIndices + numOperands * 3);
auto rawParamIndices =
map<SmallVector<unsigned, 8>>(ListOfValues.take_front(numParamIndices),
[](uint64_t i) { return (unsigned)i; });
auto *paramIndices =
IndexSubset::get(MF->getContext(), numParams, rawParamIndices);
auto rawResultIndices = map<SmallVector<unsigned, 8>>(
ListOfValues.slice(numParamIndices, numResultIndices),
[](uint64_t i) { return (unsigned)i; });
auto *resultIndices =
IndexSubset::get(MF->getContext(), numResults, rawResultIndices);
SmallVector<SILValue, 3> operands;
for (auto i = numParamIndices + numResultIndices;
i < numParamIndices + numOperands * 3; i += 3) {
auto astTy = MF->getType(ListOfValues[i]);
auto silTy = getSILType(astTy, (SILValueCategory)ListOfValues[i + 1], Fn);
operands.push_back(getLocalValue(ListOfValues[i + 2], silTy));
}
Optional<std::pair<SILValue, SILValue>> derivativeFunctions = None;
if (hasDerivativeFunctions)
derivativeFunctions = std::make_pair(operands[1], operands[2]);
ResultInst = Builder.createDifferentiableFunction(
Loc, paramIndices, resultIndices, operands[0], derivativeFunctions);
break;
}
case SILInstructionKind::LinearFunctionInst: {
auto numDiffParams = Attr;
bool hasLinearFunction = (bool)Attr2;
unsigned numOperands = hasLinearFunction ? 2 : 1;
auto numParamIndices = ListOfValues.size() - numOperands * 3;
assert(ListOfValues.size() == numParamIndices + numOperands * 3);
auto rawParamIndices =
map<SmallVector<unsigned, 8>>(ListOfValues.take_front(numParamIndices),
[](uint64_t i) { return (unsigned)i; });
auto *paramIndices =
IndexSubset::get(MF->getContext(), numDiffParams, rawParamIndices);
SmallVector<SILValue, 3> operands;
for (auto i = numParamIndices;
i < numParamIndices + numOperands * 3; i += 3) {
auto astTy = MF->getType(ListOfValues[i]);
auto silTy = getSILType(astTy, (SILValueCategory)ListOfValues[i+1], Fn);
operands.push_back(getLocalValue(ListOfValues[i+2], silTy));
}
Optional<SILValue> transposeFunction = None;
if (hasLinearFunction)
transposeFunction = operands[1];
ResultInst = Builder.createLinearFunction(Loc, paramIndices, operands[0],
transposeFunction);
break;
}
case SILInstructionKind::DifferentiableFunctionExtractInst: {
auto astTy = MF->getType(TyID);
auto silTy = getSILType(astTy, SILValueCategory::Object, Fn);
auto val = getLocalValue(ValID, silTy);
NormalDifferentiableFunctionTypeComponent extractee(Attr);
Optional<SILType> explicitExtracteeType = None;
if (Attr2) {
auto extracteeASTType = MF->getType(TyID2);
explicitExtracteeType =
getSILType(extracteeASTType, SILValueCategory::Object, Fn);
}
ResultInst = Builder.createDifferentiableFunctionExtract(
Loc, extractee, val, explicitExtracteeType);
break;
}
case SILInstructionKind::LinearFunctionExtractInst: {
auto astTy = MF->getType(TyID);
auto silTy = getSILType(astTy, SILValueCategory::Object, Fn);
auto val = getLocalValue(ValID, silTy);
LinearDifferentiableFunctionTypeComponent extractee(Attr);
ResultInst = Builder.createLinearFunctionExtract(Loc, extractee, val);
break;
}
case SILInstructionKind::DifferentiabilityWitnessFunctionInst: {
StringRef mangledKey = MF->getIdentifierText(ValID);
auto *witness = getSILDifferentiabilityWitnessForReference(mangledKey);
assert(witness && "SILDifferentiabilityWitness not found");
DifferentiabilityWitnessFunctionKind witnessKind(Attr);
Optional<SILType> explicitFnTy = None;
auto astTy = MF->getType(TyID);
if (TyID)
explicitFnTy = getSILType(astTy, SILValueCategory::Object, Fn);
ResultInst = Builder.createDifferentiabilityWitnessFunction(
Loc, witnessKind, witness, explicitFnTy);
break;
}
}
for (auto result : ResultInst->getResults()) {
LastValueID = LastValueID + 1;
setLocalValue(result, LastValueID);
}
return false;
}