Skip to content

Snapshot of alternative DISubprogram nextAtomGroup flag approach #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 21 additions & 7 deletions clang/lib/CodeGen/CGDebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
Expand Down Expand Up @@ -192,8 +193,13 @@ void CGDebugInfo::addInstToSpecificSourceAtom(llvm::Instruction *KeyInstruction,
}
}

void CGDebugInfo::completeFunction() {
// Reset the atom group number tracker as the numbers are function-local.
void CGDebugInfo::completeFunction(llvm::Function *Fn) {
// Set DISubprogram::NextAtomGroup.
if (CGM.getCodeGenOpts().DebugKeyInstructions &&
Fn->getSubprogram()->isDefinition())
Fn->getSubprogram()->updateDILocationAtomGroupWaterline(
KeyInstructionsInfo.HighestEmittedAtom + 1);

KeyInstructionsInfo.NextAtom = 1;
KeyInstructionsInfo.HighestEmittedAtom = 0;
KeyInstructionsInfo.CurrentAtom = 0;
Expand Down Expand Up @@ -1904,7 +1910,8 @@ CGDebugInfo::createInlinedSubprogram(StringRef FuncName,
/*ScopeLine=*/0,
/*Flags=*/llvm::DINode::FlagArtificial,
/*SPFlags=*/llvm::DISubprogram::SPFlagDefinition,
/*TParams=*/nullptr, /*ThrownTypes=*/nullptr, /*Annotations=*/nullptr);
/*TParams=*/nullptr, /*ThrownTypes=*/nullptr, /*Annotations=*/nullptr,
nullptr, StringRef(), CGM.getCodeGenOpts().DebugKeyInstructions);
}

return SP;
Expand Down Expand Up @@ -2284,7 +2291,8 @@ llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
llvm::DISubprogram *SP = DBuilder.createMethod(
RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
MethodTy, VIndex, ThisAdjustment, ContainingType, Flags, SPFlags,
TParamsArray.get());
TParamsArray.get(), /*ThrownTypes*/ nullptr,
CGM.getCodeGenOpts().DebugKeyInstructions);

SPCache[Method->getCanonicalDecl()].reset(SP);

Expand Down Expand Up @@ -4350,7 +4358,9 @@ llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
return DBuilder.createFunction(
DContext, Name, LinkageName, Unit, Line,
getOrCreateFunctionType(GD.getDecl(), FnType, Unit), 0, Flags, SPFlags,
TParamsArray.get(), getFunctionDeclaration(FD));
TParamsArray.get(), getFunctionDeclaration(FD), /*ThrownTypes*/ nullptr,
/*Annotations*/ nullptr, /*TargetFuncName*/ "",
CGM.getCodeGenOpts().DebugKeyInstructions);
}

llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
Expand Down Expand Up @@ -4686,8 +4696,9 @@ void CGDebugInfo::emitFunctionStart(GlobalDecl GD, SourceLocation Loc,
llvm::DISubprogram *SP = DBuilder.createFunction(
FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
FlagsForDef, SPFlagsForDef, TParamsArray.get(), Decl, nullptr,
Annotations);
Annotations, "", CGM.getCodeGenOpts().DebugKeyInstructions);
Fn->setSubprogram(SP);

// We might get here with a VarDecl in the case we're generating
// code for the initialization of globals. Do not record these decls
// as they will overwrite the actual VarDecl Decl in the cache.
Expand Down Expand Up @@ -4746,9 +4757,12 @@ void CGDebugInfo::EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc,

llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
// Key Instructions: Do not set UseKeyInstructions on declarations.
assert(~SPFlags & llvm::DISubprogram::SPFlagDefinition);
llvm::DISubprogram *SP = DBuilder.createFunction(
FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
SPFlags, TParamsArray.get(), nullptr, nullptr, Annotations);
SPFlags, TParamsArray.get(), nullptr, nullptr, Annotations,
/*TargetFunctionName*/ "", /*UseKeyInstructions*/ false);

