Skip to content

Commit 2c5d823

Browse files
committed
SIL: add var Instruction.mayCallFunction
It checks if arbitrary functions may be called by an instruction. This can be either directly, e.g. by an `apply` instruction, or indirectly by destroying a value which might have a deinitializer which can call functions.
1 parent dbc5063 commit 2c5d823

File tree

1 file changed

+48
-0
lines changed

1 file changed

+48
-0
lines changed

SwiftCompilerSources/Sources/SIL/Instruction.swift

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,11 @@ public class Instruction : CustomStringConvertible, Hashable {
143143
return bridged.mayAccessPointer()
144144
}
145145

146+
/// True if arbitrary functions may be called by this instruction.
147+
/// This can be either directly, e.g. by an `apply` instruction, or indirectly by destroying a value which
148+
/// might have a deinitializer which can call functions.
149+
public var mayCallFunction: Bool { false }
150+
146151
public final var mayLoadWeakOrUnowned: Bool {
147152
return bridged.mayLoadWeakOrUnowned()
148153
}
@@ -331,6 +336,8 @@ final public class StoreInst : Instruction, StoringInstruction {
331336
public var storeOwnership: StoreOwnership {
332337
StoreOwnership(rawValue: bridged.StoreInst_getStoreOwnership())!
333338
}
339+
340+
public override var mayCallFunction: Bool { storeOwnership == .assign }
334341
}
335342

336343
final public class StoreWeakInst : Instruction, StoringInstruction { }
@@ -345,6 +352,15 @@ final public class AssignInst : Instruction, StoringInstruction {
345352
public var assignOwnership: AssignOwnership {
346353
AssignOwnership(rawValue: bridged.AssignInst_getAssignOwnership())!
347354
}
355+
356+
public override var mayCallFunction: Bool {
357+
switch assignOwnership {
358+
case .unknown, .reassign, .reinitialize:
359+
true
360+
case .initialize:
361+
false
362+
}
363+
}
348364
}
349365

350366
final public class AssignOrInitInst : Instruction, StoringInstruction {}
@@ -382,6 +398,7 @@ final public class CopyAddrInst : Instruction, SourceDestAddrInstruction {
382398
bridged.CopyAddrInst_setIsInitializationOfDest(isInitializationOfDestination)
383399
context.notifyInstructionChanged(self)
384400
}
401+
public override var mayCallFunction: Bool { !isInitializationOfDestination }
385402
}
386403

387404
final public class ExplicitCopyAddrInst : Instruction, SourceDestAddrInstruction {
@@ -394,6 +411,7 @@ final public class ExplicitCopyAddrInst : Instruction, SourceDestAddrInstruction
394411
public var isInitializationOfDestination: Bool {
395412
bridged.ExplicitCopyAddrInst_isInitializationOfDest()
396413
}
414+
public override var mayCallFunction: Bool { !isInitializationOfDestination }
397415
}
398416

