llvm.org GIT mirror llvm / 2a694ff
[LoopDeletion] Update debug values after loop deletion. When loops are deleted, we don't keep track of variables modified inside the loops, so the DI will contain the wrong value for these. e.g. int b() { int i; for (i = 0; i < 2; i++) ; patatino(); return a; -> 6 patatino(); 7 return a; 8 } 9 int main() { b(); } (lldb) frame var i (int) i = 0 We mark instead these values as unavailable inserting a @llvm.dbg.value(undef to make sure we don't end up printing an incorrect value in the debugger. We could consider doing something fancier, for, e.g. constants, in the future. PR39868. rdar://problem/46418795) Differential Revision: https://reviews.llvm.org/D55299 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@348988 91177308-0d34-0410-b5e6-96231b3b80d8 Davide Italiano 9 months ago
2 changed file(s) with 102 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
2525 #include "llvm/Analysis/ScalarEvolutionExpressions.h"
2626 #include "llvm/Analysis/TargetTransformInfo.h"
2727 #include "llvm/Analysis/ValueTracking.h"
28 #include "llvm/IR/DIBuilder.h"
2829 #include "llvm/IR/DomTreeUpdater.h"
2930 #include "llvm/IR/Dominators.h"
3031 #include "llvm/IR/Instructions.h"
32 #include "llvm/IR/IntrinsicInst.h"
3133 #include "llvm/IR/Module.h"
3234 #include "llvm/IR/PatternMatch.h"
3335 #include "llvm/IR/ValueHandle.h"
566568 DTU.deleteEdge(Preheader, L->getHeader());
567569 }
568570
571 // Use a map to unique and a vector to guarantee deterministic ordering.
572 llvm::SmallDenseMap,
573 DbgVariableIntrinsic *, 4>
574 DeadDebugMap;
575 llvm::SmallVector DeadDebugInst;
576
569577 // Given LCSSA form is satisfied, we should not have users of instructions
570578 // within the dead loop outside of the loop. However, LCSSA doesn't take
571579 // unreachable uses into account. We handle them here.
590598 "Unexpected user in reachable block");
591599 U.set(Undef);
592600 }
601 auto *DVI = dyn_cast(&I);
602 if (!DVI)
603 continue;
604 auto Key = DeadDebugMap.find({DVI->getVariable(), DVI->getExpression()});
605 if (Key != DeadDebugMap.end())
606 continue;
607 DeadDebugMap[{DVI->getVariable(), DVI->getExpression()}] = DVI;
608 DeadDebugInst.push_back(DVI);
593609 }
610
611 // After the loop has been deleted all the values defined and modified
612 // inside the loop are going to be unavailable.
613 // Since debug values in the loop have been deleted, inserting an undef
614 // dbg.value truncates the range of any dbg.value before the loop where the
615 // loop used to be. This is particularly important for constant values.
616 DIBuilder DIB(*ExitBlock->getModule());
617 for (auto *DVI : DeadDebugInst)
618 DIB.insertDbgValueIntrinsic(
619 UndefValue::get(DVI->getType()), DVI->getVariable(),
620 DVI->getExpression(), DVI->getDebugLoc(), ExitBlock->getFirstNonPHI());
594621
595622 // Remove the block from the reference counting scheme, so that we can
596623 // delete it freely later.
0 ; RUN: opt %s -loop-deletion -S | FileCheck %s
1
2 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
3 target triple = "x86_64-apple-macosx10.14.0"
4
5 @a = common local_unnamed_addr global i32 0, align 4, !dbg !0
6
7 define i32 @b() local_unnamed_addr !dbg !12 {
8 entry:
9 call void @llvm.dbg.value(metadata i32 0, metadata !16, metadata !DIExpression()), !dbg !17
10 br label %for.cond, !dbg !18
11
12 for.cond: ; preds = %for.cond, %entry
13 %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.cond ], !dbg !20
14 call void @llvm.dbg.value(metadata i32 %i.0, metadata !16, metadata !DIExpression()), !dbg !17
15 %inc = add nuw nsw i32 %i.0, 1, !dbg !21
16 call void @llvm.dbg.value(metadata i32 %inc, metadata !16, metadata !DIExpression()), !dbg !17
17 %exitcond = icmp ne i32 %inc, 3, !dbg !23
18 br i1 %exitcond, label %for.cond, label %for.end, !dbg !24, !llvm.loop !25
19
20 ; CHECK: call void @llvm.dbg.value(metadata void undef, metadata !16, metadata !DIExpression()), !dbg !17
21 ; CHECK-NEXT: %call = tail call i32 {{.*}} @patatino()
22 for.end: ; preds = %for.cond
23 %call = tail call i32 (...) @patatino() #3, !dbg !27
24 %0 = load i32, i32* @a, align 4, !dbg !28
25 ret i32 %0, !dbg !33
26 }
27
28 declare i32 @patatino(...) local_unnamed_addr
29
30 define i32 @main() local_unnamed_addr !dbg !34 {
31 entry:
32 %call = call i32 @b(), !dbg !35
33 ret i32 0, !dbg !36
34 }
35
36 declare void @llvm.dbg.value(metadata, metadata, metadata)
37
38 !llvm.dbg.cu = !{!2}
39 !llvm.module.flags = !{!7, !8, !9, !10}
40 !llvm.ident = !{!11}
41
42 !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
43 !1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true)
44 !2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: GNU)
45 !3 = !DIFile(filename: "a.c", directory: "/Users/davide/work/llvm-project-20170507/build-debug/bin")
46 !4 = !{}
47 !5 = !{!0}
48 !6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
49 !7 = !{i32 2, !"Dwarf Version", i32 4}
50 !8 = !{i32 2, !"Debug Info Version", i32 3}
51 !9 = !{i32 1, !"wchar_size", i32 4}
52 !10 = !{i32 7, !"PIC Level", i32 2}
53 !11 = !{!"clang version 8.0.0 "}
54 !12 = distinct !DISubprogram(name: "b", scope: !3, file: !3, line: 2, type: !13, scopeLine: 2, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !15)
55 !13 = !DISubroutineType(types: !14)
56 !14 = !{!6}
57 !15 = !{!16}
58 !16 = !DILocalVariable(name: "i", scope: !12, file: !3, line: 3, type: !6)
59 !17 = !DILocation(line: 3, column: 7, scope: !12)
60 !18 = !DILocation(line: 4, column: 8, scope: !19)
61 !19 = distinct !DILexicalBlock(scope: !12, file: !3, line: 4, column: 3)
62 !20 = !DILocation(line: 0, scope: !19)
63 !21 = !DILocation(line: 4, column: 23, scope: !22)
64 !22 = distinct !DILexicalBlock(scope: !19, file: !3, line: 4, column: 3)
65 !23 = !DILocation(line: 4, column: 17, scope: !22)
66 !24 = !DILocation(line: 4, column: 3, scope: !19)
67 !25 = distinct !{!25, !24, !26}
68 !26 = !DILocation(line: 5, column: 5, scope: !19)
69 !27 = !DILocation(line: 6, column: 3, scope: !12)
70 !28 = !DILocation(line: 7, column: 10, scope: !12)
71 !33 = !DILocation(line: 7, column: 3, scope: !12)
72 !34 = distinct !DISubprogram(name: "main", scope: !3, file: !3, line: 9, type: !13, scopeLine: 9, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !4)
73 !35 = !DILocation(line: 9, column: 14, scope: !34)
74 !36 = !DILocation(line: 9, column: 19, scope: !34)