Skip to content

Commit 37baf9b

Browse files
committed
Add a SIL instruction to open a pack as an element archetype
IRGen not yet done.
1 parent d673a45 commit 37baf9b

21 files changed

+363
-5
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,10 @@ ERROR(sil_moveonlytocopyable_invalid_attribute,none,
673673
"Attribute '[%0]' can not be applied to moveonlywrapper_to_copyable", (StringRef))
674674
ERROR(sil_moveonlytocopyable_requires_attribute,none,
675675
"moveonlywrapper_to_copyable requires either a [guaranteed] or [owned] attribute", ())
676+
ERROR(expected_generic_signature,none,
677+
"expected a generic signature", ())
678+
ERROR(sil_expected_uuid,none,
679+
"expected a UUID string literal", ())
676680

677681
// SIL Basic Blocks
678682
ERROR(expected_sil_block_name,none,

include/swift/SIL/SILBuilder.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1936,6 +1936,14 @@ class SILBuilder {
19361936
getSILDebugLocation(Loc), Existential));
19371937
}
19381938

1939+
OpenPackElementInst *
1940+
createOpenPackElement(SILLocation loc, SILValue packIndex,
1941+
GenericEnvironment *openedElementEnvironment) {
1942+
return insert(OpenPackElementInst::create(getFunction(),
1943+
getSILDebugLocation(loc),
1944+
packIndex, openedElementEnvironment));
1945+
}
1946+
19391947
ProjectBlockStorageInst *createProjectBlockStorage(SILLocation Loc,
19401948
SILValue Storage) {
19411949
auto CaptureTy = Storage->getType()

include/swift/SIL/SILCloner.h

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2392,6 +2392,52 @@ void SILCloner<ImplClass>::visitDeinitExistentialValueInst(
23922392
getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand())));
23932393
}
23942394

2395+
template <typename ImplClass>
2396+
void SILCloner<ImplClass>::visitOpenPackElementInst(
2397+
OpenPackElementInst *Inst) {
2398+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
2399+
2400+
auto newIndexValue = getOpValue(Inst->getIndexOperand());
2401+
auto loc = getOpLocation(Inst->getLoc());
2402+
2403+
// We need to make a new opened-element environment. This is *not*
2404+
// a refinement of the contextual environment of the new insertion
2405+
// site; we just substitute the contextual substitutions in the
2406+
// opened environment and build a new one.
2407+
auto origEnv = Inst->getOpenedGenericEnvironment();
2408+
2409+
// Substitute the contextual substitutions.
2410+
auto newContextSubs =
2411+
getOpSubstitutionMap(origEnv->getPackElementContextSubstitutions());
2412+
2413+
// Substitute the shape class.
2414+
auto newShapeClass = getOpASTType(origEnv->getOpenedElementShapeClass());
2415+
2416+
// Build the new environment.
2417+
auto newEnv =
2418+
GenericEnvironment::forOpenedElement(origEnv->getGenericSignature(),
2419+
UUID::fromTime(), newShapeClass,
2420+
newContextSubs);
2421+
2422+
// Associate the old opened archetypes with the new ones.
2423+
SmallVector<ArchetypeType*, 4> oldOpenedArchetypes;
2424+
origEnv->forEachPackElementArchetype([&](ElementArchetypeType *oldType) {
2425+
oldOpenedArchetypes.push_back(oldType);
2426+
});
2427+
{
2428+
size_t nextOldIndex = 0;
2429+
newEnv->forEachPackElementArchetype([&](ElementArchetypeType *newType) {
2430+
ArchetypeType *oldType = oldOpenedArchetypes[nextOldIndex++];
2431+
registerLocalArchetypeRemapping(oldType, newType);
2432+
});
2433+
assert(nextOldIndex == oldOpenedArchetypes.size() &&
2434+
"different opened archetype count");
2435+
}
2436+
2437+
recordClonedInstruction(
2438+
Inst, getBuilder().createOpenPackElement(loc, newIndexValue, newEnv));
2439+
}
2440+
23952441
template<typename ImplClass>
23962442
void
23972443
SILCloner<ImplClass>::visitCopyBlockInst(CopyBlockInst *Inst) {

include/swift/SIL/SILInstruction.h

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7403,6 +7403,94 @@ class DeinitExistentialValueInst
74037403
: UnaryInstructionBase(DebugLoc, Existential) {}
74047404
};
74057405

