Add the loop end location to the loop metadata. This additional information
authorAmara Emerson <amara.emerson@arm.com>
Thu, 10 Nov 2016 14:44:30 +0000 (14:44 +0000)
committerAmara Emerson <amara.emerson@arm.com>
Thu, 10 Nov 2016 14:44:30 +0000 (14:44 +0000)
can be used to improve the locations when generating remarks for loops.

Depends on the companion LLVM change r286227.

Patch by Florian Hahn.

Differential Revision: https://reviews.llvm.org/D25764

llvm-svn: 286456

clang/lib/CodeGen/CGDebugInfo.cpp
clang/lib/CodeGen/CGDebugInfo.h
clang/lib/CodeGen/CGLoopInfo.cpp
clang/lib/CodeGen/CGLoopInfo.h
clang/lib/CodeGen/CGStmt.cpp
clang/lib/CodeGen/CGStmtOpenMP.cpp
clang/lib/CodeGen/CodeGenFunction.cpp
clang/lib/CodeGen/CodeGenFunction.h
clang/test/CodeGenCXX/debug-info-line-if.cpp
clang/test/CodeGenCXX/debug-info-loops.cpp [new file with mode: 0644]

index ef4fb06..f2f1918 100644 (file)
@@ -3924,3 +3924,12 @@ void CGDebugInfo::EmitExplicitCastType(QualType Ty) {
     // Don't ignore in case of explicit cast where it is referenced indirectly.
     DBuilder.retainType(DieTy);
 }
+
+llvm::DebugLoc CGDebugInfo::SourceLocToDebugLoc(SourceLocation Loc) {
+  if (LexicalBlockStack.empty())
+    return llvm::DebugLoc();
+
+  llvm::MDNode *Scope = LexicalBlockStack.back();
+  return llvm::DebugLoc::get(
+          getLineNumber(Loc), getColumnNumber(Loc), Scope);
+}
index f43261a..4cf7bb3 100644 (file)
@@ -320,6 +320,9 @@ public:
   /// ignored.
   void setLocation(SourceLocation Loc);
 
+  // Converts a SourceLocation to a DebugLoc
+  llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Loc);
+
   /// Emit metadata to indicate a change in line/column information in
   /// the source file. If the location is invalid, the previous
   /// location will be reused.
index 62ee571..7e44c9f 100644 (file)
@@ -20,14 +20,14 @@ using namespace clang::CodeGen;
 using namespace llvm;
 
 static MDNode *createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs,
-                              llvm::DebugLoc Location) {
+                              llvm::DebugLoc StartLoc, llvm::DebugLoc EndLoc) {
 
   if (!Attrs.IsParallel && Attrs.VectorizeWidth == 0 &&
       Attrs.InterleaveCount == 0 && Attrs.UnrollCount == 0 &&
       Attrs.VectorizeEnable == LoopAttributes::Unspecified &&
       Attrs.UnrollEnable == LoopAttributes::Unspecified &&
       Attrs.DistributeEnable == LoopAttributes::Unspecified &&
-      !Location)
+      !StartLoc && !EndLoc)
     return nullptr;
 
   SmallVector<Metadata *, 4> Args;
@@ -35,9 +35,14 @@ static MDNode *createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs,
   auto TempNode = MDNode::getTemporary(Ctx, None);
   Args.push_back(TempNode.get());
 
-  // If we have a valid debug location for the loop, add it.
-  if (Location)
-    Args.push_back(Location.getAsMDNode());
+  // If we have a valid start debug location for the loop, add it.
+  if (StartLoc) {
+    Args.push_back(StartLoc.getAsMDNode());
+
+    // If we also have a valid end debug location for the loop, add it.
+    if (EndLoc)
+      Args.push_back(EndLoc.getAsMDNode());
+  }
 
   // Setting vectorize.width
   if (Attrs.VectorizeWidth > 0) {
@@ -116,20 +121,21 @@ void LoopAttributes::clear() {
 }
 
 LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs,
-                   llvm::DebugLoc Location)
+                   llvm::DebugLoc StartLoc, llvm::DebugLoc EndLoc)
     : LoopID(nullptr), Header(Header), Attrs(Attrs) {
-  LoopID = createMetadata(Header->getContext(), Attrs, Location);
+  LoopID = createMetadata(Header->getContext(), Attrs, StartLoc, EndLoc);
 }
 
