Skip to content

Commit ad594f2

Browse files
committed
Swift SIL: add some APIs
* `AssignInst` * `Function.isDestructor` * `MarkUninitializedInst.kind` * `Type.isMoveOnly` * `RefElementAddrInst.isImmutable` and `RefElementAddrInst.set(isImmutable:)` * `BeginBorrowInst.endBorrows` * `Context.hadError` and `Context.silStage`
1 parent 0312804 commit ad594f2

File tree

9 files changed

+154
-4
lines changed

9 files changed

+154
-4
lines changed

SwiftCompilerSources/Sources/Optimizer/PassManager/Context.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,17 @@ extension Context {
2727
let bridgeCA = _bridged.getCalleeAnalysis()
2828
return CalleeAnalysis(bridged: bridgeCA)
2929
}
30+
31+
var hadError: Bool { _bridged.hadError() }
32+
33+
var silStage: SILStage {
34+
switch _bridged.getSILStage() {
35+
case .Raw: return .raw
36+
case .Canonical: return .canonical
37+
case .Lowered: return .lowered
38+
default: fatalError("unhandled SILStage case")
39+
}
40+
}
3041
}
3142

3243
/// A context which allows mutation of a function's SIL.
@@ -462,6 +473,14 @@ extension AllocRefInst {
462473
}
463474
}
464475

