Skip to content

Commit 325a0b1

Browse files
committed
swift SIL: add some Instruction, Value and Type APIs
* instructions `RefToBridgeObjectInst`, `BridgeObjectToWordInst`, `StringLiteralInst`, `ProjectBoxInst`, `InitEnumDataAddrInst`, `UncheckedTakeEnumDataAddrInst`, `InjectEnumAddrInst` * protocols `StoringInstruction` and `EnumInstruction` * load/store-weak/unowned instructions * `CopyAddrInst.isTakeOfSrc/isInitializationOfDest` * `ApplySite.calleeArgIndex/callerArgIndex` * `SILValue.definingInstruction/definingBlock/function` * `Type.isReferenceCounted` * `FunctionArgument.isExclusiveIndirectParameter` * support `CondBranchInst` in `incomingPhiValues`
1 parent ab1a989 commit 325a0b1

File tree

14 files changed

+280
-48
lines changed

14 files changed

+280
-48
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/SILPrinter.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ func runSILPrinter(function: Function, context: PassContext) {
2929
for use in arg.uses {
3030
print(" user: \(use.instruction)")
3131
}
32+
if let blockArg = arg as? BlockArgument, blockArg.isPhiArgument {
33+
for incoming in blockArg.incomingPhiValues {
34+
print(" incoming: \(incoming)")
35+
}
36+
}
3237
}
3338

3439
print(" instructions:")