-void LoopInfoStack::push(BasicBlock *Header, llvm::DebugLoc Location) {
-  Active.push_back(LoopInfo(Header, StagedAttrs, Location));
+void LoopInfoStack::push(BasicBlock *Header, llvm::DebugLoc StartLoc,
+                         llvm::DebugLoc EndLoc) {
+  Active.push_back(LoopInfo(Header, StagedAttrs, StartLoc, EndLoc));
   // Clear the attributes so nested loops do not inherit them.
   StagedAttrs.clear();
 }
 
 void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx,
                          ArrayRef<const clang::Attr *> Attrs,
-                         llvm::DebugLoc Location) {
+                         llvm::DebugLoc StartLoc, llvm::DebugLoc EndLoc) {
 
   // Identify loop hint attributes from Attrs.
   for (const auto *Attr : Attrs) {
@@ -267,7 +273,7 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx,
   }
 
   /// Stage the attributes.
-  push(Header, Location);
+  push(Header, StartLoc, EndLoc);
 }
 
 void LoopInfoStack::pop() {
index 76a039d..e2c9770 100644 (file)
@@ -67,7 +67,7 @@ class LoopInfo {
 public:
   /// \brief Construct a new LoopInfo for the loop with entry Header.
   LoopInfo(llvm::BasicBlock *Header, const LoopAttributes &Attrs,
-           llvm::DebugLoc Location);
+           llvm::DebugLoc StartLoc, llvm::DebugLoc EndLoc);
 
   /// \brief Get the loop id metadata for this loop.
   llvm::MDNode *getLoopID() const { return LoopID; }
@@ -99,14 +99,14 @@ public:
 
   /// \brief Begin a new structured loop. The set of staged attributes will be
   /// applied to the loop and then cleared.
-  void push(llvm::BasicBlock *Header,
-            llvm::DebugLoc Location = llvm::DebugLoc());
+  void push(llvm::BasicBlock *Header, llvm::DebugLoc StartLoc,
+            llvm::DebugLoc EndLoc);
 
   /// \brief Begin a new structured loop. Stage attributes from the Attrs list.
   /// The staged attributes are applied to the loop and then cleared.
   void push(llvm::BasicBlock *Header, clang::ASTContext &Ctx,
-            llvm::ArrayRef<const Attr *> Attrs,
-            llvm::DebugLoc Location = llvm::DebugLoc());
+            llvm::ArrayRef<const Attr *> Attrs, llvm::DebugLoc StartLoc,
+            llvm::DebugLoc EndLoc);
 
   /// \brief End the current loop.
   void pop();
index 770fc96..32233b1 100644 (file)
@@ -663,8 +663,10 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
   JumpDest LoopHeader = getJumpDestInCurrentScope("while.cond");
   EmitBlock(LoopHeader.getBlock());
 
+  const SourceRange &R = S.getSourceRange();
   LoopStack.push(LoopHeader.getBlock(), CGM.getContext(), WhileAttrs,
-                 Builder.getCurrentDebugLocation());
+                 SourceLocToDebugLoc(R.getBegin()),
+                 SourceLocToDebugLoc(R.getEnd()));
 
   // Create an exit block for when the condition fails, which will
   // also become the break target.
@@ -755,8 +757,10 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S,
   // Emit the body of the loop.
   llvm::BasicBlock *LoopBody = createBasicBlock("do.body");
 
