Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit 383922d

Browse files
author
Keith Walker
committed
Add @llvm.dbg.value entries for the phi node created by -mem2reg
When phi nodes are created in the -mem2reg phase, the @llvm.dbg.declare entries are converted to @llvm.dbg.value entries at the place where the store instructions existed. However no entry is created to describe the resulting value of the phi node. The effect of this is especially noticeable in for loops which have a constant for the intial value; the loop control variable's location would be described as the intial constant value in the loop body once the -mem2reg optimization phase was run. This change adds the creation of the @llvm.dbg.value entries to describe variables whose location is the result of a phi node created in -mem2reg. Also when the phi node is finally lowered to a machine instruction it is important that the lowered "load" instruction is placed before the associated DEBUG_VALUE entry describing the value loaded. Differential Revision: https://reviews.llvm.org/D23715 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@281895 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 8d46442 commit 383922d

File tree

4 files changed

+134
-0
lines changed

4 files changed

+134
-0
lines changed

include/llvm/Transforms/Utils/Local.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class BranchInst;
3232
class Instruction;
3333
class CallInst;
3434
class DbgDeclareInst;
35+
class DbgValueInst;
3536
class StoreInst;
3637
class LoadInst;
3738
class Value;
@@ -48,6 +49,8 @@ class LazyValueInfo;
4849

4950
template<typename T> class SmallVectorImpl;
5051

52+
typedef SmallVector<DbgValueInst *, 1> DbgValueList;
53+
5154
//===----------------------------------------------------------------------===//
5255
// Local constant propagation.
5356
//
@@ -263,13 +266,21 @@ bool ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
263266
bool ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
264267
LoadInst *LI, DIBuilder &Builder);
265268

269+
/// Inserts a llvm.dbg.value intrinsic after a phi of an alloca'd value
270+
/// that has an associated llvm.dbg.decl intrinsic.
271+
bool ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
272+
PHINode *LI, DIBuilder &Builder);
273+
266274
/// Lowers llvm.dbg.declare intrinsics into appropriate set of
267275
/// llvm.dbg.value intrinsics.
268276
bool LowerDbgDeclare(Function &F);
269277

270278
/// Finds the llvm.dbg.declare intrinsic corresponding to an alloca, if any.
271279
DbgDeclareInst *FindAllocaDbgDeclare(Value *V);
272280

281+
/// Finds the llvm.dbg.value intrinsics corresponding to an alloca, if any.
282+
void FindAllocaDbgValues(DbgValueList &DbgValues, Value *V);
283+
273284
/// Replaces llvm.dbg.declare instruction when the address it describes
274285
/// is replaced with a new value. If Deref is true, an additional DW_OP_deref is
275286
/// prepended to the expression. If Offset is non-zero, a constant displacement

lib/Transforms/Utils/Local.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,24 @@ static bool LdStHasDebugValue(DILocalVariable *DIVar, DIExpression *DIExpr,
10531053
return false;
10541054
}
10551055

1056+
/// See if there is a dbg.value intrinsic for DIVar for the PHI node.
1057+
static bool PhiHasDebugValue(DILocalVariable *DIVar,
1058+
DIExpression *DIExpr,
1059+
PHINode *APN) {
1060+
// Since we can't guarantee that the original dbg.declare instrinsic
1061+
// is removed by LowerDbgDeclare(), we need to make sure that we are
1062+
// not inserting the same dbg.value intrinsic over and over.
1063+
DbgValueList DbgValues;
1064+
FindAllocaDbgValues(DbgValues, APN);
1065+
for (auto DVI : DbgValues) {
1066+
assert (DVI->getValue() == APN);
1067+
assert (DVI->getOffset() == 0);
1068+
if ((DVI->getVariable() == DIVar) && (DVI->getExpression() == DIExpr))
1069+
return true;
1070+
}
1071+
return false;
1072+
}
1073+
10561074
/// Inserts a llvm.dbg.value intrinsic before a store to an alloca'd value
10571075
/// that has an associated llvm.dbg.decl intrinsic.
10581076
bool llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
@@ -1120,6 +1138,23 @@ bool llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
11201138
return true;
11211139
}
11221140

