Skip to content

Commit d781045

Browse files
committed
Revert "SIL Verifier: implement load-borrow-immutability checkin in the swift verifier"
This reverts commit b01e703.
1 parent 0666c44 commit d781045

File tree

5 files changed

+478
-131
lines changed

5 files changed

+478
-131
lines changed

SwiftCompilerSources/Sources/Optimizer/Utilities/Verifier.swift

Lines changed: 11 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -54,24 +54,6 @@ private extension Instruction {
5454
}
5555
}
5656

57-
private extension Argument {
58-
func verify(_ context: FunctionPassContext) {
59-
if let phi = Phi(self), phi.value.ownership == .guaranteed {
60-
var forwardingBorrowedFromFound = false
61-
for use in phi.value.uses {
62-
require(use.instruction is BorrowedFromInst,
63-
"guaranteed phi: \(self)\n has non borrowed-from use: \(use)")
64-
if use.index == 0 {
65-
require(!forwardingBorrowedFromFound, "phi \(self) has multiple forwarding borrowed-from uses")
66-
forwardingBorrowedFromFound = true
67-
}
68-
}
69-
require (forwardingBorrowedFromFound,
70-
"missing forwarding borrowed-from user of guaranteed phi \(phi)")
71-
}
72-
}
73-
}
74-
7557
extension BorrowedFromInst : VerifiableInstruction {
7658
func verify(_ context: FunctionPassContext) {
7759
var computedEVs = Stack<Value>(context)
@@ -92,121 +74,20 @@ extension BorrowedFromInst : VerifiableInstruction {
9274
}
9375
}
9476

95-
extension LoadBorrowInst : VerifiableInstruction {
77+
private extension Argument {
9678
func verify(_ context: FunctionPassContext) {
97-
if isUnchecked {
98-
return
99-
}
100-
101-
var mutatingInstructions = MutatingUsesWalker(context)
102-
defer { mutatingInstructions.deinitialize() }
103-
104-
mutatingInstructions.findMutatingUses(of: self.address)
105-
mutatingInstructions.verifyNoMutatingUsesInLiverange(of: self)
106-
}
107-
}
108-
109-
// Used to check if any instruction is mutating the memory location within the liverange of a `load_borrow`.
110-
// Note that it is not checking if an instruction _may_ mutate the memory, but it's checking if any instruction
111-
// _definitely_ will mutate the memory.
112-
// Otherwise the risk would be too big for false alarms. It also means that this verification is not perfect and
113-
// might miss some subtle violations.
114-
private struct MutatingUsesWalker : AddressDefUseWalker {
115-
let context: FunctionPassContext
116-
var mutatingInstructions: InstructionSet
117-
118-
init(_ context: FunctionPassContext) {
119-
self.context = context
120-
self.mutatingInstructions = InstructionSet(context)
121-
}
122-
123-
mutating func deinitialize() {
124-
self.mutatingInstructions.deinitialize()
125-
}
126-
127-
mutating func findMutatingUses(of address: Value) {
128-
_ = walkDownUses(ofAddress: address, path: UnusedWalkingPath())
129-
}
130-
131-
mutating func verifyNoMutatingUsesInLiverange(of load: LoadBorrowInst) {
132-
// The liverange of a `load_borrow` can end in a branch instruction. In such cases we handle the re-borrow liveranges
133-
// (starting at the `borrowed_from` in the successor block) separately.
134-
// This worklist contains the starts of the individual linear liveranges,
135-
// i.e. `load_borrow` and `borrowed_from` instructions.
136-
var linearLiveranges = SpecificInstructionWorklist<SingleValueInstruction>(context)
137-
defer { linearLiveranges.deinitialize() }
138-
139-
linearLiveranges.pushIfNotVisited(load)
140-
while let startInst = linearLiveranges.pop() {
141-
verifyNoMutatingUsesInLinearLiverange(of: startInst)
142-
143-
for use in startInst.uses {
144-
if let phi = Phi(using: use) {
145-
linearLiveranges.pushIfNotVisited(phi.borrowedFrom!)
146-
}
147-
}
148-
}
149-
}
150-
151-
private mutating func verifyNoMutatingUsesInLinearLiverange(of startInst: SingleValueInstruction) {
152-
assert(startInst is LoadBorrowInst || startInst is BorrowedFromInst)
153-
154-
var instWorklist = InstructionWorklist(context)
155-
defer { instWorklist.deinitialize() }
156-
157-
// It would be good enough to only consider `end_borrow`s (and branches), but adding all users doesn't harm.
158-
for use in startInst.uses {
159-
instWorklist.pushPredecessors(of: use.instruction, ignoring: startInst)
160-
}
161-
162-
while let inst = instWorklist.pop() {
163-
require(!mutatingInstructions.contains(inst),
164-
"Load borrow invalidated by a local write", atInstruction: inst)
165-
instWorklist.pushPredecessors(of: inst, ignoring: startInst)
166-
}
167-
}
168-
169-
mutating func leafUse(address: Operand, path: UnusedWalkingPath) -> WalkResult {
170-
if address.isMutatedAddress {
171-
mutatingInstructions.insert(address.instruction)
172-
}
173-
return .continueWalk
174-
}
175-
}
176-
177-
private extension Operand {
178-
// Returns true if the operand's instruction is definitely writing to the operand's address value.
179-
var isMutatedAddress: Bool {
180-
assert(value.type.isAddress)
181-
switch instruction {
182-
case let store as StoringInstruction:
183-
return self == store.destinationOperand
184-
case let copy as SourceDestAddrInstruction:
185-
if self == copy.destinationOperand {
186-
return true
187-
} else if self == copy.sourceOperand && copy.isTakeOfSrc {
188-
return true
189-
}
190-
return false
191-
case let load as LoadInst:
192-
return load.loadOwnership == .take
193-
case let partialApply as PartialApplyInst:
194-
if !partialApply.isOnStack,
195-
let convention = partialApply.convention(of: self)
196-
{
197-
switch convention {
198-
case .indirectIn, .indirectInGuaranteed:
199-
// Such operands are consumed by the `partial_apply` and therefore cound as "written".
200-
return true
201-
default:
202-
return false
79+
if let phi = Phi(self), phi.value.ownership == .guaranteed {
80+
var forwardingBorrowedFromFound = false
81+
for use in phi.value.uses {
82+
require(use.instruction is BorrowedFromInst,
83+
"guaranteed phi: \(self)\n has non borrowed-from use: \(use)")
84+
if use.index == 0 {
85+
require(!forwardingBorrowedFromFound, "phi \(self) has multiple forwarding borrowed-from uses")
86+
forwardingBorrowedFromFound = true
20387
}
20488
}
205-
return false
206-
case is DestroyAddrInst, is IsUniqueInst:
207-
return true
208-
default:
209-
return false
89+
require (forwardingBorrowedFromFound,
90+
"missing forwarding borrowed-from user of guaranteed phi \(phi)")
21091
}
21192
}
21293
}

lib/SIL/Verifier/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
target_sources(swiftSIL PRIVATE
22
DebugInfoVerifier.cpp
3+
LoadBorrowImmutabilityChecker.cpp
34
LinearLifetimeChecker.cpp
45
MemoryLifetimeVerifier.cpp
56
GuaranteedPhiVerifier.cpp

0 commit comments

Comments
 (0)