Skip to content

Commit e652f2c

Browse files
committed
SIL: add the alloc_vector and vector instructions
* `alloc_vector`: allocates an uninitialized vector of elements on the stack or in a statically initialized global * `vector`: creates an initialized vector in a statically initialized global
1 parent 2a54f98 commit e652f2c

33 files changed

+422
-5
lines changed

Diff for: SwiftCompilerSources/Sources/SIL/Builder.swift

+13
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@ public struct Builder {
9292
return notifyNew(dr.getAs(AllocStackInst.self))
9393
}
9494

95+
public func createAllocVector(capacity: Value, elementType: Type) -> AllocVectorInst {
96+
let dr = bridged.createAllocVector(capacity.bridged, elementType.bridged)
97+
return notifyNew(dr.getAs(AllocVectorInst.self))
98+
}
99+
95100
@discardableResult
96101
public func createDeallocStack(_ operand: Value) -> DeallocStackInst {
97102
let dr = bridged.createDeallocStack(operand.bridged)
@@ -292,6 +297,14 @@ public struct Builder {
292297
return notifyNew(objectInst.getAs(ObjectInst.self))
293298
}
294299

300+
@discardableResult
301+
public func createVector(type: Type, arguments: [Value]) -> VectorInst {
302+
let vectorInst = arguments.withBridgedValues { valuesRef in
303+
return bridged.createVector(valuesRef)
304+
}
305+
return notifyNew(vectorInst.getAs(VectorInst.self))
306+
}
307+
295308
public func createGlobalAddr(global: GlobalVariable) -> GlobalAddrInst {
296309
return notifyNew(bridged.createGlobalAddr(global.bridged).getAs(GlobalAddrInst.self))
297310
}

Diff for: SwiftCompilerSources/Sources/SIL/GlobalVariable.swift

+2
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ extension Instruction {
142142
is IntegerLiteralInst,
143143
is FloatLiteralInst,
144144
is ObjectInst,
145+
is VectorInst,
146+
is AllocVectorInst,
145147
is ValueToBridgeObjectInst,
146148
is ConvertFunctionInst,
147149
is ThinToThickFunctionInst,

Diff for: SwiftCompilerSources/Sources/SIL/Instruction.swift

+7
Original file line numberDiff line numberDiff line change
@@ -974,6 +974,9 @@ final public class ObjectInst : SingleValueInstruction {
974974
}
975975
}
976976

977+
final public class VectorInst : SingleValueInstruction {
978+
}
979+
977980
final public class TuplePackExtractInst: SingleValueInstruction, ForwardingInstruction {
978981
public var indexOperand: Operand { operands[0] }
979982
public var tupleOperand: Operand { operands[1] }
@@ -1001,6 +1004,10 @@ final public class AllocStackInst : SingleValueInstruction, Allocation, DebugVar
10011004
}
10021005
}
10031006

