[sil] Add tuple_addr_constructor an instruction that can be used to initial a tuple in memory from individual address and object components.

This commit just introduces the instruction. In a subsequent commit, I am going
to add support to SILGen to emit this. This ensures that when we assign into a
tuple var we initialize it with one instruction instead of doing it in pieces.
The problem with doing it in pieces is that when one is emitting diagnostics it
looks semantically like SILGen actually is emitting code for initializing in
pieces which could be an error.
This commit is contained in:
Michael Gottesman
2023-11-02 15:19:59 -07:00
parent c47e94336e
commit 6a65c7829e
23 changed files with 643 additions and 102 deletions

View File

@@ -748,6 +748,13 @@ RuntimeEffect swift::getRuntimeEffect(SILInstruction *inst, SILType &impactType)
return RuntimeEffect::MetaData | RuntimeEffect::RefCounting;
return RuntimeEffect::MetaData;
}
case SILInstructionKind::TupleAddrConstructorInst: {
auto *ca = cast<TupleAddrConstructorInst>(inst);
impactType = ca->getDestValue()->getType();
if (!ca->isInitializationOfDest())
return RuntimeEffect::MetaData | RuntimeEffect::Releasing;
return RuntimeEffect::MetaData;
}
case SILInstructionKind::ExplicitCopyAddrInst: {
auto *ca = cast<ExplicitCopyAddrInst>(inst);
impactType = ca->getSrc()->getType();
@@ -1290,3 +1297,42 @@ swift::getStaticOverloadForSpecializedPolymorphicBuiltin(BuiltinInst *bi) {
return newBI;
}
//===----------------------------------------------------------------------===//
// Exploded Tuple Visitors
//===----------------------------------------------------------------------===//
bool swift::visitExplodedTupleType(SILType inputType,
llvm::function_ref<bool(SILType)> callback) {
auto tupType = inputType.getAs<TupleType>();
if (!tupType || tupType.containsPackExpansionType()) {
return callback(inputType);
}
for (auto elt : tupType->getElementTypes()) {
auto eltSILTy = SILType::getPrimitiveType(elt->getCanonicalType(),
inputType.getCategory());
if (!visitExplodedTupleType(eltSILTy, callback))
return false;
}
return true;
}
bool swift::visitExplodedTupleValue(
SILValue inputValue,
llvm::function_ref<SILValue(SILValue, std::optional<unsigned>)> callback) {
SILType inputType = inputValue->getType();
auto tupType = inputType.getAs<TupleType>();
if (!tupType || tupType.containsPackExpansionType()) {
return callback(inputValue, {});
}
for (auto eltIndex : range(tupType->getNumElements())) {
auto elt = callback(inputValue, eltIndex);
if (!visitExplodedTupleValue(elt, callback))
return false;
}
return true;
}