Skip to content

Commit 8cab09e

Browse files
Merge pull request #67966 from nate-chandler/opaque-values/20230816/1/indirect-pack-tuple-handling
[AddressLowering] Handle indexing into variadic tuples.
2 parents 48695c6 + 84ab0eb commit 8cab09e

24 files changed

+303
-10
lines changed

docs/SIL.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6403,6 +6403,23 @@ tuple_extract
64036403

64046404
Extracts an element from a loadable tuple value.
64056405

6406+
6407+
tuple_pack_extract
6408+
``````````````````
6409+
::
6410+
6411+
sil-instruction ::= 'tuple_pack_extract' sil-value 'of' sil-operand 'as' sil-type
6412+
6413+
%value = tuple_pack_extract %index of %tuple : $(repeat each T) as $@pack_element("01234567-89AB-CDEF-0123-000000000000") U
6414+
// %index must be of $Builtin.PackIndex type
6415+
// %tuple must be of tuple type
6416+
// %addr will be the result type specified by the 'as' clause
6417+
6418+
Extracts a value at a dynamic index from a tuple value.
6419+
6420+
Only valid in opaque values mode. Lowered by AddressLowering to
6421+
tuple_pack_element_addr. For more details, see that instruction.
6422+
64066423
tuple_element_addr
64076424
``````````````````
64086425
::

include/swift/SIL/InstWrappers.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@ class ForwardingOperation {
304304
bool canForwardGuaranteedCompatibleValuesOnly() {
305305
switch (forwardingInst->getKind()) {
306306
case SILInstructionKind::TupleExtractInst:
307+
case SILInstructionKind::TuplePackExtractInst:
307308
case SILInstructionKind::StructExtractInst:
308309
case SILInstructionKind::DifferentiableFunctionExtractInst:
309310
case SILInstructionKind::LinearFunctionExtractInst:

include/swift/SIL/SILBuilder.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2150,6 +2150,16 @@ class SILBuilder {
21502150
packIndex, tupleAddr, elementType));
21512151
}
21522152

2153+
TuplePackExtractInst *createTuplePackExtract(SILLocation loc,
2154+
SILValue packIndex,
2155+
SILValue tuple,
2156+
SILType elementType) {
2157+
assert(!getFunction().getModule().useLoweredAddresses());
2158+
return insert(TuplePackExtractInst::create(
2159+
getFunction(), getSILDebugLocation(loc), packIndex, tuple, elementType,
2160+
tuple->getOwnershipKind()));
2161+
}
2162+
21532163
ProjectBlockStorageInst *createProjectBlockStorage(SILLocation Loc,
21542164
SILValue Storage) {
21552165
auto CaptureTy = Storage->getType()

include/swift/SIL/SILCloner.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2780,6 +2780,27 @@ void SILCloner<ImplClass>::visitTuplePackElementAddrInst(
27802780
newElementType));
27812781
}
27822782

2783+
template <typename ImplClass>
2784+
void SILCloner<ImplClass>::visitTuplePackExtractInst(
2785+
TuplePackExtractInst *Inst) {
2786+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
2787+
auto loc = getOpLocation(Inst->getLoc());
2788+
auto newIndex = getOpValue(Inst->getIndex());
2789+
auto newTuple = getOpValue(Inst->getTuple());
2790+
auto newElementType = getOpType(Inst->getElementType());
2791+
2792+
// If the tuple-ness of the operand disappears due to substitution,
2793+
// replace this instruction with an unchecked_value_cast.
2794+
if (doesOpTupleDisappear(Inst->getTupleType())) {
2795+
recordClonedInstruction(Inst, getBuilder().createUncheckedValueCast(
2796+
loc, newTuple, newElementType));
2797+
return;
2798+
}
2799+
2800+
recordClonedInstruction(Inst, getBuilder().createTuplePackExtract(
2801+
loc, newIndex, newTuple, newElementType));
2802+
}
2803+
27832804
template<typename ImplClass>
27842805
void
27852806
SILCloner<ImplClass>::visitCopyBlockInst(CopyBlockInst *Inst) {

include/swift/SIL/SILInstruction.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7805,6 +7805,45 @@ class TuplePackElementAddrInst final
78057805
}
78067806
};
78077807

