Skip to content

Commit 84d1630

Browse files
authored
Merge pull request swiftlang#9142 from shajrawi/loadable_by_addr_split
Code Size: Pass large loadable types by address instead of by value - Updated Version
2 parents 06643d1 + 4dc0801 commit 84d1630

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+2309
-121
lines changed

docs/ABI.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,8 @@ Globals
794794

795795
global ::= type 'Wy' // Outlined Copy Function Type
796796
global ::= type 'We' // Outlined Consume Function Type
797+
global ::= type 'Wr' // Outlined Retain Function Type
798+
global ::= type 'Ws' // Outlined Release Function Type
797799

798800
DIRECTNESS ::= 'd' // direct
799801
DIRECTNESS ::= 'i' // indirect
@@ -1101,6 +1103,7 @@ mangled in to disambiguate.
11011103
FUNC-REPRESENTATION ::= 'W' // protocol witness
11021104

11031105
PARAM-CONVENTION ::= 'i' // indirect in
1106+
PARAM-CONVENTION ::= 'c' // indirect in constant
11041107
PARAM-CONVENTION ::= 'l' // indirect inout
11051108
PARAM-CONVENTION ::= 'b' // indirect inout aliasable
11061109
PARAM-CONVENTION ::= 'n' // indirect in guaranteed

docs/SIL.rst

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,9 @@ number of ways:
479479
initialized object; both the caller and callee promise not to mutate the
480480
pointee, allowing the callee to read it.
481481

482+
- An ``@in_constant`` parameter is indirect. The address must be of an
483+
initialized object; the function will treat the value held there as read-only.
484+
482485
- Otherwise, the parameter is an unowned direct parameter.
483486

484487
- A SIL function type declares the conventions for its results.
@@ -3296,6 +3299,18 @@ For aggregate types, especially enums, it is typically both easier
32963299
and more efficient to reason about aggregate copies than it is to
32973300
reason about copies of the subobjects.
32983301

3302+
retain_value_addr
3303+
`````````````````
3304+
3305+
::
3306+
3307+
sil-instruction ::= 'retain_value_addr' sil-operand
3308+
3309+
retain_value_addr %0 : $*A
3310+
3311+
Retains a loadable value inside given address,
3312+
which simply retains any references it holds.
3313+
32993314
unmanaged_retain_value
33003315
``````````````````````
33013316

@@ -3362,6 +3377,18 @@ For aggregate types, especially enums, it is typically both easier
33623377
and more efficient to reason about aggregate destroys than it is to
33633378
reason about destroys of the subobjects.
33643379

3380+
release_value_addr
3381+
``````````````````
3382+
3383+
::
3384+
3385+
sil-instruction ::= 'release_value_addr' sil-operand
3386+
3387+
release_value_addr %0 : $*A
3388+
3389+
Destroys a loadable value inside given address,
3390+
by releasing any retainable pointers within it.
3391+
33653392
unmanaged_release_value
33663393
```````````````````````
33673394

include/swift/AST/Attr.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ TYPE_ATTR(in)
5050
TYPE_ATTR(inout)
5151
TYPE_ATTR(inout_aliasable)
5252
TYPE_ATTR(in_guaranteed)
53+
TYPE_ATTR(in_constant)
5354
TYPE_ATTR(owned)
5455
TYPE_ATTR(unowned_inner_pointer)
5556
TYPE_ATTR(guaranteed)

