diff --git a/llvm/test/tools/llvm-profgen/Inputs/recursion-compression-pseudoprobe-nommap.perfscript b/llvm/test/tools/llvm-profgen/Inputs/recursion-compression-pseudoprobe-nommap.perfscript new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-profgen/Inputs/recursion-compression-pseudoprobe-nommap.perfscript @@ -0,0 +1,21 @@ + 2017db + 2017ba + 2017e5 + 2017ba + 2017e5 + 2017d9 + 2017ba + 2017b0 + 2017b0 + 2017b0 + 2017b0 + 2017b0 + 2017b0 + 2017b0 + 2017b0 + 2017e5 + 2017d9 + 201847 + 7fcb072a67c3 + 5541f689495641d7 + 0x2017cd/0x2017db/P/-/-/0 0x2017b5/0x2017c0/P/-/-/0 0x2017a7/0x2017b2/P/-/-/0 0x2017e0/0x2017a0/P/-/-/0 0x2017cd/0x2017db/P/-/-/0 0x2017b5/0x2017c0/P/-/-/0 0x2017a7/0x2017b2/P/-/-/0 0x2017e0/0x2017a0/P/-/-/0 0x2017cd/0x2017db/P/-/-/0 0x2017d4/0x2017c0/P/-/-/0 0x2017b5/0x2017c0/P/-/-/0 0x2017a7/0x2017b2/P/-/-/0 0x2017ab/0x2017a0/P/-/-/0 0x2017ab/0x2017a0/P/-/-/0 0x2017ab/0x2017a0/P/-/-/0 0x2017ab/0x2017a0/P/-/-/0 diff --git a/llvm/test/tools/llvm-profgen/recursion-compression-pseudoprobe.test b/llvm/test/tools/llvm-profgen/recursion-compression-pseudoprobe.test --- a/llvm/test/tools/llvm-profgen/recursion-compression-pseudoprobe.test +++ b/llvm/test/tools/llvm-profgen/recursion-compression-pseudoprobe.test @@ -3,6 +3,9 @@ ; RUN: FileCheck %s --input-file %t -check-prefix=CHECK-UNCOMPRESS ; RUN: llvm-profgen --format=text --perfscript=%S/Inputs/recursion-compression-pseudoprobe.perfscript --binary=%S/Inputs/recursion-compression-pseudoprobe.perfbin --output=%t --show-unwinder-output --profile-summary-cold-count=0 | FileCheck %s --check-prefix=CHECK-UNWINDER ; RUN: FileCheck %s --input-file %t +; RUN: llvm-profgen --format=text --perfscript=%S/Inputs/recursion-compression-pseudoprobe-nommap.perfscript --binary=%S/Inputs/recursion-compression-pseudoprobe.perfbin --output=%t --show-unwinder-output --profile-summary-cold-count=0 | FileCheck %s --check-prefix=CHECK-UNWINDER +; RUN: FileCheck %s --input-file %t + ; CHECK-UNCOMPRESS: [main:2 @ foo:5 @ fa:8 @ fa:7 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:5 @ fb:6 @ fa:8 @ fa:7 @ fb:6 @ fa]:4:1 ; CHECK-UNCOMPRESS: 1: 1 diff --git a/llvm/tools/llvm-profgen/PerfReader.cpp b/llvm/tools/llvm-profgen/PerfReader.cpp --- a/llvm/tools/llvm-profgen/PerfReader.cpp +++ b/llvm/tools/llvm-profgen/PerfReader.cpp @@ -317,7 +317,14 @@ exitWithError(ErrorMsg); } - return Ret.first->second; + // Initialize the base address to preferred address. + ProfiledBinary &B = Ret.first->second; + uint64_t PreferredAddr = B.getPreferredBaseAddress(); + AddrToBinaryMap[PreferredAddr] = &B; + B.setBaseAddress(PreferredAddr); + B.setIsLoadedByMMap(false); + + return B; } void PerfReaderBase::updateBinaryAddress(const MMapEvent &Event) { @@ -327,11 +334,15 @@ auto I = BinaryTable.find(BinaryName); // Drop the event which doesn't belong to user-provided binaries - // or if its image is loaded at the same address - if (I == BinaryTable.end() || Event.Address == I->second.getBaseAddress()) + if (I == BinaryTable.end()) return; ProfiledBinary &Binary = I->second; + // Drop the event if its image is loaded at the same address + if (Event.Address == Binary.getBaseAddress()) { + Binary.setIsLoadedByMMap(true); + return; + } if (Event.Offset == Binary.getTextSegmentOffset()) { // A binary image could be unloaded and then reloaded at different @@ -344,6 +355,8 @@ // Update binary load address. Binary.setBaseAddress(Event.Address); + + Binary.setIsLoadedByMMap(true); } else { // Verify segments are loaded consecutively. const auto &Offsets = Binary.getTextSegmentOffsets(); @@ -630,7 +643,14 @@ return; } // Set the binary current sample belongs to - Sample->Binary = getBinary(Sample->CallStack.front()); + ProfiledBinary *PB = getBinary(Sample->CallStack.front()); + Sample->Binary = PB; + if (!PB->getMissingMMapWarned() && !PB->getIsLoadedByMMap()) { + WithColor::warning() << "No relevant mmap event is matched, will use " + "preferred address as the base loading address!\n"; + // Avoid redundant warning, only warn at the first unmatched sample. + PB->setMissingMMapWarned(true); + } if (!TraceIt.isAtEoF() && TraceIt.getCurrentLine().startswith(" 0x")) { // Parsing LBR stack and populate into HybridSample.LBRStack diff --git a/llvm/tools/llvm-profgen/ProfiledBinary.h b/llvm/tools/llvm-profgen/ProfiledBinary.h --- a/llvm/tools/llvm-profgen/ProfiledBinary.h +++ b/llvm/tools/llvm-profgen/ProfiledBinary.h @@ -140,6 +140,12 @@ bool UsePseudoProbes = false; + // Indicate if the base loading address is parsed from the mmap event or uses + // the preferred address + bool IsLoadedByMMap = false; + // Use to avoid redundant warning. + bool MissingMMapWarned = false; + void setPreferredTextSegmentAddresses(const ELFObjectFileBase *O); template @@ -278,6 +284,14 @@ const PseudoProbeFuncDesc *getInlinerDescForProbe(const PseudoProbe *Probe) { return ProbeDecoder.getInlinerDescForProbe(Probe); } + + bool getIsLoadedByMMap() { return IsLoadedByMMap; } + + void setIsLoadedByMMap(bool Value) { IsLoadedByMMap = Value; } + + bool getMissingMMapWarned() { return MissingMMapWarned; } + + void setMissingMMapWarned(bool Value) { MissingMMapWarned = Value; } }; } // end namespace sampleprof