Skip to content

Commit 84d1630

Browse files
authored
Merge pull request #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) {

include/swift/SIL/SILFunction.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,9 +239,9 @@ class SILFunction
239239
/// or return instructions; you need to do that yourself
240240
/// if you care.
241241
///
242-
/// This is a hack and should be removed!
242+
/// This routine does not update all the references in the module
243+
/// You have to do that yourself
243244
void rewriteLoweredTypeUnsafe(CanSILFunctionType newType) {
244-
assert(canBeDeleted());
245245
LoweredType = newType;
246246
}
247247

include/swift/SIL/SILFunctionConventions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,7 @@ inline bool SILModuleConventions::isIndirectSILParam(SILParameterInfo param,
352352
return false;
353353

354354
case ParameterConvention::Indirect_In:
355+
case ParameterConvention::Indirect_In_Constant:
355356
case ParameterConvention::Indirect_In_Guaranteed:
356357
return (loweredAddresses ||
357358
param.getType()->isOpenedExistentialWithError());

include/swift/SIL/SILInstruction.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3667,6 +3667,19 @@ class RetainValueInst : public UnaryInstructionBase<ValueKind::RetainValueInst,
36673667
}
36683668
};
36693669

3670+
/// RetainValueAddrInst - Copies a loadable value by address.
3671+
class RetainValueAddrInst
3672+
: public UnaryInstructionBase<ValueKind::RetainValueAddrInst,
3673+
RefCountingInst, /*HasValue*/ false> {
3674+
friend SILBuilder;
3675+
3676+
RetainValueAddrInst(SILDebugLocation DebugLoc, SILValue operand,
3677+
Atomicity atomicity)
3678+
: UnaryInstructionBase(DebugLoc, operand) {
3679+
setAtomicity(atomicity);
3680+
}
3681+
};
3682+
36703683
/// ReleaseValueInst - Destroys a loadable value.
36713684
class ReleaseValueInst : public UnaryInstructionBase<ValueKind::ReleaseValueInst,
36723685
RefCountingInst,
@@ -3680,6 +3693,19 @@ class ReleaseValueInst : public UnaryInstructionBase<ValueKind::ReleaseValueInst
36803693
}
36813694
};
36823695

3696+
/// ReleaseValueInst - Destroys a loadable value by address.
3697+
class ReleaseValueAddrInst
3698+
: public UnaryInstructionBase<ValueKind::ReleaseValueAddrInst,
3699+
RefCountingInst, /*HasValue*/ false> {
3700+
friend SILBuilder;
3701+
3702+
ReleaseValueAddrInst(SILDebugLocation DebugLoc, SILValue operand,
3703+
Atomicity atomicity)
3704+
: UnaryInstructionBase(DebugLoc, operand) {
3705+
setAtomicity(atomicity);
3706+
}
3707+
};
3708+
36833709
/// Copies a loadable value in an unmanaged, unbalanced way. Only meant for use
36843710
/// in ownership qualified SIL. Please do not use this EVER unless you are
36853711
/// implementing a part of the stdlib called Unmanaged.

