[clang] 800bf8e - [InstrProf] Attach debug info to counters
Ellis Hoag via cfe-commits
cfe-commits at lists.llvm.org
Mon Dec 13 17:51:32 PST 2021
Author: Ellis Hoag
Date: 2021-12-13T17:51:22-08:00
New Revision: 800bf8ed29fbcaa9436540e83bc119ec92e7d40f
URL: https://github.com/llvm/llvm-project/commit/800bf8ed29fbcaa9436540e83bc119ec92e7d40f
DIFF: https://github.com/llvm/llvm-project/commit/800bf8ed29fbcaa9436540e83bc119ec92e7d40f.diff
LOG: [InstrProf] Attach debug info to counters
Add the llvm flag `-debug-info-correlate` to attach debug info to instrumentation counters so we can correlate raw profile data to their functions. Raw profiles are dumped as `.proflite` files. The next diff enables `llvm-profdata` to consume `.proflite` and debug info files to produce a normal `.profdata` profile.
Part of the "lightweight instrumentation" work: https://groups.google.com/g/llvm-dev/c/r03Z6JoN7d4
Reviewed By: kyulee
Differential Revision: https://reviews.llvm.org/D114565
Added:
llvm/test/Instrumentation/InstrProfiling/debug-info-correlate.ll
Modified:
clang/lib/CodeGen/BackendUtil.cpp
compiler-rt/include/profile/InstrProfData.inc
compiler-rt/lib/profile/InstrProfiling.c
compiler-rt/lib/profile/InstrProfilingMerge.c
compiler-rt/lib/profile/InstrProfilingWriter.c
llvm/include/llvm/ProfileData/InstrProf.h
llvm/include/llvm/ProfileData/InstrProfData.inc
llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
llvm/lib/ProfileData/InstrProf.cpp
llvm/lib/ProfileData/InstrProfWriter.cpp
llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 510f3911939cf..e5fcf2b2c968f 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -94,10 +94,17 @@ using namespace llvm;
llvm::PassPluginLibraryInfo get##Ext##PluginInfo();
#include "llvm/Support/Extension.def"
+namespace llvm {
+extern cl::opt<bool> DebugInfoCorrelate;
+}
+
namespace {
// Default filename used for profile generation.
-static constexpr StringLiteral DefaultProfileGenName = "default_%m.profraw";
+Twine getDefaultProfileGenName() {
+ const Twine Extension = DebugInfoCorrelate ? "proflite" : "profraw";
+ return "default_%m." + Extension;
+}
class EmitAssemblyHelper {
DiagnosticsEngine &Diags;
@@ -886,7 +893,7 @@ void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM,
if (!CodeGenOpts.InstrProfileOutput.empty())
PMBuilder.PGOInstrGen = CodeGenOpts.InstrProfileOutput;
else
- PMBuilder.PGOInstrGen = std::string(DefaultProfileGenName);
+ PMBuilder.PGOInstrGen = getDefaultProfileGenName().str();
}
if (CodeGenOpts.hasProfileIRUse()) {
PMBuilder.PGOInstrUse = CodeGenOpts.ProfileInstrumentUsePath;
@@ -1231,7 +1238,7 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
if (CodeGenOpts.hasProfileIRInstr())
// -fprofile-generate.
PGOOpt = PGOOptions(CodeGenOpts.InstrProfileOutput.empty()
- ? std::string(DefaultProfileGenName)
+ ? getDefaultProfileGenName().str()
: CodeGenOpts.InstrProfileOutput,
"", "", PGOOptions::IRInstr, PGOOptions::NoCSAction,
CodeGenOpts.DebugInfoForProfiling);
@@ -1269,13 +1276,13 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
"Cannot run CSProfileGen pass with ProfileGen or SampleUse "
" pass");
PGOOpt->CSProfileGenFile = CodeGenOpts.InstrProfileOutput.empty()
- ? std::string(DefaultProfileGenName)
+ ? getDefaultProfileGenName().str()
: CodeGenOpts.InstrProfileOutput;
PGOOpt->CSAction = PGOOptions::CSIRInstr;
} else
PGOOpt = PGOOptions("",
CodeGenOpts.InstrProfileOutput.empty()
- ? std::string(DefaultProfileGenName)
+ ? getDefaultProfileGenName().str()
: CodeGenOpts.InstrProfileOutput,
"", PGOOptions::NoAction, PGOOptions::CSIRInstr,
CodeGenOpts.DebugInfoForProfiling);
diff --git a/compiler-rt/include/profile/InstrProfData.inc b/compiler-rt/include/profile/InstrProfData.inc
index 008b8dde5820a..44719126b5965 100644
--- a/compiler-rt/include/profile/InstrProfData.inc
+++ b/compiler-rt/include/profile/InstrProfData.inc
@@ -653,15 +653,17 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
/* Profile version is always of type uint64_t. Reserve the upper 8 bits in the
* version for other variants of profile. We set the lowest bit of the upper 8
- * bits (i.e. bit 56) to 1 to indicate if this is an IR-level instrumentaiton
+ * bits (i.e. bit 56) to 1 to indicate if this is an IR-level instrumentation
* generated profile, and 0 if this is a Clang FE generated profile.
* 1 in bit 57 indicates there are context-sensitive records in the profile.
+ * The 59th bit indicates whether to use debug info to correlate profiles.
*/
#define VARIANT_MASKS_ALL 0xff00000000000000ULL
#define GET_VERSION(V) ((V) & ~VARIANT_MASKS_ALL)
#define VARIANT_MASK_IR_PROF (0x1ULL << 56)
#define VARIANT_MASK_CSIR_PROF (0x1ULL << 57)
#define VARIANT_MASK_INSTR_ENTRY (0x1ULL << 58)
+#define VARIANT_MASK_DBG_CORRELATE (0x1ULL << 59)
#define INSTR_PROF_RAW_VERSION_VAR __llvm_profile_raw_version
#define INSTR_PROF_PROFILE_RUNTIME_VAR __llvm_profile_runtime
#define INSTR_PROF_PROFILE_COUNTER_BIAS_VAR __llvm_profile_counter_bias
diff --git a/compiler-rt/lib/profile/InstrProfiling.c b/compiler-rt/lib/profile/InstrProfiling.c
index 6df65f66df732..7c1d357d96fe5 100644
--- a/compiler-rt/lib/profile/InstrProfiling.c
+++ b/compiler-rt/lib/profile/InstrProfiling.c
@@ -38,7 +38,7 @@ __llvm_profile_get_num_padding_bytes(uint64_t SizeInBytes) {
}
COMPILER_RT_VISIBILITY uint64_t __llvm_profile_get_version(void) {
- return __llvm_profile_raw_version;
+ return INSTR_PROF_RAW_VERSION_VAR;
}
COMPILER_RT_VISIBILITY void __llvm_profile_reset_counters(void) {
diff --git a/compiler-rt/lib/profile/InstrProfilingMerge.c b/compiler-rt/lib/profile/InstrProfilingMerge.c
index 80db2527461e4..a952c0de40b48 100644
--- a/compiler-rt/lib/profile/InstrProfilingMerge.c
+++ b/compiler-rt/lib/profile/InstrProfilingMerge.c
@@ -95,6 +95,11 @@ static uintptr_t signextIfWin64(void *V) {
COMPILER_RT_VISIBILITY
int __llvm_profile_merge_from_buffer(const char *ProfileData,
uint64_t ProfileSize) {
+ int DebugInfoCorrelate =
+ (__llvm_profile_get_version() & VARIANT_MASK_DBG_CORRELATE) != 0ULL;
+ if (DebugInfoCorrelate)
+ return 1;
+
__llvm_profile_data *SrcDataStart, *SrcDataEnd, *SrcData, *DstData;
__llvm_profile_header *Header = (__llvm_profile_header *)ProfileData;
uint64_t *SrcCountersStart;
diff --git a/compiler-rt/lib/profile/InstrProfilingWriter.c b/compiler-rt/lib/profile/InstrProfilingWriter.c
index 9cb05570989dc..e5c0dc1479d9e 100644
--- a/compiler-rt/lib/profile/InstrProfilingWriter.c
+++ b/compiler-rt/lib/profile/InstrProfilingWriter.c
@@ -259,16 +259,19 @@ lprofWriteDataImpl(ProfDataWriter *Writer, const __llvm_profile_data *DataBegin,
const uint64_t *CountersBegin, const uint64_t *CountersEnd,
VPDataReaderType *VPDataReader, const char *NamesBegin,
const char *NamesEnd, int SkipNameDataWrite) {
+ int DebugInfoCorrelate =
+ (__llvm_profile_get_version() & VARIANT_MASK_DBG_CORRELATE) != 0ULL;
/* Calculate size of sections. */
- const uint64_t DataSize = __llvm_profile_get_data_size(DataBegin, DataEnd);
+ const uint64_t DataSize =
+ DebugInfoCorrelate ? 0 : __llvm_profile_get_data_size(DataBegin, DataEnd);
const uint64_t CountersSize = CountersEnd - CountersBegin;
- const uint64_t NamesSize = NamesEnd - NamesBegin;
+ const uint64_t NamesSize = DebugInfoCorrelate ? 0 : NamesEnd - NamesBegin;
/* Create the header. */
__llvm_profile_header Header;
- if (!DataSize)
+ if (!DataSize && (!DebugInfoCorrelate || !CountersSize))
return 0;
/* Determine how much padding is needed before/after the counters and after
@@ -289,6 +292,12 @@ lprofWriteDataImpl(ProfDataWriter *Writer, const __llvm_profile_data *DataBegin,
Header.CountersDelta = (uint32_t)Header.CountersDelta;
#endif
+ /* The data and names sections are omitted in lightweight mode. */
+ if (DebugInfoCorrelate) {
+ Header.CountersDelta = 0;
+ Header.NamesDelta = 0;
+ }
+
/* Write the profile header. */
ProfDataIOVec IOVec[] = {{&Header, sizeof(__llvm_profile_header), 1, 0}};
if (Writer->Write(Writer, IOVec, sizeof(IOVec) / sizeof(*IOVec)))
@@ -300,11 +309,13 @@ lprofWriteDataImpl(ProfDataWriter *Writer, const __llvm_profile_data *DataBegin,
/* Write the profile data. */
ProfDataIOVec IOVecData[] = {
- {DataBegin, sizeof(__llvm_profile_data), DataSize, 0},
+ {DebugInfoCorrelate ? NULL : DataBegin, sizeof(__llvm_profile_data),
+ DataSize, 0},
{NULL, sizeof(uint8_t), PaddingBytesBeforeCounters, 1},
{CountersBegin, sizeof(uint64_t), CountersSize, 0},
{NULL, sizeof(uint8_t), PaddingBytesAfterCounters, 1},
- {SkipNameDataWrite ? NULL : NamesBegin, sizeof(uint8_t), NamesSize, 0},
+ {(SkipNameDataWrite || DebugInfoCorrelate) ? NULL : NamesBegin,
+ sizeof(uint8_t), NamesSize, 0},
{NULL, sizeof(uint8_t), PaddingBytesAfterNames, 1}};
if (Writer->Write(Writer, IOVecData, sizeof(IOVecData) / sizeof(*IOVecData)))
return -1;
diff --git a/llvm/include/llvm/ProfileData/InstrProf.h b/llvm/include/llvm/ProfileData/InstrProf.h
index 4395c2abb33ee..398a18448dd12 100644
--- a/llvm/include/llvm/ProfileData/InstrProf.h
+++ b/llvm/include/llvm/ProfileData/InstrProf.h
@@ -1149,7 +1149,8 @@ void getMemOPSizeRangeFromOption(StringRef Str, int64_t &RangeStart,
// Create a COMDAT variable INSTR_PROF_RAW_VERSION_VAR to make the runtime
// aware this is an ir_level profile so it can set the version flag.
GlobalVariable *createIRLevelProfileFlagVar(Module &M, bool IsCS,
- bool InstrEntryBBEnabled);
+ bool InstrEntryBBEnabled,
+ bool DebugInfoCorrelate);
// Create the variable for the profile file name.
void createProfileFileNameVar(Module &M, StringRef InstrProfileOutput);
diff --git a/llvm/include/llvm/ProfileData/InstrProfData.inc b/llvm/include/llvm/ProfileData/InstrProfData.inc
index 008b8dde5820a..44719126b5965 100644
--- a/llvm/include/llvm/ProfileData/InstrProfData.inc
+++ b/llvm/include/llvm/ProfileData/InstrProfData.inc
@@ -653,15 +653,17 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
/* Profile version is always of type uint64_t. Reserve the upper 8 bits in the
* version for other variants of profile. We set the lowest bit of the upper 8
- * bits (i.e. bit 56) to 1 to indicate if this is an IR-level instrumentaiton
+ * bits (i.e. bit 56) to 1 to indicate if this is an IR-level instrumentation
* generated profile, and 0 if this is a Clang FE generated profile.
* 1 in bit 57 indicates there are context-sensitive records in the profile.
+ * The 59th bit indicates whether to use debug info to correlate profiles.
*/
#define VARIANT_MASKS_ALL 0xff00000000000000ULL
#define GET_VERSION(V) ((V) & ~VARIANT_MASKS_ALL)
#define VARIANT_MASK_IR_PROF (0x1ULL << 56)
#define VARIANT_MASK_CSIR_PROF (0x1ULL << 57)
#define VARIANT_MASK_INSTR_ENTRY (0x1ULL << 58)
+#define VARIANT_MASK_DBG_CORRELATE (0x1ULL << 59)
#define INSTR_PROF_RAW_VERSION_VAR __llvm_profile_raw_version
#define INSTR_PROF_PROFILE_RUNTIME_VAR __llvm_profile_runtime
#define INSTR_PROF_PROFILE_COUNTER_BIAS_VAR __llvm_profile_counter_bias
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index cea866e22664c..69adaa824bdce 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -842,13 +842,17 @@ void DwarfUnit::addAnnotation(DIE &Buffer, DINodeArray Annotations) {
for (const Metadata *Annotation : Annotations->operands()) {
const MDNode *MD = cast<MDNode>(Annotation);
const MDString *Name = cast<MDString>(MD->getOperand(0));
-
- // Currently, only MDString is supported with btf_decl_tag attribute.
- const MDString *Value = cast<MDString>(MD->getOperand(1));
+ const auto &Value = MD->getOperand(1);
DIE &AnnotationDie = createAndAddDIE(dwarf::DW_TAG_LLVM_annotation, Buffer);
addString(AnnotationDie, dwarf::DW_AT_name, Name->getString());
- addString(AnnotationDie, dwarf::DW_AT_const_value, Value->getString());
+ if (const auto *Data = dyn_cast<MDString>(Value))
+ addString(AnnotationDie, dwarf::DW_AT_const_value, Data->getString());
+ else if (const auto *Data = dyn_cast<ConstantAsMetadata>(Value))
+ addConstantValue(AnnotationDie, Data->getValue()->getUniqueInteger(),
+ /*Unsigned=*/true);
+ else
+ assert(false && "Unsupported annotation value type");
}
}
diff --git a/llvm/lib/ProfileData/InstrProf.cpp b/llvm/lib/ProfileData/InstrProf.cpp
index 69b04c835d59d..187e97851247d 100644
--- a/llvm/lib/ProfileData/InstrProf.cpp
+++ b/llvm/lib/ProfileData/InstrProf.cpp
@@ -1175,7 +1175,8 @@ bool canRenameComdatFunc(const Function &F, bool CheckAddressTaken) {
// Create a COMDAT variable INSTR_PROF_RAW_VERSION_VAR to make the runtime
// aware this is an ir_level profile so it can set the version flag.
GlobalVariable *createIRLevelProfileFlagVar(Module &M, bool IsCS,
- bool InstrEntryBBEnabled) {
+ bool InstrEntryBBEnabled,
+ bool DebugInfoCorrelate) {
const StringRef VarName(INSTR_PROF_QUOTE(INSTR_PROF_RAW_VERSION_VAR));
Type *IntTy64 = Type::getInt64Ty(M.getContext());
uint64_t ProfileVersion = (INSTR_PROF_RAW_VERSION | VARIANT_MASK_IR_PROF);
@@ -1183,6 +1184,8 @@ GlobalVariable *createIRLevelProfileFlagVar(Module &M, bool IsCS,
ProfileVersion |= VARIANT_MASK_CSIR_PROF;
if (InstrEntryBBEnabled)
ProfileVersion |= VARIANT_MASK_INSTR_ENTRY;
+ if (DebugInfoCorrelate)
+ ProfileVersion |= VARIANT_MASK_DBG_CORRELATE;
auto IRLevelVersionVariable = new GlobalVariable(
M, IntTy64, true, GlobalValue::WeakAnyLinkage,
Constant::getIntegerValue(IntTy64, APInt(64, ProfileVersion)), VarName);
diff --git a/llvm/lib/ProfileData/InstrProfWriter.cpp b/llvm/lib/ProfileData/InstrProfWriter.cpp
index 492e3541cb5a7..6628eea806400 100644
--- a/llvm/lib/ProfileData/InstrProfWriter.cpp
+++ b/llvm/lib/ProfileData/InstrProfWriter.cpp
@@ -32,6 +32,7 @@
#include <vector>
using namespace llvm;
+extern cl::opt<bool> DebugInfoCorrelate;
// A struct to define how the data stream should be patched. For Indexed
// profiling, only uint64_t data type is needed.
diff --git a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
index d1d3b8ffdf7a2..38ed291fd1a27 100644
--- a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
+++ b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
@@ -26,7 +26,9 @@
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalValue.h"
@@ -57,6 +59,13 @@ using namespace llvm;
#define DEBUG_TYPE "instrprof"
+namespace llvm {
+cl::opt<bool>
+ DebugInfoCorrelate("debug-info-correlate", cl::ZeroOrMore,
+ cl::desc("Use debug info to correlate profiles."),
+ cl::init(false));
+} // namespace llvm
+
namespace {
cl::opt<bool> DoHashBasedCounterSplit(
@@ -641,6 +650,12 @@ void InstrProfiling::computeNumValueSiteCounts(InstrProfValueProfileInst *Ind) {
}
void InstrProfiling::lowerValueProfileInst(InstrProfValueProfileInst *Ind) {
+ // TODO: Value profiling heavily depends on the data section which is omitted
+ // in lightweight mode. We need to move the value profile pointer to the
+ // Counter struct to get this working.
+ assert(
+ !DebugInfoCorrelate &&
+ "Value profiling is not yet supported with lightweight instrumentation");
GlobalVariable *Name = Ind->getName();
auto It = ProfileDataMap.find(Name);
assert(It != ProfileDataMap.end() && It->second.DataVar &&
@@ -855,6 +870,12 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
GlobalValue::LinkageTypes Linkage = NamePtr->getLinkage();
GlobalValue::VisibilityTypes Visibility = NamePtr->getVisibility();
+ // Use internal rather than private linkage so the counter variable shows up
+ // in the symbol table when using debug info for correlation.
+ if (DebugInfoCorrelate && TT.isOSBinFormatMachO() &&
+ Linkage == GlobalValue::PrivateLinkage)
+ Linkage = GlobalValue::InternalLinkage;
+
// Due to the limitation of binder as of 2021/09/28, the duplicate weak
// symbols in the same csect won't be discarded. When there are duplicate weak
// symbols, we can NOT guarantee that the relocations get resolved to the
@@ -916,6 +937,42 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
MaybeSetComdat(CounterPtr);
CounterPtr->setLinkage(Linkage);
PD.RegionCounters = CounterPtr;
+ if (DebugInfoCorrelate) {
+ if (auto *SP = Fn->getSubprogram()) {
+ DIBuilder DB(*M, true, SP->getUnit());
+ Metadata *FunctionNameAnnotation[] = {
+ MDString::get(Ctx, "Function Name"),
+ MDString::get(Ctx, getPGOFuncNameVarInitializer(NamePtr)),
+ };
+ Metadata *CFGHashAnnotation[] = {
+ MDString::get(Ctx, "CFG Hash"),
+ ConstantAsMetadata::get(Inc->getHash()),
+ };
+ Metadata *NumCountersAnnotation[] = {
+ MDString::get(Ctx, "Num Counters"),
+ ConstantAsMetadata::get(Inc->getNumCounters()),
+ };
+ auto Annotations = DB.getOrCreateArray({
+ MDNode::get(Ctx, FunctionNameAnnotation),
+ MDNode::get(Ctx, CFGHashAnnotation),
+ MDNode::get(Ctx, NumCountersAnnotation),
+ });
+ auto *DICounter = DB.createGlobalVariableExpression(
+ SP, CounterPtr->getName(), /*LinkageName=*/StringRef(), SP->getFile(),
+ /*LineNo=*/0, DB.createUnspecifiedType("Profile Data Type"),
+ CounterPtr->hasLocalLinkage(), /*IsDefined=*/true, /*Expr=*/nullptr,
+ /*Decl=*/nullptr, /*TemplateParams=*/nullptr, /*AlignInBits=*/0,
+ Annotations);
+ CounterPtr->addDebugInfo(DICounter);
+ DB.finalize();
+ } else {
+ std::string Msg = ("Missing debug info for function " + Fn->getName() +
+ "; required for profile correlation.")
+ .str();
+ Ctx.diagnose(
+ DiagnosticInfoPGOProfile(M->getName().data(), Msg, DS_Warning));
+ }
+ }
auto *Int8PtrTy = Type::getInt8PtrTy(Ctx);
// Allocate statically the array of pointers to value profile nodes for
@@ -939,6 +996,9 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
ConstantExpr::getBitCast(ValuesVar, Type::getInt8PtrTy(Ctx));
}
+ if (DebugInfoCorrelate)
+ return PD.RegionCounters;
+
// Create data variable.
auto *IntPtrTy = M->getDataLayout().getIntPtrType(M->getContext());
auto *Int16Ty = Type::getInt16Ty(Ctx);
diff --git a/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp b/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
index 5535767ea7e4d..b6ba1fc2132cb 100644
--- a/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
+++ b/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
@@ -291,6 +291,8 @@ extern cl::opt<PGOViewCountsType> PGOViewCounts;
// Command line option to specify the name of the function for CFG dump
// Defined in Analysis/BlockFrequencyInfo.cpp: -view-bfi-func-name=
extern cl::opt<std::string> ViewBlockFreqFuncName;
+
+extern cl::opt<bool> DebugInfoCorrelate;
} // namespace llvm
static cl::opt<bool>
@@ -467,8 +469,9 @@ class PGOInstrumentationGenCreateVarLegacyPass : public ModulePass {
createProfileFileNameVar(M, InstrProfileOutput);
// The variable in a comdat may be discarded by LTO. Ensure the
// declaration will be retained.
- appendToCompilerUsed(
- M, createIRLevelProfileFlagVar(M, /*IsCS=*/true, PGOInstrumentEntry));
+ appendToCompilerUsed(M, createIRLevelProfileFlagVar(M, /*IsCS=*/true,
+ PGOInstrumentEntry,
+ DebugInfoCorrelate));
return false;
}
std::string InstrProfileOutput;
@@ -1616,7 +1619,8 @@ static bool InstrumentAllFunctions(
// For the context-sensitve instrumentation, we should have a separated pass
// (before LTO/ThinLTO linking) to create these variables.
if (!IsCS)
- createIRLevelProfileFlagVar(M, /*IsCS=*/false, PGOInstrumentEntry);
+ createIRLevelProfileFlagVar(M, /*IsCS=*/false, PGOInstrumentEntry,
+ DebugInfoCorrelate);
std::unordered_multimap<Comdat *, GlobalValue *> ComdatMembers;
collectComdatMembers(M, ComdatMembers);
@@ -1638,8 +1642,9 @@ PGOInstrumentationGenCreateVar::run(Module &M, ModuleAnalysisManager &AM) {
createProfileFileNameVar(M, CSInstrName);
// The variable in a comdat may be discarded by LTO. Ensure the declaration
// will be retained.
- appendToCompilerUsed(
- M, createIRLevelProfileFlagVar(M, /*IsCS=*/true, PGOInstrumentEntry));
+ appendToCompilerUsed(M, createIRLevelProfileFlagVar(M, /*IsCS=*/true,
+ PGOInstrumentEntry,
+ DebugInfoCorrelate));
return PreservedAnalyses::all();
}
diff --git a/llvm/test/Instrumentation/InstrProfiling/debug-info-correlate.ll b/llvm/test/Instrumentation/InstrProfiling/debug-info-correlate.ll
new file mode 100644
index 0000000000000..4166352d10f5d
--- /dev/null
+++ b/llvm/test/Instrumentation/InstrProfiling/debug-info-correlate.ll
@@ -0,0 +1,74 @@
+; RUN: opt < %s -instrprof -debug-info-correlate -S > %t.ll
+; RUN: llc < %t.ll --filetype=asm > %t.s
+; RUN: llc < %t.ll --filetype=obj > %t.o
+; RUN: FileCheck < %t.ll %s
+; RUN: llvm-dwarfdump %t.o | FileCheck %s --implicit-check-not "{{DW_TAG|NULL}}" --check-prefix CHECK-DWARF
+; RUN: FileCheck < %t.s %s --check-prefix CHECK-ASM
+
+target triple = "aarch64-unknown-linux-gnu"
+
+ at __profn_foo = private constant [3 x i8] c"foo"
+; CHECK: @__profc_foo =
+; CHECK-SAME: !dbg ![[EXPR:[0-9]+]]
+
+; CHECK: ![[EXPR]] = !DIGlobalVariableExpression(var: ![[GLOBAL:[0-9]+]]
+; CHECK: ![[GLOBAL]] = {{.*}} !DIGlobalVariable(name: "__profc_foo"
+; CHECK-SAME: scope: ![[SCOPE:[0-9]+]]
+; CHECK-SAME: annotations: ![[ANNOTATIONS:[0-9]+]]
+; CHECK: ![[SCOPE]] = {{.*}} !DISubprogram(name: "foo"
+; CHECK: ![[ANNOTATIONS]] = !{![[NAME:[0-9]+]], ![[HASH:[0-9]+]], ![[COUNTERS:[0-9]+]]}
+; CHECK: ![[NAME]] = !{!"Function Name", !"foo"}
+; CHECK: ![[HASH]] = !{!"CFG Hash", i64 12345678}
+; CHECK: ![[COUNTERS]] = !{!"Num Counters", i32 2}
+
+define void @_Z3foov() !dbg !12 {
+ call void @llvm.instrprof.increment(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @__profn_foo, i32 0, i32 0), i64 12345678, i32 2, i32 0)
+ ret void
+}
+
+declare void @llvm.instrprof.increment(i8*, i64, i32, i32)
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2, !3, !4, !5, !6, !7, !8, !9, !10}
+!llvm.ident = !{!11}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 14.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "debug-info-correlate.cpp", directory: "")
+!2 = !{i32 7, !"Dwarf Version", i32 4}
+!3 = !{i32 2, !"Debug Info Version", i32 3}
+!4 = !{i32 1, !"wchar_size", i32 4}
+!5 = !{i32 1, !"branch-target-enforcement", i32 0}
+!6 = !{i32 1, !"sign-return-address", i32 0}
+!7 = !{i32 1, !"sign-return-address-all", i32 0}
+!8 = !{i32 1, !"sign-return-address-with-bkey", i32 0}
+!9 = !{i32 7, !"uwtable", i32 1}
+!10 = !{i32 7, !"frame-pointer", i32 1}
+!11 = !{!"clang version 14.0.0"}
+!12 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !13, file: !13, line: 1, type: !14, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !16)
+!13 = !DIFile(filename: "debug-info-correlate.cpp", directory: "")
+!14 = !DISubroutineType(types: !15)
+!15 = !{null}
+!16 = !{}
+
+; CHECK-DWARF: DW_TAG_compile_unit
+; CHECK-DWARF: DW_TAG_subprogram
+; CHECK-DWARF: DW_AT_name ("foo")
+; CHECK-DWARF: DW_TAG_variable
+; CHECK-DWARF: DW_AT_name ("__profc_foo")
+; CHECK-DWARF: DW_AT_type ({{.*}} "Profile Data Type")
+; CHECK-DWARF: DW_TAG_LLVM_annotation
+; CHECK-DWARF: DW_AT_name ("Function Name")
+; CHECK-DWARF: DW_AT_const_value ("foo")
+; CHECK-DWARF: DW_TAG_LLVM_annotation
+; CHECK-DWARF: DW_AT_name ("CFG Hash")
+; CHECK-DWARF: DW_AT_const_value (12345678)
+; CHECK-DWARF: DW_TAG_LLVM_annotation
+; CHECK-DWARF: DW_AT_name ("Num Counters")
+; CHECK-DWARF: DW_AT_const_value (2)
+; CHECK-DWARF: NULL
+; CHECK-DWARF: NULL
+; CHECK-DWARF: DW_TAG_unspecified_type
+; CHECK-DWARF: NULL
+
+; CHECK-ASM-NOT: .section __llvm_prf_data
+; CHECK-ASM-NOT: .section __llvm_prf_names
More information about the cfe-commits
mailing list