include/swift/AST/Types.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2663,6 +2663,11 @@ enum class ParameterConvention {
26632663
/// object.
26642664
Indirect_In,
26652665

2666+
/// This argument is passed indirectly, i.e. by directly passing the address
2667+
/// of an object in memory. The callee must treat the object as read-only
2668+
/// The callee may assume that the address does not alias any valid object.
2669+
Indirect_In_Constant,
2670+
26662671
/// This argument is passed indirectly, i.e. by directly passing the address
26672672
/// of an object in memory. The callee may not modify and does not destroy
26682673
/// the object.
@@ -2675,7 +2680,7 @@ enum class ParameterConvention {
26752680
/// single-threaded aliasing may produce inconsistent results, but should
26762681
/// remain memory safe.
26772682
Indirect_Inout,
2678-
2683+
26792684
/// This argument is passed indirectly, i.e. by directly passing the address
26802685
/// of an object in memory. The object is allowed to be aliased by other
26812686
/// well-typed references, but is not allowed to be escaped. This is the
@@ -2705,6 +2710,7 @@ static_assert(unsigned(ParameterConvention::Direct_Guaranteed) < (1<<3),
27052710
inline bool isIndirectFormalParameter(ParameterConvention conv) {
27062711
switch (conv) {
27072712
case ParameterConvention::Indirect_In:
2713+
case ParameterConvention::Indirect_In_Constant:
27082714
case ParameterConvention::Indirect_Inout:
27092715
case ParameterConvention::Indirect_InoutAliasable:
27102716
case ParameterConvention::Indirect_In_Guaranteed:
@@ -2720,6 +2726,7 @@ inline bool isIndirectFormalParameter(ParameterConvention conv) {
27202726
inline bool isConsumedParameter(ParameterConvention conv) {
27212727
switch (conv) {
27222728
case ParameterConvention::Indirect_In:
2729+
case ParameterConvention::Indirect_In_Constant:
27232730
case ParameterConvention::Direct_Owned:
27242731
return true;
27252732

@@ -2745,6 +2752,7 @@ inline bool isGuaranteedParameter(ParameterConvention conv) {
27452752
case ParameterConvention::Indirect_Inout:
27462753
case ParameterConvention::Indirect_InoutAliasable:
27472754
case ParameterConvention::Indirect_In:
2755+
case ParameterConvention::Indirect_In_Constant:
27482756
case ParameterConvention::Direct_Unowned:
27492757
case ParameterConvention::Direct_Owned:
27502758
return false;

include/swift/Demangling/DemangleNodes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,5 +181,7 @@ NODE(FirstElementMarker)
181181
NODE(VariadicMarker)
182182
NODE(OutlinedCopy)
183183
NODE(OutlinedConsume)
184+
NODE(OutlinedRetain)
185+
NODE(OutlinedRelease)
184186
#undef CONTEXT_NODE
185187
#undef NODE

include/swift/IRGen/IRGenSILPasses.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,13 @@
1212

1313
namespace swift {
1414

15-
class SILFunctionTransform;
15+
class SILTransform;
1616

1717
namespace irgen {
1818

1919
/// Create a pass to hoist alloc_stack instructions with non-fixed size.
20-
SILFunctionTransform *createAllocStackHoisting();
20+
SILTransform *createAllocStackHoisting();
21+
SILTransform *createLoadableByAddress();
2122

2223
} // end namespace irgen
2324
} // end namespace swift

include/swift/SIL/PatternMatch.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,9 @@ UNARY_OP_MATCH_WITH_ARG_MATCHER(ObjCMetatypeToObjectInst)
345345
UNARY_OP_MATCH_WITH_ARG_MATCHER(ObjCExistentialMetatypeToObjectInst)
346346
UNARY_OP_MATCH_WITH_ARG_MATCHER(IsNonnullInst)
347347
UNARY_OP_MATCH_WITH_ARG_MATCHER(RetainValueInst)
348+
UNARY_OP_MATCH_WITH_ARG_MATCHER(RetainValueAddrInst)
348349
UNARY_OP_MATCH_WITH_ARG_MATCHER(ReleaseValueInst)
350+
UNARY_OP_MATCH_WITH_ARG_MATCHER(ReleaseValueAddrInst)
349351
UNARY_OP_MATCH_WITH_ARG_MATCHER(AutoreleaseValueInst)
350352
UNARY_OP_MATCH_WITH_ARG_MATCHER(UncheckedEnumDataInst)
351353
UNARY_OP_MATCH_WITH_ARG_MATCHER(InitEnumDataAddrInst)

include/swift/SIL/SILArgumentConvention.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ enum class InoutAliasingAssumption {
3737
struct SILArgumentConvention {
3838
enum ConventionType : uint8_t {
3939
Indirect_In,
40+
Indirect_In_Constant,
4041
Indirect_In_Guaranteed,
4142
Indirect_Inout,
4243
Indirect_InoutAliasable,
@@ -55,6 +56,9 @@ struct SILArgumentConvention {
5556
case ParameterConvention::Indirect_In:
5657
Value = SILArgumentConvention::Indirect_In;
5758
return;
59+
case ParameterConvention::Indirect_In_Constant:
60+
Value = SILArgumentConvention::Indirect_In_Constant;
61+
return;
5862
case ParameterConvention::Indirect_Inout:
5963
Value = SILArgumentConvention::Indirect_Inout;
6064
return;
@@ -90,6 +94,7 @@ struct SILArgumentConvention {
9094
bool isNotAliasedIndirectParameter(InoutAliasingAssumption isInoutAliasing) {
9195
switch (Value) {
9296
case SILArgumentConvention::Indirect_In:
97+
case SILArgumentConvention::Indirect_In_Constant:
9398
case SILArgumentConvention::Indirect_Out:
9499
case SILArgumentConvention::Indirect_In_Guaranteed:
95100
return true;

include/swift/SIL/SILBuilder.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,13 +864,28 @@ class SILBuilder {
864864
operand, atomicity));
865865
}
866866

867+
RetainValueAddrInst *createRetainValueAddr(SILLocation Loc, SILValue operand,
868+
Atomicity atomicity) {
869+
assert(isParsing || F.hasUnqualifiedOwnership());
870+
return insert(new (F.getModule()) RetainValueAddrInst(
871+
getSILDebugLocation(Loc), operand, atomicity));
872+
}
873+
867874
ReleaseValueInst *createReleaseValue(SILLocation Loc, SILValue operand,
868875
Atomicity atomicity) {
869876
assert(isParsing || F.hasUnqualifiedOwnership());
870877
return insert(new (F.getModule()) ReleaseValueInst(getSILDebugLocation(Loc),
871878
operand, atomicity));
872879
}
873880

881+
ReleaseValueAddrInst *createReleaseValueAddr(SILLocation Loc,
882+
SILValue operand,
883+
Atomicity atomicity) {
884+
assert(isParsing || F.hasUnqualifiedOwnership());
885+
return insert(new (F.getModule()) ReleaseValueAddrInst(
886+
getSILDebugLocation(Loc), operand, atomicity));
887+
}
888+
874889
UnmanagedRetainValueInst *createUnmanagedRetainValue(SILLocation Loc,
875890
SILValue operand,
876891
Atomicity atomicity) {

include/swift/SIL/SILCloner.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,6 +1232,15 @@ void SILCloner<ImplClass>::visitRetainValueInst(RetainValueInst *Inst) {
12321232
Inst->getAtomicity()));
12331233
}
12341234

1235+
template <typename ImplClass>
1236+
void SILCloner<ImplClass>::visitRetainValueAddrInst(RetainValueAddrInst *Inst) {
1237+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
1238+
doPostProcess(
1239+
Inst, getBuilder().createRetainValueAddr(getOpLocation(Inst->getLoc()),
1240+
getOpValue(Inst->getOperand()),
1241+
Inst->getAtomicity()));
1242+
}
1243+
12351244
template <typename ImplClass>
12361245
void SILCloner<ImplClass>::visitUnmanagedRetainValueInst(
12371246
UnmanagedRetainValueInst *Inst) {
@@ -1268,6 +1277,16 @@ void SILCloner<ImplClass>::visitReleaseValueInst(ReleaseValueInst *Inst) {
12681277
Inst->getAtomicity()));
12691278
}
12701279

1280+
template <typename ImplClass>
1281+
void SILCloner<ImplClass>::visitReleaseValueAddrInst(
1282+
ReleaseValueAddrInst *Inst) {
1283+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
1284+
doPostProcess(
1285+
Inst, getBuilder().createReleaseValueAddr(getOpLocation(Inst->getLoc()),
1286+
getOpValue(Inst->getOperand()),
1287+
Inst->getAtomicity()));
1288+
}
1289+
12711290
template <typename ImplClass>
12721291
void SILCloner<ImplClass>::visitUnmanagedReleaseValueInst(
12731292
UnmanagedReleaseValueInst *Inst) {

0 commit comments

Comments
 (0)