[llvm-commits] [llvm] r141729 - in /llvm/trunk: docs/SourceLevelDebugging.html include/llvm/Analysis/DIBuilder.h include/llvm/Analysis/DebugInfo.h lib/Analysis/DIBuilder.cpp lib/Analysis/DebugInfo.cpp lib/CodeGen/AsmPrinter/DwarfDebug.cpp lib/CodeGen/LexicalScopes.cpp test/CodeGen/ARM/2009-10-16-Scope.ll test/CodeGen/X86/2009-10-16-Scope.ll test/DebugInfo/2010-01-05-DbgScope.ll

Eric Christopher echristo at apple.com
Tue Oct 11 15:59:12 PDT 2011


Author: echristo
Date: Tue Oct 11 17:59:11 2011
New Revision: 141729

URL: http://llvm.org/viewvc/llvm-project?rev=141729&view=rev
Log:
Add a new wrapper node for a DILexicalBlock that encapsulates it and a
file. Since it should only be used when necessary propagate it through
the backend code generation and tweak testcases accordingly.

This helps with code like in clang's test/CodeGen/debug-info-line.c where
we have multiple #line directives within a single lexical block and want
to generate only a single block that contains each file change.

Part of rdar://10246360

Modified:
    llvm/trunk/docs/SourceLevelDebugging.html
    llvm/trunk/include/llvm/Analysis/DIBuilder.h
    llvm/trunk/include/llvm/Analysis/DebugInfo.h
    llvm/trunk/lib/Analysis/DIBuilder.cpp
    llvm/trunk/lib/Analysis/DebugInfo.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
    llvm/trunk/lib/CodeGen/LexicalScopes.cpp
    llvm/trunk/test/CodeGen/ARM/2009-10-16-Scope.ll
    llvm/trunk/test/CodeGen/X86/2009-10-16-Scope.ll
    llvm/trunk/test/DebugInfo/2010-01-05-DbgScope.ll

Modified: llvm/trunk/docs/SourceLevelDebugging.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/SourceLevelDebugging.html?rev=141729&r1=141728&r2=141729&view=diff
==============================================================================
--- llvm/trunk/docs/SourceLevelDebugging.html (original)
+++ llvm/trunk/docs/SourceLevelDebugging.html Tue Oct 11 17:59:11 2011
@@ -472,10 +472,23 @@
 </pre>
 </div>
 
-<p>These descriptors provide debug information about nested blocks within a
+<p>This descriptor provides debug information about nested blocks within a
    subprogram. The line number and column numbers are used to dinstinguish
    two lexical blocks at same depth. </p>
 
+<div class="doc_code">
+<pre>
+!3 = metadata !{
+  i32,     ;; Tag = 11 + <a href="#LLVMDebugVersion">LLVMDebugVersion</a> (DW_TAG_lexical_block)
+  metadata ;; Reference to the scope we're annotating with a file change
+  metadata,;; Reference to the file the scope is enclosed in.
+}
+</pre>
+</div>
+
+<p>This descriptor provides a wrapper around a lexical scope to handle file
+   changes in the middle of a lexical block.</p>
+
 </div>
 
 <!-- ======================================================================= -->

Modified: llvm/trunk/include/llvm/Analysis/DIBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DIBuilder.h?rev=141729&r1=141728&r2=141729&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/DIBuilder.h (original)
+++ llvm/trunk/include/llvm/Analysis/DIBuilder.h Tue Oct 11 17:59:11 2011
@@ -37,6 +37,7 @@
   class DINameSpace;
   class DIVariable;
   class DISubrange;
+  class DILexicalBlockFile;
   class DILexicalBlock;
   class DISubprogram;
   class DITemplateTypeParameter;
@@ -463,6 +464,14 @@
                                 DIFile File, unsigned LineNo);
 
 