SwiftCompilerSources/Sources/SIL/ApplySite.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ public struct ApplyOperands {
1818
public protocol ApplySite : AnyObject {
1919
var operands: OperandArray { get }
2020
var numArguments: Int { get }
21+
func calleeArgIndex(callerArgIndex: Int) -> Int
22+
func callerArgIndex(calleeArgIndex: Int) -> Int?
2123
}
2224

2325
extension ApplySite {
@@ -47,3 +49,8 @@ extension ApplySite {
4749
public protocol FullApplySite : ApplySite {
4850
var singleDirectResult: Value? { get }
4951
}
52+
53+
extension FullApplySite {
54+
public func calleeArgIndex(callerArgIndex: Int) -> Int { callerArgIndex }
55+
public func callerArgIndex(calleeArgIndex: Int) -> Int? { calleeArgIndex }
56+
}

SwiftCompilerSources/Sources/SIL/Argument.swift

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,25 +35,42 @@ public class Argument : Value, Equatable {
3535
}
3636

3737
final public class FunctionArgument : Argument {
38+
public var isExclusiveIndirectParameter: Bool {
39+
SILArgument_isExclusiveIndirectParameter(bridged) != 0
40+
}
3841
}
3942

4043
final public class BlockArgument : Argument {
41-
/// Note: critical edges are not supported, i.e. this is false if there is
42-
/// a cond_br in the predecessors.
4344
public var isPhiArgument: Bool {
44-
block.predecessors.allSatisfy { $0.terminator is BranchInst }
45+
block.predecessors.allSatisfy {
46+
let term = $0.terminator
47+
return term is BranchInst || term is CondBranchInst
48+
}
4549
}
4650

4751
public var incomingPhiOperands: LazyMapSequence<PredecessorList, Operand> {
4852
assert(isPhiArgument)
4953
let idx = index
50-
return block.predecessors.lazy.map { $0.terminator.operands[idx] }
54+
return block.predecessors.lazy.map {
55+
switch $0.terminator {
56+
case let br as BranchInst:
57+
return br.operands[idx]
58+
case let condBr as CondBranchInst:
59+
if condBr.trueBlock == self.block {
60+
assert(condBr.falseBlock != self.block)
61+
return condBr.trueOperands[idx]
62+
} else {
63+
assert(condBr.falseBlock == self.block)
64+
return condBr.falseOperands[idx]
65+
}
66+
default:
67+
fatalError("wrong terminator for phi-argument")
68+
}
69+
}
5170
}
5271

53-
public var incomingPhiValues: LazyMapSequence<PredecessorList, Value> {
54-
assert(isPhiArgument)
55-
let idx = index
56-
return block.predecessors.lazy.map { $0.terminator.operands[idx].value }
72+
public var incomingPhiValues: LazyMapSequence<LazyMapSequence<PredecessorList, Operand>, Value> {
73+
incomingPhiOperands.lazy.map { $0.value }
5774
}
5875
}
5976

SwiftCompilerSources/Sources/SIL/Function.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,13 @@ final public class Function : CustomStringConvertible, HasName {
5353
public var argumentTypes: ArgumentTypeArray { ArgumentTypeArray(function: self) }
5454
public var resultType: Type { SILFunction_getSILResultType(bridged).type }
5555

56+
public var returnInstruction: ReturnInst? {
57+
for block in blocks.reversed() {
58+
if let retInst = block.terminator as? ReturnInst { return retInst }
59+
}
60+
return nil
61+
}
62+
5663
/// True, if the function runs with a swift 5.1 runtime.
5764
/// Note that this is function specific, because inlinable functions are de-serialized
5865
/// in a client module, which might be compiled with a different deployment target.

SwiftCompilerSources/Sources/SIL/Instruction.swift

Lines changed: 84 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -184,12 +184,18 @@ extension UnaryInstruction {
184184
final public class UnimplementedInstruction : Instruction {
185185
}
186186

187-
final public class StoreInst : Instruction {
187+
public protocol StoringInstruction : AnyObject {
188+
var operands: OperandArray { get }
189+
}
190+
191+
extension StoringInstruction {
188192
public var sourceOperand: Operand { return operands[0] }
189193
public var destinationOperand: Operand { return operands[1] }
190194
public var source: Value { return sourceOperand.value }
191195
public var destination: Value { return destinationOperand.value }
196+
}
192197

198+
final public class StoreInst : Instruction, StoringInstruction {
193199
// must match with enum class StoreOwnershipQualifier
194200
public enum StoreOwnership: Int {
195201
case unqualified = 0, initialize = 1, assign = 2, trivial = 3
@@ -199,11 +205,21 @@ final public class StoreInst : Instruction {
199205
}
200206
}
201207

208+
final public class StoreWeakInst : Instruction, StoringInstruction { }
209+
final public class StoreUnownedInst : Instruction, StoringInstruction { }
210+
202211
final public class CopyAddrInst : Instruction {
203212
public var sourceOperand: Operand { return operands[0] }
204213
public var destinationOperand: Operand { return operands[1] }
205214
public var source: Value { return sourceOperand.value }
206215
public var destination: Value { return destinationOperand.value }
216+
217+
public var isTakeOfSrc: Bool {
218+
CopyAddrInst_isTakeOfSrc(bridged) != 0
219+
}
220+
public var isInitializationOfDest: Bool {
221+
CopyAddrInst_isInitializationOfDest(bridged) != 0
222+
}
207223
}
208224

209225
final public class EndAccessInst : Instruction, UnaryInstruction {
@@ -262,6 +278,10 @@ final public class DestroyValueInst : Instruction, UnaryInstruction {}
262278

263279
final public class DestroyAddrInst : Instruction, UnaryInstruction {}
264280

281+
final public class InjectEnumAddrInst : Instruction, UnaryInstruction, EnumInstruction {
282+
public var caseIndex: Int { InjectEnumAddrInst_caseIndex(bridged) }
283+
}
284+
265285
final public class UnimplementedRefCountingInst : RefCountingInst {}
266286

267287
//===----------------------------------------------------------------------===//
@@ -275,6 +295,8 @@ final public class UnimplementedSingleValueInst : SingleValueInstruction {
275295

276296
final public class LoadInst : SingleValueInstruction, UnaryInstruction {}
277297

298+
final public class LoadWeakInst : SingleValueInstruction, UnaryInstruction {}
299+
final public class LoadUnownedInst : SingleValueInstruction, UnaryInstruction {}
278300
final public class LoadBorrowInst : SingleValueInstruction, UnaryInstruction {}
279301

280302
final public class BuiltinInst : SingleValueInstruction {
@@ -362,6 +384,10 @@ final public class GlobalValueInst : GlobalAccessInst {}
362384

363385
final public class IntegerLiteralInst : SingleValueInstruction {}
364386

387+
final public class StringLiteralInst : SingleValueInstruction {
388+
public var string: String { StringLiteralInst_getValue(bridged).string }
389+
}
390+
365391
final public class TupleInst : SingleValueInstruction {
366392
}
367393

@@ -386,17 +412,28 @@ class StructElementAddrInst : SingleValueInstruction, UnaryInstruction {
386412
public var fieldIndex: Int { StructElementAddrInst_fieldIndex(bridged) }
387413
}
388414

389-
final public class EnumInst : SingleValueInstruction {
415+
public protocol EnumInstruction : AnyObject {
416+
var caseIndex: Int { get }
417+
}
418+
419+
final public class EnumInst : SingleValueInstruction, UnaryInstruction, EnumInstruction {
390420
public var caseIndex: Int { EnumInst_caseIndex(bridged) }
391421

392422
public var operand: Value? { operands.first?.value }
393423
}
394424

395-
final public
396-
class UncheckedEnumDataInst : SingleValueInstruction, UnaryInstruction {
425+
final public class UncheckedEnumDataInst : SingleValueInstruction, UnaryInstruction, EnumInstruction {
397426
public var caseIndex: Int { UncheckedEnumDataInst_caseIndex(bridged) }
398427
}
399428

429+
final public class InitEnumDataAddrInst : SingleValueInstruction, UnaryInstruction, EnumInstruction {
430+
public var caseIndex: Int { InitEnumDataAddrInst_caseIndex(bridged) }
431+
}
432+
433+
final public class UncheckedTakeEnumDataAddrInst : SingleValueInstruction, UnaryInstruction, EnumInstruction {
434+
public var caseIndex: Int { UncheckedTakeEnumDataAddrInst_caseIndex(bridged) }
435+
}
436+
400437
final public class RefElementAddrInst : SingleValueInstruction, UnaryInstruction {
401438
public var fieldIndex: Int { RefElementAddrInst_fieldIndex(bridged) }
402439
}
@@ -430,13 +467,23 @@ class MarkDependenceInst : SingleValueInstruction {
430467
public var base: Value { return operands[1].value }
431468
}
432469

470+
final public class RefToBridgeObjectInst : SingleValueInstruction,
471+
UnaryInstruction {}
472+
433473
final public class BridgeObjectToRefInst : SingleValueInstruction,
434474
UnaryInstruction {}
435475

476+
final public class BridgeObjectToWordInst : SingleValueInstruction,
477+
UnaryInstruction {}
478+
436479
final public class BeginAccessInst : SingleValueInstruction, UnaryInstruction {}
437480

438481
final public class BeginBorrowInst : SingleValueInstruction, UnaryInstruction {}
439482

483+
final public class ProjectBoxInst : SingleValueInstruction, UnaryInstruction {
484+
public var fieldIndex: Int { ProjectBoxInst_fieldIndex(bridged) }
485+
}
486+
440487
final public class CopyValueInst : SingleValueInstruction, UnaryInstruction {}
441488

442489
final public class EndCOWMutationInst : SingleValueInstruction, UnaryInstruction {}
@@ -446,6 +493,19 @@ class ClassifyBridgeObjectInst : SingleValueInstruction, UnaryInstruction {}
446493

447494
final public class PartialApplyInst : SingleValueInstruction, ApplySite {
448495
public var numArguments: Int { PartialApplyInst_numArguments(bridged) }
496+
public var isOnStack: Bool { PartialApplyInst_isOnStack(bridged) != 0 }
497+
498+
public func calleeArgIndex(callerArgIndex: Int) -> Int {
499+
PartialApply_getCalleeArgIndexOfFirstAppliedArg(bridged) + callerArgIndex
500+
}
501+
502+
public func callerArgIndex(calleeArgIndex: Int) -> Int? {
503+
let firstIdx = PartialApply_getCalleeArgIndexOfFirstAppliedArg(bridged)
504+
if calleeArgIndex >= firstIdx {
505+
return calleeArgIndex - firstIdx
506+
}
507+
return nil
508+
}
449509
}
450510

451511
final public class ApplyInst : SingleValueInstruction, FullApplySite {
@@ -520,8 +580,6 @@ final public class BeginApplyInst : MultipleValueInstruction, FullApplySite {
520580
public var singleDirectResult: Value? { nil }
521581
}
522582

523-
public final class RefToBridgeObjectInst: MultipleValueInstruction {}
524-
525583
//===----------------------------------------------------------------------===//
526584
// terminator instructions
527585
//===----------------------------------------------------------------------===//
@@ -565,6 +623,26 @@ final public class BranchInst : TermInst {
565623
}
566624

567625
final public class CondBranchInst : TermInst {
626+
var trueBlock: BasicBlock { successors[0] }
627+
var falseBlock: BasicBlock { successors[1] }
628+
629+
var condition: Value { operands[0].value }
630+
631+
var trueOperands: OperandArray { operands[1...CondBranchInst_getNumTrueArgs(bridged)] }
632+
var falseOperands: OperandArray {
633+
let ops = operands
634+
return ops[(CondBranchInst_getNumTrueArgs(bridged) &+ 1)..<ops.count]
635+
}
636+
637+
public func getArgument(for operand: Operand) -> Argument {
638+
let argIdx = operand.index - 1
639+
let numTrueArgs = CondBranchInst_getNumTrueArgs(bridged)
640+
if (0..<numTrueArgs).contains(argIdx) {
641+
return trueBlock.arguments[argIdx]
642+
} else {
643+
return falseBlock.arguments[argIdx - numTrueArgs]
644+
}
645+
}
568646
}
569647

570648
final public class SwitchValueInst : TermInst {

SwiftCompilerSources/Sources/SIL/Operand.swift

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,7 @@ public struct Operand : CustomStringConvertible, CustomReflectable {
2121
}
2222

2323
public var value: Value {
24-
let v = Operand_getValue(bridged).getAs(AnyObject.self)
25-
switch v {
26-
case let inst as SingleValueInstruction:
27-
return inst
28-
case let arg as Argument:
29-
return arg
30-
case let mvr as MultipleValueInstructionResult:
31-
return mvr
32-
case let undef as Undef:
33-
return undef
34-
default:
35-
fatalError("unknown Value type")
36-
}
24+
Operand_getValue(bridged).value
3725
}
3826

3927
public static func ==(lhs: Operand, rhs: Operand) -> Bool {

SwiftCompilerSources/Sources/SIL/Registration.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ public func registerSILClasses() {
3939
register(BlockArgument.self)
4040

4141
register(StoreInst.self)
42+
register(StoreWeakInst.self)
43+
register(StoreUnownedInst.self)
4244
register(CopyAddrInst.self)
4345
register(EndAccessInst.self)
4446
register(EndBorrowInst.self)
@@ -56,7 +58,10 @@ public func registerSILClasses() {
5658
register(ReleaseValueInst.self)
5759
register(DestroyValueInst.self)
5860
register(DestroyAddrInst.self)
61+
register(InjectEnumAddrInst.self)
5962
register(LoadInst.self)
63+
register(LoadWeakInst.self)
64+
register(LoadUnownedInst.self)
6065
register(LoadBorrowInst.self)
6166
register(BuiltinInst.self)
6267
register(UpcastInst.self)
@@ -81,6 +86,7 @@ public func registerSILClasses() {
8186
register(GlobalAddrInst.self)
8287
register(GlobalValueInst.self)
8388
register(IntegerLiteralInst.self)
89+
register(StringLiteralInst.self)
8490
register(TupleInst.self)
8591
register(TupleExtractInst.self)
8692
register(TupleElementAddrInst.self)
@@ -89,6 +95,8 @@ public func registerSILClasses() {
8995
register(StructElementAddrInst.self)
9096
register(EnumInst.self)
9197
register(UncheckedEnumDataInst.self)
98+
register(InitEnumDataAddrInst.self)
99+
register(UncheckedTakeEnumDataAddrInst.self)
92100
register(RefElementAddrInst.self)
93101
register(RefTailAddrInst.self)
94102
register(UnconditionalCheckedCastInst.self)
@@ -98,9 +106,12 @@ public func registerSILClasses() {
98106
register(ObjCMetatypeToObjectInst.self)
99107
register(ValueToBridgeObjectInst.self)
100108
register(MarkDependenceInst.self)
109+
register(RefToBridgeObjectInst.self)
101110
register(BridgeObjectToRefInst.self)
111+
register(BridgeObjectToWordInst.self)
102112
register(BeginAccessInst.self)
103113
register(BeginBorrowInst.self)
114+
register(ProjectBoxInst.self)
104115
register(CopyValueInst.self)
105116
register(EndCOWMutationInst.self)
106117
register(ClassifyBridgeObjectInst.self)

SwiftCompilerSources/Sources/SIL/Type.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ public struct Type : CustomStringConvertible, CustomReflectable {
2323
return SILType_isTrivial(bridged, function.bridged) != 0
2424
}
2525

26+
public func isReferenceCounted(in function: Function) -> Bool {
27+
return SILType_isReferenceCounted(bridged, function.bridged) != 0
28+
}
29+
2630
public var isNominal: Bool { SILType_isNominal(bridged) != 0 }
2731
public var isClass: Bool { SILType_isClass(bridged) != 0 }
2832
public var isStruct: Bool { SILType_isStruct(bridged) != 0 }

0 commit comments

Comments
 (0)