// Preserve btf_decl_tag attributes for parameters of extern functions
// for BPF target. The parameters created in this loop are attached as
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/CodeGen/CGDebugInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -657,8 +657,8 @@ class CGDebugInfo {
llvm::DILocation *CreateSyntheticInlineAt(llvm::DebugLoc Location,
StringRef FuncName);

/// Reset internal state.
void completeFunction();
/// Finalize some function debug info and reset per-function internal state.
void completeFunction(llvm::Function *Fn);

/// Add \p KeyInstruction and an optional \p Backup instruction to the
/// current atom group, created using ApplyAtomGroup.
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/CodeGen/CodeGenFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1512,9 +1512,9 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
DebugInfo = nullptr;
}
// Finalize function debug info on exit.
auto Cleanup = llvm::make_scope_exit([this] {
auto Cleanup = llvm::make_scope_exit([this, Fn] {
if (CGDebugInfo *DI = getDebugInfo())
DI->completeFunction();
DI->completeFunction(Fn);
});

// The function might not have a body if we're generating thunks for a
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4609,7 +4609,7 @@ renderDebugOptions(const ToolChain &TC, const Driver &D, const llvm::Triple &T,
}

if (Args.hasFlag(options::OPT_gkey_instructions,
options::OPT_gno_key_instructions, false)) {
options::OPT_gno_key_instructions, true)) {
CmdArgs.push_back("-gkey-instructions");
CmdArgs.push_back("-mllvm");
CmdArgs.push_back("-dwarf-use-key-instructions");
Expand Down
2 changes: 1 addition & 1 deletion llvm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,7 @@ set(LLVM_ENABLE_DEBUGLOC_COVERAGE_TRACKING "DISABLED" CACHE STRING
set_property(CACHE LLVM_ENABLE_DEBUGLOC_COVERAGE_TRACKING PROPERTY STRINGS DISABLED COVERAGE)

option(LLVM_EXPERIMENTAL_KEY_INSTRUCTIONS
"Add additional fields to DILocations to support Key Instructions" OFF)
"Add additional fields to DILocations to support Key Instructions" ON)

set(WINDOWS_PREFER_FORWARD_SLASH_DEFAULT OFF)
if (MINGW)
Expand Down
22 changes: 12 additions & 10 deletions llvm/include/llvm/IR/DIBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -898,14 +898,16 @@ namespace llvm {
/// \param Annotations Attribute Annotations.
/// \param TargetFuncName The name of the target function if this is
/// a trampoline.
/// \param UseKeyInstructions Enable Key Instructions debug info.
LLVM_ABI DISubprogram *createFunction(
DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File,
unsigned LineNo, DISubroutineType *Ty, unsigned ScopeLine,
DINode::DIFlags Flags = DINode::FlagZero,
DISubprogram::DISPFlags SPFlags = DISubprogram::SPFlagZero,
DITemplateParameterArray TParams = nullptr,
DISubprogram *Decl = nullptr, DITypeArray ThrownTypes = nullptr,
DINodeArray Annotations = nullptr, StringRef TargetFuncName = "");
DINodeArray Annotations = nullptr, StringRef TargetFuncName = "",
bool UseKeyInstructions = false);

/// Identical to createFunction,
/// except that the resulting DbgNode is meant to be RAUWed.
Expand Down Expand Up @@ -936,15 +938,15 @@ namespace llvm {
/// \param SPFlags Additional flags specific to subprograms.
/// \param TParams Function template parameters.
/// \param ThrownTypes Exception types this function may throw.
LLVM_ABI DISubprogram *
createMethod(DIScope *Scope, StringRef Name, StringRef LinkageName,
DIFile *File, unsigned LineNo, DISubroutineType *Ty,
unsigned VTableIndex = 0, int ThisAdjustment = 0,
DIType *VTableHolder = nullptr,
DINode::DIFlags Flags = DINode::FlagZero,
DISubprogram::DISPFlags SPFlags = DISubprogram::SPFlagZero,
DITemplateParameterArray TParams = nullptr,
DITypeArray ThrownTypes = nullptr);
/// \param UseKeyInstructions Enable Key Instructions debug info.
LLVM_ABI DISubprogram *createMethod(
DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File,
unsigned LineNo, DISubroutineType *Ty, unsigned VTableIndex = 0,
int ThisAdjustment = 0, DIType *VTableHolder = nullptr,
DINode::DIFlags Flags = DINode::FlagZero,
DISubprogram::DISPFlags SPFlags = DISubprogram::SPFlagZero,
DITemplateParameterArray TParams = nullptr,
DITypeArray ThrownTypes = nullptr, bool UseKeyInstructions = false);

/// Create common block entry for a Fortran common block.
/// \param Scope Scope of this common block.
Expand Down
97 changes: 72 additions & 25 deletions llvm/include/llvm/IR/DebugInfoMetadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -1976,6 +1976,21 @@ class DISubprogram : public DILocalScope {
/// negative.
int ThisAdjustment;

/// Key Instructions: The next available atom group number for this function.
/// The front end is responsible for assigning source atom numbers, but
/// certain optimisations need to assign new group numbers to a set of
/// instructions. Most often code duplication optimisations like loop unroll.
///
/// NOTE: This field doesn't contribute to the identity of the DISubprogram;
/// it's not represented in MDNodeKeyImpl<DISubprogram>. This is intentional.
/// It SHOULD ONLY be written to by distinct DISubprograms.
///
/// Zero indicates the function doesn't use Key Instructions
/// There may be Key Instruction metadata on its instructions, e.g. from
/// inlined instructions, that's all going to be ignored for this function
/// at DWARF emission time.
uint32_t NextAtomGroup = 0;

public:
/// Debug info subprogram flags.
enum DISPFlags : uint32_t {
Expand Down Expand Up @@ -2003,6 +2018,33 @@ class DISubprogram : public DILocalScope {
unsigned Virtuality = SPFlagNonvirtual,
bool IsMainSubprogram = false);

/// Key Instructions: get the next available atom group number and increment
/// the function-local tracker.
uint32_t incNextDILocationAtomGroup() {
assert(isDistinct() && getKeyInstructionsEnabled());
// NOTE: This may wrap, which effectively disables Key Instructions for
// this function. As a result, instances that have already been inlined
// will also have Key Instructions disabled for them, since we look back
// to this DISubprogram to check if it's enabled during DWARF emission.
// A quirk of the implementation that only shows up in extreme edge cases.
return NextAtomGroup++;
}

/// Key Instructions: get the next available atom group number.
uint32_t getNextDILocationAtomGroup() const {
assert(isDistinct() && getKeyInstructionsEnabled());
return NextAtomGroup;
}

bool getKeyInstructionsEnabled() const { return NextAtomGroup; }

/// Key Instructions: update the highest number atom group emitted for any
/// function.
void updateDILocationAtomGroupWaterline(uint32_t NewNextGroup) {
assert(isDistinct() && getKeyInstructionsEnabled());
NextAtomGroup = std::max(NextAtomGroup, NewNextGroup);
}

private:
DIFlags Flags;
DISPFlags SPFlags;
Expand All @@ -2021,33 +2063,34 @@ class DISubprogram : public DILocalScope {
DITemplateParameterArray TemplateParams, DISubprogram *Declaration,
DINodeArray RetainedNodes, DITypeArray ThrownTypes,
DINodeArray Annotations, StringRef TargetFuncName,
StorageType Storage, bool ShouldCreate = true) {
uint32_t KeyInstNextAtomGroup, StorageType Storage,
bool ShouldCreate = true) {
return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
getCanonicalMDString(Context, LinkageName), File, Line, Type,
ScopeLine, ContainingType, VirtualIndex, ThisAdjustment,
Flags, SPFlags, Unit, TemplateParams.get(), Declaration,
RetainedNodes.get(), ThrownTypes.get(), Annotations.get(),
getCanonicalMDString(Context, TargetFuncName),
Storage, ShouldCreate);
KeyInstNextAtomGroup, Storage, ShouldCreate);
}

LLVM_ABI static DISubprogram *
getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
unsigned ScopeLine, Metadata *ContainingType, unsigned VirtualIndex,
int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,
Metadata *TemplateParams, Metadata *Declaration,
Metadata *RetainedNodes, Metadata *ThrownTypes, Metadata *Annotations,
MDString *TargetFuncName, StorageType Storage,
bool ShouldCreate = true);
MDString *TargetFuncName, uint32_t KeyInstNextAtomGroup,
StorageType Storage, bool ShouldCreate = true);

TempDISubprogram cloneImpl() const {
return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
getFile(), getLine(), getType(), getScopeLine(),
getContainingType(), getVirtualIndex(),
getThisAdjustment(), getFlags(), getSPFlags(),
getUnit(), getTemplateParams(), getDeclaration(),
getRetainedNodes(), getThrownTypes(), getAnnotations(),
getTargetFuncName());
return getTemporary(
getContext(), getScope(), getName(), getLinkageName(), getFile(),
getLine(), getType(), getScopeLine(), getContainingType(),
getVirtualIndex(), getThisAdjustment(), getFlags(), getSPFlags(),
getUnit(), getTemplateParams(), getDeclaration(), getRetainedNodes(),
getThrownTypes(), getAnnotations(), getTargetFuncName(), NextAtomGroup);
}

