[llvm] r284998 - add-discriminators: Fix handling of lexical scopes.

Adrian Prantl via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 24 11:23:52 PDT 2016


Author: adrian
Date: Mon Oct 24 13:23:51 2016
New Revision: 284998

URL: http://llvm.org/viewvc/llvm-project?rev=284998&view=rev
Log:
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.

Added:
    llvm/trunk/test/Transforms/AddDiscriminators/inlined.ll
Modified:
    llvm/trunk/lib/Transforms/Utils/AddDiscriminators.cpp
    llvm/trunk/test/Transforms/AddDiscriminators/oneline.ll

Modified: llvm/trunk/lib/Transforms/Utils/AddDiscriminators.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/AddDiscriminators.cpp?rev=284998&r1=284997&r2=284998&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/AddDiscriminators.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/AddDiscriminators.cpp Mon Oct 24 13:23:51 2016
@@ -168,7 +168,8 @@ static bool addDiscriminators(Function &
   DIBuilder Builder(*M, /*AllowUnresolved*/ false);
 
   typedef std::pair<StringRef, unsigned> Location;
-  typedef DenseMap<const BasicBlock *, Metadata *> BBScopeMap;
+  typedef SmallDenseMap<DIScope *, DILexicalBlockFile *, 1> ScopeMap;
+  typedef DenseMap<const BasicBlock *, ScopeMap> BBScopeMap;
   typedef DenseMap<Location, BBScopeMap> LocationBBMap;
   typedef DenseMap<Location, unsigned> LocationDiscriminatorMap;
   typedef DenseSet<Location> LocationSet;
@@ -186,20 +187,23 @@ static bool addDiscriminators(Function &
       const DILocation *DIL = I.getDebugLoc();
       if (!DIL)
         continue;
+      DIScope *Scope = DIL->getScope();
       Location L = std::make_pair(DIL->getFilename(), DIL->getLine());
       auto &BBMap = LBM[L];
-      auto R = BBMap.insert(std::make_pair(&B, (Metadata *)nullptr));
+      auto R = BBMap.insert({&B, ScopeMap()});
       if (BBMap.size() == 1)
         continue;
       bool InsertSuccess = R.second;
-      Metadata *&NewScope = R.first->second;
-      // If we could insert a different block in the same location, a
+      ScopeMap &Scopes = R.first->second; 
+      // If we could insert more than one block with the same line+file, a
       // discriminator is needed to distinguish both instructions.
-      if (InsertSuccess) {
-        auto *Scope = DIL->getScope();
-        auto *File =
-            Builder.createFile(DIL->getFilename(), Scope->getDirectory());
-        NewScope = Builder.createLexicalBlockFile(Scope, File, ++LDM[L]);
+      auto R1 = Scopes.insert({Scope, nullptr});
+      DILexicalBlockFile *&NewScope = R1.first->second;
+      unsigned Discriminator = InsertSuccess ? ++LDM[L] : LDM[L];
+      if (!NewScope) {
+        auto *File = Builder.createFile(DIL->getFilename(),
+                                        Scope->getDirectory());
+        NewScope = Builder.createLexicalBlockFile(Scope, File, Discriminator);
       }
       I.setDebugLoc(DILocation::get(Ctx, DIL->getLine(), DIL->getColumn(),
                                     NewScope, DIL->getInlinedAt()));

Added: llvm/trunk/test/Transforms/AddDiscriminators/inlined.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/AddDiscriminators/inlined.ll?rev=284998&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/AddDiscriminators/inlined.ll (added)
+++ llvm/trunk/test/Transforms/AddDiscriminators/inlined.ll Mon Oct 24 13:23:51 2016
@@ -0,0 +1,85 @@
+; RUN: opt < %s -add-discriminators -S | FileCheck %s
+;
+; Generated at -O3 from:
+; g();f(){for(;;){g();}}g(){__builtin___memset_chk(0,0,0,__builtin_object_size(1,0));}
+; The fact that everything is on one line is significant!
+;
+; This test ensures that inline info isn't dropped even if the call site and the
+; inlined function are defined on the same line.
+source_filename = "t.c"
+target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+target triple = "arm64-apple-ios"
+
+; Function Attrs: noreturn nounwind ssp
+define i32 @f() local_unnamed_addr #0 !dbg !7 {
+entry:
+  %0 = tail call i64 @llvm.objectsize.i64.p0i8(i8* inttoptr (i64 1 to i8*), i1 false) #2, !dbg !11
+  br label %for.cond, !dbg !18
+
+for.cond:                                         ; preds = %for.cond, %entry
+  ; CHECK: %call.i
+  %call.i = tail call i8* @__memset_chk(i8* null, i32 0, i64 0, i64 %0) #2, !dbg !19 
+  ; CHECK: br label %for.cond, !dbg ![[BR:[0-9]+]]
+  br label %for.cond, !dbg !20, !llvm.loop !21
+}
+
+; Function Attrs: nounwind ssp
+define i32 @g() local_unnamed_addr #1 !dbg !12 {
+entry:
+  %0 = tail call i64 @llvm.objectsize.i64.p0i8(i8* inttoptr (i64 1 to i8*), i1 false), !dbg !22
+  %call = tail call i8* @__memset_chk(i8* null, i32 0, i64 0, i64 %0) #2, !dbg !23
+  ret i32 undef, !dbg !24
+}
+
+; Function Attrs: nounwind
+declare i8* @__memset_chk(i8*, i32, i64, i64) local_unnamed_addr #2
+
+; Function Attrs: nounwind readnone
+declare i64 @llvm.objectsize.i64.p0i8(i8*, i1) #3
+
+attributes #0 = { noreturn nounwind ssp }
+attributes #1 = { nounwind ssp  }
+attributes #2 = { nounwind }
+attributes #3 = { nounwind readnone }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "LLVM version 4.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+!1 = !DIFile(filename: "t.c", directory: "/")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 4}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"PIC Level", i32 2}
+!6 = !{!"LLVM version 4.0.0"}
+; CHECK: ![[F:.*]] = distinct !DISubprogram(name: "f",
+!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)
+!8 = !DISubroutineType(types: !9)
+!9 = !{!10}
+!10 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
+!11 = !DILocation(line: 1, column: 56, scope: !12, inlinedAt: !13)
+!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)
+!13 = distinct !DILocation(line: 1, column: 17, scope: !14)
+; CHECK: ![[BF:.*]] = !DILexicalBlockFile(scope: ![[LB1:[0-9]+]],
+; CHECK-SAME:                             discriminator: 1)
+!14 = !DILexicalBlockFile(scope: !15, file: !1, discriminator: 1)
+; CHECK: ![[LB1]] = distinct !DILexicalBlock(scope: ![[LB2:[0-9]+]],
+; CHECK-SAME:                                line: 1, column: 16)
+!15 = distinct !DILexicalBlock(scope: !16, file: !1, line: 1, column: 16)
+; CHECK: ![[LB2]] = distinct !DILexicalBlock(scope: ![[LB3:[0-9]+]],
+; CHECK-SAME:                                line: 1, column: 9)
+!16 = distinct !DILexicalBlock(scope: !17, file: !1, line: 1, column: 9)
+; CHECK: ![[LB3]] = distinct !DILexicalBlock(scope: ![[F]],
+; CHECK-SAME:                                line: 1, column: 9)
+!17 = distinct !DILexicalBlock(scope: !7, file: !1, line: 1, column: 9)
+!18 = !DILocation(line: 1, column: 9, scope: !7)
+!19 = !DILocation(line: 1, column: 27, scope: !12, inlinedAt: !13)
+; CHECK: ![[BR]] =  !DILocation(line: 1, column: 9, scope: ![[BF2:[0-9]+]])
+; CHECK: ![[BF2]] = !DILexicalBlockFile(scope: ![[BF]],
+; CHECK-SAME:                           discriminator: 1)
+!20 = !DILocation(line: 1, column: 9, scope: !14)
+!21 = distinct !{!21, !18}
+!22 = !DILocation(line: 1, column: 56, scope: !12)
+!23 = !DILocation(line: 1, column: 27, scope: !12)
+!24 = !DILocation(line: 1, column: 84, scope: !12)

