Skip to content

Commit 6bd3543

Browse files
authored
[KeyInstr][Clang] While stmt atom (#134645)
See test comment for possible future improvement. This patch is part of a stack that teaches Clang to generate Key Instructions metadata for C and C++. RFC: https://discourse.llvm.org/t/rfc-improving-is-stmt-placement-for-better-interactive-debugging/82668 The feature is only functional in LLVM if LLVM is built with CMake flag LLVM_EXPERIMENTAL_KEY_INSTRUCTIONs. Eventually that flag will be removed.
1 parent fd1c4c3 commit 6bd3543

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

clang/lib/CodeGen/CGStmt.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1130,7 +1130,15 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
11301130
if (!Weights && CGM.getCodeGenOpts().OptimizationLevel)
11311131
BoolCondVal = emitCondLikelihoodViaExpectIntrinsic(
11321132
BoolCondVal, Stmt::getLikelihood(S.getBody()));
1133-
Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock, Weights);
1133+
auto *I = Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock, Weights);
1134+
// Key Instructions: Emit the condition and branch as separate source
1135+
// location atoms otherwise we may omit a step onto the loop condition in
1136+
// favour of the `while` keyword.
1137+
// FIXME: We could have the branch as the backup location for the condition,
1138+
// which would probably be a better experience. Explore this later.
1139+
if (auto *CondI = dyn_cast<llvm::Instruction>(BoolCondVal))
1140+
addInstToNewSourceAtom(CondI, nullptr);
1141+
addInstToNewSourceAtom(I, nullptr);
11341142

11351143
if (ExitBlock != LoopExit.getBlock()) {
11361144
EmitBlock(ExitBlock);
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// RUN: %clang_cc1 -gkey-instructions -x c++ -std=c++17 %s -debug-info-kind=line-tables-only -emit-llvm -o - \
2+
// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank
3+
4+
// RUN: %clang_cc1 -gkey-instructions -x c %s -debug-info-kind=line-tables-only -emit-llvm -o - \
5+
// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank
6+
7+
// Perennial question: should the `dec` be in its own source atom or not
8+
// (currently it is).
9+
10+
// We've made the cmp and br separate source atoms for now, to match existing
11+
// behaviour in this case:
12+
// 1. while (
13+
// 2. int i = --End
14+
// 3. ) {
15+
// 4. useValue(i);
16+
// 5. }
17+
// Without Key Instructions we go: 2, 1[, 4, 2, 1]+
18+
// Without separating cmp and br with Key Instructions we'd get:
19+
// 1[, 4, 1]+. If we made the cmp higher precedence than the
20+
// br and had them in the same group, we could get:
21+
// 2, [4, 2]+ which might be nicer. FIXME: do that later.
22+
23+
void a(int A) {
24+
// CHECK: %dec = add nsw i32 %0, -1, !dbg [[G1R2:!.*]]
25+
// CHECK: store i32 %dec, ptr %A.addr{{.*}}, !dbg [[G1R1:!.*]]
26+
// CHECK: %tobool = icmp ne i32 %dec, 0, !dbg [[G2R1:!.*]]
27+
// CHECK: br i1 %tobool, label %while.body, label %while.end, !dbg [[G3R1:!.*]]
28+
while (--A) { };
29+
}
30+
31+
// CHECK: [[G1R2]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 2)
32+
// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
33+
// CHECK: [[G2R1]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
34+
// CHECK: [[G3R1]] = !DILocation({{.*}}, atomGroup: 3, atomRank: 1)

0 commit comments

Comments
 (0)