@@ -7414,6 +7414,133 @@ class DeinitExistentialValueInst
74147414 : UnaryInstructionBase(DebugLoc, Existential) {}
74157415};
74167416
7417+ // / An abstract class for instructions which producing variadic
7418+ // / pack indices.
7419+ // /
7420+ // / All of these instructions produce a Builtin.PackIndex value which
7421+ // / can only be used in packs with a specific shape class. In
7422+ // / principle, that shape class could be reflected into the result type,
7423+ // / but we actually need more structue than that in order to get the
7424+ // / type-safety properties we want. It therefore makes more sense to
7425+ // / enforce structural properties on pack-index derivation than try
7426+ // / to go all-in on dependent types.
7427+ class AnyPackIndexInst : public SingleValueInstruction {
7428+ CanPackType IndexedPackType;
7429+
7430+ protected:
7431+ AnyPackIndexInst (SILInstructionKind kind, SILDebugLocation loc,
7432+ SILType type, CanPackType packType)
7433+ : SingleValueInstruction(kind, loc, type), IndexedPackType(packType) {
7434+ assert (type.isObject () && type.is <BuiltinPackIndexType>());
7435+ }
7436+
7437+ public:
7438+ // / Return the type that this pack index indexes into.
7439+ CanPackType getIndexedPackType () const { return IndexedPackType; }
7440+
7441+ static bool classof (const AnyPackIndexInst *) { return true ; }
7442+ static bool classof (SILNodePointer node) {
7443+ return node->getKind () >= SILNodeKind::First_AnyPackIndexInst &&
7444+ node->getKind () <= SILNodeKind::Last_AnyPackIndexInst;
7445+ }
7446+ };
7447+
7448+ // / Produce a dynamic pack index from a Builtin.Int32.
7449+ // /
7450+ // / This instruction has undefined behavior if the value is out of
7451+ // / bounds for the given pack (including the "one past the end" value).
7452+ class DynamicPackIndexInst final :
7453+ public UnaryInstructionWithTypeDependentOperandsBase<
7454+ SILInstructionKind::DynamicPackIndexInst,
7455+ DynamicPackIndexInst,
7456+ AnyPackIndexInst> {
7457+ friend SILBuilder;
7458+ DynamicPackIndexInst (SILDebugLocation loc,
7459+ SILValue indexOperand,
7460+ ArrayRef<SILValue> typeDependentOperands,
7461+ SILType type, CanPackType packType)
7462+ : UnaryInstructionWithTypeDependentOperandsBase(loc, indexOperand,
7463+ typeDependentOperands,
7464+ type, packType) {}
7465+
7466+ static DynamicPackIndexInst *create (SILFunction &parent,
7467+ SILDebugLocation loc,
7468+ SILValue indexOperand,
7469+ CanPackType packType);
7470+ };
7471+
7472+ // / Compute the pack index of an element of a slice of a pack.
7473+ class PackPackIndexInst final :
7474+ public UnaryInstructionWithTypeDependentOperandsBase<
7475+ SILInstructionKind::PackPackIndexInst,
7476+ PackPackIndexInst,
7477+ AnyPackIndexInst> {
7478+ unsigned ComponentStartIndex;
7479+
7480+ friend SILBuilder;
7481+ PackPackIndexInst (SILDebugLocation loc,
7482+ unsigned componentStartIndex,
7483+ SILValue indexWithinComponent,
7484+ ArrayRef<SILValue> typeDependentOperands,
7485+ SILType type, CanPackType packType)
7486+ : UnaryInstructionWithTypeDependentOperandsBase(loc,
7487+ indexWithinComponent,
7488+ typeDependentOperands,
7489+ type, packType),
7490+ ComponentStartIndex (componentStartIndex) {}
7491+
7492+ static PackPackIndexInst *create (SILFunction &parent,
7493+ SILDebugLocation loc,
7494+ unsigned componentIndex,
7495+ SILValue indexWithinComponent,
7496+ CanPackType packType);
7497+ public:
7498+ // / Return the instruction which produces the index within the
7499+ // / pack slice.
7500+ AnyPackIndexInst *getSliceIndexOperand () const {
7501+ return cast<AnyPackIndexInst>(getOperand ());
7502+ }
7503+
7504+ // / Return the structural index of the start of the pack slice.
7505+ unsigned getComponentStartIndex () const {
7506+ return ComponentStartIndex;
7507+ }
7508+
7509+ // / Return the structural index of the end of the pack slice.
7510+ unsigned getComponentEndIndex () const {
7511+ return getComponentStartIndex ()
7512+ + getSliceIndexOperand ()->getIndexedPackType ()->getNumElements ();
7513+ }
7514+ };
7515+
7516+ // / Compute the pack index of a scalar component of a pack.
7517+ class ScalarPackIndexInst final :
7518+ public NullaryInstructionWithTypeDependentOperandsBase<
7519+ SILInstructionKind::ScalarPackIndexInst,
7520+ ScalarPackIndexInst,
7521+ AnyPackIndexInst> {
7522+ unsigned ComponentIndex;
7523+
7524+ friend SILBuilder;
7525+ ScalarPackIndexInst (SILDebugLocation loc,
7526+ unsigned componentIndex,
7527+ ArrayRef<SILValue> typeDependentOperands,
7528+ SILType type, CanPackType packType)
7529+ : NullaryInstructionWithTypeDependentOperandsBase(loc,
7530+ typeDependentOperands, type, packType),
7531+ ComponentIndex (componentIndex) {}
7532+
7533+ static ScalarPackIndexInst *create (SILFunction &parent,
7534+ SILDebugLocation loc,
7535+ unsigned index,
7536+ CanPackType packType);
7537+ public:
7538+ // / Return the structural index of the component within the pack.
7539+ unsigned getComponentIndex () const {
7540+ return ComponentIndex;
7541+ }
7542+ };
7543+
74177544// / Bind archetypes to the given element of one or more type packs.
74187545// /
74197546// / The result of this instruction is just for use in recording type
@@ -7425,11 +7552,8 @@ class DeinitExistentialValueInst
74257552// / shape $t_1_0,
74267553// / uuid "01234567-89AB-CDEF-0123-000000000000"
74277554// /
7428- // / In the printed representation, only the relevant portions of the
7429- // / opened generic environment are given: the pack type parameters,
7430- // / the opened element archetypes, the contextual substitutions of
7431- // / the pack type parameters, and the requirements on the pack type
7432- // / parameters.
7555+ // / The %index operand is always a $Builtin.PackIndex and must be
7556+ // / the immediate result of one of the pack-indexing instructions.
74337557class OpenPackElementInst final
74347558 : public UnaryInstructionWithTypeDependentOperandsBase<
74357559 SILInstructionKind::OpenPackElementInst,
@@ -7490,8 +7614,12 @@ class OpenPackElementInst final
74907614 return Env;
74917615 }
74927616
7493- SILValue getIndexOperand () const {
7494- return getAllOperands ()[0 ].get ();
7617+ // / Return a pack type which represents the contextual shape class
7618+ // / of the types this opens.
7619+ CanPackType getOpenedShapeClass () const ;
7620+
7621+ AnyPackIndexInst *getIndexOperand () const {
7622+ return cast<AnyPackIndexInst>(getOperand ());
74957623 }
74967624};
74977625
0 commit comments