7406+
/// Bind archetypes to the given element of one or more type packs.
7407+
///
7408+
/// The result of this instruction is just for use in recording type
7409+
/// dependencies on the bound archetypes.
7410+
///
7411+
/// %0 = open_pack_element %index
7412+
/// of <t_1_0... as $@opened t_10101 from {T...}>
7413+
/// where t_1_0: Equatable
7414+
///
7415+
/// %index is always a $Builtin.Word.
7416+
///
7417+
/// In the printed representation, only the relevant portions of the
7418+
/// opened generic environment are given: the pack type parameters,
7419+
/// the opened element archetypes, the contextual substitutions of
7420+
/// the pack type parameters, and the requirements on the pack type
7421+
/// parameters.
7422+
class OpenPackElementInst final
7423+
: public InstructionBaseWithTrailingOperands<
7424+
SILInstructionKind::OpenPackElementInst,
7425+
OpenPackElementInst,
7426+
SingleValueInstruction> {
7427+
friend SILBuilder;
7428+
7429+
/// The opened-element generic environment for this operation.
7430+
///
7431+
/// In the AST, the opened element generic environment of a
7432+
/// PackExpansionExpr extends the contextual generic environment with
7433+
/// a new, innermost level of parameters representing the opened
7434+
/// elements. These parameters are not pack parameters, but they are
7435+
/// 1-1 with the expanded pack parameters, and the requirements laid
7436+
/// on them are copied from the requirements on those parameters.
7437+
/// The substitutions in the environment map the contextual generic
7438+
/// parameters to their current archetypes, and only the new element
7439+
/// parameters acquire new archetypes within the environment.
7440+
///
7441+
/// Parts of this correspondence break down for open_pack_element.
7442+
/// In particular, SIL instructions can be cloned into new contexts,
7443+
/// applying a substitution that can change or even erase the pack
7444+
/// parameters in the contextual environment. Rather than require
7445+
/// the opened element environment to continue to be an extension
7446+
/// of the contextual environment, SIL allows the two to diverge:
7447+
/// there is no presumed relationship between the generic signature
7448+
/// of the opened environment and that of the contextual environment.
7449+
/// The generic environment should be treated as a source of
7450+
/// information about the expanded packs, the contextual pack
7451+
/// substitutions, and the opened archetype for each pack.
7452+
///
7453+
/// An alternative representation would be to remove the non-pack
7454+
/// parameters from the opened generic environment, replacing them
7455+
/// in the requirements with references to the contextual archetypes.
7456+
/// However, this would require various algorithms working with
7457+
/// generic signatures and environments to work with a mixture of
7458+
/// archetypes and type parameters, which can introduce problems
7459+
/// when reasoning about certain kinds of generic signatures.
7460+
GenericEnvironment *Env;
7461+
7462+
OpenPackElementInst(SILDebugLocation debugLoc,
7463+
ArrayRef<SILValue> allOperands,
7464+
SILType type,
7465+
GenericEnvironment *env);
7466+
7467+
static OpenPackElementInst *
7468+
create(SILFunction &F, SILDebugLocation debugLoc, SILValue index,
7469+
GenericEnvironment *env);
7470+
7471+
public:
7472+
/// Call the given function for each element archetype that this
7473+
/// instruction opens.
7474+
void forEachDefinedLocalArchetype(
7475+
llvm::function_ref<void(CanLocalArchetypeType, SILValue)> fn) const;
7476+
7477+
GenericEnvironment *getOpenedGenericEnvironment() const {
7478+
return Env;
7479+
}
7480+
7481+
SILValue getIndexOperand() const {
7482+
return getAllOperands()[0].get();
7483+
}
7484+
7485+
ArrayRef<Operand> getTypeDependentOperands() const {
7486+
return getAllOperands().slice(1);
7487+
}
7488+
7489+
MutableArrayRef<Operand> getTypeDependentOperands() {
7490+
return getAllOperands().slice(1);
7491+
}
7492+
};
7493+
74067494
/// Projects the capture storage address from a @block_storage address.
74077495
class ProjectBlockStorageInst
74087496
: public UnaryInstructionBase<SILInstructionKind::ProjectBlockStorageInst,

include/swift/SIL/SILNodes.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,10 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
597597
SINGLE_VALUE_INST(OpenExistentialBoxValueInst, open_existential_box_value,
598598
SingleValueInstruction, MayRead, DoesNotRelease)
599599

