Skip to content

Commit 082aec0

Browse files
committed
Swift SIL: add var FunctionArgument.convention
Also: * move the `ArgumentConvention` enum from Function.swift to Argument.swift. * `FunctionArgument.isExclusiveIndirectParameter` -> `ArgumentConvention.isExclusiveIndirect` * add `ArgumentConvention.isInout`
1 parent 5f49ba1 commit 082aec0

File tree

6 files changed

+134
-96
lines changed

6 files changed

+134
-96
lines changed

SwiftCompilerSources/Sources/Optimizer/Utilities/AccessUtils.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ enum AccessBase : CustomStringConvertible, Hashable {
174174
}
175175

176176
func argIsDistinct(_ arg: FunctionArgument, from other: AccessBase) -> Bool {
177-
if arg.isExclusiveIndirectParameter {
177+
if arg.convention.isExclusiveIndirect {
178178
// Exclusive indirect arguments cannot alias with an address for which we know that it
179179
// is not derived from that argument (which might be the case for `pointer` and `yield`).
180180
return other.hasKnownStorageKind
@@ -199,7 +199,7 @@ enum AccessBase : CustomStringConvertible, Hashable {
199199
case (.tail(let rta), .tail(let otherRta)):
200200
return isDifferentAllocation(rta.operand, otherRta.operand)
201201
case (.argument(let arg), .argument(let otherArg)):
202-
return (arg.isExclusiveIndirectParameter || otherArg.isExclusiveIndirectParameter) && arg != otherArg
202+
return (arg.convention.isExclusiveIndirect || otherArg.convention.isExclusiveIndirect) && arg != otherArg
203203

204204
// Handle arguments vs non-arguments
205205
case (.argument(let arg), _):

SwiftCompilerSources/Sources/Optimizer/Utilities/EscapeInfo.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -734,7 +734,7 @@ fileprivate struct EscapeInfoWalker<V: EscapeInfoVisitor> : ValueDefUseWalker,
734734
case is AllocStackInst:
735735
return cachedWalkDown(addressOrValue: def, path: path.with(knownType: nil))
736736
case let arg as FunctionArgument:
737-
if canIgnoreForLoadOrArgument(path) && arg.isExclusiveIndirectParameter && !path.followStores {
737+
if canIgnoreForLoadOrArgument(path) && arg.convention.isExclusiveIndirect && !path.followStores {
738738
return cachedWalkDown(addressOrValue: def, path: path.with(knownType: nil))
739739
} else {
740740
return isEscaping

SwiftCompilerSources/Sources/SIL/Argument.swift

Lines changed: 104 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ public class Argument : Value, Hashable {
4040
}
4141

4242
final public class FunctionArgument : Argument {
43-
public var isExclusiveIndirectParameter: Bool {
44-
SILArgument_isExclusiveIndirectParameter(bridged) != 0
43+
public var convention: ArgumentConvention {
44+
SILArgument_getConvention(bridged).convention
4545
}
4646
}
4747

@@ -79,10 +79,112 @@ final public class BlockArgument : Argument {
7979
}
8080
}
8181

82+
public enum ArgumentConvention {
83+
/// This argument is passed indirectly, i.e. by directly passing the address
84+
/// of an object in memory. The callee is responsible for destroying the
85+
/// object. The callee may assume that the address does not alias any valid
86+
/// object.
87+
case indirectIn
88+
89+
/// This argument is passed indirectly, i.e. by directly passing the address
90+
/// of an object in memory. The callee must treat the object as read-only
91+
/// The callee may assume that the address does not alias any valid object.
92+
case indirectInConstant
93+
94+
/// This argument is passed indirectly, i.e. by directly passing the address
95+
/// of an object in memory. The callee may not modify and does not destroy
96+
/// the object.
97+
case indirectInGuaranteed
98+
99+
/// This argument is passed indirectly, i.e. by directly passing the address
100+
/// of an object in memory. The object is always valid, but the callee may
101+
/// assume that the address does not alias any valid object and reorder loads
102+
/// stores to the parameter as long as the whole object remains valid. Invalid
103+
/// single-threaded aliasing may produce inconsistent results, but should
104+
/// remain memory safe.
105+
case indirectInout
106+
107+
/// This argument is passed indirectly, i.e. by directly passing the address
108+
/// of an object in memory. The object is allowed to be aliased by other
109+
/// well-typed references, but is not allowed to be escaped. This is the
110+
/// convention used by mutable captures in @noescape closures.
111+
case indirectInoutAliasable
112+
113+
/// This argument represents an indirect return value address. The callee stores
114+
/// the returned value to this argument. At the time when the function is called,
115+
/// the memory location referenced by the argument is uninitialized.
116+
case indirectOut
117+
118+
/// This argument is passed directly. Its type is non-trivial, and the callee
119+
/// is responsible for destroying it.
120+
case directOwned
121+
122+
/// This argument is passed directly. Its type may be trivial, or it may
123+
/// simply be that the callee is not responsible for destroying it. Its
124+
/// validity is guaranteed only at the instant the call begins.
125+
case directUnowned
126+
127+
/// This argument is passed directly. Its type is non-trivial, and the caller
128+
/// guarantees its validity for the entirety of the call.
129+
case directGuaranteed
130+
131+
public var isExclusiveIndirect: Bool {
132+
switch self {
133+
case .indirectIn,
134+
.indirectInConstant,
135+
.indirectOut,
136+
.indirectInGuaranteed,
137+
.indirectInout:
138+
return true
139+
140+
case .indirectInoutAliasable,
141+
.directUnowned,
142+
.directGuaranteed,
143+
.directOwned:
144+
return false
145+
}
146+
}
147+
148+
public var isInout: Bool {
149+
switch self {
150+
case .indirectInout,
151+
.indirectInoutAliasable:
152+
return true
153+
154+
case .indirectIn,
155+
.indirectInConstant,
156+
.indirectOut,
157+
.indirectInGuaranteed,
158+
.directUnowned,
159+
.directGuaranteed,
160+
.directOwned:
161+
return false
162+
}
163+
}
164+
}
165+
82166
// Bridging utilities
83167

84168
extension BridgedArgument {
85169
public var argument: Argument { obj.getAs(Argument.self) }
86170
public var blockArgument: BlockArgument { obj.getAs(BlockArgument.self) }
87171
public var functionArgument: FunctionArgument { obj.getAs(FunctionArgument.self) }
88172
}
173+
174+
extension BridgedArgumentConvention {
175+
var convention: ArgumentConvention {
176+
switch self {
177+
case ArgumentConvention_Indirect_In: return .indirectIn
178+
case ArgumentConvention_Indirect_In_Constant: return .indirectInConstant
179+
case ArgumentConvention_Indirect_In_Guaranteed: return .indirectInGuaranteed
180+
case ArgumentConvention_Indirect_Inout: return .indirectInout
181+
case ArgumentConvention_Indirect_InoutAliasable: return .indirectInoutAliasable
182+
case ArgumentConvention_Indirect_Out: return .indirectOut
183+
case ArgumentConvention_Direct_Owned: return .directOwned
184+
case ArgumentConvention_Direct_Unowned: return .directUnowned
185+
case ArgumentConvention_Direct_Guaranteed: return .directGuaranteed
186+
default:
187+
fatalError("unsupported argument convention")
188+
}
189+
}
190+
}

SwiftCompilerSources/Sources/SIL/Function.swift

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -210,56 +210,6 @@ public struct ArgumentTypeArray : RandomAccessCollection, FormattedLikeArray {
210210
}
211211
}
212212

213-
public enum ArgumentConvention {
214-
/// This argument is passed indirectly, i.e. by directly passing the address
215-
/// of an object in memory. The callee is responsible for destroying the
216-
/// object. The callee may assume that the address does not alias any valid
217-
/// object.
218-
case indirectIn
219-
220-
/// This argument is passed indirectly, i.e. by directly passing the address
221-
/// of an object in memory. The callee must treat the object as read-only
222-
/// The callee may assume that the address does not alias any valid object.
223-
case indirectInConstant
224-
225-
/// This argument is passed indirectly, i.e. by directly passing the address
226-
/// of an object in memory. The callee may not modify and does not destroy
227-
/// the object.
228-
case indirectInGuaranteed
229-
230-
/// This argument is passed indirectly, i.e. by directly passing the address
231-
/// of an object in memory. The object is always valid, but the callee may
232-
/// assume that the address does not alias any valid object and reorder loads
233-
/// stores to the parameter as long as the whole object remains valid. Invalid
234-
/// single-threaded aliasing may produce inconsistent results, but should
235-
/// remain memory safe.
236-
case indirectInout
237-
238-
/// This argument is passed indirectly, i.e. by directly passing the address
239-
/// of an object in memory. The object is allowed to be aliased by other
240-
/// well-typed references, but is not allowed to be escaped. This is the
241-
/// convention used by mutable captures in @noescape closures.
242-
case indirectInoutAliasable
243-
244-
/// This argument represents an indirect return value address. The callee stores
245-
/// the returned value to this argument. At the time when the function is called,
246-
/// the memory location referenced by the argument is uninitialized.
247-
case indirectOut
248-
249-
/// This argument is passed directly. Its type is non-trivial, and the callee
250-
/// is responsible for destroying it.
251-
case directOwned
252-
253-
/// This argument is passed directly. Its type may be trivial, or it may
254-
/// simply be that the callee is not responsible for destroying it. Its
255-
/// validity is guaranteed only at the instant the call begins.
256-
case directUnowned
257-
258-
/// This argument is passed directly. Its type is non-trivial, and the caller
259-
/// guarantees its validity for the entirety of the call.
260-
case directGuaranteed
261-
}
262-
263213
// Bridging utilities
264214

265215
extension BridgedFunction {
@@ -269,21 +219,3 @@ extension BridgedFunction {
269219
extension OptionalBridgedFunction {
270220
public var function: Function? { obj.getAs(Function.self) }
271221
}
272-
273-
extension BridgedArgumentConvention {
274-
var convention: ArgumentConvention {
275-
switch self {
276-
case ArgumentConvention_Indirect_In: return .indirectIn
277-
case ArgumentConvention_Indirect_In_Constant: return .indirectInConstant
278-
case ArgumentConvention_Indirect_In_Guaranteed: return .indirectInGuaranteed
279-
case ArgumentConvention_Indirect_Inout: return .indirectInout
280-
case ArgumentConvention_Indirect_InoutAliasable: return .indirectInoutAliasable
281-
case ArgumentConvention_Indirect_Out: return .indirectOut
282-
case ArgumentConvention_Direct_Owned: return .directOwned
283-
case ArgumentConvention_Direct_Unowned: return .directUnowned
284-
case ArgumentConvention_Direct_Guaranteed: return .directGuaranteed
285-
default:
286-
fatalError("unsupported argument convention")
287-
}
288-
}
289-
}

include/swift/SIL/SILBridging.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ BridgedSubstitutionMap SubstitutionMap_getEmpty();
337337
BridgedLocation SILLocation_getAutogeneratedLocation();
338338

339339
BridgedBasicBlock SILArgument_getParent(BridgedArgument argument);
340-
SwiftInt SILArgument_isExclusiveIndirectParameter(BridgedArgument argument);
340+
BridgedArgumentConvention SILArgument_getConvention(BridgedArgument argument);
341341

342342
OptionalBridgedInstruction SILInstruction_next(BridgedInstruction inst);
343343
OptionalBridgedInstruction SILInstruction_previous(BridgedInstruction inst);

lib/SIL/Utils/SILBridging.cpp

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -327,9 +327,32 @@ BridgedBasicBlock SILArgument_getParent(BridgedArgument argument) {
327327
return {castToArgument(argument)->getParent()};
328328
}
329329

330-
SwiftInt SILArgument_isExclusiveIndirectParameter(BridgedArgument argument) {
330+
static BridgedArgumentConvention bridgeArgumentConvention(SILArgumentConvention convention) {
331+
switch (convention) {
332+
case SILArgumentConvention::Indirect_Inout:
333+
return ArgumentConvention_Indirect_Inout;
334+
case SILArgumentConvention::Indirect_InoutAliasable:
335+
return ArgumentConvention_Indirect_InoutAliasable;
336+
case SILArgumentConvention::Indirect_In_Guaranteed:
337+
return ArgumentConvention_Indirect_In_Guaranteed;
338+
case SILArgumentConvention::Indirect_In:
339+
return ArgumentConvention_Indirect_In;
340+
case SILArgumentConvention::Indirect_In_Constant:
341+
return ArgumentConvention_Indirect_In_Constant;
342+
case SILArgumentConvention::Indirect_Out:
343+
return ArgumentConvention_Indirect_Out;
344+
case SILArgumentConvention::Direct_Unowned:
345+
return ArgumentConvention_Direct_Unowned;
346+
case SILArgumentConvention::Direct_Owned:
347+
return ArgumentConvention_Direct_Owned;
348+
case SILArgumentConvention::Direct_Guaranteed:
349+
return ArgumentConvention_Direct_Guaranteed;
350+
}
351+
}
352+
353+
BridgedArgumentConvention SILArgument_getConvention(BridgedArgument argument) {
331354
auto *arg = castToArgument<SILFunctionArgument>(argument);
332-
return arg->getArgumentConvention().isExclusiveIndirectParameter();
355+
return bridgeArgumentConvention(arg->getArgumentConvention());
333356
}
334357

335358
//===----------------------------------------------------------------------===//
@@ -914,26 +937,7 @@ BridgedArgumentConvention
914937
ApplySite_getArgumentConvention(BridgedInstruction inst, SwiftInt calleeArgIdx) {
915938
auto as = ApplySite(castToInst(inst));
916939
auto conv = as.getSubstCalleeConv().getSILArgumentConvention(calleeArgIdx);
917-
switch (conv.Value) {
918-
case SILArgumentConvention::Indirect_Inout:
919-
return ArgumentConvention_Indirect_In;
920-
case SILArgumentConvention::Indirect_InoutAliasable:
921-
return ArgumentConvention_Indirect_In_Constant;
922-
case SILArgumentConvention::Indirect_In_Guaranteed:
923-
return ArgumentConvention_Indirect_In_Guaranteed;
924-
case SILArgumentConvention::Indirect_In:
925-
return ArgumentConvention_Indirect_Inout;
926-
case SILArgumentConvention::Indirect_In_Constant:
927-
return ArgumentConvention_Indirect_InoutAliasable;
928-
case SILArgumentConvention::Indirect_Out:
929-
return ArgumentConvention_Indirect_Out;
930-
case SILArgumentConvention::Direct_Unowned:
931-
return ArgumentConvention_Direct_Owned;
932-
case SILArgumentConvention::Direct_Owned:
933-
return ArgumentConvention_Direct_Unowned;
934-
case SILArgumentConvention::Direct_Guaranteed:
935-
return ArgumentConvention_Direct_Guaranteed;
936-
}
940+
return bridgeArgumentConvention(conv.Value);
937941
}
938942

939943
SwiftInt ApplySite_getNumArguments(BridgedInstruction inst) {

0 commit comments

Comments
 (0)