Skip to content

Commit eecea08

Browse files
committed
Swift Bridging: use C++ instead of C bridging for BridgedOperand and BridgedValue
1 parent 4c135aa commit eecea08

File tree

11 files changed

+193
-183
lines changed

11 files changed

+193
-183
lines changed

SwiftCompilerSources/Sources/Optimizer/PassManager/Context.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ extension Builder {
217217

218218
extension Undef {
219219
static func get(type: Type, _ context: some MutatingContext) -> Undef {
220-
SILUndef_get(type.bridged, context._bridged).getAs(Undef.self)
220+
SILUndef_get(type.bridged, context._bridged).value as! Undef
221221
}
222222
}
223223

SwiftCompilerSources/Sources/SIL/Instruction.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ public class Instruction : CustomStringConvertible, Hashable {
4343
}
4444

4545
final public var operands: OperandArray {
46-
return OperandArray(opArray: SILInstruction_getOperands(bridged))
46+
let operands = SILInstruction_getOperands(bridged)
47+
return OperandArray(base: operands.base, count: operands.count)
4748
}
4849

4950
fileprivate var resultCount: Int { 0 }

SwiftCompilerSources/Sources/SIL/Operand.swift

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,49 +16,48 @@ import SILBridging
1616
public struct Operand : CustomStringConvertible, NoReflectionChildren {
1717
fileprivate let bridged: BridgedOperand
1818

19-
init(_ bridged: BridgedOperand) {
19+
init(bridged: BridgedOperand) {
2020
self.bridged = bridged
2121
}
2222

23-
public var value: Value {
24-
Operand_getValue(bridged).value
25-
}
23+
public var value: Value { bridged.getValue().value }
2624

2725
public static func ==(lhs: Operand, rhs: Operand) -> Bool {
2826
return lhs.bridged.op == rhs.bridged.op
2927
}
3028

3129
public var instruction: Instruction {
32-
return Operand_getUser(bridged).instruction
30+
return bridged.getUser().instruction
3331
}
3432

3533
public var index: Int { instruction.operands.getIndex(of: self) }
3634

3735
/// True if the operand is used to describe a type dependency, but it's not
3836
/// used as value.
39-
public var isTypeDependent: Bool { Operand_isTypeDependent(bridged) != 0 }
37+
public var isTypeDependent: Bool { bridged.isTypeDependent() }
4038

4139
public var description: String { "operand #\(index) of \(instruction)" }
4240
}
4341

4442
public struct OperandArray : RandomAccessCollection, CustomReflectable {
45-
private let opArray: BridgedArrayRef
43+
private let base: OptionalBridgedOperand
44+
public let count: Int
4645

47-
init(opArray: BridgedArrayRef) {
48-
self.opArray = opArray
46+
init(base: OptionalBridgedOperand, count: Int) {
47+
self.base = base
48+
self.count = count
4949
}
50-
50+
5151
public var startIndex: Int { return 0 }
52-
public var endIndex: Int { return Int(opArray.numElements) }
52+
public var endIndex: Int { return count }
5353

5454
public subscript(_ index: Int) -> Operand {
55-
assert(index >= 0 && index < endIndex)
56-
return Operand(BridgedOperand(op: opArray.data! + index &* BridgedOperandSize))
55+
assert(index >= startIndex && index < endIndex)
56+
return Operand(bridged: base.advancedBy(index))
5757
}
5858

5959
public func getIndex(of operand: Operand) -> Int {
60-
let idx = (operand.bridged.op - UnsafeRawPointer(opArray.data!)) /
61-
BridgedOperandSize
60+
let idx = base.distanceTo(operand.bridged)
6261
assert(self[idx].bridged.op == operand.bridged.op)
6362
return idx
6463
}
@@ -72,38 +71,38 @@ public struct OperandArray : RandomAccessCollection, CustomReflectable {
7271
///
7372
/// Note: this does not return a Slice. The first index of the returnd array is always 0.
7473
public subscript(bounds: Range<Int>) -> OperandArray {
75-
assert(bounds.lowerBound >= 0)
76-
assert(bounds.upperBound <= endIndex)
77-
return OperandArray(opArray: BridgedArrayRef(
78-
data: opArray.data! + bounds.lowerBound &* BridgedOperandSize,
79-
numElements: bounds.upperBound - bounds.lowerBound))
74+
assert(bounds.lowerBound >= startIndex && bounds.upperBound <= endIndex)
75+
return OperandArray(
76+
base: OptionalBridgedOperand(op: base.advancedBy(bounds.lowerBound).op),
77+
count: bounds.upperBound - bounds.lowerBound)
8078
}
8179
}
8280

8381
public struct UseList : CollectionLikeSequence {
8482
public struct Iterator : IteratorProtocol {
85-
var currentOpPtr: UnsafeRawPointer?
83+
var currentOpPtr: OptionalBridgedOperand
8684

8785
public mutating func next() -> Operand? {
88-
if let opPtr = currentOpPtr {
89-
let bridged = BridgedOperand(op: opPtr)
90-
currentOpPtr = Operand_nextUse(bridged).op
91-
return Operand(bridged)
86+
if let op = currentOpPtr.operand {
87+
currentOpPtr = op.getNextUse()
88+
return Operand(bridged: op)
9289
}
9390
return nil
9491
}
9592
}
9693

97-
private let firstOpPtr: UnsafeRawPointer?
94+
private let firstOpPtr: OptionalBridgedOperand
9895

9996
init(_ firstOpPtr: OptionalBridgedOperand) {
100-
self.firstOpPtr = firstOpPtr.op
97+
self.firstOpPtr = firstOpPtr
10198
}
10299

103100
public var singleUse: Operand? {
104-
if let opPtr = firstOpPtr {
105-
if Operand_nextUse(BridgedOperand(op: opPtr)).op != nil { return nil }
106-
return Operand(BridgedOperand(op: opPtr))
101+
if let op = firstOpPtr.operand {
102+
if op.getNextUse().operand != nil {
103+
return nil
104+
}
105+
return Operand(bridged: op)
107106
}
108107
return nil
109108
}
@@ -114,3 +113,12 @@ public struct UseList : CollectionLikeSequence {
114113
return Iterator(currentOpPtr: firstOpPtr)
115114
}
116115
}
116+
117+
extension OptionalBridgedOperand {
118+
var operand: BridgedOperand? {
119+
if let op = op {
120+
return BridgedOperand(op: op)
121+
}
122+
return nil
123+
}
124+
}

SwiftCompilerSources/Sources/SIL/Utils.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,11 @@ public struct ParsingError : Error {
189189

190190
extension Array where Element == Value {
191191
public func withBridgedValues<T>(_ c: (BridgedValueArray) -> T) -> T {
192-
return self.withUnsafeBytes { valPtr in
193-
assert(valPtr.count == self.count * 16)
194-
return c(BridgedValueArray(data: valPtr.baseAddress, count: self.count))
192+
return self.withUnsafeBufferPointer { bufPtr in
193+
assert(bufPtr.count == self.count)
194+
return bufPtr.withMemoryRebound(to: BridgeValueExistential.self) { valPtr in
195+
return c(BridgedValueArray(base: valPtr.baseAddress, count: self.count))
196+
}
195197
}
196198
}
197199
}

SwiftCompilerSources/Sources/SIL/Value.swift

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,12 @@ public enum Ownership {
7676
/// statically available on some control flow paths.
7777
case none
7878

79-
public var _bridged: BridgedOwnership {
79+
public var _bridged: BridgedValue.Ownership {
8080
switch self {
81-
case .unowned: return Ownership_Unowned
82-
case .owned: return Ownership_Owned
83-
case .guaranteed: return Ownership_Guaranteed
84-
case .none: return Ownership_None
81+
case .unowned: return BridgedValue.Ownership.Unowned
82+
case .owned: return BridgedValue.Ownership.Owned
83+
case .guaranteed: return BridgedValue.Ownership.Guaranteed
84+
case .none: return BridgedValue.Ownership.None
8585
}
8686
}
8787
}
@@ -92,21 +92,19 @@ extension Value {
9292
return String(_cxxString: stdString)
9393
}
9494

95-
public var uses: UseList {
96-
UseList(SILValue_firstUse(bridged))
97-
}
95+
public var uses: UseList { UseList(bridged.getFirstUse()) }
9896

9997
public var parentFunction: Function { parentBlock.parentFunction }
10098

101-
public var type: Type { SILValue_getType(bridged).type }
99+
public var type: Type { bridged.getType().type }
102100

103101
/// True if the value has a trivial type.
104102
public var hasTrivialType: Bool { type.isTrivial(in: parentFunction) }
105103

106104
/// True if the value has a trivial type which is and does not contain a Builtin.RawPointer.
107105
public var hasTrivialNonPointerType: Bool { type.isTrivialNonPointer(in: parentFunction) }
108106

109-
public var ownership: Ownership { SILValue_getOwnership(bridged).ownership }
107+
public var ownership: Ownership { bridged.getOwnership().ownership }
110108

111109
public var hashable: HashableValue { ObjectIdentifier(self) }
112110

@@ -156,15 +154,10 @@ extension Value {
156154

157155

158156
extension BridgedValue {
159-
public func getAs<T: AnyObject>(_ valueType: T.Type) -> T { obj.getAs(T.self) }
160-
161-
public var value: Value { getAs(AnyObject.self) as! Value }
162-
}
163-
164-
extension BridgedClassifiedValue {
165157
public var value: Value {
166158
// Doing the type check in C++ is much faster than a conformance lookup with `as! Value`.
167-
switch kind {
159+
// And it makes a difference because this is a time critical function.
160+
switch getKind() {
168161
case .SingleValueInstruction:
169162
return obj.getAs(SingleValueInstruction.self)
170163
case .Argument:
@@ -206,13 +199,13 @@ extension OptionalBridgedValue {
206199
var value: Value? { obj.getAs(AnyObject.self) as? Value }
207200
}
208201

209-
extension BridgedOwnership {
202+
extension BridgedValue.Ownership {
210203
var ownership: Ownership {
211204
switch self {
212-
case Ownership_Unowned: return .unowned
213-
case Ownership_Owned: return .owned
214-
case Ownership_Guaranteed: return .guaranteed
215-
case Ownership_None: return .none
205+
case .Unowned: return .unowned
206+
case .Owned: return .owned
207+
case .Guaranteed: return .guaranteed
208+
case .None: return .none
216209
default:
217210
fatalError("unsupported ownership")
218211
}

0 commit comments

Comments
 (0)