7808+
/// Extracts a tuple element as appropriate for the given
7809+
/// pack element index. The pack index must index into a pack with
7810+
/// the same shape as the tuple element type list.
7811+
///
7812+
/// Legal only in opaque values mode. Transformed by AddressLowering to
7813+
/// TuplePackElementAddrInst.
7814+
class TuplePackExtractInst final
7815+
: public InstructionBaseWithTrailingOperands<
7816+
SILInstructionKind::TuplePackExtractInst, TuplePackExtractInst,
7817+
OwnershipForwardingSingleValueInstruction> {
7818+
public:
7819+
enum { IndexOperand = 0, TupleOperand = 1 };
7820+
7821+
private:
7822+
friend SILBuilder;
7823+
7824+
TuplePackExtractInst(SILDebugLocation debugLoc,
7825+
ArrayRef<SILValue> allOperands, SILType elementType,
7826+
ValueOwnershipKind forwardingOwnershipKind)
7827+
: InstructionBaseWithTrailingOperands(allOperands, debugLoc, elementType,
7828+
forwardingOwnershipKind) {}
7829+
7830+
static TuplePackExtractInst *
7831+
create(SILFunction &F, SILDebugLocation debugLoc, SILValue indexOperand,
7832+
SILValue tupleOperand, SILType elementType,
7833+
ValueOwnershipKind forwardingOwnershipKind);
7834+
7835+
public:
7836+
SILValue getIndex() const { return getAllOperands()[IndexOperand].get(); }
7837+
7838+
SILValue getTuple() const { return getAllOperands()[TupleOperand].get(); }
7839+
7840+
CanTupleType getTupleType() const {
7841+
return getTuple()->getType().castTo<TupleType>();
7842+
}
7843+
7844+
SILType getElementType() const { return getType(); }
7845+
};
7846+
78087847
/// Projects the capture storage address from a @block_storage address.
78097848
class ProjectBlockStorageInst
78107849
: public UnaryInstructionBase<SILInstructionKind::ProjectBlockStorageInst,
@@ -10543,6 +10582,7 @@ OwnershipForwardingSingleValueInstruction::classof(SILInstructionKind kind) {
1054310582
case SILInstructionKind::CopyableToMoveOnlyWrapperValueInst:
1054410583
case SILInstructionKind::MarkUninitializedInst:
1054510584
case SILInstructionKind::TupleExtractInst:
10585+
case SILInstructionKind::TuplePackExtractInst:
1054610586
case SILInstructionKind::StructExtractInst:
1054710587
case SILInstructionKind::DifferentiableFunctionExtractInst:
1054810588
case SILInstructionKind::LinearFunctionExtractInst:

include/swift/SIL/SILNodes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,8 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
588588
SingleValueInstruction, None, DoesNotRelease)
589589
SINGLE_VALUE_INST(TuplePackElementAddrInst, tuple_pack_element_addr,
590590
SingleValueInstruction, None, DoesNotRelease)
591+
SINGLE_VALUE_INST(TuplePackExtractInst, tuple_pack_extract,
592+
SingleValueInstruction, None, DoesNotRelease)
591593
SINGLE_VALUE_INST(PackElementGetInst, pack_element_get,
592594
SingleValueInstruction, None, DoesNotRelease)
593595
SINGLE_VALUE_INST(StructInst, struct,

lib/IRGen/IRGenSIL.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1355,6 +1355,7 @@ class IRGenSILFunction :
13551355
void visitPackElementGetInst(PackElementGetInst *i);
13561356
void visitPackElementSetInst(PackElementSetInst *i);
13571357
void visitTuplePackElementAddrInst(TuplePackElementAddrInst *i);
1358+
void visitTuplePackExtractInst(TuplePackExtractInst *i);
13581359

13591360
void visitProjectBlockStorageInst(ProjectBlockStorageInst *i);
13601361
void visitInitBlockStorageHeaderInst(InitBlockStorageHeaderInst *i);
@@ -7192,6 +7193,11 @@ void IRGenSILFunction::visitTuplePackElementAddrInst(
71927193
setLoweredAddress(i, elementAddr);
71937194
}
71947195

7196+
void IRGenSILFunction::visitTuplePackExtractInst(TuplePackExtractInst *i) {
7197+
llvm::report_fatal_error(
7198+
"tuple_pack_extract not lowered by AddressLowering!?");
7199+
}
7200+
71957201
void IRGenSILFunction::visitProjectBlockStorageInst(ProjectBlockStorageInst *i){
71967202
// TODO
71977203
Address block = getLoweredAddress(i->getOperand());

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@ OPERAND_OWNERSHIP(PointerEscape, ExtractExecutor)
312312

313313
// Instructions that propagate a value within a borrow scope.
314314
OPERAND_OWNERSHIP(GuaranteedForwarding, TupleExtract)
315+
OPERAND_OWNERSHIP(GuaranteedForwarding, TuplePackExtract)
315316
OPERAND_OWNERSHIP(GuaranteedForwarding, StructExtract)
316317
OPERAND_OWNERSHIP(GuaranteedForwarding, DifferentiableFunctionExtract)
317318
OPERAND_OWNERSHIP(GuaranteedForwarding, LinearFunctionExtract)

lib/SIL/IR/SILInstructions.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2423,6 +2423,26 @@ TuplePackElementAddrInst::create(SILFunction &F,
24232423
elementType);
24242424
}
24252425

2426+
TuplePackExtractInst *
2427+
TuplePackExtractInst::create(SILFunction &F, SILDebugLocation debugLoc,
2428+
SILValue indexOperand, SILValue tupleOperand,
2429+
SILType elementType,
2430+
ValueOwnershipKind forwardingOwnershipKind) {
2431+
assert(indexOperand->getType().is<BuiltinPackIndexType>());
2432+
assert(tupleOperand->getType().isObject() &&
2433+
tupleOperand->getType().is<TupleType>());
2434+
2435+
SmallVector<SILValue, 8> allOperands;
2436+
allOperands.push_back(indexOperand);
2437+
allOperands.push_back(tupleOperand);
2438+
collectTypeDependentOperands(allOperands, F, elementType);
2439+
2440+
auto size = totalSizeToAlloc<swift::Operand>(allOperands.size());
2441+
auto buffer = F.getModule().allocateInst(size, alignof(TuplePackExtractInst));
2442+
return ::new (buffer) TuplePackExtractInst(debugLoc, allOperands, elementType,
2443+
forwardingOwnershipKind);
2444+
}
2445+
24262446
BeginCOWMutationInst::BeginCOWMutationInst(SILDebugLocation loc,
24272447
SILValue operand,
24282448
ArrayRef<SILType> resultTypes,

lib/SIL/IR/SILPrinter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2431,6 +2431,10 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
24312431
<< getIDAndType(I->getTuple()) << " as "
24322432
<< I->getElementType();
24332433
}
2434+
void visitTuplePackExtractInst(TuplePackExtractInst *I) {
2435+
*this << Ctx.getID(I->getIndex()) << " of " << getIDAndType(I->getTuple())
2436+
<< " as " << I->getElementType();
2437+
}
24342438
void visitProjectBlockStorageInst(ProjectBlockStorageInst *PBSI) {
24352439
*this << getIDAndType(PBSI->getOperand());
24362440
}

0 commit comments

Comments
 (0)