Skip to content

Commit 4d730d8

Browse files
committed
Merging r344589:
------------------------------------------------------------------------ r344589 | dstenb | 2018-10-16 01:06:48 -0700 (Tue, 16 Oct 2018) | 41 lines [DebugInfo][LCSSA] Rewrite pre-existing debug values outside loop Summary: Extend LCSSA so that debug values outside loops are rewritten to use the PHI nodes that the pass creates. This fixes PR39019. In that case, we ran LCSSA on a loop that was later on vectorized, which left us with something like this: for.cond.cleanup: %add.lcssa = phi i32 [ %add, %for.body ], [ %34, %middle.block ] call void @llvm.dbg.value(metadata i32 %add, ret i32 %add.lcssa for.body: %add = [...] br i1 %exitcond, label %for.cond.cleanup, label %for.body which later resulted in the debug.value becoming undef when removing the scalar loop (and the location would have probably been wrong for the vectorized case otherwise). As we now may need to query the AvailableVals cache more than once for a basic block, FindAvailableVals() in SSAUpdaterImpl is changed so that it updates the cache for blocks that we do not create a PHI node for, regardless of the block's number of predecessors. The debug value in the attached IR reproducer would not be properly rewritten without this. Debug values residing in blocks where we have not inserted any PHI nodes are currently left as-is by this patch. I'm not sure what should be done with those uses. Reviewers: mattd, aprantl, vsk, probinson Reviewed By: mattd, aprantl Subscribers: jmorse, gbedwell, JDevlieghere, llvm-commits Differential Revision: https://reviews.llvm.org/D53130 ------------------------------------------------------------------------ llvm-svn: 348011
1 parent 4a6ae60 commit 4d730d8

File tree

5 files changed

+97
-4
lines changed

5 files changed

+97
-4
lines changed

llvm/include/llvm/Transforms/Utils/SSAUpdater.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ class SSAUpdater {
7676
/// block.
7777
bool HasValueForBlock(BasicBlock *BB) const;
7878

79+
/// Return the value for the specified block if the SSAUpdater has one,
80+
/// otherwise return nullptr.
81+
Value *FindValueForBlock(BasicBlock *BB) const;
82+
7983
/// Construct SSA form, materializing a value that is live at the end
8084
/// of the specified block.
8185
Value *GetValueAtEndOfBlock(BasicBlock *BB);

llvm/include/llvm/Transforms/Utils/SSAUpdaterImpl.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -357,10 +357,9 @@ class SSAUpdaterImpl {
357357
BBInfo *Info = *I;
358358

359359
if (Info->DefBB != Info) {
360-
// Record the available value at join nodes to speed up subsequent
361-
// uses of this SSAUpdater for the same value.
362-
if (Info->NumPreds > 1)
363-
(*AvailableVals)[Info->BB] = Info->DefBB->AvailableVal;
360+
// Record the available value to speed up subsequent uses of this
361+
// SSAUpdater for the same value.
362+
(*AvailableVals)[Info->BB] = Info->DefBB->AvailableVal;
364363
continue;
365364
}
366365

llvm/lib/Transforms/Utils/LCSSA.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include "llvm/IR/Dominators.h"
4242
#include "llvm/IR/Function.h"
4343
#include "llvm/IR/Instructions.h"
44+
#include "llvm/IR/IntrinsicInst.h"
4445
#include "llvm/IR/PredIteratorCache.h"
4546
#include "llvm/Pass.h"
4647
#include "llvm/Transforms/Utils.h"
@@ -201,6 +202,21 @@ bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
201202
SSAUpdate.RewriteUse(*UseToRewrite);
202203
}
203204

205+
SmallVector<DbgValueInst *, 4> DbgValues;
206+
llvm::findDbgValues(DbgValues, I);
207+
208+
// Update pre-existing debug value uses that reside outside the loop.
209+
auto &Ctx = I->getContext();
210+
for (auto DVI : DbgValues) {
211+
BasicBlock *UserBB = DVI->getParent();
212+
if (InstBB == UserBB || L->contains(UserBB))
213+
continue;
214+
// We currently only handle debug values residing in blocks where we have
215+
// inserted a PHI instruction.
216+
if (Value *V = SSAUpdate.FindValueForBlock(UserBB))
217+
DVI->setOperand(0, MetadataAsValue::get(Ctx, ValueAsMetadata::get(V)));
218+
}
219+
204220
// SSAUpdater might have inserted phi-nodes inside other loops. We'll need
205221
// to post-process them to keep LCSSA form.
206222
for (PHINode *InsertedPN : InsertedPHIs) {

llvm/lib/Transforms/Utils/SSAUpdater.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ bool SSAUpdater::HasValueForBlock(BasicBlock *BB) const {
6464
return getAvailableVals(AV).count(BB);
6565
}
6666

67+
Value *SSAUpdater::FindValueForBlock(BasicBlock *BB) const {
68+
AvailableValsTy::iterator AVI = getAvailableVals(AV).find(BB);
69+
return (AVI != getAvailableVals(AV).end()) ? AVI->second : nullptr;
70+
}
71+
6772
void SSAUpdater::AddAvailableValue(BasicBlock *BB, Value *V) {
6873
assert(ProtoType && "Need to initialize SSAUpdater");
6974
assert(ProtoType == V->getType() &&
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
; RUN: opt -S -lcssa < %s | FileCheck %s
2+
3+
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
4+
target triple = "x86_64-unknown-linux-gnu"
5+
6+
; Reproducer for PR39019.
7+
;
8+
; Verify that the llvm.dbg.value in the %for.cond.cleanup2 block is rewritten
9+
; to use the PHI node for %add that is created by LCSSA.
10+
11+
; CHECK-LABEL: for.cond.cleanup2:
12+
; CHECK-NEXT: [[PN:%[^ ]*]] = phi i32 [ %add.lcssa, %for.cond.cleanup1 ]
13+
; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 [[PN]], metadata [[VAR:![0-9]+]], metadata !DIExpression())
14+
; CHECK-NEXT: call void @bar(i32 [[PN]])
15+
16+
; CHECK-LABEL: for.body:
17+
; CHECK: %add = add nsw i32 0, 2
18+
; CHECK: call void @llvm.dbg.value(metadata i32 %add, metadata [[VAR]], metadata !DIExpression())
19+
20+
; CHECK: [[VAR]] = !DILocalVariable(name: "sum",
21+
22+
; Function Attrs: nounwind
23+
define void @foo() #0 !dbg !6 {
24+
entry:
25+
br label %for.cond.preheader, !dbg !12
26+
27+
for.cond.preheader: ; preds = %for.cond.cleanup1, %entry
28+
br label %for.body, !dbg !12
29+
30+
for.cond.cleanup2: ; preds = %for.cond.cleanup1
31+
call void @llvm.dbg.value(metadata i32 %add, metadata !9, metadata !DIExpression()), !dbg !12
32+
tail call void @bar(i32 %add) #0, !dbg !12
33+
ret void, !dbg !12
34+
35+
for.cond.cleanup1: ; preds = %for.body
36+
br i1 false, label %for.cond.preheader, label %for.cond.cleanup2, !dbg !12
37+
38+
for.body: ; preds = %for.body, %for.cond.preheader
39+
%add = add nsw i32 0, 2, !dbg !12
40+
call void @llvm.dbg.value(metadata i32 %add, metadata !9, metadata !DIExpression()), !dbg !12
41+
br i1 false, label %for.body, label %for.cond.cleanup1, !dbg !12
42+
}
43+
44+
; Function Attrs: nounwind
45+
declare void @bar(i32) #0
46+
47+
; Function Attrs: nounwind readnone speculatable
48+
declare void @llvm.dbg.value(metadata, metadata, metadata) #1
49+
50+
attributes #0 = { nounwind }
51+
attributes #1 = { nounwind readnone speculatable }
52+
53+
!llvm.dbg.cu = !{!0}
54+
!llvm.module.flags = !{!3, !4}
55+
!llvm.ident = !{!5}
56+
57+
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 8.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !2)
58+
!1 = !DIFile(filename: "foo.c", directory: "/")
59+
!2 = !{}
60+
!3 = !{i32 2, !"Dwarf Version", i32 4}
61+
!4 = !{i32 2, !"Debug Info Version", i32 3}
62+
!5 = !{!"clang version 8.0.0"}
63+
!6 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 10, type: !7, isLocal: false, isDefinition: true, scopeLine: 10, isOptimized: true, unit: !0, retainedNodes: !8)
64+
!7 = !DISubroutineType(types: !2)
65+
!8 = !{!9}
66+
!9 = !DILocalVariable(name: "sum", scope: !10, file: !1, line: 11, type: !11)
67+
!10 = !DILexicalBlockFile(scope: !6, file: !1, discriminator: 0)
68+
!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
69+
!12 = !DILocation(line: 0, scope: !10)

0 commit comments

Comments
 (0)