Skip to content

Commit a91d541

Browse files
committed
Swift SIL: add ApplySite.substitutionMap and ApplySite.getArgumentConvention()
1 parent 1a933fc commit a91d541

File tree

4 files changed

+128
-1
lines changed

4 files changed

+128
-1
lines changed

SwiftCompilerSources/Sources/SIL/ApplySite.swift

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,20 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
import SILBridging
14+
1315
public struct ApplyOperands {
1416
public static let calleeOperandIndex: Int = 0
1517
public static let firstArgumentIndex = 1
1618
}
1719

18-
public protocol ApplySite : AnyObject {
20+
public protocol ApplySite : Instruction {
1921
var operands: OperandArray { get }
2022
var numArguments: Int { get }
23+
var substitutionMap: SubstitutionMap { get }
2124
func calleeArgIndex(callerArgIndex: Int) -> Int
2225
func callerArgIndex(calleeArgIndex: Int) -> Int?
26+
func getArgumentConvention(calleeArgIndex: Int) -> ArgumentConvention
2327
}
2428

2529
extension ApplySite {
@@ -29,6 +33,10 @@ extension ApplySite {
2933
operands[1..<operands.count].lazy.map { $0.value }
3034
}
3135

36+
public var substitutionMap: SubstitutionMap {
37+
SubstitutionMap(ApplySite_getSubstitutionMap(bridged))
38+
}
39+
3240
public func argumentIndex(of operand: Operand) -> Int? {
3341
let opIdx = operand.index
3442
if opIdx >= ApplyOperands.firstArgumentIndex &&
@@ -38,6 +46,10 @@ extension ApplySite {
3846
return nil
3947
}
4048

49+
public func getArgumentConvention(calleeArgIndex: Int) -> ArgumentConvention {
50+
return ApplySite_getArgumentConvention(bridged, calleeArgIndex).convention
51+
}
52+
4153
public var referencedFunction: Function? {
4254
if let fri = callee as? FunctionRefInst {
4355
return fri.referencedFunction

SwiftCompilerSources/Sources/SIL/Function.swift

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,56 @@ public struct ArgumentTypeArray : RandomAccessCollection, FormattedLikeArray {
185185
}
186186
}
187187

188+
public enum ArgumentConvention {
189+
/// This argument is passed indirectly, i.e. by directly passing the address
190+
/// of an object in memory. The callee is responsible for destroying the
191+
/// object. The callee may assume that the address does not alias any valid
192+
/// object.
193+
case indirectIn
194+
195+
/// This argument is passed indirectly, i.e. by directly passing the address
196+
/// of an object in memory. The callee must treat the object as read-only
197+
/// The callee may assume that the address does not alias any valid object.
198+
case indirectInConstant
199+
200+
/// This argument is passed indirectly, i.e. by directly passing the address
201+
/// of an object in memory. The callee may not modify and does not destroy
202+
/// the object.
203+
case indirectInGuaranteed
204+
205+
/// This argument is passed indirectly, i.e. by directly passing the address
206+
/// of an object in memory. The object is always valid, but the callee may
207+
/// assume that the address does not alias any valid object and reorder loads
208+
/// stores to the parameter as long as the whole object remains valid. Invalid
209+
/// single-threaded aliasing may produce inconsistent results, but should
210+
/// remain memory safe.
211+
case indirectInout
212+
213+
/// This argument is passed indirectly, i.e. by directly passing the address
214+
/// of an object in memory. The object is allowed to be aliased by other
215+
/// well-typed references, but is not allowed to be escaped. This is the
216+
/// convention used by mutable captures in @noescape closures.
217+
case indirectInoutAliasable
218+
219+
/// This argument represents an indirect return value address. The callee stores
220+
/// the returned value to this argument. At the time when the function is called,
221+
/// the memory location referenced by the argument is uninitialized.
222+
case indirectOut
223+
224+
/// This argument is passed directly. Its type is non-trivial, and the callee
225+
/// is responsible for destroying it.
226+
case directOwned
227+
228+
/// This argument is passed directly. Its type may be trivial, or it may
229+
/// simply be that the callee is not responsible for destroying it. Its
230+
/// validity is guaranteed only at the instant the call begins.
231+
case directUnowned
232+
233+
/// This argument is passed directly. Its type is non-trivial, and the caller
234+
/// guarantees its validity for the entirety of the call.
235+
case directGuaranteed
236+
}
237+
188238
// Bridging utilities
189239

190240
extension BridgedFunction {
@@ -194,3 +244,21 @@ extension BridgedFunction {
194244
extension OptionalBridgedFunction {
195245
public var function: Function? { obj.getAs(Function.self) }
196246
}
247+
248+
extension BridgedArgumentConvention {
249+
var convention: ArgumentConvention {
250+
switch self {
251+
case ArgumentConvention_Indirect_In: return .indirectIn
252+
case ArgumentConvention_Indirect_In_Constant: return .indirectInConstant
253+
case ArgumentConvention_Indirect_In_Guaranteed: return .indirectInGuaranteed
254+
case ArgumentConvention_Indirect_Inout: return .indirectInout
255+
case ArgumentConvention_Indirect_InoutAliasable: return .indirectInoutAliasable
256+
case ArgumentConvention_Indirect_Out: return .indirectOut
257+
case ArgumentConvention_Direct_Owned: return .directOwned
258+
case ArgumentConvention_Direct_Unowned: return .directUnowned
259+
case ArgumentConvention_Direct_Guaranteed: return .directGuaranteed
260+
default:
261+
fatalError("unsupported argument convention")
262+
}
263+
}
264+
}

include/swift/SIL/SILBridging.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,18 @@ typedef enum {
147147
Ownership_None
148148
} BridgedOwnership;
149149

150+
typedef enum {
151+
ArgumentConvention_Indirect_In,
152+
ArgumentConvention_Indirect_In_Constant,
153+
ArgumentConvention_Indirect_In_Guaranteed,
154+
ArgumentConvention_Indirect_Inout,
155+
ArgumentConvention_Indirect_InoutAliasable,
156+
ArgumentConvention_Indirect_Out,
157+
ArgumentConvention_Direct_Owned,
158+
ArgumentConvention_Direct_Unowned,
159+
ArgumentConvention_Direct_Guaranteed,
160+
} BridgedArgumentConvention;
161+
150162
// AST bridging
151163

152164
typedef struct {
@@ -313,6 +325,10 @@ void RefCountingInst_setIsAtomic(BridgedInstruction rc, bool isAtomic);
313325
bool RefCountingInst_getIsAtomic(BridgedInstruction rc);
314326
SwiftInt CondBranchInst_getNumTrueArgs(BridgedInstruction cbr);
315327

328+
BridgedSubstitutionMap ApplySite_getSubstitutionMap(BridgedInstruction inst);
329+
BridgedArgumentConvention
330+
ApplySite_getArgumentConvention(BridgedInstruction inst, SwiftInt calleeArgIdx);
331+
316332
BridgedInstruction SILBuilder_createBuiltinBinaryFunction(
317333
BridgedBuilder builder, BridgedStringRef name,
318334
BridgedType operandType, BridgedType resultType,

lib/SIL/Utils/SILBridging.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,37 @@ SwiftInt CondBranchInst_getNumTrueArgs(BridgedInstruction cbr) {
746746
return castToInst<CondBranchInst>(cbr)->getNumTrueArgs();
747747
}
748748

749+
BridgedSubstitutionMap ApplySite_getSubstitutionMap(BridgedInstruction inst) {
750+
auto as = ApplySite(castToInst(inst));
751+
return {as.getSubstitutionMap().getOpaqueValue()};
752+
}
753+
754+
BridgedArgumentConvention
755+
ApplySite_getArgumentConvention(BridgedInstruction inst, SwiftInt calleeArgIdx) {
756+
auto as = ApplySite(castToInst(inst));
757+
auto conv = as.getSubstCalleeConv().getSILArgumentConvention(calleeArgIdx);
758+
switch (conv.Value) {
759+
case SILArgumentConvention::Indirect_Inout:
760+
return ArgumentConvention_Indirect_In;
761+
case SILArgumentConvention::Indirect_InoutAliasable:
762+
return ArgumentConvention_Indirect_In_Constant;
763+
case SILArgumentConvention::Indirect_In_Guaranteed:
764+
return ArgumentConvention_Indirect_In_Guaranteed;
765+
case SILArgumentConvention::Indirect_In:
766+
return ArgumentConvention_Indirect_Inout;
767+
case SILArgumentConvention::Indirect_In_Constant:
768+
return ArgumentConvention_Indirect_InoutAliasable;
769+
case SILArgumentConvention::Indirect_Out:
770+
return ArgumentConvention_Indirect_Out;
771+
case SILArgumentConvention::Direct_Unowned:
772+
return ArgumentConvention_Direct_Owned;
773+
case SILArgumentConvention::Direct_Owned:
774+
return ArgumentConvention_Direct_Unowned;
775+
case SILArgumentConvention::Direct_Guaranteed:
776+
return ArgumentConvention_Direct_Guaranteed;
777+
}
778+
}
779+
749780
//===----------------------------------------------------------------------===//
750781
// SILBuilder
751782
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)