Skip to content

Commit 800bf8e

Browse files
committed
[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
1 parent a290770 commit 800bf8e

File tree

13 files changed

+199
-24
lines changed

13 files changed

+199
-24
lines changed

clang/lib/CodeGen/BackendUtil.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,17 @@ using namespace llvm;
9494
llvm::PassPluginLibraryInfo get##Ext##PluginInfo();
9595
#include "llvm/Support/Extension.def"
9696

97+
namespace llvm {
98+
extern cl::opt<bool> DebugInfoCorrelate;
99+
}
100+
97101
namespace {
98102

99103
// Default filename used for profile generation.
100-
static constexpr StringLiteral DefaultProfileGenName = "default_%m.profraw";
104+
Twine getDefaultProfileGenName() {
105+
const Twine Extension = DebugInfoCorrelate ? "proflite" : "profraw";
106+
return "default_%m." + Extension;
107+
}
101108

102109
class EmitAssemblyHelper {
103110
DiagnosticsEngine &Diags;
@@ -886,7 +893,7 @@ void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM,
886893
if (!CodeGenOpts.InstrProfileOutput.empty())
887894
PMBuilder.PGOInstrGen = CodeGenOpts.InstrProfileOutput;
888895
else
889-
PMBuilder.PGOInstrGen = std::string(DefaultProfileGenName);
896+
PMBuilder.PGOInstrGen = getDefaultProfileGenName().str();
890897
}
891898
if (CodeGenOpts.hasProfileIRUse()) {
892899
PMBuilder.PGOInstrUse = CodeGenOpts.ProfileInstrumentUsePath;
@@ -1231,7 +1238,7 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
12311238
if (CodeGenOpts.hasProfileIRInstr())
12321239
// -fprofile-generate.
12331240
PGOOpt = PGOOptions(CodeGenOpts.InstrProfileOutput.empty()
1234-
? std::string(DefaultProfileGenName)
1241+
? getDefaultProfileGenName().str()
12351242
: CodeGenOpts.InstrProfileOutput,
12361243
"", "", PGOOptions::IRInstr, PGOOptions::NoCSAction,
12371244
CodeGenOpts.DebugInfoForProfiling);
@@ -1269,13 +1276,13 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
12691276
"Cannot run CSProfileGen pass with ProfileGen or SampleUse "
12701277
" pass");
12711278
PGOOpt->CSProfileGenFile = CodeGenOpts.InstrProfileOutput.empty()
1272-
? std::string(DefaultProfileGenName)
1279+
? getDefaultProfileGenName().str()
12731280
: CodeGenOpts.InstrProfileOutput;
12741281
PGOOpt->CSAction = PGOOptions::CSIRInstr;
12751282
} else
12761283
PGOOpt = PGOOptions("",
12771284
CodeGenOpts.InstrProfileOutput.empty()
1278-
? std::string(DefaultProfileGenName)
1285+
? getDefaultProfileGenName().str()
12791286
: CodeGenOpts.InstrProfileOutput,
12801287
"", PGOOptions::NoAction, PGOOptions::CSIRInstr,
12811288
CodeGenOpts.DebugInfoForProfiling);

compiler-rt/include/profile/InstrProfData.inc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -653,15 +653,17 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
653653

654654
/* Profile version is always of type uint64_t. Reserve the upper 8 bits in the
655655
* version for other variants of profile. We set the lowest bit of the upper 8
656-
* bits (i.e. bit 56) to 1 to indicate if this is an IR-level instrumentaiton
656+
* bits (i.e. bit 56) to 1 to indicate if this is an IR-level instrumentation
657657
* generated profile, and 0 if this is a Clang FE generated profile.
658658
* 1 in bit 57 indicates there are context-sensitive records in the profile.
659+
* The 59th bit indicates whether to use debug info to correlate profiles.
659660
*/
660661
#define VARIANT_MASKS_ALL 0xff00000000000000ULL
661662
#define GET_VERSION(V) ((V) & ~VARIANT_MASKS_ALL)
662663
#define VARIANT_MASK_IR_PROF (0x1ULL << 56)
663664
#define VARIANT_MASK_CSIR_PROF (0x1ULL << 57)
664665
#define VARIANT_MASK_INSTR_ENTRY (0x1ULL << 58)
666+
#define VARIANT_MASK_DBG_CORRELATE (0x1ULL << 59)
665667
#define INSTR_PROF_RAW_VERSION_VAR __llvm_profile_raw_version
666668
#define INSTR_PROF_PROFILE_RUNTIME_VAR __llvm_profile_runtime
667669
#define INSTR_PROF_PROFILE_COUNTER_BIAS_VAR __llvm_profile_counter_bias

compiler-rt/lib/profile/InstrProfiling.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ __llvm_profile_get_num_padding_bytes(uint64_t SizeInBytes) {
3838
}
3939

4040
COMPILER_RT_VISIBILITY uint64_t __llvm_profile_get_version(void) {
41-
return __llvm_profile_raw_version;
41+
return INSTR_PROF_RAW_VERSION_VAR;
4242
}
4343

4444
COMPILER_RT_VISIBILITY void __llvm_profile_reset_counters(void) {

compiler-rt/lib/profile/InstrProfilingMerge.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,11 @@ static uintptr_t signextIfWin64(void *V) {
9595
COMPILER_RT_VISIBILITY
9696
int __llvm_profile_merge_from_buffer(const char *ProfileData,
9797
uint64_t ProfileSize) {
98+
int DebugInfoCorrelate =
99+
(__llvm_profile_get_version() & VARIANT_MASK_DBG_CORRELATE) != 0ULL;
100+
if (DebugInfoCorrelate)
101+
return 1;
102+
98103
__llvm_profile_data *SrcDataStart, *SrcDataEnd, *SrcData, *DstData;
99104
__llvm_profile_header *Header = (__llvm_profile_header *)ProfileData;
100105
uint64_t *SrcCountersStart;

compiler-rt/lib/profile/InstrProfilingWriter.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -259,16 +259,19 @@ lprofWriteDataImpl(ProfDataWriter *Writer, const __llvm_profile_data *DataBegin,
259259
const uint64_t *CountersBegin, const uint64_t *CountersEnd,
260260
VPDataReaderType *VPDataReader, const char *NamesBegin,
261261
const char *NamesEnd, int SkipNameDataWrite) {
262+
int DebugInfoCorrelate =
263+
(__llvm_profile_get_version() & VARIANT_MASK_DBG_CORRELATE) != 0ULL;
262264

263265
/* Calculate size of sections. */
264-
const uint64_t DataSize = __llvm_profile_get_data_size(DataBegin, DataEnd);
266+
const uint64_t DataSize =
267+
DebugInfoCorrelate ? 0 : __llvm_profile_get_data_size(DataBegin, DataEnd);
265268
const uint64_t CountersSize = CountersEnd - CountersBegin;
266-
const uint64_t NamesSize = NamesEnd - NamesBegin;
269+
const uint64_t NamesSize = DebugInfoCorrelate ? 0 : NamesEnd - NamesBegin;
267270

268271
/* Create the header. */
269272
__llvm_profile_header Header;
270273

271-
if (!DataSize)
274+
if (!DataSize && (!DebugInfoCorrelate || !CountersSize))
272275
return 0;
273276

274277
/* Determine how much padding is needed before/after the counters and after
@@ -289,6 +292,12 @@ lprofWriteDataImpl(ProfDataWriter *Writer, const __llvm_profile_data *DataBegin,
289292
Header.CountersDelta = (uint32_t)Header.CountersDelta;
290293
#endif
291294

295+
/* The data and names sections are omitted in lightweight mode. */
296+
if (DebugInfoCorrelate) {
297+
Header.CountersDelta = 0;
298+
Header.NamesDelta = 0;
299+
}
300+
292301
/* Write the profile header. */
293302
ProfDataIOVec IOVec[] = {{&Header, sizeof(__llvm_profile_header), 1, 0}};
294303
if (Writer->Write(Writer, IOVec, sizeof(IOVec) / sizeof(*IOVec)))
@@ -300,11 +309,13 @@ lprofWriteDataImpl(ProfDataWriter *Writer, const __llvm_profile_data *DataBegin,
300309

301310
/* Write the profile data. */
302311
ProfDataIOVec IOVecData[] = {
303-
{DataBegin, sizeof(__llvm_profile_data), DataSize, 0},
312+
{DebugInfoCorrelate ? NULL : DataBegin, sizeof(__llvm_profile_data),
313+
DataSize, 0},
304314
{NULL, sizeof(uint8_t), PaddingBytesBeforeCounters, 1},
305315
{CountersBegin, sizeof(uint64_t), CountersSize, 0},
306316
{NULL, sizeof(uint8_t), PaddingBytesAfterCounters, 1},
307-
{SkipNameDataWrite ? NULL : NamesBegin, sizeof(uint8_t), NamesSize, 0},
317+
{(SkipNameDataWrite || DebugInfoCorrelate) ? NULL : NamesBegin,
318+
sizeof(uint8_t), NamesSize, 0},
308319
{NULL, sizeof(uint8_t), PaddingBytesAfterNames, 1}};
309320
if (Writer->Write(Writer, IOVecData, sizeof(IOVecData) / sizeof(*IOVecData)))
310321
return -1;

llvm/include/llvm/ProfileData/InstrProf.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1149,7 +1149,8 @@ void getMemOPSizeRangeFromOption(StringRef Str, int64_t &RangeStart,
11491149
// Create a COMDAT variable INSTR_PROF_RAW_VERSION_VAR to make the runtime
11501150
// aware this is an ir_level profile so it can set the version flag.
11511151
GlobalVariable *createIRLevelProfileFlagVar(Module &M, bool IsCS,
1152-
bool InstrEntryBBEnabled);
1152+
bool InstrEntryBBEnabled,
1153+
bool DebugInfoCorrelate);
11531154

11541155
// Create the variable for the profile file name.
11551156
void createProfileFileNameVar(Module &M, StringRef InstrProfileOutput);

llvm/include/llvm/ProfileData/InstrProfData.inc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -653,15 +653,17 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
653653

654654
/* Profile version is always of type uint64_t. Reserve the upper 8 bits in the
655655
* version for other variants of profile. We set the lowest bit of the upper 8
656-
* bits (i.e. bit 56) to 1 to indicate if this is an IR-level instrumentaiton
656+
* bits (i.e. bit 56) to 1 to indicate if this is an IR-level instrumentation
657657
* generated profile, and 0 if this is a Clang FE generated profile.
658658
* 1 in bit 57 indicates there are context-sensitive records in the profile.
659+
* The 59th bit indicates whether to use debug info to correlate profiles.
659660
*/
660661
#define VARIANT_MASKS_ALL 0xff00000000000000ULL
661662
#define GET_VERSION(V) ((V) & ~VARIANT_MASKS_ALL)
662663
#define VARIANT_MASK_IR_PROF (0x1ULL << 56)
663664
#define VARIANT_MASK_CSIR_PROF (0x1ULL << 57)
664665
#define VARIANT_MASK_INSTR_ENTRY (0x1ULL << 58)
666+
#define VARIANT_MASK_DBG_CORRELATE (0x1ULL << 59)
665667
#define INSTR_PROF_RAW_VERSION_VAR __llvm_profile_raw_version
666668
#define INSTR_PROF_PROFILE_RUNTIME_VAR __llvm_profile_runtime
667669
#define INSTR_PROF_PROFILE_COUNTER_BIAS_VAR __llvm_profile_counter_bias

llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -842,13 +842,17 @@ void DwarfUnit::addAnnotation(DIE &Buffer, DINodeArray Annotations) {
842842
for (const Metadata *Annotation : Annotations->operands()) {
843843
const MDNode *MD = cast<MDNode>(Annotation);
844844
const MDString *Name = cast<MDString>(MD->getOperand(0));
845-
846-
// Currently, only MDString is supported with btf_decl_tag attribute.
847-
const MDString *Value = cast<MDString>(MD->getOperand(1));
845+
const auto &Value = MD->getOperand(1);
848846

849847
DIE &AnnotationDie = createAndAddDIE(dwarf::DW_TAG_LLVM_annotation, Buffer);
850848
addString(AnnotationDie, dwarf::DW_AT_name, Name->getString());
851-
addString(AnnotationDie, dwarf::DW_AT_const_value, Value->getString());
849+
if (const auto *Data = dyn_cast<MDString>(Value))
850+
addString(AnnotationDie, dwarf::DW_AT_const_value, Data->getString());
851+
else if (const auto *Data = dyn_cast<ConstantAsMetadata>(Value))
852+
addConstantValue(AnnotationDie, Data->getValue()->getUniqueInteger(),
853+
/*Unsigned=*/true);
854+
else
855+
assert(false && "Unsupported annotation value type");
852856
}
853857
}
854858

llvm/lib/ProfileData/InstrProf.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1175,14 +1175,17 @@ bool canRenameComdatFunc(const Function &F, bool CheckAddressTaken) {
11751175
// Create a COMDAT variable INSTR_PROF_RAW_VERSION_VAR to make the runtime
11761176
// aware this is an ir_level profile so it can set the version flag.
11771177
GlobalVariable *createIRLevelProfileFlagVar(Module &M, bool IsCS,
1178-
bool InstrEntryBBEnabled) {
1178+
bool InstrEntryBBEnabled,
1179+
bool DebugInfoCorrelate) {
11791180
const StringRef VarName(INSTR_PROF_QUOTE(INSTR_PROF_RAW_VERSION_VAR));
11801181
Type *IntTy64 = Type::getInt64Ty(M.getContext());
11811182
uint64_t ProfileVersion = (INSTR_PROF_RAW_VERSION | VARIANT_MASK_IR_PROF);
11821183
if (IsCS)
11831184
ProfileVersion |= VARIANT_MASK_CSIR_PROF;
11841185
if (InstrEntryBBEnabled)
11851186
ProfileVersion |= VARIANT_MASK_INSTR_ENTRY;
1187+
if (DebugInfoCorrelate)
1188+
ProfileVersion |= VARIANT_MASK_DBG_CORRELATE;
11861189
auto IRLevelVersionVariable = new GlobalVariable(
11871190
M, IntTy64, true, GlobalValue::WeakAnyLinkage,
11881191
Constant::getIntegerValue(IntTy64, APInt(64, ProfileVersion)), VarName);

llvm/lib/ProfileData/InstrProfWriter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <vector>
3333

3434
using namespace llvm;
35+
extern cl::opt<bool> DebugInfoCorrelate;
3536

3637
// A struct to define how the data stream should be patched. For Indexed
3738
// profiling, only uint64_t data type is needed.

0 commit comments

Comments
 (0)