Skip to content

Commit c07e19b

Browse files
author
Hal Finkel
committed
Add a loop's debug location to its llvm.loop metadata
Getting accurate locations for loops is important, because those locations are used by the frontend to generate optimization remarks. Currently, optimization remarks for loops often appear on the wrong line, often the first line of the loop body instead of the loop itself. This is confusing because that line might itself be another loop, or might be somewhere else completely if the body was an inlined function call. This happens because of the way we find the loop's starting location. First, we look for a preheader, and if we find one, and its terminator has a debug location, then we use that. Otherwise, we look for a location on an instruction in the loop header. The fallback heuristic is not bad, but will almost always find the beginning of the body, and not the loop statement itself. The preheader location search often fails because there's often not a preheader, and even when there is a preheader, depending on how it was formed, it sometimes carries the location of some preceeding code. I don't see any good theoretical way to fix this problem. On the other hand, this seems like a straightforward solution: Put the debug location in the loop's llvm.loop metadata. When emitting debug information, this commit causes us to add the debug location as an operand to each loop's llvm.loop metadata. Thus, we now generate this metadata for all loops (not just loops with optimization hints) when we're otherwise generating debug information. The remark test case changes depend on the companion LLVM commit r270771. llvm-svn: 270772
1 parent 2f68868 commit c07e19b

File tree

7 files changed

+57
-27
lines changed

7 files changed

+57
-27
lines changed

clang/lib/CodeGen/CGLoopInfo.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,25 @@
1919
using namespace clang::CodeGen;
2020
using namespace llvm;
2121

22-
static MDNode *createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs) {
22+
static MDNode *createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs,
23+
llvm::DebugLoc Location) {
2324

2425
if (!Attrs.IsParallel && Attrs.VectorizeWidth == 0 &&
2526
Attrs.InterleaveCount == 0 && Attrs.UnrollCount == 0 &&
2627
Attrs.VectorizeEnable == LoopAttributes::Unspecified &&
27-
Attrs.UnrollEnable == LoopAttributes::Unspecified)
28+
Attrs.UnrollEnable == LoopAttributes::Unspecified &&
29+
!Location)
2830
return nullptr;
2931

3032
SmallVector<Metadata *, 4> Args;
3133
// Reserve operand 0 for loop id self reference.
3234
auto TempNode = MDNode::getTemporary(Ctx, None);
3335
Args.push_back(TempNode.get());
3436

37+
// If we have a valid debug location for the loop, add it.
38+
if (Location)
39+
Args.push_back(Location.getAsMDNode());
40+
3541
// Setting vectorize.width
3642
if (Attrs.VectorizeWidth > 0) {
3743
Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.vectorize.width"),
@@ -98,19 +104,21 @@ void LoopAttributes::clear() {
98104
UnrollEnable = LoopAttributes::Unspecified;
99105
}
100106

101-
LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs)
107+
LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs,
108+
llvm::DebugLoc Location)
102109
: LoopID(nullptr), Header(Header), Attrs(Attrs) {
103-
LoopID = createMetadata(Header->getContext(), Attrs);
110+
LoopID = createMetadata(Header->getContext(), Attrs, Location);
104111
}
105112

106-
void LoopInfoStack::push(BasicBlock *Header) {
107-
Active.push_back(LoopInfo(Header, StagedAttrs));
113+
void LoopInfoStack::push(BasicBlock *Header, llvm::DebugLoc Location) {
114+
Active.push_back(LoopInfo(Header, StagedAttrs, Location));
108115
// Clear the attributes so nested loops do not inherit them.
109116
StagedAttrs.clear();
110117
}
111118

112119
void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx,
113-
ArrayRef<const clang::Attr *> Attrs) {
120+
ArrayRef<const clang::Attr *> Attrs,
121+
llvm::DebugLoc Location) {
114122

115123
// Identify loop hint attributes from Attrs.
116124
for (const auto *Attr : Attrs) {
@@ -239,7 +247,7 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx,
239247
}
240248

241249
/// Stage the attributes.
242-
push(Header);
250+
push(Header, Location);
243251
}
244252

