diff options
author | Hongtao Yu <hoy@fb.com> | 2022-05-11 21:33:09 -0700 |
---|---|---|
committer | wlei <wlei@fb.com> | 2022-05-12 10:58:50 -0700 |
commit | 9f732af583c0dba58847b753a87cc5432ec33f09 (patch) | |
tree | 8004d995f4391a99bec4731b4cbfab93ee897f6e /llvm/tools/llvm-profgen/PerfReader.cpp | |
parent | 9145cb8b7c9acd6e7980047e048007bc58b7fab9 (diff) | |
download | llvm-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.cpp | 13 |
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() { |