================
@@ -0,0 +1,120 @@
+# Key Instructions in Clang
+
+Key Instructions is an LLVM feature that reduces the jumpiness of optimized 
code debug stepping. This document explains how Clang applies the necessary 
metadata.
+
+## Implementation
+
+See the [LLVM docs](../../llvm/docs/KeyInstructionsDebugInfo.md) for general 
info about the feature (and LLVM implementation details).
+
+Clang needs to annotate key instructions with the new metadata. Variable 
assignments (stores, memory intrinsics), control flow (branches and their 
conditions, some unconditional branches), and exception handling instructions 
are annotated. Calls are ignored as they're unconditionally marked `is_stmt`. 
This is achieved with a few simple constructs:
+
+Class `ApplyAtomGroup` - This is a scoped helper similar to 
`ApplyDebugLocation` that creates a new source atom group which instructions 
can be added to. It's used during CodeGen to declare that a new source atom has 
started, e.g. in `CodeGenFunction::EmitBinaryOperatorLValue`.
+
+`CodeGenFunction::addInstToCurrentSourceAtom(llvm::Instruction 
*KeyInstruction, llvm::Value *Backup)` adds an instruction (and a backup 
instruction if non-null) to the current "atom group" defined with 
`ApplyAtomGroup`. The Key Instruction gets rank 1, and backup instructions get 
higher ranks (the function looks through casts, applying increasing rank as it 
goes). There are a lot of sites in Clang that need to call this (mostly stores 
and store-like instructions). FIXME?: Currently it's called at the CGBuilderTy 
callsites; it could instead make sense to always call the function inside the 
CGBuilderTy calls, with some calls opting out.
+
+`CodeGenFunction::addInstToNewSourceAtom(llvm::Instruction *KeyInstruction, 
llvm::Value *Backup)` adds an instruction (and a backup instruction if 
non-null) to a new "atom group". Currently mostly used in loop handling code.
+
+There are a couple of other helpers, including 
`addRetToOverrideOrNewSourceAtom` used for `rets` which is covered in the 
examples below.
+
+## Examples
+
+A simple example walk through:
+```
+void fun(int a) {
+  int b = a;
+}
+```
+
+There are two key instructions here, the assignment and the implicit return. 
We want to emit metadata that looks like this:
+
+```
+define hidden void @_Z3funi(i32 noundef %a) #0 !dbg !11 {
+entry:
+  %a.addr = alloca i32, align 4
+  %b = alloca i32, align 4
+  store i32 %a, ptr %a.addr, align 4
+  %0 = load i32, ptr %a.addr, align 4, !dbg !DILocation(line: 2, scope: !11, 
atomGroup: 1, atomRank: 2)
+  store i32 %0, ptr %b, align 4,       !dbg !DILocation(line: 2, scope: !11, 
atomGroup: 1, atomRank: 1)
+  ret void,                            !dbg !DILocation(line: 3, scope: !11, 
atomGroup: 2, atomRank: 1)
+}
+```
+
+The store is the key instruction for the assignment (`atomGroup` 1). The 
instruction corresponding to the final (and in this case only) RHS value, the 
load from `%a.addr`, is a good backup location for `is_stmt` if the store gets 
optimized away. It's part of the same source atom, but has lower `is_stmt` 
precedence, so it gets a higher `atomRank`.
+
+This is all handled during CodeGen. The atom group is set here:
+```
+>  clang::CodeGen::ApplyAtomGroup::ApplyAtomGroup(clang::CodeGen::CGDebugInfo 
* DI) Line 187
+   clang::CodeGen::CodeGenFunction::EmitAutoVarInit(const 
clang::CodeGen::CodeGenFunction::AutoVarEmission & emission) Line 1961
+   clang::CodeGen::CodeGenFunction::EmitAutoVarDecl(const clang::VarDecl & D) 
Line 1361
+   clang::CodeGen::CodeGenFunction::EmitVarDecl(const clang::VarDecl & D) Line 
219
+   clang::CodeGen::CodeGenFunction::EmitDecl(const clang::Decl & D) Line 164
+   clang::CodeGen::CodeGenFunction::EmitDeclStmt(const clang::DeclStmt & S) 
Line 1611
+   clang::CodeGen::CodeGenFunction::EmitSimpleStmt(const clang::Stmt * S, 
llvm::ArrayRef<clang::Attr const *> Attrs) Line 466
+   clang::CodeGen::CodeGenFunction::EmitStmt(const clang::Stmt * S, 
llvm::ArrayRef<clang::Attr const *> Attrs) Line 72
+   clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(const 
clang::CompoundStmt & S, bool GetLast, clang::CodeGen::AggValueSlot AggSlot) 
Line 556+
+   clang::CodeGen::CodeGenFunction::EmitFunctionBody(const clang::Stmt * Body) 
Line 1307
----------------
nikic wrote:

Uh, I don't think this listing (especially the line numbers!) is going to age 
well..

https://github.com/llvm/llvm-project/pull/137991
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to