+    /// createLexicalBlockFile - This creates a descriptor for a lexical
+    /// block with a new file attached. This merely extends the existing
+    /// lexical block as it crosses a file.
+    /// @param Scope       Lexical block.
+    /// @param File        Source file.
+    DILexicalBlockFile createLexicalBlockFile(DIDescriptor Scope,
+					      DIFile File);
+    
     /// createLexicalBlock - This creates a descriptor for a lexical block
     /// with the specified parent context.
     /// @param Scope       Parent lexical scope.

Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DebugInfo.h?rev=141729&r1=141728&r2=141729&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/DebugInfo.h (original)
+++ llvm/trunk/include/llvm/Analysis/DebugInfo.h Tue Oct 11 17:59:11 2011
@@ -40,6 +40,7 @@
   class DIFile;
   class DISubprogram;
   class DILexicalBlock;
+  class DILexicalBlockFile;
   class DIVariable;
   class DIType;
 
@@ -84,6 +85,7 @@
     explicit DIDescriptor(const MDNode *N) : DbgNode(N) {}
     explicit DIDescriptor(const DIFile F);
     explicit DIDescriptor(const DISubprogram F);
+    explicit DIDescriptor(const DILexicalBlockFile F);
     explicit DIDescriptor(const DILexicalBlock F);
     explicit DIDescriptor(const DIVariable F);
     explicit DIDescriptor(const DIType F);
@@ -117,6 +119,7 @@
     bool isFile() const;
     bool isCompileUnit() const;
     bool isNameSpace() const;
+    bool isLexicalBlockFile() const;
     bool isLexicalBlock() const;
     bool isSubrange() const;
     bool isEnumerator() const;
@@ -699,6 +702,26 @@
     }
   };
 
+  /// DILexicalBlockFile - This is a wrapper for a lexical block with
+  /// a filename change.
+  class DILexicalBlockFile : public DIScope {
+  public:
+    explicit DILexicalBlockFile(const MDNode *N = 0) : DIScope(N) {}
+    DIScope getContext() const { return getScope().getFieldAs<DIScope>(1); }
+    unsigned getLineNumber() const { return getScope().getUnsignedField(2); }
+    unsigned getColumnNumber() const { return getScope().getUnsignedField(3); }
+    StringRef getDirectory() const {
+      StringRef dir = getFieldAs<DIFile>(2).getDirectory();
+      return !dir.empty() ? dir : getContext().getDirectory();
+    }
+    StringRef getFilename() const {
+      StringRef filename = getFieldAs<DIFile>(2).getFilename();
+      assert(!filename.empty() && "Why'd you create this then?");
+      return filename;
+    }
+    DILexicalBlock getScope() const { return getFieldAs<DILexicalBlock>(1); }
+  };
+
   /// DINameSpace - A wrapper for a C++ style name space.
   class DINameSpace : public DIScope { 
   public:

Modified: llvm/trunk/lib/Analysis/DIBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DIBuilder.cpp?rev=141729&r1=141728&r2=141729&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/DIBuilder.cpp (original)
+++ llvm/trunk/lib/Analysis/DIBuilder.cpp Tue Oct 11 17:59:11 2011
@@ -851,6 +851,18 @@
   return DINameSpace(MDNode::get(VMContext, Elts));
 }
 
+/// createLexicalBlockFile - This creates a new MDNode that encapsulates
+/// an existing scope with a new filename.
+DILexicalBlockFile DIBuilder::createLexicalBlockFile(DIDescriptor Scope,
+						     DIFile File) {
+  Value *Elts[] = {
+    GetTagConstant(VMContext, dwarf::DW_TAG_lexical_block),
+    Scope,
+    File
+  };
+  return DILexicalBlockFile(MDNode::get(VMContext, Elts));
+}
+
 DILexicalBlock DIBuilder::createLexicalBlock(DIDescriptor Scope, DIFile File,
                                              unsigned Line, unsigned Col) {
   // Defeat MDNode uniqing for lexical blocks by using unique id.

Modified: llvm/trunk/lib/Analysis/DebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DebugInfo.cpp?rev=141729&r1=141728&r2=141729&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/DebugInfo.cpp (original)
+++ llvm/trunk/lib/Analysis/DebugInfo.cpp Tue Oct 11 17:59:11 2011
@@ -39,6 +39,9 @@
 DIDescriptor::DIDescriptor(const DISubprogram F) : DbgNode(F.DbgNode) {
 }
 
+DIDescriptor::DIDescriptor(const DILexicalBlockFile F) : DbgNode(F.DbgNode) {
+}
+
 DIDescriptor::DIDescriptor(const DILexicalBlock F) : DbgNode(F.DbgNode) {
 }
 
@@ -263,9 +266,17 @@
   return DbgNode && getTag() == dwarf::DW_TAG_namespace;
 }
 
