-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[DebugInfo] Salvage all stores #72964
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
523a769
450db6e
00a93d9
584d1db
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -391,6 +391,16 @@ class SILLocation { | |||||
/// Check is this location is part of a function's implicit prologue. | ||||||
bool isInPrologue() const { return kindAndFlags.fields.inPrologue; } | ||||||
|
||||||
/// Returns this location with the auto-generated and prologue bits stripped. | ||||||
/// These bits only make sense for instructions, and should be stripped for | ||||||
/// variables. | ||||||
SILLocation strippedForDebugVariable() const { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
SILLocation loc = *this; | ||||||
loc.kindAndFlags.fields.autoGenerated = false; | ||||||
loc.kindAndFlags.fields.inPrologue = false; | ||||||
return loc; | ||||||
} | ||||||
|
||||||
/// Check if the corresponding source code location definitely points | ||||||
/// to the end of the AST node. | ||||||
bool pointsToEnd() const; | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1826,6 +1826,44 @@ void swift::endLifetimeAtLeakingBlocks(SILValue value, | |
}); | ||
} | ||
|
||
/// Create a new debug value from a store and a debug variable. | ||
static void transferStoreDebugValue(DebugVarCarryingInst DefiningInst, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does
and not
? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is a DebugVarCarryingInst, so it will be called in both cases: in the first case DefiningInst will be the alloc_stack, in the second case the DefiningInst is the debug_value |
||
SILInstruction *SI, | ||
SILValue original) { | ||
auto VarInfo = DefiningInst.getVarInfo(); | ||
if (!VarInfo) | ||
return; | ||
// Transfer the location and scope of the debug value to the debug variable, | ||
// unless they are the same, in which case we don't need to store it twice. | ||
// That way, the variable will point to its declaration, and the debug_value | ||
// will point to the assignment point. | ||
if (!VarInfo->Loc && !SI->getLoc().hasSameSourceLocation(DefiningInst->getLoc())) | ||
Snowy1803 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
VarInfo->Loc = DefiningInst->getLoc(); | ||
if (!VarInfo->Scope && SI->getDebugScope() != DefiningInst->getDebugScope()) | ||
VarInfo->Scope = DefiningInst->getDebugScope(); | ||
// Fix the op_deref. | ||
if (!isa<CopyAddrInst>(SI) && VarInfo->DIExpr.startsWithDeref()) | ||
VarInfo->DIExpr.eraseElement(VarInfo->DIExpr.element_begin()); | ||
else if (isa<CopyAddrInst>(SI) && !VarInfo->DIExpr.startsWithDeref()) | ||
VarInfo->DIExpr.prependElements({ | ||
SILDIExprElement::createOperator(SILDIExprOperator::Dereference)}); | ||
// Note: The instruction should logically be in the SI's scope. | ||
// However, LLVM does not support variables and stores in different scopes, | ||
// so we use the variable's scope. | ||
SILBuilder(SI, DefiningInst->getDebugScope()) | ||
.createDebugValue(SI->getLoc(), original, *VarInfo); | ||
} | ||
|
||
void swift::salvageStoreDebugInfo(SILInstruction *SI, | ||
SILValue SrcVal, SILValue DestVal) { | ||
if (auto *ASI = dyn_cast_or_null<AllocStackInst>( | ||
DestVal.getDefiningInstruction())) { | ||
transferStoreDebugValue(ASI, SI, SrcVal); | ||
for (Operand *U : getDebugUses(ASI)) | ||
transferStoreDebugValue(U->getUser(), SI, SrcVal); | ||
} | ||
} | ||
|
||
// TODO: this currently fails to notify the pass with notifyNewInstruction. | ||
// | ||
// TODO: whenever a debug_value is inserted at a new location, check that no | ||
|
@@ -1837,18 +1875,13 @@ void swift::salvageDebugInfo(SILInstruction *I) { | |
|
||
if (auto *SI = dyn_cast<StoreInst>(I)) { | ||
if (SILValue DestVal = SI->getDest()) | ||
if (auto *ASI = dyn_cast_or_null<AllocStackInst>( | ||
DestVal.getDefiningInstruction())) { | ||
if (auto VarInfo = ASI->getVarInfo()) { | ||
// Always propagate destination location for incoming arguments (as | ||
// their location must be unique) as well as when store source | ||
// location is compiler-generated. | ||
bool UseDestLoc = VarInfo->ArgNo || SI->getLoc().isAutoGenerated(); | ||
SILBuilder(SI, ASI->getDebugScope()) | ||
.createDebugValue(UseDestLoc ? ASI->getLoc() : SI->getLoc(), | ||
SI->getSrc(), *VarInfo); | ||
} | ||
} | ||
salvageStoreDebugInfo(SI, SI->getSrc(), DestVal); | ||
} | ||
if (auto *SI = dyn_cast<StoreBorrowInst>(I)) { | ||
if (SILValue DestVal = SI->getDest()) | ||
salvageStoreDebugInfo(SI, SI->getSrc(), DestVal); | ||
for (Operand *U : getDebugUses(SI)) | ||
transferStoreDebugValue(U->getUser(), SI, SI->getSrc()); | ||
} | ||
// If a `struct` SIL instruction is "unwrapped" and removed, | ||
// for instance, in favor of using its enclosed value directly, | ||
|
Uh oh!
There was an error while loading. Please reload this page.