Skip to content

Commit a2c0b51

Browse files
committed
Enforce skipflatprof for text format sample profile
1 parent fd97012 commit a2c0b51

File tree

2 files changed

+30
-12
lines changed

2 files changed

+30
-12
lines changed

llvm/include/llvm/ProfileData/SampleProfReader.h

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -495,9 +495,9 @@ class SampleProfileReader {
495495
/// are present.
496496
virtual void setProfileUseMD5() { ProfileIsMD5 = true; }
497497

498-
/// Don't read profile without context if the flag is set. This is only meaningful
499-
/// for ExtBinary format.
500-
virtual void setSkipFlatProf(bool Skip) {}
498+
/// Don't read profile without context if the flag is set.
499+
void setSkipFlatProf(bool Skip) { SkipFlatProf = Skip; }
500+
501501
/// Return whether any name in the profile contains ".__uniq." suffix.
502502
virtual bool hasUniqSuffix() { return false; }
503503

@@ -581,6 +581,10 @@ class SampleProfileReader {
581581
/// Whether the profile uses MD5 for Sample Contexts and function names. This
582582
/// can be one-way overriden by the user to force use MD5.
583583
bool ProfileIsMD5 = false;
584+
585+
/// If SkipFlatProf is true, skip functions marked with !Flat in text mode or
586+
/// sections with SecFlagFlat flag in ExtBinary mode.
587+
bool SkipFlatProf = false;
584588
};
585589

586590
class SampleProfileReaderText : public SampleProfileReader {
@@ -789,10 +793,6 @@ class SampleProfileReaderExtBinaryBase : public SampleProfileReaderBinary {
789793
/// The set containing the functions to use when compiling a module.
790794
DenseSet<StringRef> FuncsToUse;
791795

792-
/// If SkipFlatProf is true, skip the sections with
793-
/// SecFlagFlat flag.
794-
bool SkipFlatProf = false;
795-
796796
public:
797797
SampleProfileReaderExtBinaryBase(std::unique_ptr<MemoryBuffer> B,
798798
LLVMContext &C, SampleProfileFormat Format)
@@ -815,8 +815,6 @@ class SampleProfileReaderExtBinaryBase : public SampleProfileReaderBinary {
815815
return std::move(ProfSymList);
816816
};
817817

818-
void setSkipFlatProf(bool Skip) override { SkipFlatProf = Skip; }
819-
820818
private:
821819
/// Read the profiles on-demand for the given functions. This is used after
822820
/// stale call graph matching finds new functions whose profiles aren't loaded

llvm/lib/ProfileData/SampleProfReader.cpp

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,8 @@ static bool ParseLine(const StringRef &Input, LineType &LineTy, uint32_t &Depth,
215215
uint64_t &NumSamples, uint32_t &LineOffset,
216216
uint32_t &Discriminator, StringRef &CalleeName,
217217
DenseMap<StringRef, uint64_t> &TargetCountMap,
218-
uint64_t &FunctionHash, uint32_t &Attributes) {
218+
uint64_t &FunctionHash, uint32_t &Attributes,
219+
bool &IsFlat) {
219220
for (Depth = 0; Input[Depth] == ' '; Depth++)
220221
;
221222
if (Depth == 0)
@@ -226,8 +227,10 @@ static bool ParseLine(const StringRef &Input, LineType &LineTy, uint32_t &Depth,
226227
// This metadata is only for manual inspection only. We already created a
227228
// FunctionSamples and put it in the profile map, so there is no point
228229
// to skip profiles even they have no use for ThinLTO.
229-
if (Input == StringRef(" !Flat"))
230+
if (Input == StringRef(" !Flat")) {
231+
IsFlat = true;
230232
return true;
233+
}
231234
return parseMetadata(Input.substr(Depth), FunctionHash, Attributes);
232235
}
233236

@@ -330,6 +333,8 @@ std::error_code SampleProfileReaderText::readImpl() {
330333
// top-level or nested function profile.
331334
uint32_t DepthMetadata = 0;
332335

336+
std::vector<SampleContext *> FlatSamples;
337+
333338
ProfileIsFS = ProfileIsFSDisciminator;
334339
FunctionSamples::ProfileIsFS = ProfileIsFS;
335340
for (; !LineIt.is_at_eof(); ++LineIt) {
@@ -373,9 +378,10 @@ std::error_code SampleProfileReaderText::readImpl() {
373378
LineType LineTy;
374379
uint64_t FunctionHash = 0;
375380
uint32_t Attributes = 0;
381+
bool IsFlat = false;
376382
if (!ParseLine(*LineIt, LineTy, Depth, NumSamples, LineOffset,
377383
Discriminator, FName, TargetCountMap, FunctionHash,
378-
Attributes)) {
384+
Attributes, IsFlat)) {
379385
reportError(LineIt.line_number(),
380386
"Expected 'NUM[.NUM]: NUM[ mangled_name:NUM]*', found " +
381387
*LineIt);
@@ -431,12 +437,26 @@ std::error_code SampleProfileReaderText::readImpl() {
431437
if (Attributes & (uint32_t)ContextShouldBeInlined)
432438
ProfileIsPreInlined = true;
433439
DepthMetadata = Depth;
440+
if (IsFlat) {
441+
if (Depth == 1)
442+
FlatSamples.push_back(&FProfile.getContext());
443+
else
444+
Ctx.diagnose(DiagnosticInfoSampleProfile(
445+
Buffer->getBufferIdentifier(), LineIt.line_number(),
446+
"!Flat may only be used at top level function.", DS_Warning));
447+
}
434448
break;
435449
}
436450
}
437451
}
438452
}
439453

454+
// Honor the option to skip flat functions. Since they are already added to
455+
// the profile map, remove them all here.
456+
if (SkipFlatProf)
457+
for (SampleContext *FlatSample : FlatSamples)
458+
Profiles.erase(*FlatSample);
459+
440460
assert((CSProfileCount == 0 || CSProfileCount == Profiles.size()) &&
441461
"Cannot have both context-sensitive and regular profile");
442462
ProfileIsCS = (CSProfileCount > 0);

0 commit comments

Comments
 (0)