+/// isLexicalBlockFile - Return true if the specified descriptor is a
+/// lexical block with an extra file.
+bool DIDescriptor::isLexicalBlockFile() const {
+  return DbgNode && getTag() == dwarf::DW_TAG_lexical_block &&
+    (DbgNode->getNumOperands() == 3);
+}
+
 /// isLexicalBlock - Return true if the specified tag is DW_TAG_lexical_block.
 bool DIDescriptor::isLexicalBlock() const {
-  return DbgNode && getTag() == dwarf::DW_TAG_lexical_block;
+  return DbgNode && getTag() == dwarf::DW_TAG_lexical_block &&
+    (DbgNode->getNumOperands() > 3);
 }
 
 /// isSubrange - Return true if the specified tag is DW_TAG_subrange_type.
@@ -540,6 +551,8 @@
 StringRef DIScope::getFilename() const {
   if (!DbgNode)
     return StringRef();
+  if (isLexicalBlockFile())
+    return DILexicalBlockFile(DbgNode).getFilename();
   if (isLexicalBlock())
     return DILexicalBlock(DbgNode).getFilename();
   if (isSubprogram())
@@ -559,6 +572,8 @@
 StringRef DIScope::getDirectory() const {
   if (!DbgNode)
     return StringRef();
+  if (isLexicalBlockFile())
+    return DILexicalBlockFile(DbgNode).getDirectory();
   if (isLexicalBlock())
     return DILexicalBlock(DbgNode).getDirectory();
   if (isSubprogram())
@@ -934,6 +949,10 @@
           addCompileUnit(DICompileUnit(Scope));
         else if (Scope.isSubprogram())
           processSubprogram(DISubprogram(Scope));
+        else if (Scope.isLexicalBlockFile()) {
+          DILexicalBlockFile DBF = DILexicalBlockFile(Scope);
+          processLexicalBlock(DILexicalBlock(DBF.getScope()));
+        }
         else if (Scope.isLexicalBlock())
           processLexicalBlock(DILexicalBlock(Scope));
 
@@ -967,6 +986,10 @@
     processSubprogram(DISubprogram(S));
   else if (S.isLexicalBlock())
     processLexicalBlock(DILexicalBlock(S));
+  else if (S.isLexicalBlockFile()) {
+    DILexicalBlockFile DBF = DILexicalBlockFile(S);
+    processLexicalBlock(DILexicalBlock(DBF.getScope()));
+  }
   processLocation(Loc.getOrigLocation());
 }
 
@@ -998,6 +1021,10 @@
   DIScope Context = LB.getContext();
   if (Context.isLexicalBlock())
     return processLexicalBlock(DILexicalBlock(Context));
+  else if (Context.isLexicalBlockFile()) {
+    DILexicalBlockFile DBF = DILexicalBlockFile(Context);
+    return processLexicalBlock(DILexicalBlock(DBF.getScope()));
+  }
   else
     return processSubprogram(DISubprogram(Context));
 }
@@ -1081,6 +1108,9 @@
   if (D.isSubprogram())
     return DISubprogram(Scope);
 
+  if (D.isLexicalBlockFile())
+    return getDISubprogram(DILexicalBlockFile(Scope).getContext());
+  
   if (D.isLexicalBlock())
     return getDISubprogram(DILexicalBlock(Scope).getContext());
 

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=141729&r1=141728&r2=141729&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Tue Oct 11 17:59:11 2011
@@ -1371,6 +1371,10 @@
       DISubprogram SP(S);
       Fn = SP.getFilename();
       Dir = SP.getDirectory();
