Skip to content

Commit 0eb7f46

Browse files
committed
Add createDebugFragments utility API
Create debug_value fragment for a new partial value based on a projection of an old debug_value.
1 parent 962c290 commit 0eb7f46

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

include/swift/SILOptimizer/Utils/DebugOptUtils.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#define SWIFT_SILOPTIMIZER_DEBUGOPTUTILS_H
2020

2121
#include "swift/SIL/DebugUtils.h"
22+
#include "swift/SIL/Projection.h"
2223
#include "swift/SIL/SILValue.h"
2324
#include "swift/SILOptimizer/Utils/InstOptUtils.h"
2425

@@ -47,6 +48,13 @@ inline void deleteAllDebugUses(SILInstruction *inst,
4748
/// new `debug_value` instruction before \p I is deleted.
4849
void salvageDebugInfo(SILInstruction *I);
4950

51+
/// Create debug_value fragment for a new partial value.
52+
///
53+
/// Precondition: \p oldValue is a struct or class aggregate. \p proj projects a
54+
/// field from the aggregate into \p newValue corresponding to struct_extract.
55+
void createDebugFragments(SILValue oldValue, Projection proj,
56+
SILValue newValue);
57+
5058
/// Erases the instruction \p I from it's parent block and deletes it, including
5159
/// all debug instructions which use \p I.
5260
/// Precondition: The instruction may only have debug instructions as uses.

lib/SILOptimizer/Utils/InstOptUtils.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1792,6 +1792,7 @@ void swift::endLifetimeAtLeakingBlocks(SILValue value,
17921792
});
17931793
}
17941794

1795+
// TODO: this currently fails to notify the pass with notifyNewInstruction.
17951796
void swift::salvageDebugInfo(SILInstruction *I) {
17961797
if (!I)
17971798
return;
@@ -1872,6 +1873,38 @@ void swift::salvageDebugInfo(SILInstruction *I) {
18721873
}
18731874
}
18741875

1876+
// TODO: this currently fails to notify the pass with notifyNewInstruction.
1877+
void swift::createDebugFragments(SILValue oldValue, Projection proj,
1878+
SILValue newValue) {
1879+
if (proj.getKind() != ProjectionKind::Struct)
1880+
return;
1881+
1882+
for (auto *use : getDebugUses(oldValue)) {
1883+
auto debugVal = dyn_cast<DebugValueInst>(use->getUser());
1884+
if (!debugVal)
1885+
continue;
1886+
1887+
// Can't create a fragment of a fragment.
1888+
auto varInfo = debugVal->getVarInfo();
1889+
if (!varInfo || varInfo->DIExpr.hasFragment())
1890+
continue;
1891+
1892+
SILType baseType = oldValue->getType();
1893+
1894+
// Copy VarInfo and add the corresponding fragment DIExpression.
1895+
SILDebugVariable newVarInfo = *varInfo;
1896+
newVarInfo.DIExpr.append(
1897+
SILDebugInfoExpression::createFragment(proj.getVarDecl(baseType)));
1898+
1899+
if (!newVarInfo.Type)
1900+
newVarInfo.Type = baseType;
1901+
1902+
// Create a new debug_value
1903+
SILBuilder(debugVal, debugVal->getDebugScope())
1904+
.createDebugValue(debugVal->getLoc(), newValue, newVarInfo);
1905+
}
1906+
}
1907+
18751908
IntegerLiteralInst *swift::optimizeBuiltinCanBeObjCClass(BuiltinInst *bi,
18761909
SILBuilder &builder) {
18771910
assert(bi->getBuiltinInfo().ID == BuiltinValueKind::CanBeObjCClass);

0 commit comments

Comments
 (0)