+  const SourceRange &R = S.getSourceRange();
   LoopStack.push(LoopBody, CGM.getContext(), DoAttrs,
-                 Builder.getCurrentDebugLocation());
+                 SourceLocToDebugLoc(R.getBegin()),
+                 SourceLocToDebugLoc(R.getEnd()));
 
   EmitBlockWithFallThrough(LoopBody, &S);
   {
@@ -808,8 +812,6 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S,
 
   LexicalScope ForScope(*this, S.getSourceRange());
 
-  llvm::DebugLoc DL = Builder.getCurrentDebugLocation();
-
   // Evaluate the first part before the loop.
   if (S.getInit())
     EmitStmt(S.getInit());
@@ -821,7 +823,10 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S,
   llvm::BasicBlock *CondBlock = Continue.getBlock();
   EmitBlock(CondBlock);
 
-  LoopStack.push(CondBlock, CGM.getContext(), ForAttrs, DL);
+  const SourceRange &R = S.getSourceRange();
+  LoopStack.push(CondBlock, CGM.getContext(), ForAttrs,
+                 SourceLocToDebugLoc(R.getBegin()),
+                 SourceLocToDebugLoc(R.getEnd()));
 
   // If the for loop doesn't have an increment we can just use the
   // condition as the continue block.  Otherwise we'll need to create
@@ -906,8 +911,6 @@ CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S,
 
   LexicalScope ForScope(*this, S.getSourceRange());
 
-  llvm::DebugLoc DL = Builder.getCurrentDebugLocation();
-
   // Evaluate the first pieces before the loop.
   EmitStmt(S.getRangeStmt());
   EmitStmt(S.getBeginStmt());
@@ -919,7 +922,10 @@ CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S,
   llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
   EmitBlock(CondBlock);
 
-  LoopStack.push(CondBlock, CGM.getContext(), ForAttrs, DL);
+  const SourceRange &R = S.getSourceRange();
+  LoopStack.push(CondBlock, CGM.getContext(), ForAttrs,
+                 SourceLocToDebugLoc(R.getBegin()),
+                 SourceLocToDebugLoc(R.getEnd()));
 
   // If there are any cleanups between here and the loop-exit scope,
   // create a block to stage a loop exit along.
index 4dd12ea..937295e 100644 (file)
@@ -1304,7 +1304,9 @@ void CodeGenFunction::EmitOMPInnerLoop(
   // Start the loop with a block that tests the condition.
   auto CondBlock = createBasicBlock("omp.inner.for.cond");
   EmitBlock(CondBlock);
-  LoopStack.push(CondBlock, Builder.getCurrentDebugLocation());
+  const SourceRange &R = S.getSourceRange();
+  LoopStack.push(CondBlock, SourceLocToDebugLoc(R.getBegin()),
+                 SourceLocToDebugLoc(R.getEnd()));
 
   // If there are any cleanups between here and the loop-exit scope,
   // create a block to stage a loop exit along.
@@ -1705,7 +1707,9 @@ void CodeGenFunction::EmitOMPOuterLoop(bool DynamicOrOrdered, bool IsMonotonic,
   // Start the loop with a block that tests the condition.
   auto CondBlock = createBasicBlock("omp.dispatch.cond");
   EmitBlock(CondBlock);
-  LoopStack.push(CondBlock, Builder.getCurrentDebugLocation());
+  const SourceRange &R = S.getSourceRange();
+  LoopStack.push(CondBlock, SourceLocToDebugLoc(R.getBegin()),
+                 SourceLocToDebugLoc(R.getEnd()));
 
   llvm::Value *BoolCondVal = nullptr;
   if (!DynamicOrOrdered) {
index 538b50d..aac8f0a 100644 (file)
@@ -2080,3 +2080,10 @@ void CodeGenFunction::EmitSanitizerStatReport(llvm::SanitizerStatKind SSK) {
   IRB.SetCurrentDebugLocation(Builder.getCurrentDebugLocation());
   CGM.getSanStats().create(IRB, SSK);
 }
+
+llvm::DebugLoc CodeGenFunction::SourceLocToDebugLoc(SourceLocation Location) {
+  if (CGDebugInfo *DI = getDebugInfo())
+    return DI->SourceLocToDebugLoc(Location);
+
+  return llvm::DebugLoc();
+}
index dade461..e5ca9bc 100644 (file)
@@ -2113,6 +2113,10 @@ public:
                                       OffsetValue);
   }
 
+  /// Converts Location to a DebugLoc, if debug information is enabled.
+  llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Location);
+
+
   //===--------------------------------------------------------------------===//
   //                            Declaration Emission
   //===--------------------------------------------------------------------===//
index b3f9c32..41770b1 100644 (file)
@@ -53,15 +53,19 @@ int main() {
   // CHECK-DAG: [[DBG3]] = !DILocation(line: 300, scope: !{{.*}})
   // CHECK-DAG: [[DBG4]] = !DILocation(line: 401, scope: !{{.*}})
 
-  // CHECK-DAG: [[L1]] = distinct !{[[L1]], [[LDBG1:![0-9]*]]}
-  // CHECK-DAG: [[LDBG1]] = !DILocation(line: 100, scope: !{{.*}})
+  // CHECK-DAG: [[L1]] = distinct !{[[L1]], [[SLDBG1:![0-9]*]], [[ELDBG1:![0-9]*]]}
+  // CHECK-DAG: [[SLDBG1]] = !DILocation(line: 100, scope: !{{.*}})
+  // CHECK-DAG: [[ELDBG1]] = !DILocation(line: 104, scope: !{{.*}})
 
-  // CHECK-DAG: [[L2]] = distinct !{[[L2]], [[LDBG2:![0-9]*]]}
-  // CHECK-DAG: [[LDBG2]] = !DILocation(line: 200, scope: !{{.*}})
+  // CHECK-DAG: [[L2]] = distinct !{[[L2]], [[SLDBG2:![0-9]*]], [[ELDBG2:![0-9]*]]}
+  // CHECK-DAG: [[SLDBG2]] = !DILocation(line: 200, scope: !{{.*}})
+  // CHECK-DAG: [[ELDBG2]] = !DILocation(line: 204, scope: !{{.*}})
 
-  // CHECK-DAG: [[L3]] = distinct !{[[L3]], [[LDBG3:![0-9]*]]}
-  // CHECK-DAG: [[LDBG3]] = !DILocation(line: 300, scope: !{{.*}})
+  // CHECK-DAG: [[L3]] = distinct !{[[L3]], [[SLDBG3:![0-9]*]], [[ELDBG3:![0-9]*]]}
+  // CHECK-DAG: [[SLDBG3]] = !DILocation(line: 300, scope: !{{.*}})
+  // CHECK-DAG: [[ELDBG3]] = !DILocation(line: 304, scope: !{{.*}})
 
-  // CHECK-DAG: [[L4]] = distinct !{[[L4]], [[LDBG4:![0-9]*]]}
-  // CHECK-DAG: [[LDBG4]] = !DILocation(line: 401, scope: !{{.*}})
+  // CHECK-DAG: [[L4]] = distinct !{[[L4]], [[SLDBG4:![0-9]*]], [[ELDBG4:![0-9]*]]}
+  // CHECK-DAG: [[SLDBG4]] = !DILocation(line: 401, scope: !{{.*}})
+  // CHECK-DAG: [[ELDBG4]] = !DILocation(line: 405, scope: !{{.*}})
 }
diff --git a/clang/test/CodeGenCXX/debug-info-loops.cpp b/clang/test/CodeGenCXX/debug-info-loops.cpp
new file mode 100644 (file)
index 0000000..69948ea
--- /dev/null
@@ -0,0 +1,49 @@
+// RUN: %clang -g -gcolumn-info -std=c++11 -S -emit-llvm %s -o - | FileCheck %s
+extern int v[2];
+int a = 0, b = 0;
+int main() {
+#line 100
+  for (int x : v) {
+    if (x)
+      ++b;
+    else
+      ++a;
+  }
+
+  // CHECK: br label {{.*}}, !dbg [[DBG1:![0-9]*]], !llvm.loop [[L1:![0-9]*]]
+
+#line 200
+  while (a)
+    if (b)
+      ++b;
+    else
+      ++a;
+  // CHECK: br label {{.*}}, !dbg [[DBG2:![0-9]*]], !llvm.loop [[L2:![0-9]*]]
+
+#line 300
+  for (unsigned i = 0; i < 100; i++) {
+    a++;
+    for (int y : v)
+      ++b;
+  }
+
+  // CHECK: br label {{.*}}, !dbg [[DBG3:![0-9]*]], !llvm.loop [[L3:![0-9]*]]
+  // CHECK: br label {{.*}}, !dbg [[DBG3:![0-9]*]], !llvm.loop [[L4:![0-9]*]]
+
+
+  // CHECK-DAG: [[L1]] = distinct !{[[L1]], [[SLDBG1:![0-9]*]], [[ELDBG1:![0-9]*]]}
+  // CHECK-DAG: [[SLDBG1]] = !DILocation(line: 100, column: 3, scope: !{{.*}})
+  // CHECK-DAG: [[ELDBG1]] = !DILocation(line: 105, column: 3, scope: !{{.*}})
+
+  // CHECK-DAG: [[L2]] = distinct !{[[L2]], [[SLDBG2:![0-9]*]], [[ELDBG2:![0-9]*]]}
+  // CHECK-DAG: [[SLDBG2]] = !DILocation(line: 200, column: 3, scope: !{{.*}})
+  // CHECK-DAG: [[ELDBG2]] = !DILocation(line: 204, column: 9, scope: !{{.*}})
+
+  // CHECK-DAG: [[L3]] = distinct !{[[L3]], [[SLDBG3:![0-9]*]], [[ELDBG3:![0-9]*]]}
+  // CHECK-DAG: [[SLDBG3]] = !DILocation(line: 302, column: 5, scope: !{{.*}})
+  // CHECK-DAG: [[ELDBG3]] = !DILocation(line: 303, column: 9, scope: !{{.*}})
+  //
+  // CHECK-DAG: [[L4]] = distinct !{[[L4]], [[SLDBG4:![0-9]*]], [[ELDBG4:![0-9]*]]}
+  // CHECK-DAG: [[SLDBG4]] = !DILocation(line: 300, column: 3, scope: !{{.*}})
+  // CHECK-DAG: [[ELDBG4]] = !DILocation(line: 304, column: 3, scope: !{{.*}})
+}