Skip to content

Commit

Permalink
[CodeExtractor] Preserve entire scope of !DIVariables when moving them
Browse files Browse the repository at this point in the history
When a dbg.value is moved into a new function, the corresponding
variable should have its entire scope chain reparented with the new
function. The current implementation drops the scope chain and replaces
it with a subprogram for the new function.

Differential Revision: https://reviews.llvm.org/D139671
  • Loading branch information
felipepiovezan committed Dec 12, 2022
1 parent 73472b6 commit d23b7f5
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 3 deletions.
9 changes: 6 additions & 3 deletions llvm/lib/Transforms/Utils/CodeExtractor.cpp
Expand Up @@ -1556,6 +1556,7 @@ static void fixupDebugInfoPostExtraction(Function &OldFunc, Function &NewFunc,
// point to a variable in the wrong scope.
SmallDenseMap<DINode *, DINode *> RemappedMetadata;
SmallVector<Instruction *, 4> DebugIntrinsicsToDelete;
DenseMap<const MDNode *, MDNode *> Cache;
for (Instruction &I : instructions(NewFunc)) {
auto *DII = dyn_cast<DbgInfoIntrinsic>(&I);
if (!DII)
Expand Down Expand Up @@ -1593,11 +1594,14 @@ static void fixupDebugInfoPostExtraction(Function &OldFunc, Function &NewFunc,
if (!DVI->getDebugLoc().getInlinedAt()) {
DILocalVariable *OldVar = DVI->getVariable();
DINode *&NewVar = RemappedMetadata[OldVar];
if (!NewVar)
if (!NewVar) {
DILocalScope *NewScope = DILocalScope::cloneScopeForSubprogram(
*OldVar->getScope(), *NewSP, Ctx, Cache);
NewVar = DIB.createAutoVariable(
NewSP, OldVar->getName(), OldVar->getFile(), OldVar->getLine(),
NewScope, OldVar->getName(), OldVar->getFile(), OldVar->getLine(),
OldVar->getType(), /*AlwaysPreserve=*/false, DINode::FlagZero,
OldVar->getAlignInBits());
}
DVI->setVariable(cast<DILocalVariable>(NewVar));
}
}
Expand All @@ -1608,7 +1612,6 @@ static void fixupDebugInfoPostExtraction(Function &OldFunc, Function &NewFunc,

// Fix up the scope information attached to the line locations in the new
// function.
DenseMap<const MDNode *, MDNode *> Cache;
for (Instruction &I : instructions(NewFunc)) {
if (const DebugLoc &DL = I.getDebugLoc())
I.setDebugLoc(
Expand Down
14 changes: 14 additions & 0 deletions llvm/test/Transforms/HotColdSplit/transfer-debug-info.ll
Expand Up @@ -35,6 +35,11 @@ target triple = "x86_64-apple-macosx10.14.0"
; CHECK-SAME: metadata [[VAR_FROM_INLINE_ME:![0-9]+]]
; CHECK-SAME: !dbg [[LINE2]]

; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 [[ADD1]]
; CHECK-SAME: metadata [[VAR2:![0-9]+]]
; CHECK-SAME: !dbg [[LINE4:![0-9]+]]


; - The DISubprogram for @foo.cold.1 has an empty DISubroutineType
; CHECK: [[FILE:![0-9]+]] = !DIFile(filename: "<stdin>"
; CHECK: [[EMPTY_MD:![0-9]+]] = !{}
Expand All @@ -54,6 +59,11 @@ target triple = "x86_64-apple-macosx10.14.0"
; CHECK: [[VAR_FROM_INLINE_ME]] = !DILocalVariable(name: "var_from_inline_me",
; CHECK-SAME: scope: [[INLINE_ME_SCOPE]]

; CHECK: [[VAR2]] = !DILocalVariable(name: "var_from_scope_in_foo",
; CHECK-SAME: scope: [[NEWSCOPE2:![0-9]+]]
; CHECK: [[NEWSCOPE2]] = !DILexicalBlock(scope: [[NEWSCOPE]], file: [[FILE]], line: 7, column: 7)
; CHECK: [[LINE4]] = !DILocation(line: 6, column: 6, scope: [[NEWSCOPE2]]

define void @foo(i32 %arg1) !dbg !6 {
entry:
%var = add i32 0, 0, !dbg !11
Expand All @@ -72,6 +82,7 @@ if.end: ; preds = %entry
call void @sink(i32 %add1), !dbg !13 ; inlined from @inline_me
call void @sink(i32 %add1), !dbg !14 ; not inlined, but inside some scope of foo
call void @llvm.dbg.value(metadata i32 %add1, metadata !17, metadata !DIExpression()), !dbg !13 ; variable from @inline_me, should preserve scope in !17.
call void @llvm.dbg.value(metadata i32 %add1, metadata !18, metadata !DIExpression()), !dbg !19 ; variable not inlined, but inside some scope of foo
ret void
}

Expand Down Expand Up @@ -105,3 +116,6 @@ define void @inline_me() !dbg !12{
!15 = distinct !DILexicalBlock(scope: !16, file: !1, line: 4, column: 4)
!16 = distinct !DILexicalBlock(scope: !6, file: !1, line: 5, column: 5)
!17 = !DILocalVariable(name: "var_from_inline_me", scope: !12, file: !1, line: 1, type: !10)
!18 = !DILocalVariable(name: "var_from_scope_in_foo", scope: !20, file: !1, line: 1, type: !10)
!19 = !DILocation(line: 6, column: 6, scope: !20)
!20 = distinct !DILexicalBlock(scope: !6, file: !1, line: 7, column: 7)

0 comments on commit d23b7f5

Please sign in to comment.