1007+
final public class AllocVectorInst : SingleValueInstruction, Allocation, UnaryInstruction {
1008+
public var capacity: Value { operand.value }
1009+
}
1010+
10041011
public class AllocRefInstBase : SingleValueInstruction, Allocation {
10051012
final public var isObjC: Bool { bridged.AllocRefInstBase_isObjc() }
10061013

Diff for: SwiftCompilerSources/Sources/SIL/Registration.swift

+2
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ public func registerSILClasses() {
8787
register(UncheckedTrivialBitCastInst.self)
8888
register(MarkUnresolvedNonCopyableValueInst.self)
8989
register(ObjectInst.self)
90+
register(VectorInst.self)
9091
register(TuplePackExtractInst.self)
9192
register(DifferentiableFunctionInst.self)
9293
register(LinearFunctionInst.self)
@@ -161,6 +162,7 @@ public func registerSILClasses() {
161162
register(IsUniqueInst.self)
162163
register(IsEscapingClosureInst.self)
163164
register(AllocStackInst.self)
165+
register(AllocVectorInst.self)
164166
register(AllocRefInst.self)
165167
register(AllocRefDynamicInst.self)
166168
register(AllocBoxInst.self)

Diff for: docs/SIL.rst

+36
Original file line numberDiff line numberDiff line change
@@ -3790,6 +3790,28 @@ type, use ``alloc_box``.
37903790

37913791
``T`` must not be a pack type. To allocate a pack, use ``alloc_pack``.
37923792

3793+
alloc_vector
3794+
````````````
3795+
::
3796+
3797+
sil-instruction ::= 'alloc_vector' sil-type, sil-operand
3798+
3799+
%1 = alloc_vector $T, %0 : $Builtin.Word
3800+
// %1 has type $*T
3801+
3802+
Allocates uninitialized memory that is sufficiently aligned on the stack to
3803+
contain a vector of values of type ``T``. The result of the instruction is
3804+
the address of the allocated memory.
3805+
The number of vector elements is specified by the operand, which must be a
3806+
builtin integer value.
3807+
3808+
``alloc_vector`` either allocates memory on the stack or - if contained in a
3809+
global variable static initializer list - in the data section.
3810+
3811+
``alloc_vector`` is a stack allocation instruction, unless it's contained in a
3812+
global initializer list. See the section above on stack discipline. The
3813+
corresponding stack deallocation instruction is ``dealloc_stack``.
3814+
37933815
alloc_pack
37943816
``````````
37953817

@@ -6689,6 +6711,20 @@ object
66896711
Constructs a statically initialized object. This instruction can only appear
66906712
as final instruction in a global variable static initializer list.
66916713

6714+
vector
6715+
``````
6716+
6717+
::
6718+
6719+
sil-instruction ::= 'vector' '(' (sil-operand (',' sil-operand)*)? ')'
6720+
6721+
vector (%a : $T, %b : $T, ...)
6722+
// $T must be a non-generic or bound generic reference type
6723+
// All operands must have the same type
6724+
6725+
Constructs a statically initialized vector of elements. This instruction can only appear
6726+
as final instruction in a global variable static initializer list.
6727+
66926728
ref_element_addr
66936729
````````````````
66946730
::

Diff for: include/swift/SIL/SILBridging.h

+3
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,8 @@ struct BridgedBuilder{
900900
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction createIntegerLiteral(BridgedType type, SwiftInt value) const;
901901
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction createAllocStack(BridgedType type,
902902
bool hasDynamicLifetime, bool isLexical, bool wasMoved) const;
903+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction createAllocVector(BridgedValue capacity,
904+
BridgedType type) const;
903905
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction createDeallocStack(BridgedValue operand) const;
904906
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction createDeallocStackRef(BridgedValue operand) const;
905907
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction createAddressToPointer(BridgedValue address,
@@ -950,6 +952,7 @@ struct BridgedBuilder{
950952
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction createUnreachable() const;
951953
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction createObject(BridgedType type, BridgedValueArray arguments,
952954
SwiftInt numBaseElements) const;
955+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction createVector(BridgedValueArray arguments) const;
953956
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction createGlobalAddr(BridgedGlobalVar global) const;
954957
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedInstruction createGlobalValue(BridgedGlobalVar global,
955958
bool isBare) const;

Diff for: include/swift/SIL/SILBridgingImpl.h

+9
Original file line numberDiff line numberDiff line change
@@ -1262,6 +1262,10 @@ BridgedInstruction BridgedBuilder::createAllocStack(BridgedType type,
12621262
isLexical, wasMoved)};
12631263
}
12641264

1265+
BridgedInstruction BridgedBuilder::createAllocVector(BridgedValue capacity, BridgedType type) const {
1266+
return {unbridged().createAllocVector(regularLoc(), capacity.getSILValue(), type.unbridged())};
1267+
}
1268+
12651269
BridgedInstruction BridgedBuilder::createDeallocStack(BridgedValue operand) const {
12661270
return {unbridged().createDeallocStack(regularLoc(), operand.getSILValue())};
12671271
}
@@ -1423,6 +1427,11 @@ BridgedInstruction BridgedBuilder::createObject(BridgedType type,
14231427
arguments.getValues(argValues), numBaseElements)};
14241428
}
14251429

1430+
BridgedInstruction BridgedBuilder::createVector(BridgedValueArray arguments) const {
1431+
llvm::SmallVector<swift::SILValue, 16> argValues;
1432+
return {unbridged().createVector(swift::ArtificialUnreachableLocation(), arguments.getValues(argValues))};
1433+
}
1434+
14261435
BridgedInstruction BridgedBuilder::createGlobalAddr(BridgedGlobalVar global) const {
14271436
return {unbridged().createGlobalAddr(regularLoc(), global.getGlobal())};
14281437
}

Diff for: include/swift/SIL/SILBuilder.h

+15
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,16 @@ class SILBuilder {
418418
wasMoved));
419419
}
420420