399417
final public class MarkUninitializedInst : SingleValueInstruction, UnaryInstruction {
@@ -639,10 +657,12 @@ final public class RetainValueAddrInst : RefCountingInst {
639657
}
640658

641659
final public class ReleaseValueAddrInst : RefCountingInst {
660+
public override var mayCallFunction: Bool { true }
642661
}
643662

644663
final public class StrongReleaseInst : RefCountingInst {
645664
public var instance: Value { operand.value }
665+
public override var mayCallFunction: Bool { true }
646666
}
647667

648668
final public class UnownedReleaseInst : RefCountingInst {
@@ -651,10 +671,12 @@ final public class UnownedReleaseInst : RefCountingInst {
651671

652672
final public class ReleaseValueInst : RefCountingInst {
653673
public var value: Value { return operand.value }
674+
public override var mayCallFunction: Bool { true }
654675
}
655676

656677
final public class UnmanagedReleaseValueInst : RefCountingInst {
657678
public var value: Value { return operand.value }
679+
public override var mayCallFunction: Bool { true }
658680
}
659681

660682
final public class AutoreleaseValueInst : RefCountingInst {}
@@ -667,10 +689,14 @@ final public class DestroyValueInst : Instruction, UnaryInstruction {
667689
/// end the lifetime of its operand.
668690
/// Such `destroy_value` instructions are lowered to no-ops.
669691
public var isDeadEnd: Bool { bridged.DestroyValueInst_isDeadEnd() }
692+
693+
public override var mayCallFunction: Bool { true }
670694
}
671695

672696
final public class DestroyAddrInst : Instruction, UnaryInstruction {
673697
public var destroyedAddress: Value { operand.value }
698+
699+
public override var mayCallFunction: Bool { true }
674700
}
675701

676702
final public class EndLifetimeInst : Instruction, UnaryInstruction {}
@@ -762,6 +788,15 @@ final public class BuiltinInst : SingleValueInstruction {
762788
public var arguments: LazyMapSequence<OperandArray, Value> {
763789
operands.values
764790
}
791+
792+
public override var mayCallFunction: Bool {
793+
switch id {
794+
case .Once, .OnFastPath, .Destroy, .DestroyArray, .DestroyTaskGroup, .DestroyDefaultActor, .Release:
795+
true
796+
default:
797+
false
798+
}
799+
}
765800
}
766801

767802
final public class UpcastInst : SingleValueInstruction, UnaryInstruction {
@@ -1371,6 +1406,8 @@ final public class ApplyInst : SingleValueInstruction, FullApplySite {
13711406
public typealias SpecializationInfo = BridgedGenericSpecializationInformation
13721407

13731408
public var specializationInfo: SpecializationInfo { bridged.ApplyInst_getSpecializationInfo() }
1409+
1410+
public override var mayCallFunction: Bool { true }
13741411
}
13751412

13761413
final public class FunctionExtractIsolationInst : SingleValueInstruction {}
@@ -1648,7 +1685,12 @@ final public class BeginAccessInst : SingleValueInstruction, UnaryInstruction {
16481685
case read = 1
16491686
case modify = 2
16501687
case `deinit` = 3
1688+
1689+
public func conflicts(with other: AccessKind) -> Bool {
1690+
return self != .read || other != .read
1691+
}
16511692
}
1693+
16521694
public var accessKind: AccessKind {
16531695
AccessKind(rawValue: bridged.BeginAccessInst_getAccessKind())!
16541696
}
@@ -1730,11 +1772,15 @@ final public class BeginApplyInst : MultipleValueInstruction, FullApplySite {
17301772

17311773
public var isNonThrowing: Bool { bridged.BeginApplyInst_getNonThrowing() }
17321774
public var isNonAsync: Bool { bridged.BeginApplyInst_getNonAsync() }
1775+
1776+
public override var mayCallFunction: Bool { true }
17331777
}
17341778

17351779
final public class EndApplyInst : SingleValueInstruction, UnaryInstruction {
17361780
public var token: MultipleValueInstructionResult { operand.value as! MultipleValueInstructionResult }
17371781
public var beginApply: BeginApplyInst { token.parentInstruction as! BeginApplyInst }
1782+
1783+
public override var mayCallFunction: Bool { true }
17381784
}
17391785

17401786
final public class AbortApplyInst : Instruction, UnaryInstruction {
@@ -1931,6 +1977,8 @@ final public class TryApplyInst : TermInst, FullApplySite {
19311977

19321978
public var isNonAsync: Bool { bridged.TryApplyInst_getNonAsync() }
19331979
public var specializationInfo: ApplyInst.SpecializationInfo { bridged.TryApplyInst_getSpecializationInfo() }
1980+
1981+
public override var mayCallFunction: Bool { true }
19341982
}
19351983

19361984
final public class BranchInst : TermInst {

0 commit comments

Comments
 (0)