+    } else if (Scope.isLexicalBlockFile()) {
+      DILexicalBlockFile DBF(S);
+      Fn = DBF.getFilename();
+      Dir = DBF.getDirectory();
     } else if (Scope.isLexicalBlock()) {
       DILexicalBlock DB(S);
       Fn = DB.getFilename();

Modified: llvm/trunk/lib/CodeGen/LexicalScopes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LexicalScopes.cpp?rev=141729&r1=141728&r2=141729&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LexicalScopes.cpp (original)
+++ llvm/trunk/lib/CodeGen/LexicalScopes.cpp Tue Oct 11 17:59:11 2011
@@ -118,9 +118,16 @@
   MDNode *IA = NULL;
   DL.getScopeAndInlinedAt(Scope, IA, MF->getFunction()->getContext());
   if (!Scope) return NULL;
+
+  // The scope that we were created with could have an extra file - which
+  // isn't what we care about in this case.
+  DIDescriptor D = DIDescriptor(Scope);
+  if (D.isLexicalBlockFile())
+    Scope = DILexicalBlockFile(Scope).getScope();
+  
   if (IA)
     return InlinedLexicalScopeMap.lookup(DebugLoc::getFromDILocation(IA));
-  return LexicalScopeMap.lookup(DL.getScope(Scope->getContext()));
+  return LexicalScopeMap.lookup(Scope);
 }
 
 /// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If
@@ -129,6 +136,7 @@
   MDNode *Scope = NULL;
   MDNode *InlinedAt = NULL;
   DL.getScopeAndInlinedAt(Scope, InlinedAt, MF->getFunction()->getContext());
