Skip to content

Commit 7bddaf3

Browse files
committed
[SIL] Added tuple_pack_extract.
The new instruction is needed for opaque values mode to allow values to be extracted from tuples containing packs which will appear for example as function arguments.
1 parent 117a5ec commit 7bddaf3

22 files changed

+258
-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
@@ -1360,6 +1360,7 @@ class IRGenSILFunction :
13601360
void visitPackElementGetInst(PackElementGetInst *i);
13611361
void visitPackElementSetInst(PackElementSetInst *i);
13621362
void visitTuplePackElementAddrInst(TuplePackElementAddrInst *i);
1363+
void visitTuplePackExtractInst(TuplePackExtractInst *i);
13631364

13641365
void visitProjectBlockStorageInst(ProjectBlockStorageInst *i);
13651366
void visitInitBlockStorageHeaderInst(InitBlockStorageHeaderInst *i);
@@ -7197,6 +7198,11 @@ void IRGenSILFunction::visitTuplePackElementAddrInst(
71977198
setLoweredAddress(i, elementAddr);
71987199
}
71997200

7201+
void IRGenSILFunction::visitTuplePackExtractInst(TuplePackExtractInst *i) {
7202+
llvm::report_fatal_error(
7203+
"tuple_pack_extract not lowered by AddressLowering!?");
7204+
}
7205+
72007206
void IRGenSILFunction::visitProjectBlockStorageInst(ProjectBlockStorageInst *i){
72017207
// TODO
72027208
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
@@ -2434,6 +2434,10 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
24342434
<< getIDAndType(I->getTuple()) << " as "
24352435
<< I->getElementType();
24362436
}
2437+
void visitTuplePackExtractInst(TuplePackExtractInst *I) {
2438+
*this << Ctx.getID(I->getIndex()) << " of " << getIDAndType(I->getTuple())
2439+
<< " as " << I->getElementType();
2440+
}
24372441
void visitProjectBlockStorageInst(ProjectBlockStorageInst *PBSI) {
24382442
*this << getIDAndType(PBSI->getOperand());
24392443
}

0 commit comments

Comments
 (0)