[KeyInstr][Clang] Aggregate init + copy (#134639)

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.
This commit is contained in:
Orlando Cazalet-Hyams 2025-05-22 17:35:49 +01:00 committed by GitHub
parent 28046438ed
commit 0ee40ca5cc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 35 additions and 15 deletions

View File

@ -892,20 +892,6 @@ private:
}
};
/// A scoped helper to set the current source atom group for
/// CGDebugInfo::addInstToCurrentSourceAtom. A source atom is a source construct
/// that is "interesting" for debug stepping purposes. We use an atom group
/// number to track the instruction(s) that implement the functionality for the
/// atom, plus backup instructions/source locations.
class ApplyAtomGroup {
uint64_t OriginalAtom = 0;
CGDebugInfo *DI = nullptr;
public:
ApplyAtomGroup(CGDebugInfo *DI);
~ApplyAtomGroup();
};
/// A scoped helper to set the current debug location to the specified
/// location or preferred location of the specified Expr.
class ApplyDebugLocation {

View File

@ -1332,6 +1332,7 @@ static bool isBlockVarRef(const Expr *E) {
}
void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
ApplyAtomGroup Grp(CGF.getDebugInfo());
// For an assignment to work, the value on the right has
// to be compatible with the value on the left.
assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(),
@ -2393,7 +2394,8 @@ void CodeGenFunction::EmitAggregateCopy(LValue Dest, LValue Src, QualType Ty,
}
}
auto Inst = Builder.CreateMemCpy(DestPtr, SrcPtr, SizeVal, isVolatile);
auto *Inst = Builder.CreateMemCpy(DestPtr, SrcPtr, SizeVal, isVolatile);
addInstToCurrentSourceAtom(Inst, nullptr);
// Determine the metadata to describe the position of any padding in this
// memcpy, as well as the TBAA tags for the members of the struct, in case

View File

@ -258,6 +258,20 @@ template <> struct DominatingValue<RValue> {
}
};
/// A scoped helper to set the current source atom group for
/// CGDebugInfo::addInstToCurrentSourceAtom. A source atom is a source construct
/// that is "interesting" for debug stepping purposes. We use an atom group
/// number to track the instruction(s) that implement the functionality for the
/// atom, plus backup instructions/source locations.
class ApplyAtomGroup {
uint64_t OriginalAtom = 0;
CGDebugInfo *DI = nullptr;
public:
ApplyAtomGroup(CGDebugInfo *DI);
~ApplyAtomGroup();
};
/// CodeGenFunction - This class organizes the per-function state that is used
/// while generating LLVM code.
class CodeGenFunction : public CodeGenTypeCache {
@ -3035,6 +3049,7 @@ public:
/// Emit an aggregate assignment.
void EmitAggregateAssign(LValue Dest, LValue Src, QualType EltTy) {
ApplyAtomGroup Grp(getDebugInfo());
bool IsVolatile = hasVolatileMember(EltTy);
EmitAggregateCopy(Dest, Src, EltTy, AggValueSlot::MayOverlap, IsVolatile);
}

View File

@ -0,0 +1,17 @@
// RUN: %clang_cc1 -gkey-instructions -x c++ %s -debug-info-kind=line-tables-only -emit-llvm -o - \
// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank
// RUN: %clang_cc1 -gkey-instructions -x c %s -debug-info-kind=line-tables-only -emit-llvm -o - \
// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank
typedef struct { int a, b, c; } Struct;
void fun(Struct a) {
// CHECK: call void @llvm.memcpy{{.*}}, !dbg [[G1R1:!.*]]
Struct b = a;
// CHECK: call void @llvm.memcpy{{.*}}, !dbg [[G2R1:!.*]]
b = a;
}
// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
// CHECK: [[G2R1]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)