From ba58685ce88db472f3774944435eb4948d762bb9 Mon Sep 17 00:00:00 2001 From: Amara Emerson <amara.emerson@arm.com> Date: Thu, 10 Nov 2016 14:44:30 +0000 Subject: [PATCH] Add the loop end location to the loop metadata. This additional information 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 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@286456 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGDebugInfo.cpp | 9 +++++ lib/CodeGen/CGDebugInfo.h | 3 ++ lib/CodeGen/CGLoopInfo.cpp | 28 +++++++++------ lib/CodeGen/CGLoopInfo.h | 10 +++--- lib/CodeGen/CGStmt.cpp | 22 +++++++----- lib/CodeGen/CGStmtOpenMP.cpp | 8 +++-- lib/CodeGen/CodeGenFunction.cpp | 7 ++++ lib/CodeGen/CodeGenFunction.h | 4 +++ test/CodeGenCXX/debug-info-line-if.cpp | 20 ++++++----- test/CodeGenCXX/debug-info-loops.cpp | 49 ++++++++++++++++++++++++++ 10 files changed, 126 insertions(+), 34 deletions(-) create mode 100644 test/CodeGenCXX/debug-info-loops.cpp diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index ef4fb06c183..f2f1918c90e 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -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); +} diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h index f43261a47d2..4cf7bb32380 100644 --- a/lib/CodeGen/CGDebugInfo.h +++ b/lib/CodeGen/CGDebugInfo.h @@ -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. diff --git a/lib/CodeGen/CGLoopInfo.cpp b/lib/CodeGen/CGLoopInfo.cpp index 62ee57112b4..7e44c9fc564 100644 --- a/lib/CodeGen/CGLoopInfo.cpp +++ b/lib/CodeGen/CGLoopInfo.cpp @@ -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() { diff --git a/lib/CodeGen/CGLoopInfo.h b/lib/CodeGen/CGLoopInfo.h index 76a039ddd58..e2c9770531b 100644 --- a/lib/CodeGen/CGLoopInfo.h +++ b/lib/CodeGen/CGLoopInfo.h @@ -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(); diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp index 770fc969c09..32233b19d6a 100644 --- a/lib/CodeGen/CGStmt.cpp +++ b/lib/CodeGen/CGStmt.cpp @@ -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. diff --git a/lib/CodeGen/CGStmtOpenMP.cpp b/lib/CodeGen/CGStmtOpenMP.cpp index 4dd12ea3df0..937295e6600 100644 --- a/lib/CodeGen/CGStmtOpenMP.cpp +++ b/lib/CodeGen/CGStmtOpenMP.cpp @@ -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) { diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index 538b50d56d4..aac8f0af860 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -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(); +} diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index dade4612ce7..e5ca9bc980e 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -2113,6 +2113,10 @@ public: OffsetValue); } + /// Converts Location to a DebugLoc, if debug information is enabled. + llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Location); + + //===--------------------------------------------------------------------===// // Declaration Emission //===--------------------------------------------------------------------===// diff --git a/test/CodeGenCXX/debug-info-line-if.cpp b/test/CodeGenCXX/debug-info-line-if.cpp index b3f9c32e091..41770b13561 100644 --- a/test/CodeGenCXX/debug-info-line-if.cpp +++ b/test/CodeGenCXX/debug-info-line-if.cpp @@ -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/test/CodeGenCXX/debug-info-loops.cpp b/test/CodeGenCXX/debug-info-loops.cpp new file mode 100644 index 00000000000..69948ea0f88 --- /dev/null +++ b/test/CodeGenCXX/debug-info-loops.cpp @@ -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: !{{.*}}) +} -- GitLab