[llvm] a03cf33 - [llvm-profgen] Strip context to support non-CS profile generation for hybrid sample
via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 28 12:21:18 PDT 2021
Author: wlei
Date: 2021-09-28T12:20:23-07:00
New Revision: a03cf331e1e9dfb43d7cba750296cd3b78e83cf3
URL: https://github.com/llvm/llvm-project/commit/a03cf331e1e9dfb43d7cba750296cd3b78e83cf3
DIFF: https://github.com/llvm/llvm-project/commit/a03cf331e1e9dfb43d7cba750296cd3b78e83cf3.diff
LOG: [llvm-profgen] Strip context to support non-CS profile generation for hybrid sample
Differential Revision: https://reviews.llvm.org/D109769
Added:
Modified:
llvm/test/tools/llvm-profgen/inline-cs-noprobe.test
llvm/test/tools/llvm-profgen/noinline-cs-noprobe.test
llvm/tools/llvm-profgen/PerfReader.cpp
llvm/tools/llvm-profgen/PerfReader.h
llvm/tools/llvm-profgen/ProfileGenerator.cpp
llvm/tools/llvm-profgen/ProfileGenerator.h
llvm/tools/llvm-profgen/llvm-profgen.cpp
Removed:
################################################################################
diff --git a/llvm/test/tools/llvm-profgen/inline-cs-noprobe.test b/llvm/test/tools/llvm-profgen/inline-cs-noprobe.test
index dfdc189f6bea7..df6ac1c397316 100644
--- a/llvm/test/tools/llvm-profgen/inline-cs-noprobe.test
+++ b/llvm/test/tools/llvm-profgen/inline-cs-noprobe.test
@@ -2,6 +2,8 @@
; RUN: FileCheck %s --input-file %t --check-prefix=CHECK-UNWINDER
; RUN: llvm-profgen --format=text --perfscript=%S/Inputs/inline-cs-noprobe.perfscript --binary=%S/Inputs/inline-cs-noprobe.perfbin --output=%t --profile-summary-cold-count=0
; RUN: FileCheck %s --input-file %t
+; RUN: llvm-profgen --format=text --perfscript=%S/Inputs/inline-cs-noprobe.perfscript --binary=%S/Inputs/inline-cs-noprobe.perfbin --output=%t --profile-summary-cold-count=0 --ignore-stack-samples
+; RUN: FileCheck %s --input-file %t --check-prefix=CHECK-STRIP-CTX
; CHECK:[main:1 @ foo]:309:0
; CHECK: 2.1: 14
@@ -11,6 +13,18 @@
; CHECK:[main:1 @ foo:3.1 @ bar]:84:0
; CHECK: 1: 14
+; CHECK-STRIP-CTX: main:379:0
+; CHECK-STRIP-CTX: 0: 0
+; CHECK-STRIP-CTX: 2: 0
+; CHECK-STRIP-CTX: 1: foo:379
+; CHECK-STRIP-CTX: 2.1: 14
+; CHECK-STRIP-CTX: 3: 15
+; CHECK-STRIP-CTX: 3.2: 1
+; CHECK-STRIP-CTX: 4: 0
+; CHECK-STRIP-CTX: 7: 0
+; CHECK-STRIP-CTX: 3.1: bar:84
+; CHECK-STRIP-CTX: 1: 14
+
; CHECK-UNWINDER: [main:1 @ foo]
; CHECK-UNWINDER: 4
; CHECK-UNWINDER: 670-6ad:1
diff --git a/llvm/test/tools/llvm-profgen/noinline-cs-noprobe.test b/llvm/test/tools/llvm-profgen/noinline-cs-noprobe.test
index c26cac969b815..46d358f9a669f 100644
--- a/llvm/test/tools/llvm-profgen/noinline-cs-noprobe.test
+++ b/llvm/test/tools/llvm-profgen/noinline-cs-noprobe.test
@@ -4,6 +4,8 @@
; RUN: FileCheck %s --input-file %t --check-prefix=CHECK-UNWINDER
; RUN: llvm-profgen --format=text --perfscript=%S/Inputs/noinline-cs-noprobe.perfscript --binary=%S/Inputs/noinline-cs-noprobe.perfbin --output=%t --profile-summary-cold-count=0
; RUN: FileCheck %s --input-file %t
+; RUN: llvm-profgen --format=text --perfscript=%S/Inputs/noinline-cs-noprobe.perfscript --binary=%S/Inputs/noinline-cs-noprobe.perfbin --output=%t --profile-summary-cold-count=0 --ignore-stack-samples
+; RUN: FileCheck %s --input-file %t --check-prefix=CHECK-STRIP-CTX
; RUN: llvm-profgen --format=text --perfscript=%S/Inputs/noinline-cs-noprobe.aggperfscript --binary=%S/Inputs/noinline-cs-noprobe.perfbin --output=%t --skip-symbolization --profile-summary-cold-count=0
; RUN: FileCheck %s --input-file %t --check-prefix=CHECK-AGG-UNWINDER
; RUN: llvm-profgen --format=text --perfscript=%S/Inputs/noinline-cs-noprobe.aggperfscript --binary=%S/Inputs/noinline-cs-noprobe.perfbin --output=%t --profile-summary-cold-count=0
@@ -58,6 +60,19 @@
; CHECK: 4: 1
; CHECK: 5: 3
+; CHECK-STRIP-CTX: foo:57:0
+; CHECK-STRIP-CTX: 0: 0
+; CHECK-STRIP-CTX: 1: 0
+; CHECK-STRIP-CTX: 2: 3
+; CHECK-STRIP-CTX: 3: 3 bar:3
+; CHECK-STRIP-CTX: 4: 0
+; CHECK-STRIP-CTX: 5: 0
+; CHECK-STRIP-CTX: bar:50:3
+; CHECK-STRIP-CTX: 0: 3
+; CHECK-STRIP-CTX: 1: 3
+; CHECK-STRIP-CTX: 2: 2
+; CHECK-STRIP-CTX: 4: 1
+; CHECK-STRIP-CTX: 5: 3
; CHECK-UNWINDER: [main:1 @ foo]
; CHECK-UNWINDER-NEXT: 3
diff --git a/llvm/tools/llvm-profgen/PerfReader.cpp b/llvm/tools/llvm-profgen/PerfReader.cpp
index 9b7332f7c8367..80d70044378e4 100644
--- a/llvm/tools/llvm-profgen/PerfReader.cpp
+++ b/llvm/tools/llvm-profgen/PerfReader.cpp
@@ -24,6 +24,11 @@ cl::opt<bool> UseOffset("use-offset", cl::ReallyHidden, cl::init(true),
cl::ZeroOrMore,
cl::desc("Work with `--skip-symbolization` to dump the "
"offset instead of virtual address."));
+cl::opt<bool>
+ IgnoreStackSamples("ignore-stack-samples", cl::ReallyHidden,
+ cl::init(false), cl::ZeroOrMore,
+ cl::desc("Ignore call stack samples for hybrid samples "
+ "and produce context-insensitive profile."));
extern cl::opt<bool> ShowDisassemblyOnly;
extern cl::opt<bool> ShowSourceLocations;
@@ -365,9 +370,6 @@ void HybridPerfReader::unwindSamples() {
WithColor::warning() << "Profile context truncated due to missing probe "
<< "for call instruction at "
<< format("%" PRIx64, Address) << "\n";
-
- if (SkipSymbolization)
- writeRawProfile(OutputFilename);
}
bool PerfReaderBase::extractLBRStack(TraceStream &TraceIt,
@@ -675,14 +677,18 @@ void LBRPerfReader::parseSample(TraceStream &TraceIt, uint64_t Count) {
}
void LBRPerfReader::generateRawProfile() {
- assert(SampleCounters.size() == 1 && "Must have one entry of sample counter");
+ // There is no context for LBR only sample, so initialize one entry with
+ // fake "empty" context key.
+ assert(SampleCounters.empty() &&
+ "Sample counter map should be empty before raw profile generation");
+ std::shared_ptr<StringBasedCtxKey> Key =
+ std::make_shared<StringBasedCtxKey>();
+ Key->genHashCode();
+ SampleCounters.emplace(Hashable<ContextKey>(Key), SampleCounter());
for (const auto &Item : AggregatedSamples) {
const PerfSample *Sample = Item.first.getPtr();
computeCounterFromLBR(Sample, Item.second);
}
-
- if (SkipSymbolization)
- PerfReaderBase::writeRawProfile(OutputFilename);
}
uint64_t PerfReaderBase::parseAggregatedCount(TraceStream &TraceIt) {
@@ -774,7 +780,13 @@ PerfReaderBase::extractPerfType(cl::list<std::string> &PerfTraceFilenames) {
return PerfType;
}
-void HybridPerfReader::generateRawProfile() { unwindSamples(); }
+void HybridPerfReader::generateRawProfile() {
+ ProfileIsCS = !IgnoreStackSamples;
+ if (ProfileIsCS)
+ unwindSamples();
+ else
+ LBRPerfReader::generateRawProfile();
+}
void PerfReaderBase::warnTruncatedStack() {
for (auto Address : InvalidReturnAddresses) {
@@ -793,6 +805,9 @@ void PerfReaderBase::parsePerfTraces(
warnTruncatedStack();
generateRawProfile();
+
+ if (SkipSymbolization)
+ writeRawProfile(OutputFilename);
}
} // end namespace sampleprof
diff --git a/llvm/tools/llvm-profgen/PerfReader.h b/llvm/tools/llvm-profgen/PerfReader.h
index 1a8a2a3014a98..86de6555457a3 100644
--- a/llvm/tools/llvm-profgen/PerfReader.h
+++ b/llvm/tools/llvm-profgen/PerfReader.h
@@ -574,12 +574,12 @@ class PerfReaderBase {
};
void updateBinaryAddress(const MMapEvent &Event);
- PerfScriptType getPerfScriptType() const { return PerfType; }
// Entry of the reader to parse multiple perf traces
void parsePerfTraces(cl::list<std::string> &PerfTraceFilenames);
const ContextSampleCounterMap &getSampleCounters() const {
return SampleCounters;
}
+ bool profileIsCS() { return ProfileIsCS; }
protected:
static PerfScriptType
@@ -623,6 +623,27 @@ class PerfReaderBase {
PerfScriptType PerfType = PERF_UNKNOWN;
// Keep track of all invalid return addresses
std::set<uint64_t> InvalidReturnAddresses;
+
+ bool ProfileIsCS = false;
+};
+
+/*
+ The reader of LBR only perf script.
+ A typical LBR sample is like:
+ 40062f 0x4005c8/0x4005dc/P/-/-/0 0x40062f/0x4005b0/P/-/-/0 ...
+ ... 0x4005c8/0x4005dc/P/-/-/0
+*/
+class LBRPerfReader : public PerfReaderBase {
+public:
+ LBRPerfReader(ProfiledBinary *Binary) : PerfReaderBase(Binary) {
+ PerfType = PERF_LBR;
+ };
+ // Parse the LBR only sample.
+ virtual void parseSample(TraceStream &TraceIt, uint64_t Count) override;
+ virtual void generateRawProfile() override;
+
+private:
+ void computeCounterFromLBR(const PerfSample *Sample, uint64_t Repeat);
};
/*
@@ -634,9 +655,9 @@ class PerfReaderBase {
0x4005c8/0x4005dc/P/-/-/0 0x40062f/0x4005b0/P/-/-/0 ...
... 0x4005c8/0x4005dc/P/-/-/0 # LBR Entries
*/
-class HybridPerfReader : public PerfReaderBase {
+class HybridPerfReader : public LBRPerfReader {
public:
- HybridPerfReader(ProfiledBinary *Binary) : PerfReaderBase(Binary) {
+ HybridPerfReader(ProfiledBinary *Binary) : LBRPerfReader(Binary) {
PerfType = PERF_LBR_STACK;
};
// Parse the hybrid sample including the call and LBR line
@@ -648,32 +669,6 @@ class HybridPerfReader : public PerfReaderBase {
void unwindSamples();
};
-/*
- The reader of LBR only perf script.
- A typical LBR sample is like:
- 40062f 0x4005c8/0x4005dc/P/-/-/0 0x40062f/0x4005b0/P/-/-/0 ...
- ... 0x4005c8/0x4005dc/P/-/-/0
-*/
-class LBRPerfReader : public PerfReaderBase {
-public:
- LBRPerfReader(ProfiledBinary *Binary) : PerfReaderBase(Binary) {
- // There is no context for LBR only sample, so initialize one entry with
- // fake "empty" context key.
- std::shared_ptr<StringBasedCtxKey> Key =
- std::make_shared<StringBasedCtxKey>();
- Key->genHashCode();
- SampleCounters.emplace(Hashable<ContextKey>(Key), SampleCounter());
- PerfType = PERF_LBR;
- };
-
- // Parse the LBR only sample.
- void parseSample(TraceStream &TraceIt, uint64_t Count) override;
- void generateRawProfile() override;
-
-private:
- void computeCounterFromLBR(const PerfSample *Sample, uint64_t Repeat);
-};
-
} // end namespace sampleprof
} // end namespace llvm
diff --git a/llvm/tools/llvm-profgen/ProfileGenerator.cpp b/llvm/tools/llvm-profgen/ProfileGenerator.cpp
index 05e8e4dc78a0d..6e43e53cc6215 100644
--- a/llvm/tools/llvm-profgen/ProfileGenerator.cpp
+++ b/llvm/tools/llvm-profgen/ProfileGenerator.cpp
@@ -77,15 +77,12 @@ int CSProfileGenerator::MaxContextDepth = -1;
std::unique_ptr<ProfileGeneratorBase>
ProfileGeneratorBase::create(ProfiledBinary *Binary,
const ContextSampleCounterMap &SampleCounters,
- enum PerfScriptType SampleType) {
+ bool ProfileIsCS) {
std::unique_ptr<ProfileGeneratorBase> Generator;
- if (SampleType == PERF_LBR) {
- // TODO: Support probe based profile generation
- Generator.reset(new ProfileGenerator(Binary, SampleCounters));
- } else if (SampleType == PERF_LBR_STACK) {
+ if (ProfileIsCS) {
Generator.reset(new CSProfileGenerator(Binary, SampleCounters));
} else {
- llvm_unreachable("Unsupported perfscript!");
+ Generator.reset(new ProfileGenerator(Binary, SampleCounters));
}
return Generator;
diff --git a/llvm/tools/llvm-profgen/ProfileGenerator.h b/llvm/tools/llvm-profgen/ProfileGenerator.h
index 86e2d68f216e4..71f4cded5ce42 100644
--- a/llvm/tools/llvm-profgen/ProfileGenerator.h
+++ b/llvm/tools/llvm-profgen/ProfileGenerator.h
@@ -34,7 +34,7 @@ class ProfileGeneratorBase {
virtual ~ProfileGeneratorBase() = default;
static std::unique_ptr<ProfileGeneratorBase>
create(ProfiledBinary *Binary, const ContextSampleCounterMap &SampleCounters,
- enum PerfScriptType SampleType);
+ bool ProfileIsCS);
virtual void generateProfile() = 0;
void write();
diff --git a/llvm/tools/llvm-profgen/llvm-profgen.cpp b/llvm/tools/llvm-profgen/llvm-profgen.cpp
index b7cad8fee2c36..0cdf0fa8621cd 100644
--- a/llvm/tools/llvm-profgen/llvm-profgen.cpp
+++ b/llvm/tools/llvm-profgen/llvm-profgen.cpp
@@ -95,7 +95,7 @@ int main(int argc, const char *argv[]) {
std::unique_ptr<ProfileGeneratorBase> Generator =
ProfileGeneratorBase::create(Binary.get(), Reader->getSampleCounters(),
- Reader->getPerfScriptType());
+ Reader->profileIsCS());
Generator->generateProfile();
Generator->write();
More information about the llvm-commits
mailing list