include/swift/SIL/SILNodes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,9 @@ ABSTRACT_VALUE(SILInstruction, ValueBase)
152152
INST(UnownedReleaseInst, RefCountingInst, unowned_release, MayHaveSideEffects,
153153
MayRelease)
154154
INST(RetainValueInst, RefCountingInst, retain_value, MayHaveSideEffects, DoesNotRelease)
155+
INST(RetainValueAddrInst, RefCountingInst, retain_value_addr, MayHaveSideEffects, DoesNotRelease)
155156
INST(ReleaseValueInst, RefCountingInst, release_value, MayHaveSideEffects, MayRelease)
157+
INST(ReleaseValueAddrInst, RefCountingInst, release_value_addr, MayHaveSideEffects, MayRelease)
156158
INST(SetDeallocatingInst, RefCountingInst, set_deallocating, MayHaveSideEffects,
157159
DoesNotRelease)
158160
INST(AutoreleaseValueInst, RefCountingInst, autorelease_value, MayHaveSideEffects,

include/swift/SILOptimizer/PassManager/PassManager.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ class SILPassManager {
9999

100100

101101
/// The IRGen SIL passes. These have to be dynamically added by IRGen.
102-
llvm::DenseMap<unsigned, SILFunctionTransform *> IRGenPasses;
102+
llvm::DenseMap<unsigned, SILTransform *> IRGenPasses;
103103

104104
public:
105105
/// C'tor. It creates and registers all analysis passes, which are defined
@@ -247,7 +247,7 @@ class SILPassManager {
247247
}
248248
}
249249

250-
void registerIRGenPass(PassKind Kind, SILFunctionTransform *Transform) {
250+
void registerIRGenPass(PassKind Kind, SILTransform *Transform) {
251251
assert(IRGenPasses.find(unsigned(Kind)) == IRGenPasses.end() &&
252252
"Pass already registered");
253253
assert(

include/swift/SILOptimizer/PassManager/Passes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,8 @@ PASS(ReleaseHoisting, "release-hoisting",
222222
"SIL release Hoisting")
223223
PASS(LateReleaseHoisting, "late-release-hoisting",
224224
"Late SIL release Hoisting Preserving Epilogues")
225+
IRGEN_PASS(LoadableByAddress, "loadable-address",
226+
"SIL Loadable type by-address lowering.")
225227
PASS(RemovePins, "remove-pins",
226228
"Remove SIL pin/unpin pairs")
227229
PASS(SideEffectsDumper, "side-effects-dump",

include/swift/SILOptimizer/PassManager/Transforms.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ namespace swift {
6666
/// Inject the pass manager running this pass.
6767
void injectPassManager(SILPassManager *PMM) { PM = PMM; }
6868

69+
irgen::IRGenModule *getIRGenModule() {
70+
auto *Mod = PM->getIRGenModule();
71+
assert(Mod && "Expecting a valid module");
72+
return Mod;
73+
}
74+
6975
/// Get the name of the transform.
7076
llvm::StringRef getName() { return PassKindName(getPassKind()); }
7177

@@ -116,12 +122,6 @@ namespace swift {
116122
protected:
117123
SILFunction *getFunction() { return F; }
118124

119-
irgen::IRGenModule *getIRGenModule() {
120-
auto *Mod = PM->getIRGenModule();
121-
assert(Mod && "Expecting a valid module");
122-
return Mod;
123-
}
124-
125125
void invalidateAnalysis(SILAnalysis::InvalidationKind K) {
126126
PM->invalidateAnalysis(F, K);
127127
}

include/swift/Serialization/ModuleFormat.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ const uint16_t VERSION_MAJOR = 0;
5454
/// in source control, you should also update the comment to briefly
5555
/// describe what change you made. The content of this comment isn't important;
5656
/// it just ensures a conflict if two people change the module format.
57-
const uint16_t VERSION_MINOR = 339; // Last change: member canonical types
57+
const uint16_t VERSION_MINOR = 341; // Last change: retain/release addr
5858

5959
using DeclID = PointerEmbeddedInt<unsigned, 31>;
6060
using DeclIDField = BCFixed<31>;
@@ -199,6 +199,7 @@ enum class ParameterConvention : uint8_t {
199199
Direct_Unowned,
200200
Direct_Guaranteed,
201201
Indirect_In_Guaranteed,
202+
Indirect_In_Constant,
202203
};
203204
using ParameterConventionField = BCFixed<4>;
204205

lib/AST/ASTMangler.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -947,6 +947,8 @@ static char getParamConvention(ParameterConvention conv) {
947947
// different places.
948948
switch (conv) {
949949
case ParameterConvention::Indirect_In: return 'i';
950+
case ParameterConvention::Indirect_In_Constant:
951+
return 'c';
950952
case ParameterConvention::Indirect_Inout: return 'l';
951953
case ParameterConvention::Indirect_InoutAliasable: return 'b';
952954
case ParameterConvention::Indirect_In_Guaranteed: return 'n';

0 commit comments

Comments
 (0)