476+
extension RefElementAddrInst {
477+
func set(isImmutable: Bool, _ context: some MutatingContext) {
478+
context.notifyInstructionsChanged()
479+
bridged.RefElementAddrInst_setImmutable(isImmutable)
480+
context.notifyInstructionChanged(self)
481+
}
482+
}
483+
465484
extension GlobalValueInst {
466485
func setIsBare(_ context: some MutatingContext) {
467486
context.notifyInstructionsChanged()

SwiftCompilerSources/Sources/SIL/Function.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ final public class Function : CustomStringConvertible, HasShortDescription, Hash
137137
/// It's called from a `[global_init]` function via a `builtin "once"`.
138138
public var isGlobalInitOnceFunction: Bool { bridged.isGlobalInitOnceFunction() }
139139

140+
public var isDestructor: Bool { bridged.isDestructor() }
141+
140142
public var isGenericFunction: Bool { bridged.isGenericFunction() }
141143

142144
/// Kinds of effect attributes which can be defined for a Swift function.

SwiftCompilerSources/Sources/SIL/Instruction.swift

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,17 @@ final public class StoreInst : Instruction, StoringInstruction {
259259
final public class StoreWeakInst : Instruction, StoringInstruction { }
260260
final public class StoreUnownedInst : Instruction, StoringInstruction { }
261261

262+
final public class AssignInst : Instruction, StoringInstruction {
263+
// must match with enum class swift::AssignOwnershipQualifier
264+
public enum AssignOwnership: Int {
265+
case unknown = 0, reassign = 1, reinitialize = 2, initialize = 3
266+
}
267+
268+
public var assignOwnership: AssignOwnership {
269+
AssignOwnership(rawValue: bridged.AssignInst_getAssignOwnership())!
270+
}
271+
}
272+
262273
final public class CopyAddrInst : Instruction {
263274
public var sourceOperand: Operand { return operands[0] }
264275
public var destinationOperand: Operand { return operands[1] }
@@ -282,6 +293,42 @@ final public class EndAccessInst : Instruction, UnaryInstruction {
282293
final public class EndBorrowInst : Instruction, UnaryInstruction {}
283294

284295
final public class MarkUninitializedInst : SingleValueInstruction, UnaryInstruction {
296+
297+
/// This enum captures what the mark_uninitialized instruction is designating.
298+
///
299+
// Warning: this enum must be in sync with MarkUninitializedInst::Kind
300+
public enum Kind: Int {
301+
/// The start of a normal variable live range.
302+
case variable = 0
303+
304+
/// "self" in a struct, enum, or root class.
305+
case rootSelf = 1
306+
307+
/// The same as "RootSelf", but in a case where it's not really safe to treat 'self' as root
308+
/// because the original module might add more stored properties.
309+
///
310+
/// This is only used for Swift 4 compatibility. In Swift 5, cross-module initializers are always delegatingSelf.
311+
case crossModuleRootSelf = 2
312+
313+
/// "self" in a derived (non-root) class.
314+
case derivedSelf = 3
315+
316+
/// "self" in a derived (non-root) class whose stored properties have already been initialized.
317+
case derivedSelfOnly = 4
318+
319+
/// "self" on a struct, enum, or class in a delegating constructor (one that calls self.init).
320+
case delegatingSelf = 5
321+
322+
/// "self" in a delegating class initializer where memory has already been allocated.
323+
case delegatingSelfAllocated = 6
324+
325+
/// An indirectly returned result which has to be checked for initialization.
326+
case indirectResult = 7
327+
}
328+
329+
public var kind: Kind { Kind(rawValue: bridged.MarkUninitializedInst_getKind())! }
330+
331+
public var canForwardGuaranteedValues: Bool { false }
285332
}
286333

287334
final public class CondFailInst : Instruction, UnaryInstruction {
@@ -396,9 +443,13 @@ final public class DeallocExistentialBoxInst : Instruction, UnaryInstruction, De
396443
final public class UnimplementedSingleValueInst : SingleValueInstruction {
397444
}
398445

399-
final public class LoadInst : SingleValueInstruction, UnaryInstruction {
446+
public protocol LoadInstruction: SingleValueInstruction, UnaryInstruction {}
447+
448+
extension LoadInstruction {
400449
public var address: Value { operand.value }
450+
}
401451

452+
final public class LoadInst : SingleValueInstruction, LoadInstruction {
402453
// must match with enum class LoadOwnershipQualifier
403454
public enum LoadOwnership: Int {
404455
case unqualified = 0, take = 1, copy = 2, trivial = 3
@@ -408,9 +459,9 @@ final public class LoadInst : SingleValueInstruction, UnaryInstruction {
408459
}
409460
}
410461

411-
final public class LoadWeakInst : SingleValueInstruction, UnaryInstruction {}
412-
final public class LoadUnownedInst : SingleValueInstruction, UnaryInstruction {}
413-
final public class LoadBorrowInst : SingleValueInstruction, UnaryInstruction {}
462+
final public class LoadWeakInst : SingleValueInstruction, LoadInstruction {}
463+
final public class LoadUnownedInst : SingleValueInstruction, LoadInstruction {}
464+
final public class LoadBorrowInst : SingleValueInstruction, LoadInstruction {}
414465

415466
final public class BuiltinInst : SingleValueInstruction {
416467
public typealias ID = swift.BuiltinValueKind
@@ -643,6 +694,8 @@ final public class RefElementAddrInst : SingleValueInstruction, UnaryInstruction
643694
public var fieldIndex: Int { bridged.RefElementAddrInst_fieldIndex() }
644695

645696
public var fieldIsLet: Bool { bridged.RefElementAddrInst_fieldIsLet() }
697+
698+
public var isImmutable: Bool { bridged.RefElementAddrInst_isImmutable() }
646699
}
647700

648701
final public class RefTailAddrInst : SingleValueInstruction, UnaryInstruction {
@@ -742,6 +795,13 @@ extension BeginAccessInst : ScopedInstruction {
742795

743796
final public class BeginBorrowInst : SingleValueInstruction, UnaryInstruction {
744797
public var borrowedValue: Value { operand.value }
798+
799+
public typealias EndBorrowSequence = LazyMapSequence<LazyFilterSequence<LazyMapSequence<UseList, EndBorrowInst?>>,
800+
EndBorrowInst>
801+
802+
public var endBorrows: EndBorrowSequence {
803+
uses.lazy.compactMap({ $0.instruction as? EndBorrowInst })
804+
}
745805
}
746806

747807
final public class ProjectBoxInst : SingleValueInstruction, UnaryInstruction {

SwiftCompilerSources/Sources/SIL/Registration.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public func registerSILClasses() {
4141
register(StoreInst.self)
4242
register(StoreWeakInst.self)
4343
register(StoreUnownedInst.self)
44+
register(AssignInst.self)
4445
register(CopyAddrInst.self)
4546
register(EndAccessInst.self)
4647
register(EndBorrowInst.self)

SwiftCompilerSources/Sources/SIL/Type.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ public struct Type : CustomStringConvertible, NoReflectionChildren {
6060

6161
public var canBeClass: swift.TypeTraitResult { bridged.canBeClass() }
6262

63+
public var isMoveOnly: Bool { bridged.isMoveOnly() }
64+
6365
/// Can only be used if the type is in fact a nominal type (`isNominal` is true).
6466
public var nominal: NominalTypeDecl {
6567
NominalTypeDecl(_bridged: BridgedNominalTypeDecl(decl: bridged.getNominalOrBoundGenericNominal()))

SwiftCompilerSources/Sources/SIL/Utils.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,39 @@ import SILBridging
1717
// Otherwise The Optimizer would fall back to Swift's assert implementation.
1818
@_exported import Basic
1919

20+
//===----------------------------------------------------------------------===//
21+
// SIL Stage
22+
//===----------------------------------------------------------------------===//
23+
24+
public enum SILStage: Int {
25+
/// "Raw" SIL, emitted by SILGen, but not yet run through guaranteed
26+
/// optimization and diagnostic passes.
27+
///
28+
/// Raw SIL does not have fully-constructed SSA and may contain undiagnosed
29+
/// dataflow errors.
30+
case raw
31+
32+
/// Canonical SIL, which has been run through at least the guaranteed
33+
/// optimization and diagnostic passes.
34+
///
35+
/// Canonical SIL has stricter invariants than raw SIL. It must not contain
36+
/// dataflow errors, and some instructions must be canonicalized to simpler
37+
/// forms.
38+
case canonical
39+
40+
/// Lowered SIL, which has been prepared for IRGen and will no longer
41+
/// be passed to canonical SIL transform passes.
42+
///
43+
/// In lowered SIL, the SILType of all SILValues is its SIL storage
44+
/// type. Explicit storage is required for all address-only and resilient
45+
/// types.
46+
///
47+
/// Generating the initial Raw SIL is typically referred to as lowering (from
48+
/// the AST). To disambiguate, refer to the process of generating the lowered
49+
/// stage of SIL as "address lowering".
50+
case lowered
51+
}
52+
2053
//===----------------------------------------------------------------------===//
2154
// Sequence Utilities
2255
//===----------------------------------------------------------------------===//

include/swift/SIL/SILBridging.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,13 @@ struct BridgedFunction {
260260
return getFunction()->isGlobalInitOnceFunction();
261261
}
262262

263+
bool isDestructor() const {
264+
if (auto *declCtxt = getFunction()->getDeclContext()) {
265+
return llvm::isa<swift::DestructorDecl>(declCtxt);
266+
}
267+
return false;
268+
}
269+
263270
bool isGenericFunction() const {
264271
return !getFunction()->getGenericSignature().isNull();
265272
}
@@ -655,6 +662,14 @@ struct BridgedInstruction {
655662
return getAs<swift::RefElementAddrInst>()->getField()->isLet();
656663
}
657664

665+
bool RefElementAddrInst_isImmutable() const {
666+
return getAs<swift::RefElementAddrInst>()->isImmutable();
667+
}
668+
669+
void RefElementAddrInst_setImmutable(bool isImmutable) const {
670+
getAs<swift::RefElementAddrInst>()->setImmutable(isImmutable);
671+
}
672+
658673
SwiftInt PartialApplyInst_numArguments() const {
659674
return getAs<swift::PartialApplyInst>()->getNumArguments();
660675
}
@@ -739,6 +754,10 @@ struct BridgedInstruction {
739754
return (SwiftInt)getAs<swift::StoreInst>()->getOwnershipQualifier();
740755
}
741756

757+
SwiftInt AssignInst_getAssignOwnership() const {
758+
return (SwiftInt)getAs<swift::AssignInst>()->getOwnershipQualifier();
759+
}
760+
742761
swift::SILAccessKind BeginAccessInst_getAccessKind() const {
743762
return getAs<swift::BeginAccessInst>()->getAccessKind();
744763
}
@@ -755,6 +774,10 @@ struct BridgedInstruction {
755774
return getAs<swift::CopyAddrInst>()->isInitializationOfDest();
756775
}
757776

777+
SwiftInt MarkUninitializedInst_getKind() const {
778+
return (SwiftInt)getAs<swift::MarkUninitializedInst>()->getMarkUninitializedKind();
779+
}
780+
758781
void RefCountingInst_setIsAtomic(bool isAtomic) const {
759782
getAs<swift::RefCountingInst>()->setAtomicity(
760783
isAtomic ? swift::RefCountingInst::Atomicity::Atomic

include/swift/SIL/SILInstruction.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4931,6 +4931,8 @@ class MarkUninitializedInst
49314931

49324932
public:
49334933
/// This enum captures what the mark_uninitialized instruction is designating.
4934+
///
4935+
/// Warning: this enum must be in sync with the swift `MarkUninitializedInst.Kind`
49344936
enum Kind {
49354937
/// Var designates the start of a normal variable live range.
49364938
Var,

include/swift/SILOptimizer/OptimizerBridging.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,14 @@ struct BridgedPassContext {
190190
return {invocation->getPassManager()->getAnalysis<swift::BasicCalleeAnalysis>()};
191191
}
192192

193+
bool hadError() const {
194+
return invocation->getPassManager()->getModule()->getASTContext().hadError();
195+
}
196+
197+
swift::SILStage getSILStage() const {
198+
return invocation->getPassManager()->getModule()->getStage();
199+
}
200+
193201
SWIFT_IMPORT_UNSAFE
194202
BridgedDeadEndBlocksAnalysis getDeadEndBlocksAnalysis() const {
195203
auto *dba = invocation->getPassManager()->getAnalysis<swift::DeadEndBlocksAnalysis>();

0 commit comments

Comments
 (0)