llvm.org GIT mirror llvm / d848744
add-discriminators: Fix handling of lexical scopes. This fixes a bug in the handling of lexical scopes, when more than one scope is defined on the same line or functions are inlined into call sites that are on the same line as the function definition. This situation can easily happen in macro expansions. The problem is solved by introducing a SmallDenseMap<DIScope *, DILexicalBlockFile *, 1> that keeps track of all the different lexical scopes that share a line/file location. Fixes PR30681. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@284998 91177308-0d34-0410-b5e6-96231b3b80d8 Adrian Prantl 2 years ago
3 changed file(s) with 105 addition(s) and 13 deletion(s). Raw diff Collapse all Expand all
167167 DIBuilder Builder(*M, /*AllowUnresolved*/ false);
168168
169169 typedef std::pair Location;
170 typedef DenseMap BBScopeMap;
170 typedef SmallDenseMap ScopeMap;
171 typedef DenseMap BBScopeMap;
171172 typedef DenseMap LocationBBMap;
172173 typedef DenseMap LocationDiscriminatorMap;
173174 typedef DenseSet LocationSet;
185186 const DILocation *DIL = I.getDebugLoc();
186187 if (!DIL)
187188 continue;
189 DIScope *Scope = DIL->getScope();
188190 Location L = std::make_pair(DIL->getFilename(), DIL->getLine());
189191 auto &BBMap = LBM[L];
190 auto R = BBMap.insert(std::make_pair(&B, (Metadata *)nullptr));
192 auto R = BBMap.insert({&B, ScopeMap()});
191193 if (BBMap.size() == 1)
192194 continue;
193195 bool InsertSuccess = R.second;
194 Metadata *&NewScope = R.first->second;
195 // If we could insert a different block in the same location, a
196 ScopeMap &Scopes = R.first->second;
197 // If we could insert more than one block with the same line+file, a
196198 // discriminator is needed to distinguish both instructions.
197 if (InsertSuccess) {
198 auto *Scope = DIL->getScope();
199 auto *File =
200 Builder.createFile(DIL->getFilename(), Scope->getDirectory());
201 NewScope = Builder.createLexicalBlockFile(Scope, File, ++LDM[L]);
199 auto R1 = Scopes.insert({Scope, nullptr});
200 DILexicalBlockFile *&NewScope = R1.first->second;
201 unsigned Discriminator = InsertSuccess ? ++LDM[L] : LDM[L];
202 if (!NewScope) {
203 auto *File = Builder.createFile(DIL->getFilename(),
204 Scope->getDirectory());
205 NewScope = Builder.createLexicalBlockFile(Scope, File, Discriminator);
202206 }
203207 I.setDebugLoc(DILocation::get(Ctx, DIL->getLine(), DIL->getColumn(),
204208 NewScope, DIL->getInlinedAt()));
0 ; RUN: opt < %s -add-discriminators -S | FileCheck %s
1 ;
2 ; Generated at -O3 from:
3 ; g();f(){for(;;){g();}}g(){__builtin___memset_chk(0,0,0,__builtin_object_size(1,0));}
4 ; The fact that everything is on one line is significant!
5 ;
6 ; This test ensures that inline info isn't dropped even if the call site and the
7 ; inlined function are defined on the same line.
8 source_filename = "t.c"
9 target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
10 target triple = "arm64-apple-ios"
11
12 ; Function Attrs: noreturn nounwind ssp
13 define i32 @f() local_unnamed_addr #0 !dbg !7 {
14 entry:
15 %0 = tail call i64 @llvm.objectsize.i64.p0i8(i8* inttoptr (i64 1 to i8*), i1 false) #2, !dbg !11
16 br label %for.cond, !dbg !18
17
18 for.cond: ; preds = %for.cond, %entry
19 ; CHECK: %call.i
20 %call.i = tail call i8* @__memset_chk(i8* null, i32 0, i64 0, i64 %0) #2, !dbg !19
21 ; CHECK: br label %for.cond, !dbg ![[BR:[0-9]+]]
22 br label %for.cond, !dbg !20, !llvm.loop !21
23 }
24
25 ; Function Attrs: nounwind ssp
26 define i32 @g() local_unnamed_addr #1 !dbg !12 {
27 entry:
28 %0 = tail call i64 @llvm.objectsize.i64.p0i8(i8* inttoptr (i64 1 to i8*), i1 false), !dbg !22
29 %call = tail call i8* @__memset_chk(i8* null, i32 0, i64 0, i64 %0) #2, !dbg !23
30 ret i32 undef, !dbg !24
31 }
32
33 ; Function Attrs: nounwind
34 declare i8* @__memset_chk(i8*, i32, i64, i64) local_unnamed_addr #2
35
36 ; Function Attrs: nounwind readnone
37 declare i64 @llvm.objectsize.i64.p0i8(i8*, i1) #3
38
39 attributes #0 = { noreturn nounwind ssp }
40 attributes #1 = { nounwind ssp }
41 attributes #2 = { nounwind }
42 attributes #3 = { nounwind readnone }
43
44 !llvm.dbg.cu = !{!0}
45 !llvm.module.flags = !{!3, !4, !5}
46 !llvm.ident = !{!6}
47
48 !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "LLVM version 4.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
49 !1 = !DIFile(filename: "t.c", directory: "/")
50 !2 = !{}
51 !3 = !{i32 2, !"Dwarf Version", i32 4}
52 !4 = !{i32 2, !"Debug Info Version", i32 3}
53 !5 = !{i32 1, !"PIC Level", i32 2}
54 !6 = !{!"LLVM version 4.0.0"}
55 ; CHECK: ![[F:.*]] = distinct !DISubprogram(name: "f",
56 !7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: true, unit: !0, variables: !2)
57 !8 = !DISubroutineType(types: !9)
58 !9 = !{!10}
59 !10 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
60 !11 = !DILocation(line: 1, column: 56, scope: !12, inlinedAt: !13)
61 !12 = distinct !DISubprogram(name: "g", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: true, unit: !0, variables: !2)
62 !13 = distinct !DILocation(line: 1, column: 17, scope: !14)
63 ; CHECK: ![[BF:.*]] = !DILexicalBlockFile(scope: ![[LB1:[0-9]+]],
64 ; CHECK-SAME: discriminator: 1)
65 !14 = !DILexicalBlockFile(scope: !15, file: !1, discriminator: 1)
66 ; CHECK: ![[LB1]] = distinct !DILexicalBlock(scope: ![[LB2:[0-9]+]],
67 ; CHECK-SAME: line: 1, column: 16)
68 !15 = distinct !DILexicalBlock(scope: !16, file: !1, line: 1, column: 16)
69 ; CHECK: ![[LB2]] = distinct !DILexicalBlock(scope: ![[LB3:[0-9]+]],
70 ; CHECK-SAME: line: 1, column: 9)
71 !16 = distinct !DILexicalBlock(scope: !17, file: !1, line: 1, column: 9)
72 ; CHECK: ![[LB3]] = distinct !DILexicalBlock(scope: ![[F]],
73 ; CHECK-SAME: line: 1, column: 9)
74 !17 = distinct !DILexicalBlock(scope: !7, file: !1, line: 1, column: 9)
75 !18 = !DILocation(line: 1, column: 9, scope: !7)
76 !19 = !DILocation(line: 1, column: 27, scope: !12, inlinedAt: !13)
77 ; CHECK: ![[BR]] = !DILocation(line: 1, column: 9, scope: ![[BF2:[0-9]+]])
78 ; CHECK: ![[BF2]] = !DILexicalBlockFile(scope: ![[BF]],
79 ; CHECK-SAME: discriminator: 1)
80 !20 = !DILocation(line: 1, column: 9, scope: !14)
81 !21 = distinct !{!21, !18}
82 !22 = !DILocation(line: 1, column: 56, scope: !12)
83 !23 = !DILocation(line: 1, column: 27, scope: !12)
84 !24 = !DILocation(line: 1, column: 84, scope: !12)
8787 !27 = !DILocation(line: 2, column: 42, scope: !20)
8888 !28 = !DILocation(line: 3, column: 1, scope: !4)
8989
90 ; CHECK: ![[F:.*]] = distinct !DISubprogram(name: "foo",
91 ; CHECK: ![[IF:.*]] = distinct !DILexicalBlock(scope: ![[F]],{{.*}}line: 2, column: 7)
9092 ; CHECK: ![[THEN1]] = !DILocation(line: 2, column: 17, scope: ![[THENBLOCK:[0-9]+]])
91 ; CHECK: ![[THENBLOCK]] = !DILexicalBlockFile({{.*}} discriminator: 1)
93 ; CHECK: ![[THENBLOCK]] = !DILexicalBlockFile(scope: ![[IF]],{{.*}} discriminator: 1)
9294 ; CHECK: ![[THEN2]] = !DILocation(line: 2, column: 19, scope: ![[THENBLOCK]])
93 ; CHECK: ![[THEN3]] = !DILocation(line: 2, column: 7, scope: ![[THENBLOCK]])
95 ; CHECK: ![[THEN3]] = !DILocation(line: 2, column: 7, scope: ![[BRBLOCK:[0-9]+]])
96 ; CHECK: ![[BRBLOCK]] = !DILexicalBlockFile(scope: ![[F]],{{.*}} discriminator: 1)
9497 ; CHECK: ![[ELSE]] = !DILocation(line: 2, column: 25, scope: ![[ELSEBLOCK:[0-9]+]])
95 ; CHECK: ![[ELSEBLOCK]] = !DILexicalBlockFile({{.*}} discriminator: 2)
98 ; CHECK: ![[ELSEBLOCK]] = !DILexicalBlockFile(scope: ![[IF]],{{.*}} discriminator: 2)
9699 ; CHECK: ![[COMBINE]] = !DILocation(line: 2, column: 42, scope: ![[COMBINEBLOCK:[0-9]+]])
97 ; CHECK: ![[COMBINEBLOCK]] = !DILexicalBlockFile({{.*}} discriminator: 3)
100 ; CHECK: ![[COMBINEBLOCK]] = !DILexicalBlockFile(scope: ![[IF]],{{.*}} discriminator: 3)