aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-profgen/PerfReader.cpp
diff options
context:
space:
mode:
authorHongtao Yu <hoy@fb.com>2022-05-11 21:33:09 -0700
committerwlei <wlei@fb.com>2022-05-12 10:58:50 -0700
commit9f732af583c0dba58847b753a87cc5432ec33f09 (patch)
tree8004d995f4391a99bec4731b4cbfab93ee897f6e /llvm/tools/llvm-profgen/PerfReader.cpp
parent9145cb8b7c9acd6e7980047e048007bc58b7fab9 (diff)
downloadllvm-9f732af583c0dba58847b753a87cc5432ec33f09.zip
llvm-9f732af583c0dba58847b753a87cc5432ec33f09.tar.gz
llvm-9f732af583c0dba58847b753a87cc5432ec33f09.tar.bz2
[llvm-profgen] Filter out oversized LBR ranges.
As a follow up to {D123271}, LBR ranges that are too big should also be considered as invalid. For example, the last two pairs in the following trace form a range [0x0d7b02b0, 0x368ba706] that covers a ton of functions in the binary. Such oversized range should also be ignored. 0x0c74505f/0x368b99a0 **0x368ba706**/0x0c745040 0x0d7b1c3f/**0x0d7b02b0** Add a defensive check to filter out those ranges based that the valid range should not cross the unconditional branch(Call, return, unconditional jmp). Reviewed By: hoy, wenlei Differential Revision: https://reviews.llvm.org/D125448
Diffstat (limited to 'llvm/tools/llvm-profgen/PerfReader.cpp')
-rw-r--r--llvm/tools/llvm-profgen/PerfReader.cpp13
1 files changed, 7 insertions, 6 deletions
diff --git a/llvm/tools/llvm-profgen/PerfReader.cpp b/llvm/tools/llvm-profgen/PerfReader.cpp
index 6888e93..2c4912c 100644
--- a/llvm/tools/llvm-profgen/PerfReader.cpp
+++ b/llvm/tools/llvm-profgen/PerfReader.cpp
@@ -99,7 +99,8 @@ void VirtualUnwinder::unwindLinear(UnwindState &State, uint64_t Repeat) {
return;
}
- if (Target > End) {
+ if (!isValidFallThroughRange(Binary->virtualAddrToOffset(Target),
+ Binary->virtualAddrToOffset(End), Binary)) {
// Skip unwinding the rest of LBR trace when a bogus range is seen.
State.setInvalid();
return;
@@ -581,7 +582,6 @@ bool PerfScriptReader::extractLBRStack(TraceStream &TraceIt,
if (!SrcIsInternal && !DstIsInternal)
continue;
- // TODO: filter out buggy duplicate branches on Skylake
LBRStack.emplace_back(LBREntry(Src, Dst));
}
TraceIt.advance();
@@ -878,7 +878,7 @@ void PerfScriptReader::computeCounterFromLBR(const PerfSample *Sample,
// LBR and FROM of next LBR.
uint64_t StartOffset = TargetOffset;
if (Binary->offsetIsCode(StartOffset) && Binary->offsetIsCode(EndOffeset) &&
- StartOffset <= EndOffeset)
+ isValidFallThroughRange(StartOffset, EndOffeset, Binary))
Counter.recordRangeCount(StartOffset, EndOffeset, Repeat);
EndOffeset = SourceOffset;
}
@@ -1124,7 +1124,7 @@ void PerfScriptReader::warnInvalidRange() {
const char *RangeCrossFuncMsg =
"Fall through range should not cross function boundaries, likely due to "
"profile and binary mismatch.";
- const char *BogusRangeMsg = "Range start is after range end.";
+ const char *BogusRangeMsg = "Range start is after or too far from range end.";
uint64_t TotalRangeNum = 0;
uint64_t InstNotBoundary = 0;
@@ -1155,7 +1155,7 @@ void PerfScriptReader::warnInvalidRange() {
WarnInvalidRange(StartOffset, EndOffset, RangeCrossFuncMsg);
}
- if (StartOffset > EndOffset) {
+ if (!isValidFallThroughRange(StartOffset, EndOffset, Binary)) {
BogusRange += I.second;
WarnInvalidRange(StartOffset, EndOffset, BogusRangeMsg);
}
@@ -1172,7 +1172,8 @@ void PerfScriptReader::warnInvalidRange() {
"of samples are from ranges that do cross function boundaries.");
emitWarningSummary(
BogusRange, TotalRangeNum,
- "of samples are from ranges that have range start after range end.");
+ "of samples are from ranges that have range start after or too far from "
+ "range end acrossing the unconditinal jmp.");
}
void PerfScriptReader::parsePerfTraces() {