Skip to content

Commit 170c563

Browse files
committed
[NFC] cleanup Instruction/Value.findVarDecl() APIs.
These APIs are quite convoluted. The checks for var_decl need to be performed in just the right order. The is a consequence of complexity in the SIL representation itself, not a problem with the APIs. It is common for code to accidentally call a less-complete form of the API. It is essential that they be defined in a central location, and the we get the same answer whether we start with an Instruction, Argument, or Value. The primary public interface should always check for debug_value users. The varDecl property is actually an implementation detail. It is questionable whether a function like findVarDecl() that returns a basic property of SIL and does not require arguments should be a property instead. It is a function to hint that it may scan the use-list, which is not something we normally want SIL properties to do. Use-lists can grow linearly in function size. But, again, this is a natural result of the SIL representation and needs to be considered an implementation detail.
1 parent 4436e94 commit 170c563

File tree

3 files changed

+19
-19
lines changed

3 files changed

+19
-19
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/LifetimeDependenceDiagnostics.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ private struct LifetimeVariable {
342342

343343
private init(introducer: Value, _ context: some Context) {
344344
if let arg = introducer as? FunctionArgument {
345-
self.varDecl = arg.varDecl
345+
self.varDecl = arg.findVarDecl()
346346
self.sourceLoc = arg.sourceLoc
347347
self.isArgument = true
348348
self.isClosureCapture = arg.isClosureCapture

SwiftCompilerSources/Sources/SIL/Argument.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,14 @@ public class Argument : Value, Hashable {
3434

3535
public var isLexical: Bool { false }
3636

37-
public var varDecl: VarDecl? {
37+
public func findVarDecl() -> VarDecl? {
3838
if let varDecl = bridged.getVarDecl().getAs(VarDecl.self) {
3939
return varDecl
4040
}
41-
return debugUserDecl
41+
return findVarDeclFromDebugUsers()
4242
}
4343

44-
public var sourceLoc: SourceLoc? { varDecl?.nameLoc }
44+
public var sourceLoc: SourceLoc? { findVarDecl()?.nameLoc }
4545

4646
public static func ==(lhs: Argument, rhs: Argument) -> Bool {
4747
lhs === rhs

SwiftCompilerSources/Sources/SIL/Instruction.swift

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -450,17 +450,17 @@ public enum VariableScopeInstruction {
450450
scopeBegin.uses.lazy.filter { $0.endsLifetime || $0.instruction is ExtendLifetimeInst }
451451
}
452452

453-
// TODO: with SIL verification, we might be able to make varDecl non-Optional.
454-
public var varDecl: VarDecl? {
455-
if let debugVarDecl = instruction.debugResultDecl {
456-
return debugVarDecl
457-
}
453+
// TODO: assert that VarDecl is valid whenever isFromVarDecl returns tyue.
454+
public func findVarDecl() -> VarDecl? {
458455
// SILGen may produce double var_decl instructions for the same variable:
459456
// %box = alloc_box [var_decl] "x"
460457
// begin_borrow %box [var_decl]
461458
//
462-
// Assume that, if the begin_borrow or move_value does not have its own debug_value, then it must actually be
463-
// associated with its operand's var_decl.
459+
// Therefore, first check if begin_borrow or move_value has any debug_value users.
460+
if let debugVarDecl = instruction.findVarDeclFromDebugUsers() {
461+
return debugVarDecl
462+
}
463+
// Otherwise, assume that the var_decl is associated with its operand's var_decl.
464464
return instruction.operands[0].value.definingInstruction?.findVarDecl()
465465
}
466466
}
@@ -472,14 +472,14 @@ extension Instruction {
472472
return varDeclInst.varDecl
473473
}
474474
if let varScopeInst = VariableScopeInstruction(self) {
475-
return varScopeInst.varDecl
475+
return varScopeInst.findVarDecl()
476476
}
477-
return debugResultDecl
477+
return findVarDeclFromDebugUsers()
478478
}
479479

480-
var debugResultDecl: VarDecl? {
480+
func findVarDeclFromDebugUsers() -> VarDecl? {
481481
for result in results {
482-
if let varDecl = result.debugUserDecl {
482+
if let varDecl = result.findVarDeclFromDebugUsers() {
483483
return varDecl
484484
}
485485
}
@@ -488,14 +488,14 @@ extension Instruction {
488488
}
489489

490490
extension Value {
491-
var debugValDecl: VarDecl? {
491+
public func findVarDecl() -> VarDecl? {
492492
if let arg = self as? Argument {
493-
return arg.varDecl
493+
return arg.findVarDecl()
494494
}
495-
return debugUserDecl
495+
return findVarDeclFromDebugUsers()
496496
}
497497

498-
var debugUserDecl: VarDecl? {
498+
func findVarDeclFromDebugUsers() -> VarDecl? {
499499
for use in uses {
500500
if let debugVal = use.instruction as? DebugValueInst {
501501
return debugVal.varDecl

0 commit comments

Comments
 (0)