421+
AllocVectorInst *
422+
createAllocVector(SILLocation loc, SILValue capacity, SILType elementType) {
423+
if (isInsertingIntoGlobal()) {
424+
return insert(AllocVectorInst::createInInitializer(
425+
getSILDebugLocation(loc, true), capacity, elementType, getModule()));
426+
}
427+
return insert(AllocVectorInst::create(
428+
getSILDebugLocation(loc, true), capacity, elementType, getFunction()));
429+
}
430+
421431
AllocPackInst *createAllocPack(SILLocation loc, SILType packType) {
422432
return insert(AllocPackInst::create(getSILDebugLocation(loc), packType,
423433
getFunction()));
@@ -1614,6 +1624,11 @@ class SILBuilder {
16141624
forwardingOwnershipKind));
16151625
}
16161626

1627+
VectorInst *createVector(SILLocation Loc, ArrayRef<SILValue> Elements) {
1628+
return insert(VectorInst::create(getSILDebugLocation(Loc), Elements,
1629+
getModule()));
1630+
}
1631+
16171632
StructInst *createStruct(SILLocation Loc, SILType Ty,
16181633
ArrayRef<SILValue> Elements) {
16191634
return createStruct(Loc, Ty, Elements,

Diff for: include/swift/SIL/SILCloner.h

+21
Original file line numberDiff line numberDiff line change
@@ -889,6 +889,17 @@ SILCloner<ImplClass>::visitAllocStackInst(AllocStackInst *Inst) {
889889
recordClonedInstruction(Inst, NewInst);
890890
}
891891

892+
template <typename ImplClass>
893+
void SILCloner<ImplClass>::visitAllocVectorInst(
894+
AllocVectorInst *Inst) {
895+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
896+
recordClonedInstruction(Inst, getBuilder().createAllocVector(
897+
getOpLocation(Inst->getLoc()),
898+
getOpValue(Inst->getCapacity()),
899+
getOpType(Inst->getElementType())));
900+
}
901+
902+
892903
template <typename ImplClass>
893904
void SILCloner<ImplClass>::visitAllocPackMetadataInst(
894905
AllocPackMetadataInst *Inst) {
@@ -2154,6 +2165,16 @@ SILCloner<ImplClass>::visitObjectInst(ObjectInst *Inst) {
21542165
: ValueOwnershipKind(OwnershipKind::None)));
21552166
}
21562167

2168+
template<typename ImplClass>
2169+
void
2170+
SILCloner<ImplClass>::visitVectorInst(VectorInst *Inst) {
2171+
auto Elements = getOpValueArray<8>(Inst->getElements());
2172+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
2173+
recordClonedInstruction(
2174+
Inst,
2175+
getBuilder().createVector(getOpLocation(Inst->getLoc()), Elements));
2176+
}
2177+
21572178
template<typename ImplClass>
21582179
void
21592180
SILCloner<ImplClass>::visitStructInst(StructInst *Inst) {

Diff for: include/swift/SIL/SILInstruction.h

+51
Original file line numberDiff line numberDiff line change
@@ -2115,6 +2115,35 @@ class AllocStackInst final
21152115
DeallocStackInst *getSingleDeallocStack() const;
21162116
};
21172117

2118+
/// AllocVectorInst - Like AllocStackInst, but allocates a vector of elements.
2119+
class AllocVectorInst final
2120+
: public UnaryInstructionWithTypeDependentOperandsBase<
2121+
SILInstructionKind::AllocVectorInst, AllocVectorInst, AllocationInst> {
2122+
friend SILBuilder;
2123+
2124+
AllocVectorInst(SILDebugLocation loc, SILValue capacity, SILType resultType,
2125+
ArrayRef<SILValue> typeDependentOperands)
2126+
: UnaryInstructionWithTypeDependentOperandsBase(loc, capacity,
2127+
typeDependentOperands,
2128+
resultType) {
2129+
}
2130+
2131+
static AllocVectorInst *create(SILDebugLocation Loc, SILValue capacity,
2132+
SILType elementType, SILFunction &F);
2133+
2134+
static AllocVectorInst *createInInitializer(SILDebugLocation Loc,
2135+
SILValue capacity, SILType elementType, SILModule &M);
2136+
2137+
public:
2138+
/// getElementType - Get the type of the allocated memory (as opposed to the
2139+
/// type of the instruction itself, which will be an address type).
2140+
SILType getElementType() const {
2141+
return getType().getObjectType();
2142+
}
2143+
2144+
SILValue getCapacity() const { return getOperand(); }
2145+
};
2146+
21182147
/// AllocPackInst - This represents the allocation of a value pack
21192148
/// in stack memory. The memory is provided uninitialized.
21202149
class AllocPackInst final
@@ -6294,6 +6323,28 @@ class ObjectInst final : public InstructionBaseWithTrailingOperands<
62946323
}
62956324
};
62966325