1141+
/// Inserts a llvm.dbg.value intrinsic after a phi
1142+
/// that has an associated llvm.dbg.decl intrinsic.
1143+
bool llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
1144+
PHINode *APN, DIBuilder &Builder) {
1145+
auto *DIVar = DDI->getVariable();
1146+
auto *DIExpr = DDI->getExpression();
1147+
assert(DIVar && "Missing variable");
1148+
1149+
if (PhiHasDebugValue(DIVar, DIExpr, APN))
1150+
return true;
1151+
1152+
Instruction *DbgValue = Builder.insertDbgValueIntrinsic(
1153+
APN, 0, DIVar, DIExpr, DDI->getDebugLoc(), (Instruction *)nullptr);
1154+
DbgValue->insertBefore(&*APN->getParent()->getFirstInsertionPt());
1155+
return true;
1156+
}
1157+
11231158
/// Determine whether this alloca is either a VLA or an array.
11241159
static bool isArray(AllocaInst *AI) {
11251160
return AI->isArrayAllocation() ||
@@ -1187,6 +1222,16 @@ DbgDeclareInst *llvm::FindAllocaDbgDeclare(Value *V) {
11871222
return nullptr;
11881223
}
11891224

1225+
/// FindAllocaDbgValues - Finds the llvm.dbg.value intrinsics describing the
1226+
/// alloca 'V', if any.
1227+
void llvm::FindAllocaDbgValues(DbgValueList &DbgValues, Value *V) {
1228+
if (auto *L = LocalAsMetadata::getIfExists(V))
1229+
if (auto *MDV = MetadataAsValue::getIfExists(V->getContext(), L))
1230+
for (User *U : MDV->users())
1231+
if (DbgValueInst *DVI = dyn_cast<DbgValueInst>(U))
1232+
DbgValues.push_back(DVI);
1233+
}
1234+
11901235
static void DIExprAddDeref(SmallVectorImpl<uint64_t> &Expr) {
11911236
Expr.push_back(dwarf::DW_OP_deref);
11921237
}

lib/Transforms/Utils/PromoteMemoryToRegister.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -907,6 +907,8 @@ void PromoteMem2Reg::RenamePass(BasicBlock *BB, BasicBlock *Pred,
907907

908908
// The currently active variable for this block is now the PHI.
909909
IncomingVals[AllocaNo] = APN;
910+
if (DbgDeclareInst *DDI = AllocaDbgDeclares[AllocaNo])
911+
ConvertDebugDeclareToDebugValue(DDI, APN, DIB);
910912

911913
// Get the next phi node.
912914
++PNI;

test/Transforms/Util/mem2reg-dbg.ll

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
; RUN: opt -mem2reg -S < %s | FileCheck %s
2+
3+
; Test that a @llvm.dbg.value node is created to describe the value returned by a phi node when
4+
; lowering a @llvm.dbg.declare node
5+
6+
; Created from the C code, compiled with -O0 -g:
7+
;
8+
; int func(int a)
9+
; {
10+
; int c = 1;
11+
; if (a < 0 ) {
12+
; c = 12;
13+
; }
14+
; return c;
15+
; }
16+
17+
; Function Attrs: nounwind
18+
define i32 @func(i32 %a) #0 !dbg !8 {
19+
entry:
20+
%a.addr = alloca i32, align 4
21+
%c = alloca i32, align 4
22+
store i32 %a, i32* %a.addr, align 4
23+
call void @llvm.dbg.declare(metadata i32* %a.addr, metadata !12, metadata !13), !dbg !14
24+
call void @llvm.dbg.declare(metadata i32* %c, metadata !15, metadata !13), !dbg !16
25+
store i32 1, i32* %c, align 4, !dbg !16
26+
%0 = load i32, i32* %a.addr, align 4, !dbg !17
27+
%cmp = icmp slt i32 %0, 0, !dbg !19
28+
br i1 %cmp, label %if.then, label %if.end, !dbg !20
29+
30+
if.then: ; preds = %entry
31+
store i32 12, i32* %c, align 4, !dbg !21
32+
br label %if.end, !dbg !23
33+
34+
if.end: ; preds = %if.then, %entry
35+
%1 = load i32, i32* %c, align 4, !dbg !24
36+
; CHECK: [[PHI:%.*]] = phi i32 [ 12, {{.*}} ], [ 1, {{.*}} ]
37+
; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 [[PHI]], i64 0, metadata !15, metadata !13), !dbg !16
38+
ret i32 %1, !dbg !25
39+
}
40+
41+
; Function Attrs: nounwind readnone
42+
declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
43+
44+
attributes #1 = { nounwind readnone }
45+
46+
!llvm.dbg.cu = !{!0}
47+
!llvm.module.flags = !{!3, !4, !5, !6}
48+
!llvm.ident = !{!7}
49+
50+
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
51+
!1 = !DIFile(filename: "a.c", directory: "/tmp")
52+
!2 = !{}
53+
!3 = !{i32 2, !"Dwarf Version", i32 4}
54+
!4 = !{i32 2, !"Debug Info Version", i32 3}
55+
!5 = !{i32 1, !"wchar_size", i32 4}
56+
!6 = !{i32 1, !"min_enum_size", i32 4}
57+
!7 = !{!"clang"}
58+
!8 = distinct !DISubprogram(name: "func", scope: !1, file: !1, line: 1, type: !9, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)
59+
!9 = !DISubroutineType(types: !10)
60+
!10 = !{!11, !11}
61+
!11 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
62+
!12 = !DILocalVariable(name: "a", arg: 1, scope: !8, file: !1, line: 1, type: !11)
63+
!13 = !DIExpression()
64+
!14 = !DILocation(line: 1, column: 14, scope: !8)
65+
!15 = !DILocalVariable(name: "c", scope: !8, file: !1, line: 3, type: !11)
66+
!16 = !DILocation(line: 3, column: 6, scope: !8)
67+
!17 = !DILocation(line: 4, column: 6, scope: !18)
68+
!18 = distinct !DILexicalBlock(scope: !8, file: !1, line: 4, column: 6)
69+
!19 = !DILocation(line: 4, column: 8, scope: !18)
70+
!20 = !DILocation(line: 4, column: 6, scope: !8)
71+
!21 = !DILocation(line: 5, column: 5, scope: !22)
72+
!22 = distinct !DILexicalBlock(scope: !18, file: !1, line: 4, column: 14)
73+
!23 = !DILocation(line: 6, column: 2, scope: !22)
74+
!24 = !DILocation(line: 7, column: 9, scope: !8)
75+
!25 = !DILocation(line: 7, column: 2, scope: !8)
76+

0 commit comments

Comments
 (0)