Skip to content

Commit c1f5cb9

Browse files
author
git apple-llvm automerger
committed
Merge commit '9459c8309c67' from llvm.org/main into next
2 parents cd224a2 + 9459c83 commit c1f5cb9

File tree

4 files changed

+167
-1
lines changed

4 files changed

+167
-1
lines changed

clang/lib/CodeGen/CGDebugInfo.cpp

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include "llvm/IR/Constants.h"
4444
#include "llvm/IR/DataLayout.h"
4545
#include "llvm/IR/DerivedTypes.h"
46+
#include "llvm/IR/Instruction.h"
4647
#include "llvm/IR/Instructions.h"
4748
#include "llvm/IR/Intrinsics.h"
4849
#include "llvm/IR/Metadata.h"
@@ -52,6 +53,7 @@
5253
#include "llvm/Support/SHA1.h"
5354
#include "llvm/Support/SHA256.h"
5455
#include "llvm/Support/TimeProfiler.h"
56+
#include <cstdint>
5557
#include <optional>
5658
using namespace clang;
5759
using namespace clang::CodeGen;
@@ -125,6 +127,97 @@ CGDebugInfo::~CGDebugInfo() {
125127
"Region stack mismatch, stack not empty!");
126128
}
127129

130+
void CGDebugInfo::addInstSourceAtomMetadata(llvm::Instruction *I,
131+
uint64_t Group, uint8_t Rank) {
132+
if (!I->getDebugLoc() || Group == 0 || !I->getDebugLoc()->getLine())
133+
return;
134+
135+
// Saturate the 3-bit rank.
136+
Rank = std::min<uint8_t>(Rank, 7);
137+
138+
const llvm::DebugLoc &DL = I->getDebugLoc();
139+
140+
// Each instruction can only be attributed to one source atom (a limitation of
141+
// the implementation). If this instruction is already part of a source atom,
142+
// pick the group in which it has highest precedence (lowest rank).
143+
if (DL.get()->getAtomGroup() && DL.get()->getAtomRank() &&
144+
DL.get()->getAtomRank() < Rank) {
145+
Group = DL.get()->getAtomGroup();
146+
Rank = DL.get()->getAtomRank();
147+
}
148+
149+
// Update the function-local watermark so we don't reuse this number for
150+
// another atom.
151+
KeyInstructionsInfo.HighestEmittedAtom =
152+
std::max(Group, KeyInstructionsInfo.HighestEmittedAtom);
153+
154+
// Apply the new DILocation to the instruction.
155+
llvm::DILocation *NewDL = llvm::DILocation::get(
156+
I->getContext(), DL.getLine(), DL.getCol(), DL.getScope(),
157+
DL.getInlinedAt(), DL.isImplicitCode(), Group, Rank);
158+
I->setDebugLoc(NewDL);
159+
};
160+
161+
void CGDebugInfo::addInstToCurrentSourceAtom(llvm::Instruction *KeyInstruction,
162+
llvm::Value *Backup) {
163+
addInstToSpecificSourceAtom(KeyInstruction, Backup,
164+
KeyInstructionsInfo.CurrentAtom);
165+
}
166+
167+
void CGDebugInfo::addInstToSpecificSourceAtom(llvm::Instruction *KeyInstruction,
168+
llvm::Value *Backup,
169+
uint64_t Group) {
170+
if (!Group || !CGM.getCodeGenOpts().DebugKeyInstructions)
171+
return;
172+
173+
addInstSourceAtomMetadata(KeyInstruction, Group, /*Rank=*/1);
174+
175+
llvm::Instruction *BackupI =
176+
llvm::dyn_cast_or_null<llvm::Instruction>(Backup);
177+
if (!BackupI)
178+
return;
179+
180+
// Add the backup instruction to the group.
181+
addInstSourceAtomMetadata(BackupI, Group, /*Rank=*/2);
182+
183+
// Look through chains of casts too, as they're probably going to evaporate.
184+
// FIXME: And other nops like zero length geps?
185+
// FIXME: Should use Cast->isNoopCast()?
186+
uint8_t Rank = 3;
187+
while (auto *Cast = dyn_cast<llvm::CastInst>(BackupI)) {
188+
BackupI = dyn_cast<llvm::Instruction>(Cast->getOperand(0));
189+
if (!BackupI)
190+
break;
191+
addInstSourceAtomMetadata(BackupI, Group, Rank++);
192+
}
193+
}
194+
195+
void CGDebugInfo::completeFunction() {
196+
// Reset the atom group number tracker as the numbers are function-local.
197+
KeyInstructionsInfo.NextAtom = 1;
198+
KeyInstructionsInfo.HighestEmittedAtom = 0;
199+
KeyInstructionsInfo.CurrentAtom = 0;
200+
}
201+
202+
ApplyAtomGroup::ApplyAtomGroup(CGDebugInfo *DI) : DI(DI) {
203+
if (!DI)
204+
return;
205+
OriginalAtom = DI->KeyInstructionsInfo.CurrentAtom;
206+
DI->KeyInstructionsInfo.CurrentAtom = DI->KeyInstructionsInfo.NextAtom++;
207+
}
208+
209+
ApplyAtomGroup::~ApplyAtomGroup() {
210+
if (!DI)
211+
return;
212+
213+
// We may not have used the group number at all.
214+
DI->KeyInstructionsInfo.NextAtom =
215+
std::min(DI->KeyInstructionsInfo.HighestEmittedAtom + 1,
216+
DI->KeyInstructionsInfo.NextAtom);
217+
218+
DI->KeyInstructionsInfo.CurrentAtom = OriginalAtom;
219+
}
220+
128221
ApplyDebugLocation::ApplyDebugLocation(CodeGenFunction &CGF,
129222
SourceLocation TemporaryLocation)
130223
: CGF(&CGF) {
@@ -180,8 +273,15 @@ ApplyDebugLocation::ApplyDebugLocation(CodeGenFunction &CGF, llvm::DebugLoc Loc)
180273
return;
181274
}
182275
OriginalLocation = CGF.Builder.getCurrentDebugLocation();
183-
if (Loc)
276+
if (Loc) {
277+
// Key Instructions: drop the atom group and rank to avoid accidentally
278+
// propagating it around.
279+
if (Loc->getAtomGroup())
280+
Loc = llvm::DILocation::get(Loc->getContext(), Loc.getLine(),
281+
Loc->getColumn(), Loc->getScope(),
282+
Loc->getInlinedAt(), Loc.isImplicitCode());
184283
CGF.Builder.SetCurrentDebugLocation(std::move(Loc));
284+
}
185285
}
186286