Modified: llvm/trunk/test/Transforms/AddDiscriminators/oneline.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/AddDiscriminators/oneline.ll?rev=284998&r1=284997&r2=284998&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/AddDiscriminators/oneline.ll (original)
+++ llvm/trunk/test/Transforms/AddDiscriminators/oneline.ll Mon Oct 24 13:23:51 2016
@@ -88,11 +88,14 @@ attributes #1 = { nounwind readnone }
 !27 = !DILocation(line: 2, column: 42, scope: !20)
 !28 = !DILocation(line: 3, column: 1, scope: !4)
 
+; CHECK: ![[F:.*]] = distinct !DISubprogram(name: "foo",
+; CHECK: ![[IF:.*]] = distinct !DILexicalBlock(scope: ![[F]],{{.*}}line: 2, column: 7)
 ; CHECK: ![[THEN1]] = !DILocation(line: 2, column: 17, scope: ![[THENBLOCK:[0-9]+]])
-; CHECK: ![[THENBLOCK]] = !DILexicalBlockFile({{.*}} discriminator: 1)
+; CHECK: ![[THENBLOCK]] = !DILexicalBlockFile(scope: ![[IF]],{{.*}} discriminator: 1)
 ; CHECK: ![[THEN2]] = !DILocation(line: 2, column: 19, scope: ![[THENBLOCK]])
-; CHECK: ![[THEN3]] = !DILocation(line: 2, column: 7, scope: ![[THENBLOCK]])
+; CHECK: ![[THEN3]] = !DILocation(line: 2, column: 7, scope: ![[BRBLOCK:[0-9]+]])
+; CHECK: ![[BRBLOCK]] = !DILexicalBlockFile(scope: ![[F]],{{.*}} discriminator: 1)
 ; CHECK: ![[ELSE]] = !DILocation(line: 2, column: 25, scope: ![[ELSEBLOCK:[0-9]+]])
-; CHECK: ![[ELSEBLOCK]] = !DILexicalBlockFile({{.*}} discriminator: 2)
+; CHECK: ![[ELSEBLOCK]] = !DILexicalBlockFile(scope: ![[IF]],{{.*}} discriminator: 2)
 ; CHECK: ![[COMBINE]] = !DILocation(line: 2, column: 42, scope: ![[COMBINEBLOCK:[0-9]+]])
-; CHECK: ![[COMBINEBLOCK]] = !DILexicalBlockFile({{.*}} discriminator: 3)
+; CHECK: ![[COMBINEBLOCK]] = !DILexicalBlockFile(scope: ![[IF]],{{.*}} discriminator: 3)




More information about the llvm-commits mailing list