public:
Expand All @@ -2060,10 +2103,11 @@ class DISubprogram : public DILocalScope {
DITemplateParameterArray TemplateParams = nullptr,
DISubprogram *Declaration = nullptr, DINodeArray RetainedNodes = nullptr,
DITypeArray ThrownTypes = nullptr, DINodeArray Annotations = nullptr,
StringRef TargetFuncName = ""),
StringRef TargetFuncName = "", uint32_t UseKeyInstructions = 0),
(Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType,
VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams,
Declaration, RetainedNodes, ThrownTypes, Annotations, TargetFuncName))
Declaration, RetainedNodes, ThrownTypes, Annotations, TargetFuncName,
UseKeyInstructions))

DEFINE_MDNODE_GET(
DISubprogram,
Expand All @@ -2073,10 +2117,12 @@ class DISubprogram : public DILocalScope {
DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,
Metadata *TemplateParams = nullptr, Metadata *Declaration = nullptr,
Metadata *RetainedNodes = nullptr, Metadata *ThrownTypes = nullptr,
Metadata *Annotations = nullptr, MDString *TargetFuncName = nullptr),
Metadata *Annotations = nullptr, MDString *TargetFuncName = nullptr,
uint32_t UseKeyInstructions = 0),
(Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType,
VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams,
Declaration, RetainedNodes, ThrownTypes, Annotations, TargetFuncName))
Declaration, RetainedNodes, ThrownTypes, Annotations, TargetFuncName,
UseKeyInstructions))