6326+
/// VectorInst - Represents a vector value type.
6327+
///
6328+
/// This instruction can only appear at the end of a global variable's
6329+
/// static initializer list.
6330+
class VectorInst final : public InstructionBaseWithTrailingOperands<
6331+
SILInstructionKind::VectorInst, VectorInst,
6332+
SingleValueInstruction> {
6333+
friend SILBuilder;
6334+
6335+
VectorInst(SILDebugLocation DebugLoc, ArrayRef<SILValue> Elements)
6336+
: InstructionBaseWithTrailingOperands(Elements, DebugLoc,
6337+
Elements[0]->getType()) {}
6338+
6339+
static VectorInst *create(SILDebugLocation DebugLoc,
6340+
ArrayRef<SILValue> Elements,
6341+
SILModule &M);
6342+
public:
6343+
OperandValueArrayRef getElements() const {
6344+
return OperandValueArrayRef(getAllOperands());
6345+
}
6346+
};
6347+
62976348
/// TupleInst - Represents a constructed loadable tuple.
62986349
class TupleInst final : public InstructionBaseWithTrailingOperands<
62996350
SILInstructionKind::TupleInst, TupleInst,

Diff for: include/swift/SIL/SILNodes.def

+4
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,8 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
313313
ABSTRACT_SINGLE_VALUE_INST(AllocationInst, SingleValueInstruction)
314314
SINGLE_VALUE_INST(AllocStackInst, alloc_stack,
315315
AllocationInst, None, DoesNotRelease)
316+
SINGLE_VALUE_INST(AllocVectorInst, alloc_vector,
317+
AllocationInst, None, DoesNotRelease)
316318
SINGLE_VALUE_INST(AllocPackInst, alloc_pack,
317319
AllocationInst, None, DoesNotRelease)
318320
SINGLE_VALUE_INST(AllocPackMetadataInst, alloc_pack_metadata,
@@ -580,6 +582,8 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
580582
// Aggregate Types
581583
SINGLE_VALUE_INST(ObjectInst, object,
582584
SingleValueInstruction, None, DoesNotRelease)
585+
SINGLE_VALUE_INST(VectorInst, vector,
586+
SingleValueInstruction, None, DoesNotRelease)
583587
SINGLE_VALUE_INST(TupleInst, tuple,
584588
SingleValueInstruction, None, DoesNotRelease)
585589
SINGLE_VALUE_INST(TupleExtractInst, tuple_extract,

Diff for: lib/IRGen/FixedTypeInfo.h

+2
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ class FixedTypeInfo : public TypeInfo {
8282

8383
StackAddress allocateStack(IRGenFunction &IGF, SILType T,
8484
const llvm::Twine &name) const override;
85+
StackAddress allocateVector(IRGenFunction &IGF, SILType T,
86+
llvm::Value *capacity, const Twine &name) const override;
8587
void deallocateStack(IRGenFunction &IGF, StackAddress addr, SILType T) const override;
8688
void destroyStack(IRGenFunction &IGF, StackAddress addr, SILType T,
8789
bool isOutlined) const override;

Diff for: lib/IRGen/GenInit.cpp

+17
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,23 @@ StackAddress FixedTypeInfo::allocateStack(IRGenFunction &IGF, SILType T,
7171
return { alloca };
7272
}
7373

74+
StackAddress FixedTypeInfo::allocateVector(IRGenFunction &IGF, SILType T,
75+
llvm::Value *capacity,
76+
const Twine &name) const {
77+
// If the type is known to be empty, don't actually allocate anything.
78+
if (isKnownEmpty(ResilienceExpansion::Maximal)) {
79+
auto addr = getUndefAddress();
80+
return { addr };
81+
}
82+
83+
StackAddress alloca =
84+
IGF.emitDynamicAlloca(getStorageType(), capacity, getFixedAlignment(),
85+
/*allowTaskAlloc*/ true, name);
86+
IGF.Builder.CreateLifetimeStart(alloca.getAddress(), getFixedSize());
87+
88+
return { alloca };
89+
}
90+
7491
void FixedTypeInfo::destroyStack(IRGenFunction &IGF, StackAddress addr,
7592
SILType T, bool isOutlined) const {
7693
destroy(IGF, addr.getAddress(), T, isOutlined);

Diff for: lib/IRGen/GenType.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -1374,6 +1374,11 @@ namespace {
13741374
const llvm::Twine &name) const override {
13751375
llvm_unreachable("should not call on an immovable opaque type");
13761376
}
1377+
StackAddress allocateVector(IRGenFunction &IGF, SILType T,
1378+
llvm::Value *capacity,
1379+
const Twine &name) const override {
1380+
llvm_unreachable("should not call on an immovable opaque type");
1381+
}
13771382
void deallocateStack(IRGenFunction &IGF, StackAddress addr,
13781383
SILType T) const override {
13791384
llvm_unreachable("should not call on an immovable opaque type");

Diff for: lib/IRGen/IRGenSIL.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -1134,6 +1134,7 @@ class IRGenSILFunction :
11341134
void emitDebugInfoForAllocStack(AllocStackInst *i, const TypeInfo &type,
11351135
llvm::Value *addr);
11361136
void visitAllocStackInst(AllocStackInst *i);
1137+
void visitAllocVectorInst(AllocVectorInst *i);
11371138
void visitAllocPackInst(AllocPackInst *i);
11381139
void visitAllocPackMetadataInst(AllocPackMetadataInst *i);
11391140
void visitAllocRefInst(AllocRefInst *i);
@@ -1237,6 +1238,9 @@ class IRGenSILFunction :
12371238
void visitObjectInst(ObjectInst *i) {
12381239
llvm_unreachable("object instruction cannot appear in a function");
12391240
}
1241+
void visitVectorInst(VectorInst *i) {
1242+
llvm_unreachable("vector instruction cannot appear in a function");
1243+
}
12401244
void visitStructInst(StructInst *i);
12411245
void visitTupleInst(TupleInst *i);
12421246
void visitEnumInst(EnumInst *i);
@@ -5884,6 +5888,15 @@ void IRGenSILFunction::visitAllocStackInst(swift::AllocStackInst *i) {
58845888
emitDebugInfoForAllocStack(i, type, addr.getAddress());
58855889
}
58865890

5891+
void IRGenSILFunction::visitAllocVectorInst(AllocVectorInst *i) {
5892+
const TypeInfo &type = getTypeInfo(i->getElementType());
5893+
Explosion capacity = getLoweredExplosion(i->getCapacity());
5894+
auto stackAddr = type.allocateVector(*this, i->getElementType(),
5895+
capacity.claimNext(), StringRef());
5896+
setLoweredStackAddress(i, stackAddr);
5897+
}
5898+
5899+
58875900
void IRGenSILFunction::visitAllocPackInst(swift::AllocPackInst *i) {
58885901
auto addr = allocatePack(*this, i->getPackType());
58895902
setLoweredStackAddress(i, addr);

0 commit comments

Comments
 (0)