diff --git a/llvm/test/tools/llvm-profgen/inline-noprobe2.test b/llvm/test/tools/llvm-profgen/inline-noprobe2.test index 9ae27d1a80ac4e..8635fee50fd2d0 100644 --- a/llvm/test/tools/llvm-profgen/inline-noprobe2.test +++ b/llvm/test/tools/llvm-profgen/inline-noprobe2.test @@ -22,30 +22,41 @@ ;CHECK-NEXT: 1: 6 ;CHECK-NEXT: 2: 6 ;CHECK-NEXT: 3: 6 -;CHECK-NEXT: quick_sort:414:25 -;CHECK-NEXT: 1: 24 -;CHECK-NEXT: 2: 12 partition_pivot_last:7 partition_pivot_first:5 -;CHECK-NEXT: 3: 11 quick_sort:12 -;CHECK-NEXT: 4: 12 quick_sort:12 -;CHECK-NEXT: 6: 24 -;CHECK-NEXT: partition_pivot_last:391:7 +;CHECK-NEXT: partition_pivot_last:649:7 ;CHECK-NEXT: 1: 6 ;CHECK-NEXT: 2: 6 ;CHECK-NEXT: 3: 6 -;CHECK-NEXT: 3.1: 18 -;CHECK-NEXT: 3.3: 18 -;CHECK-NEXT: 4: 19 -;CHECK-NEXT: 5: 9 + +;w/o duplication factor : 3.1: 18 +;w/o duplication factor : 3.3: 18 +;w/o duplication factor : 4: 19 +;w/o duplication factor : 5: 9 +;CHECK-NEXT: 3.1: 36 +;CHECK-NEXT: 3.3: 36 +;CHECK-NEXT: 4: 38 +;CHECK-NEXT: 5: 18 + ;CHECK-NEXT: 6: 5 ;CHECK-NEXT: 7: 5 -;CHECK-NEXT: 5: swap:61 -;CHECK-NEXT: 1: 9 -;CHECK-NEXT: 2: 9 -;CHECK-NEXT: 3: 9 +;CHECK-NEXT: 5: swap:116 + +;w/o duplication factor : 1: 9 +;w/o duplication factor : 2: 9 +;w/o duplication factor : 3: 9 +;CHECK-NEXT: 1: 18 +;CHECK-NEXT: 2: 18 +;CHECK-NEXT: 3: 18 + ;CHECK-NEXT: 6: swap:20 ;CHECK-NEXT: 1: 5 ;CHECK-NEXT: 2: 5 ;CHECK-NEXT: 3: 5 +;CHECK-NEXT: quick_sort:414:25 +;CHECK-NEXT: 1: 24 +;CHECK-NEXT: 2: 12 partition_pivot_last:7 partition_pivot_first:5 +;CHECK-NEXT: 3: 11 quick_sort:12 +;CHECK-NEXT: 4: 12 quick_sort:12 +;CHECK-NEXT: 6: 24 ;CHECK-NEXT: main:213:0 ;CHECK-NEXT: 0: 0 ;CHECK-NEXT: 3: 0 diff --git a/llvm/tools/llvm-profgen/ProfileGenerator.cpp b/llvm/tools/llvm-profgen/ProfileGenerator.cpp index 0cfe0215b2007b..0eb69b30c15af4 100644 --- a/llvm/tools/llvm-profgen/ProfileGenerator.cpp +++ b/llvm/tools/llvm-profgen/ProfileGenerator.cpp @@ -256,12 +256,13 @@ void ProfileGeneratorBase::updateBodySamplesforFunctionProfile( if (LeafLoc.Location.LineOffset & 0x80000000) return; // Use the maximum count of samples with same line location - ErrorOr R = FunctionProfile.findSamplesAt( - LeafLoc.Location.LineOffset, LeafLoc.Location.Discriminator); + uint32_t Discriminator = getBaseDiscriminator(LeafLoc.Location.Discriminator); + ErrorOr R = + FunctionProfile.findSamplesAt(LeafLoc.Location.LineOffset, Discriminator); + uint64_t PreviousCount = R ? R.get() : 0; if (PreviousCount <= Count) { - FunctionProfile.addBodySamples(LeafLoc.Location.LineOffset, - LeafLoc.Location.Discriminator, + FunctionProfile.addBodySamples(LeafLoc.Location.LineOffset, Discriminator, Count - PreviousCount); } } @@ -303,8 +304,11 @@ FunctionSamples &ProfileGenerator::getLeafProfileAndAddTotalSamples( FunctionProfile->addTotalSamples(Count); for (size_t I = 1; I < FrameVec.size(); I++) { + LineLocation Callsite( + FrameVec[I - 1].Location.LineOffset, + getBaseDiscriminator(FrameVec[I - 1].Location.Discriminator)); FunctionSamplesMap &SamplesMap = - FunctionProfile->functionSamplesAt(FrameVec[I - 1].Location); + FunctionProfile->functionSamplesAt(Callsite); auto Ret = SamplesMap.emplace(FrameVec[I].FuncName.str(), FunctionSamples()); if (Ret.second) { @@ -363,10 +367,12 @@ void ProfileGenerator::populateBodySamplesForAllFunctions( const SampleContextFrameVector &FrameVec = Binary->getFrameLocationStack(Offset); if (!FrameVec.empty()) { + uint64_t DC = Count * getDuplicationFactor( + FrameVec.back().Location.Discriminator); FunctionSamples &FunctionProfile = - getLeafProfileAndAddTotalSamples(FrameVec, Count); + getLeafProfileAndAddTotalSamples(FrameVec, DC); updateBodySamplesforFunctionProfile(FunctionProfile, FrameVec.back(), - Count); + DC); } // Move to next IP within the range. IP.advance(); @@ -391,11 +397,13 @@ void ProfileGenerator::populateBoundarySamplesForAllFunctions( const SampleContextFrameVector &FrameVec = Binary->getFrameLocationStack(SourceOffset); if (!FrameVec.empty()) { + Count *= getDuplicationFactor(FrameVec.back().Location.Discriminator); FunctionSamples &FunctionProfile = getLeafProfileAndAddTotalSamples(FrameVec, Count); FunctionProfile.addCalledTargetSamples( FrameVec.back().Location.LineOffset, - FrameVec.back().Location.Discriminator, CalleeName, Count); + getBaseDiscriminator(FrameVec.back().Location.Discriminator), + CalleeName, Count); } // Add head samples for callee. FunctionSamples &CalleeProfile = getTopLevelFunctionProfile(CalleeName); @@ -504,10 +512,12 @@ void CSProfileGenerator::populateBodySamplesForFunction( auto LeafLoc = Binary->getInlineLeafFrameLoc(Offset); if (LeafLoc.hasValue()) { // Recording body sample for this specific context - updateBodySamplesforFunctionProfile(FunctionProfile, *LeafLoc, Count); + uint64_t DC = + Count * getDuplicationFactor(LeafLoc->Location.Discriminator); + updateBodySamplesforFunctionProfile(FunctionProfile, *LeafLoc, DC); + FunctionProfile.addTotalSamples(DC); } - // Accumulate total sample count even it's a line with invalid debug info - FunctionProfile.addTotalSamples(Count); + // Move to next IP within the range IP.advance(); } @@ -534,9 +544,11 @@ void CSProfileGenerator::populateBoundarySamplesForFunction( auto LeafLoc = Binary->getInlineLeafFrameLoc(SourceOffset); if (!LeafLoc.hasValue()) continue; - FunctionProfile.addCalledTargetSamples(LeafLoc->Location.LineOffset, - LeafLoc->Location.Discriminator, - CalleeName, Count); + Count *= getDuplicationFactor(LeafLoc->Location.Discriminator); + FunctionProfile.addCalledTargetSamples( + LeafLoc->Location.LineOffset, + getBaseDiscriminator(LeafLoc->Location.Discriminator), CalleeName, + Count); // Record head sample for called target(callee) SampleContextFrameVector CalleeCtx(ContextId.begin(), ContextId.end()); diff --git a/llvm/tools/llvm-profgen/ProfileGenerator.h b/llvm/tools/llvm-profgen/ProfileGenerator.h index 71f4cded5ce423..4d334de0f41ea5 100644 --- a/llvm/tools/llvm-profgen/ProfileGenerator.h +++ b/llvm/tools/llvm-profgen/ProfileGenerator.h @@ -38,6 +38,16 @@ class ProfileGeneratorBase { virtual void generateProfile() = 0; void write(); + static uint32_t getDuplicationFactor(unsigned Discriminator) { + return llvm::DILocation::getDuplicationFactorFromDiscriminator( + Discriminator); + } + + static uint32_t getBaseDiscriminator(unsigned Discriminator) { + return DILocation::getBaseDiscriminatorFromDiscriminator( + Discriminator, /* IsFSDiscriminator */ false); + } + protected: // Use SampleProfileWriter to serialize profile map void write(std::unique_ptr Writer, diff --git a/llvm/tools/llvm-profgen/ProfiledBinary.cpp b/llvm/tools/llvm-profgen/ProfiledBinary.cpp index b7a18c2e912e8e..eca16712c03d79 100644 --- a/llvm/tools/llvm-profgen/ProfiledBinary.cpp +++ b/llvm/tools/llvm-profgen/ProfiledBinary.cpp @@ -218,6 +218,12 @@ ProfiledBinary::getExpandedContext(const SmallVectorImpl &Stack, ContextVec.append(ExpandedContext); } + // Replace with decoded base discriminator + for (auto &Frame : ContextVec) { + Frame.Location.Discriminator = ProfileGeneratorBase::getBaseDiscriminator( + Frame.Location.Discriminator); + } + assert(ContextVec.size() && "Context length should be at least 1"); // Compress the context string except for the leaf frame @@ -540,10 +546,6 @@ SampleContextFrameVector ProfiledBinary::symbolize(const InstructionPointer &IP, LineOffset = PseudoProbeDwarfDiscriminator::extractProbeIndex(Discriminator); Discriminator = 0; - } else { - Discriminator = DILocation::getBaseDiscriminatorFromDiscriminator( - CallerFrame.Discriminator, - /* IsFSDiscriminator */ false); } LineLocation Line(LineOffset, Discriminator);