TempDISubprogram clone() const { return cloneImpl(); }

Expand Down Expand Up @@ -2245,23 +2291,24 @@ class DILocation : public MDNode {
friend class LLVMContextImpl;
friend class MDNode;
#ifdef EXPERIMENTAL_KEY_INSTRUCTIONS
uint64_t AtomGroup : 61;
uint64_t AtomRank : 3;
uint32_t AtomGroup : 29;
uint32_t AtomRank : 3;
#endif

DILocation(LLVMContext &C, StorageType Storage, unsigned Line,
unsigned Column, uint64_t AtomGroup, uint8_t AtomRank,
ArrayRef<Metadata *> MDs, bool ImplicitCode);
DILocation(LLVMContext &C, StorageType Storage,
DISubprogram *SPForKeyInstructions, unsigned Line, unsigned Column,
uint32_t AtomGroup, uint8_t AtomRank, ArrayRef<Metadata *> MDs,
bool ImplicitCode);
~DILocation() { dropAllReferences(); }

LLVM_ABI static DILocation *
getImpl(LLVMContext &Context, unsigned Line, unsigned Column, Metadata *Scope,
Metadata *InlinedAt, bool ImplicitCode, uint64_t AtomGroup,
Metadata *InlinedAt, bool ImplicitCode, uint32_t AtomGroup,
uint8_t AtomRank, StorageType Storage, bool ShouldCreate = true);
static DILocation *getImpl(LLVMContext &Context, unsigned Line,
unsigned Column, DILocalScope *Scope,
DILocation *InlinedAt, bool ImplicitCode,
uint64_t AtomGroup, uint8_t AtomRank,
uint32_t AtomGroup, uint8_t AtomRank,
StorageType Storage, bool ShouldCreate = true) {
return getImpl(Context, Line, Column, static_cast<Metadata *>(Scope),
static_cast<Metadata *>(InlinedAt), ImplicitCode, AtomGroup,
Expand All @@ -2277,7 +2324,7 @@ class DILocation : public MDNode {
}

public:
uint64_t getAtomGroup() const {
uint32_t getAtomGroup() const {
#ifdef EXPERIMENTAL_KEY_INSTRUCTIONS
return AtomGroup;
#else
Expand Down Expand Up @@ -2305,13 +2352,13 @@ class DILocation : public MDNode {
DEFINE_MDNODE_GET(DILocation,
(unsigned Line, unsigned Column, Metadata *Scope,
Metadata *InlinedAt = nullptr, bool ImplicitCode = false,
uint64_t AtomGroup = 0, uint8_t AtomRank = 0),
uint32_t AtomGroup = 0, uint8_t AtomRank = 0),
(Line, Column, Scope, InlinedAt, ImplicitCode, AtomGroup,
AtomRank))
DEFINE_MDNODE_GET(DILocation,
(unsigned Line, unsigned Column, DILocalScope *Scope,
DILocation *InlinedAt = nullptr, bool ImplicitCode = false,
uint64_t AtomGroup = 0, uint8_t AtomRank = 0),
uint32_t AtomGroup = 0, uint8_t AtomRank = 0),
(Line, Column, Scope, InlinedAt, ImplicitCode, AtomGroup,
AtomRank))

Expand Down
8 changes: 0 additions & 8 deletions llvm/include/llvm/IR/LLVMContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -341,14 +341,6 @@ class LLVMContext {
LLVM_ABI StringRef getDefaultTargetFeatures();
LLVM_ABI void setDefaultTargetFeatures(StringRef Features);

/// Key Instructions: update the highest number atom group emitted for any
/// function.
LLVM_ABI void updateDILocationAtomGroupWaterline(uint64_t G);

/// Key Instructions: get the next free atom group number and increment
/// the global tracker.
LLVM_ABI uint64_t incNextDILocationAtomGroup();

private:
// Module needs access to the add/removeModule methods.
friend class Module;
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/IR/ValueMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ class ValueMap {
using MapT = DenseMap<ValueMapCVH, ValueT, DenseMapInfo<ValueMapCVH>>;
using MDMapT = DenseMap<const Metadata *, TrackingMDRef>;
/// Map {(InlinedAt, old atom number) -> new atom number}.
using DMAtomT = SmallDenseMap<std::pair<Metadata *, uint64_t>, uint64_t>;
using DMAtomT = SmallDenseMap<std::pair<Metadata *, uint32_t>, uint32_t>;
using ExtraData = typename Config::ExtraData;

MapT Map;
Expand Down
5 changes: 3 additions & 2 deletions llvm/include/llvm/Transforms/Utils/Cloning.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,14 @@ struct ClonedCodeInfo {
/// but is sometimes unnecessary, causing extra work that could be avoided by
/// setting the parameter to false.
LLVM_ABI BasicBlock *
CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap,
CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap, DISubprogram *SP,
const Twine &NameSuffix = "", Function *F = nullptr,
ClonedCodeInfo *CodeInfo = nullptr, bool MapAtoms = true);

/// Mark a cloned instruction as a new instance so that its source loc can
/// be updated when remapped.
LLVM_ABI void mapAtomInstance(const DebugLoc &DL, ValueToValueMapTy &VMap);
LLVM_ABI void mapAtomInstance(DISubprogram *Target, const DebugLoc &DL,
ValueToValueMapTy &VMap);

/// Return a copy of the specified function and add it to that
/// function's module. Also, any references specified in the VMap are changed
Expand Down
Loading