600+
// Variadic generics
601+
SINGLE_VALUE_INST(OpenPackElementInst, open_pack_element,
602+
SingleValueInstruction, None, DoesNotRelease)
603+
600604
// Blocks
601605
SINGLE_VALUE_INST(ProjectBlockStorageInst, project_block_storage,
602606
SingleValueInstruction, None, DoesNotRelease)

include/swift/SIL/SILType.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,9 @@ class SILType {
737737
/// Get the SIL token type.
738738
static SILType getSILTokenType(const ASTContext &C);
739739

740+
/// Get the type for pack indexes.
741+
static SILType getPackIndexType(const ASTContext &C);
742+
740743
/// Return '()'
741744
static SILType getEmptyTupleType(const ASTContext &C);
742745

lib/IRGen/IRGenSIL.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1259,6 +1259,8 @@ class IRGenSILFunction :
12591259
void visitProjectExistentialBoxInst(ProjectExistentialBoxInst *i);
12601260
void visitDeallocExistentialBoxInst(DeallocExistentialBoxInst *i);
12611261

1262+
void visitOpenPackElementInst(swift::OpenPackElementInst *i);
1263+
12621264
void visitProjectBlockStorageInst(ProjectBlockStorageInst *i);
12631265
void visitInitBlockStorageHeaderInst(InitBlockStorageHeaderInst *i);
12641266

@@ -6741,6 +6743,15 @@ void IRGenSILFunction::visitOpenExistentialValueInst(
67416743
llvm_unreachable("unsupported instruction during IRGen");
67426744
}
67436745

6746+
void IRGenSILFunction::visitOpenPackElementInst(swift::OpenPackElementInst *i) {
6747+
llvm::Value *index = getLoweredSingletonExplosion(i->getIndexOperand());
6748+
6749+
// FIXME: bind the archetypes
6750+
(void) index;
6751+
6752+
// The result is just used for type dependencies.
6753+
}
6754+
67446755
void IRGenSILFunction::visitProjectBlockStorageInst(ProjectBlockStorageInst *i){
67456756
// TODO
67466757
Address block = getLoweredAddress(i->getOperand());

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ OPERAND_OWNERSHIP(TrivialUse, ObjCMetatypeToObject)
174174
OPERAND_OWNERSHIP(TrivialUse, ObjCToThickMetatype)
175175
OPERAND_OWNERSHIP(TrivialUse, OpenExistentialAddr)
176176
OPERAND_OWNERSHIP(TrivialUse, OpenExistentialMetatype)
177+
OPERAND_OWNERSHIP(TrivialUse, OpenPackElement)
177178
OPERAND_OWNERSHIP(TrivialUse, PointerToAddress)
178179
OPERAND_OWNERSHIP(TrivialUse, ProjectBlockStorage)
179180
OPERAND_OWNERSHIP(TrivialUse, RawPointerToRef)

lib/SIL/IR/SILInstruction.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1557,11 +1557,22 @@ void SILInstruction::forEachDefinedLocalArchetype(
15571557
SINGLE_VALUE_SINGLE_OPEN(OpenExistentialMetatypeInst)
15581558
SINGLE_VALUE_SINGLE_OPEN(OpenExistentialValueInst)
15591559
#undef SINGLE_VALUE_SINGLE_OPEN
1560+
case SILInstructionKind::OpenPackElementInst:
1561+
return cast<OpenPackElementInst>(this)->forEachDefinedLocalArchetype(fn);
15601562
default:
15611563
return;
15621564
}
15631565
}
15641566

1567+
void OpenPackElementInst::forEachDefinedLocalArchetype(
1568+
llvm::function_ref<void(CanLocalArchetypeType, SILValue)> fn) const {
1569+
getOpenedGenericEnvironment()->forEachPackElementBinding(
1570+
[&](ElementArchetypeType *elementType,
1571+
PackType *packSubstitution) {
1572+
fn(CanElementArchetypeType(elementType), this);
1573+
});
1574+
}
1575+
15651576
//===----------------------------------------------------------------------===//
15661577
// Multiple Value Instruction
15671578
//===----------------------------------------------------------------------===//

lib/SIL/IR/SILInstructions.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2244,6 +2244,36 @@ OpenExistentialValueInst::OpenExistentialValueInst(
22442244
: UnaryInstructionBase(debugLoc, operand, selfTy, forwardingOwnershipKind) {
22452245
}
22462246

2247+
OpenPackElementInst::OpenPackElementInst(
2248+
SILDebugLocation debugLoc, ArrayRef<SILValue> allOperands,
2249+
SILType type, GenericEnvironment *env)
2250+
: InstructionBaseWithTrailingOperands(allOperands, debugLoc, type),
2251+
Env(env) {
2252+
}
2253+
2254+
OpenPackElementInst *OpenPackElementInst::create(
2255+
SILFunction &F, SILDebugLocation debugLoc, SILValue indexOperand,
2256+
GenericEnvironment *env) {
2257+
SmallVector<SILValue, 8> allOperands;
2258+
allOperands.push_back(indexOperand);
2259+
2260+
// open_pack_element references the pack substitutions and
2261+
// the types used in the shape class.
2262+
TypeDependentOperandCollector typeDependentOperands;
2263+
env->forEachPackElementBinding([&](ElementArchetypeType *elementType,
2264+
PackType *packSubstitution) {
2265+
typeDependentOperands.collect(packSubstitution->getCanonicalType());
2266+
});
2267+
typeDependentOperands.collect(env->getOpenedElementShapeClass());
2268+
typeDependentOperands.addTo(allOperands, F);
2269+
2270+
SILType type = SILType::getSILTokenType(F.getASTContext());
2271+
2272+
auto size = totalSizeToAlloc<swift::Operand>(allOperands.size());
2273+
auto buffer = F.getModule().allocateInst(size, alignof(OpenPackElementInst));
2274+
return ::new (buffer) OpenPackElementInst(debugLoc, allOperands, type, env);
2275+
}
2276+
22472277
BeginCOWMutationInst::BeginCOWMutationInst(SILDebugLocation loc,
22482278
SILValue operand,
22492279
ArrayRef<SILType> resultTypes,

lib/SIL/IR/SILPrinter.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,8 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
645645
SIMPLE_PRINTER(SILDeclRef)
646646
SIMPLE_PRINTER(APInt)
647647
SIMPLE_PRINTER(ValueOwnershipKind)
648+
SIMPLE_PRINTER(UUID)
649+
SIMPLE_PRINTER(GenericSignature)
648650
#undef SIMPLE_PRINTER
649651

650652
SILPrinter &operator<<(SILValuePrinterInfo i) {
@@ -2277,6 +2279,16 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
22772279
void visitDeallocExistentialBoxInst(DeallocExistentialBoxInst *DEI) {
22782280
*this << getIDAndType(DEI->getOperand()) << ", $" << DEI->getConcreteType();
22792281
}
2282+
void visitOpenPackElementInst(OpenPackElementInst *OPEI) {
2283+
auto env = OPEI->getOpenedGenericEnvironment();
2284+
auto subs = env->getPackElementContextSubstitutions();
2285+
*this << Ctx.getID(OPEI->getIndexOperand())
2286+
<< " of " << subs.getGenericSignature()
2287+
<< " at ";
2288+
printSubstitutions(subs);
2289+
*this << ", shape $" << env->getOpenedElementShapeClass()
2290+
<< ", uuid \"" << env->getOpenedElementUUID() << "\"";
2291+
}
22802292
void visitProjectBlockStorageInst(ProjectBlockStorageInst *PBSI) {
22812293
*this << getIDAndType(PBSI->getOperand());
22822294
}

lib/SIL/IR/SILType.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ SILType SILType::getSILTokenType(const ASTContext &C) {
103103
return getPrimitiveObjectType(C.TheSILTokenType);
104104
}
105105

106+
SILType SILType::getPackIndexType(const ASTContext &C) {
107+
return getPrimitiveObjectType(CanType(BuiltinIntegerType::getWordType(C)));
108+
}
109+
106110
bool SILType::isTrivial(const SILFunction &F) const {
107111
auto contextType = hasTypeParameter() ? F.mapTypeIntoContext(*this) : *this;
108112

lib/SIL/IR/ValueOwnership.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ CONSTANT_OWNERSHIP_INST(None, GetAsyncContinuation)
154154
CONSTANT_OWNERSHIP_INST(None, GetAsyncContinuationAddr)
155155
CONSTANT_OWNERSHIP_INST(None, ThinToThickFunction)
156156
CONSTANT_OWNERSHIP_INST(None, ExtractExecutor)
157+
CONSTANT_OWNERSHIP_INST(None, OpenPackElement)
157158

158159
#undef CONSTANT_OWNERSHIP_INST
159160

0 commit comments

Comments
 (0)