187287
ApplyDebugLocation::~ApplyDebugLocation() {

clang/lib/CodeGen/CGDebugInfo.h

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ class CGBlockInfo;
5858
class CGDebugInfo {
5959
friend class ApplyDebugLocation;
6060
friend class SaveAndRestoreLocation;
61+
friend class ApplyAtomGroup;
62+
6163
CodeGenModule &CGM;
6264
const llvm::codegenoptions::DebugInfoKind DebugKind;
6365
bool DebugTypeExtRefs;
@@ -179,6 +181,16 @@ class CGDebugInfo {
179181
/// The key is coroutine real parameters, value is DIVariable in LLVM IR.
180182
Param2DILocTy ParamDbgMappings;
181183

184+
/// Key Instructions bookkeeping.
185+
/// Source atoms are identified by a {AtomGroup, InlinedAt} pair, meaning
186+
/// AtomGroup numbers can be repeated across different functions.
187+
struct {
188+
uint64_t NextAtom = 1;
189+
uint64_t HighestEmittedAtom = 0;
190+
uint64_t CurrentAtom = 0;
191+
} KeyInstructionsInfo;
192+
193+
private:
182194
/// Helper functions for getOrCreateType.
183195
/// @{
184196
/// Currently the checksum of an interface includes the number of
@@ -647,7 +659,27 @@ class CGDebugInfo {
647659
llvm::DILocation *CreateSyntheticInlineAt(llvm::DebugLoc Location,
648660
StringRef FuncName);
649661

662+
/// Reset internal state.
663+
void completeFunction();
664+
665+
/// Add \p KeyInstruction and an optional \p Backup instruction to the
666+
/// current atom group, created using ApplyAtomGroup.
667+
void addInstToCurrentSourceAtom(llvm::Instruction *KeyInstruction,
668+
llvm::Value *Backup);
669+
670+
/// Add \p KeyInstruction and an optional \p Backup instruction to the atom
671+
/// group \p Atom.
672+
void addInstToSpecificSourceAtom(llvm::Instruction *KeyInstruction,
673+
llvm::Value *Backup, uint64_t Atom);
674+
650675
private:
676+
/// Amend \p I's DebugLoc with \p Group (its source atom group) and \p
677+
/// Rank (lower nonzero rank is higher precedence). Does nothing if \p I
678+
/// has no DebugLoc, and chooses the atom group in which the instruction
679+
/// has the highest precedence if it's already in one.
680+
void addInstSourceAtomMetadata(llvm::Instruction *I, uint64_t Group,
681+
uint8_t Rank);
682+
651683
/// Emit call to llvm.dbg.declare for a variable declaration.
652684
/// Returns a pointer to the DILocalVariable associated with the
653685
/// llvm.dbg.declare, or nullptr otherwise.
@@ -864,6 +896,20 @@ class CGDebugInfo {
864896
}
865897
};
866898

899+
/// A scoped helper to set the current source atom group for
900+
/// CGDebugInfo::addInstToCurrentSourceAtom. A source atom is a source construct
901+
/// that is "interesting" for debug stepping purposes. We use an atom group
902+
/// number to track the instruction(s) that implement the functionality for the
903+
/// atom, plus backup instructions/source locations.
904+
class ApplyAtomGroup {
905+
uint64_t OriginalAtom = 0;
906+
CGDebugInfo *DI = nullptr;
907+
908+
public:
909+
ApplyAtomGroup(CGDebugInfo *DI);
910+
~ApplyAtomGroup();
911+
};
912+
867913
/// A scoped helper to set the current debug location to the specified
868914
/// location or preferred location of the specified Expr.
869915
class ApplyDebugLocation {

clang/lib/CodeGen/CodeGenFunction.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3415,3 +3415,15 @@ CodeGenFunction::EmitPointerAuthAuth(const CGPointerAuthInfo &PointerAuth,
34153415
return EmitPointerAuthCommon(*this, PointerAuth, Pointer,
34163416
llvm::Intrinsic::ptrauth_auth);
34173417
}
3418+
3419+
void CodeGenFunction::addInstToCurrentSourceAtom(
3420+
llvm::Instruction *KeyInstruction, llvm::Value *Backup) {
3421+
if (CGDebugInfo *DI = getDebugInfo())
3422+
DI->addInstToCurrentSourceAtom(KeyInstruction, Backup);
3423+
}
3424+
3425+
void CodeGenFunction::addInstToSpecificSourceAtom(
3426+
llvm::Instruction *KeyInstruction, llvm::Value *Backup, uint64_t Atom) {
3427+
if (CGDebugInfo *DI = getDebugInfo())
3428+
DI->addInstToSpecificSourceAtom(KeyInstruction, Backup, Atom);
3429+
}

clang/lib/CodeGen/CodeGenFunction.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,6 +1785,14 @@ class CodeGenFunction : public CodeGenTypeCache {
17851785
/// recently incremented counter.
17861786
uint64_t getCurrentProfileCount() { return PGO.getCurrentRegionCount(); }
17871787

1788+
/// See CGDebugInfo::addInstToCurrentSourceAtom.
1789+
void addInstToCurrentSourceAtom(llvm::Instruction *KeyInstruction,
1790+
llvm::Value *Backup);
1791+
1792+
/// See CGDebugInfo::addInstToSpecificSourceAtom.
1793+
void addInstToSpecificSourceAtom(llvm::Instruction *KeyInstruction,
1794+
llvm::Value *Backup, uint64_t Atom);
1795+
17881796
private:
17891797
/// SwitchInsn - This is nearest current switch instruction. It is null if
17901798
/// current context is not in a switch.

0 commit comments

Comments
 (0)