245253
void LoopInfoStack::pop() {

clang/lib/CodeGen/CGLoopInfo.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "llvm/ADT/ArrayRef.h"
1919
#include "llvm/ADT/DenseMap.h"
2020
#include "llvm/ADT/SmallVector.h"
21+
#include "llvm/IR/DebugLoc.h"
2122
#include "llvm/IR/Value.h"
2223
#include "llvm/Support/Compiler.h"
2324

@@ -63,7 +64,8 @@ struct LoopAttributes {
6364
class LoopInfo {
6465
public:
6566
/// \brief Construct a new LoopInfo for the loop with entry Header.
66-
LoopInfo(llvm::BasicBlock *Header, const LoopAttributes &Attrs);
67+
LoopInfo(llvm::BasicBlock *Header, const LoopAttributes &Attrs,
68+
llvm::DebugLoc Location);
6769

6870
/// \brief Get the loop id metadata for this loop.
6971
llvm::MDNode *getLoopID() const { return LoopID; }
@@ -95,12 +97,14 @@ class LoopInfoStack {
9597

9698
/// \brief Begin a new structured loop. The set of staged attributes will be
9799
/// applied to the loop and then cleared.
98-
void push(llvm::BasicBlock *Header);
100+
void push(llvm::BasicBlock *Header,
101+
llvm::DebugLoc Location = llvm::DebugLoc());
99102

100103
/// \brief Begin a new structured loop. Stage attributes from the Attrs list.
101104
/// The staged attributes are applied to the loop and then cleared.
102105
void push(llvm::BasicBlock *Header, clang::ASTContext &Ctx,
103-
llvm::ArrayRef<const Attr *> Attrs);
106+
llvm::ArrayRef<const Attr *> Attrs,
107+
llvm::DebugLoc Location = llvm::DebugLoc());
104108

105109
/// \brief End the current loop.
106110
void pop();

clang/lib/CodeGen/CGStmt.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,8 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
629629
JumpDest LoopHeader = getJumpDestInCurrentScope("while.cond");
630630
EmitBlock(LoopHeader.getBlock());
631631

632-
LoopStack.push(LoopHeader.getBlock(), CGM.getContext(), WhileAttrs);
632+
LoopStack.push(LoopHeader.getBlock(), CGM.getContext(), WhileAttrs,
633+
Builder.getCurrentDebugLocation());
633634

634635
// Create an exit block for when the condition fails, which will
635636
// also become the break target.
@@ -720,7 +721,8 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S,
720721
// Emit the body of the loop.
721722
llvm::BasicBlock *LoopBody = createBasicBlock("do.body");
722723

723-
LoopStack.push(LoopBody, CGM.getContext(), DoAttrs);
724+
LoopStack.push(LoopBody, CGM.getContext(), DoAttrs,
725+
Builder.getCurrentDebugLocation());
724726

725727
EmitBlockWithFallThrough(LoopBody, &S);
726728
{
@@ -772,6 +774,8 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S,
772774

773775
LexicalScope ForScope(*this, S.getSourceRange());
774776

777+
llvm::DebugLoc DL = Builder.getCurrentDebugLocation();
778+
775779
// Evaluate the first part before the loop.
776780
if (S.getInit())
777781
EmitStmt(S.getInit());
@@ -783,7 +787,7 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S,
783787
llvm::BasicBlock *CondBlock = Continue.getBlock();
784788
EmitBlock(CondBlock);
785789

786-
LoopStack.push(CondBlock, CGM.getContext(), ForAttrs);
790+
LoopStack.push(CondBlock, CGM.getContext(), ForAttrs, DL);
787791

788792
// If the for loop doesn't have an increment we can just use the
789793
// condition as the continue block. Otherwise we'll need to create
@@ -868,6 +872,8 @@ CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S,
868872

869873
LexicalScope ForScope(*this, S.getSourceRange());
870874

875+
llvm::DebugLoc DL = Builder.getCurrentDebugLocation();
876+
871877
// Evaluate the first pieces before the loop.
872878
EmitStmt(S.getRangeStmt());
873879
EmitStmt(S.getBeginStmt());
@@ -879,7 +885,7 @@ CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S,
879885
llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
880886
EmitBlock(CondBlock);
881887

882-
LoopStack.push(CondBlock, CGM.getContext(), ForAttrs);
888+
LoopStack.push(CondBlock, CGM.getContext(), ForAttrs, DL);
883889

884890
// If there are any cleanups between here and the loop-exit scope,
885891
// create a block to stage a loop exit along.

clang/lib/CodeGen/CGStmtOpenMP.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,7 +1271,7 @@ void CodeGenFunction::EmitOMPInnerLoop(
12711271
// Start the loop with a block that tests the condition.
12721272
auto CondBlock = createBasicBlock("omp.inner.for.cond");
12731273
EmitBlock(CondBlock);
1274-
LoopStack.push(CondBlock);
1274+
LoopStack.push(CondBlock, Builder.getCurrentDebugLocation());
12751275

12761276
// If there are any cleanups between here and the loop-exit scope,
12771277
// create a block to stage a loop exit along.
@@ -1672,7 +1672,7 @@ void CodeGenFunction::EmitOMPOuterLoop(bool DynamicOrOrdered, bool IsMonotonic,
16721672
// Start the loop with a block that tests the condition.
16731673
auto CondBlock = createBasicBlock("omp.dispatch.cond");
16741674
EmitBlock(CondBlock);
1675-
LoopStack.push(CondBlock);
1675+
LoopStack.push(CondBlock, Builder.getCurrentDebugLocation());
16761676

16771677
llvm::Value *BoolCondVal = nullptr;
16781678
if (!DynamicOrOrdered) {

clang/test/CodeGenCXX/debug-info-line-if.cpp

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ int main() {
1515

1616
// CHECK: br label
1717
// CHECK: br label
18-
// CHECK: br label {{.*}}, !dbg [[DBG1:!.*]]
18+
// CHECK: br label {{.*}}, !dbg [[DBG1:![0-9]*]], !llvm.loop [[L1:![0-9]*]]
1919

2020
#line 200
2121
while (a)
@@ -25,7 +25,7 @@ int main() {
2525
++a; // CHECK: add nsw{{.*}}, 1
2626

2727
// CHECK: br label
28-
// CHECK: br label {{.*}}, !dbg [[DBG2:!.*]]
28+
// CHECK: br label {{.*}}, !dbg [[DBG2:![0-9]*]], !llvm.loop [[L2:![0-9]*]]
2929

3030
#line 300
3131
for (; a; )
@@ -35,7 +35,7 @@ int main() {
3535
++a; // CHECK: add nsw{{.*}}, 1
3636

3737
// CHECK: br label
38-
// CHECK: br label {{.*}}, !dbg [[DBG3:!.*]]
38+
// CHECK: br label {{.*}}, !dbg [[DBG3:![0-9]*]], !llvm.loop [[L3:![0-9]*]]
3939

4040
#line 400
4141
int x[] = {1, 2};
@@ -46,10 +46,22 @@ int main() {
4646
++a; // CHECK: add nsw{{.*}}, 1
4747

4848
// CHECK: br label
49-
// CHECK: br label {{.*}}, !dbg [[DBG4:!.*]]
49+
// CHECK: br label {{.*}}, !dbg [[DBG4:![0-9]*]], !llvm.loop [[L4:![0-9]*]]
5050

51-
// CHECK: [[DBG1]] = !DILocation(line: 100, scope: !{{.*}})
52-
// CHECK: [[DBG2]] = !DILocation(line: 200, scope: !{{.*}})
53-
// CHECK: [[DBG3]] = !DILocation(line: 300, scope: !{{.*}})
54-
// CHECK: [[DBG4]] = !DILocation(line: 401, scope: !{{.*}})
51+
// CHECK-DAG: [[DBG1]] = !DILocation(line: 100, scope: !{{.*}})
52+
// CHECK-DAG: [[DBG2]] = !DILocation(line: 200, scope: !{{.*}})
53+
// CHECK-DAG: [[DBG3]] = !DILocation(line: 300, scope: !{{.*}})
54+
// CHECK-DAG: [[DBG4]] = !DILocation(line: 401, scope: !{{.*}})
55+
56+
// CHECK-DAG: [[L1]] = distinct !{[[L1]], [[LDBG1:![0-9]*]]}
57+
// CHECK-DAG: [[LDBG1]] = !DILocation(line: 100, scope: !{{.*}})
58+
59+
// CHECK-DAG: [[L2]] = distinct !{[[L2]], [[LDBG2:![0-9]*]]}
60+
// CHECK-DAG: [[LDBG2]] = !DILocation(line: 200, scope: !{{.*}})
61+
62+
// CHECK-DAG: [[L3]] = distinct !{[[L3]], [[LDBG3:![0-9]*]]}
63+
// CHECK-DAG: [[LDBG3]] = !DILocation(line: 300, scope: !{{.*}})
64+
65+
// CHECK-DAG: [[L4]] = distinct !{[[L4]], [[LDBG4:![0-9]*]]}
66+
// CHECK-DAG: [[LDBG4]] = !DILocation(line: 401, scope: !{{.*}})
5567
}

clang/test/Frontend/optimization-remark-options.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ double foo(int N) {
1111
return v;
1212
}
1313

14-
// CHECK: {{.*}}:18:13: remark: loop not vectorized: cannot prove it is safe to reorder memory operations; allow reordering by specifying '#pragma clang loop vectorize(enable)' before the loop. If the arrays will always be independent specify '#pragma clang loop vectorize(assume_safety)' before the loop or provide the '__restrict__' qualifier with the independent array arguments. Erroneous results will occur if these options are incorrectly applied!
14+
// CHECK: {{.*}}:17:3: remark: loop not vectorized: cannot prove it is safe to reorder memory operations; allow reordering by specifying '#pragma clang loop vectorize(enable)' before the loop. If the arrays will always be independent specify '#pragma clang loop vectorize(assume_safety)' before the loop or provide the '__restrict__' qualifier with the independent array arguments. Erroneous results will occur if these options are incorrectly applied!
1515

1616
void foo2(int *dw, int *uw, int *A, int *B, int *C, int *D, int N) {
1717
for (int i = 0; i < N; i++) {

clang/test/Misc/backend-optimization-failure.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
void test_switch(int *A, int *B, int Length) {
88
#pragma clang loop vectorize(enable) unroll(disable)
99
for (int i = 0; i < Length; i++) {
10-
/* expected-warning {{loop not vectorized: failed explicitly specified loop vectorization}} */ switch (A[i]) {
10+
/* expected-warning@-1 {{loop not vectorized: failed explicitly specified loop vectorization}} */ switch (A[i]) {
1111
case 0:
1212
B[i] = 1;
1313
break;

0 commit comments

Comments
 (0)