+
   if (InlinedAt) {
     // Create an abstract scope for inlined function.
     getOrCreateAbstractScope(Scope);
@@ -141,12 +149,16 @@
 
 /// getOrCreateRegularScope - Find or create a regular lexical scope.
 LexicalScope *LexicalScopes::getOrCreateRegularScope(MDNode *Scope) {
+  DIDescriptor D = DIDescriptor(Scope);
+  if (D.isLexicalBlockFile())
+    Scope = DILexicalBlockFile(Scope).getScope();
+ 
   LexicalScope *WScope = LexicalScopeMap.lookup(Scope);
   if (WScope)
     return WScope;
 
   LexicalScope *Parent = NULL;
-  if (DIDescriptor(Scope).isLexicalBlock())
+  if (D.isLexicalBlock())
     Parent = getOrCreateLexicalScope(DebugLoc::getFromDILexicalBlock(Scope));
   WScope = new LexicalScope(Parent, DIDescriptor(Scope), NULL, false);
   LexicalScopeMap.insert(std::make_pair(Scope, WScope));
@@ -176,12 +188,14 @@
 LexicalScope *LexicalScopes::getOrCreateAbstractScope(const MDNode *N) {
   assert(N && "Invalid Scope encoding!");
 
+  DIDescriptor Scope(N);
+  if (Scope.isLexicalBlockFile())
+    Scope = DILexicalBlockFile(Scope).getScope();
   LexicalScope *AScope = AbstractScopeMap.lookup(N);
   if (AScope)
     return AScope;
 
   LexicalScope *Parent = NULL;
-  DIDescriptor Scope(N);
   if (Scope.isLexicalBlock()) {
     DILexicalBlock DB(N);
     DIDescriptor ParentDesc = DB.getContext();

Modified: llvm/trunk/test/CodeGen/ARM/2009-10-16-Scope.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2009-10-16-Scope.ll?rev=141729&r1=141728&r2=141729&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/2009-10-16-Scope.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/2009-10-16-Scope.ll Tue Oct 11 17:59:11 2011
@@ -23,10 +23,10 @@
 declare i32 @foo(i32) ssp
 
 !0 = metadata !{i32 5, i32 2, metadata !1, null}
-!1 = metadata !{i32 458763, metadata !2}; [DW_TAG_lexical_block ]
+!1 = metadata !{i32 458763, metadata !2, i32 1, i32 1}; [DW_TAG_lexical_block ]
 !2 = metadata !{i32 458798, i32 0, metadata !3, metadata !"bar", metadata !"bar", metadata !"bar", metadata !3, i32 4, null, i1 false, i1 true}; [DW_TAG_subprogram ]
 !3 = metadata !{i32 458769, i32 0, i32 12, metadata !"genmodes.i", metadata !"/Users/yash/Downloads", metadata !"clang 1.1", i1 true, i1 false, metadata !"", i32 0}; [DW_TAG_compile_unit ]
 !4 = metadata !{i32 459008, metadata !5, metadata !"count_", metadata !3, i32 5, metadata !6}; [ DW_TAG_auto_variable ]
-!5 = metadata !{i32 458763, metadata !1}; [DW_TAG_lexical_block ]
+!5 = metadata !{i32 458763, metadata !1, i32 1, i32 1}; [DW_TAG_lexical_block ]
 !6 = metadata !{i32 458788, metadata !3, metadata !"int", metadata !3, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5}; [DW_TAG_base_type ]
 !7 = metadata !{i32 6, i32 1, metadata !2, null}

Modified: llvm/trunk/test/CodeGen/X86/2009-10-16-Scope.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2009-10-16-Scope.ll?rev=141729&r1=141728&r2=141729&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/2009-10-16-Scope.ll (original)
+++ llvm/trunk/test/CodeGen/X86/2009-10-16-Scope.ll Tue Oct 11 17:59:11 2011
@@ -23,10 +23,10 @@
 declare i32 @foo(i32) ssp
 
 !0 = metadata !{i32 5, i32 2, metadata !1, null}
-!1 = metadata !{i32 458763, metadata !2}; [DW_TAG_lexical_block ]
+!1 = metadata !{i32 458763, metadata !2, i32 1, i32 1}; [DW_TAG_lexical_block ]
 !2 = metadata !{i32 458798, i32 0, metadata !3, metadata !"bar", metadata !"bar", metadata !"bar", metadata !3, i32 4, null, i1 false, i1 true}; [DW_TAG_subprogram ]
 !3 = metadata !{i32 458769, i32 0, i32 12, metadata !"genmodes.i", metadata !"/Users/yash/Downloads", metadata !"clang 1.1", i1 true, i1 false, metadata !"", i32 0}; [DW_TAG_compile_unit ]
 !4 = metadata !{i32 459008, metadata !5, metadata !"count_", metadata !3, i32 5, metadata !6}; [ DW_TAG_auto_variable ]
-!5 = metadata !{i32 458763, metadata !1}; [DW_TAG_lexical_block ]
+!5 = metadata !{i32 458763, metadata !1, i32 1, i32 1}; [DW_TAG_lexical_block ]
 !6 = metadata !{i32 458788, metadata !3, metadata !"int", metadata !3, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5}; [DW_TAG_base_type ]
 !7 = metadata !{i32 6, i32 1, metadata !2, null}

Modified: llvm/trunk/test/DebugInfo/2010-01-05-DbgScope.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/2010-01-05-DbgScope.ll?rev=141729&r1=141728&r2=141729&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/2010-01-05-DbgScope.ll (original)
+++ llvm/trunk/test/DebugInfo/2010-01-05-DbgScope.ll Tue Oct 11 17:59:11 2011
@@ -9,7 +9,7 @@
 }
 
 !0 = metadata !{i32 571, i32 3, metadata !1, null}
-!1 = metadata !{i32 458763, metadata !2}; [DW_TAG_lexical_block ]
+!1 = metadata !{i32 458763, metadata !2, i32 1, i32 1}; [DW_TAG_lexical_block ]
 !2 = metadata !{i32 458798, i32 0, metadata !3, metadata !"foo", metadata !"foo", metadata !"foo", metadata !3, i32 561, metadata !4, i1 false, i1 true}; [DW_TAG_subprogram ]
 !3 = metadata !{i32 458769, i32 0, i32 12, metadata !"hashtab.c", metadata !"/usr/src/gnu/usr.bin/cc/cc_tools/../../../../contrib/gcclibs/libiberty", metadata !"clang 1.1", i1 true, i1 false, metadata !"", i32 0}; [DW_TAG_compile_unit ]
 !4 = metadata !{i32 458773, metadata !3, metadata !"", null, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !5, i32 0}; [DW_TAG_subroutine_type ]





More information about the llvm-commits mailing list