[llvm-profgen] Add duplication factor for line-number based profile
authorwlei <wlei@fb.com>
Fri, 1 Oct 2021 23:58:59 +0000 (16:58 -0700)
committerwlei <wlei@fb.com>
Tue, 5 Oct 2021 02:08:55 +0000 (19:08 -0700)
This change adds duplication factor multiplier while accumulating body samples for line-number based profile. The body sample count will be `duplication-factor * count`. Base discriminator and duplication factor is decoded from the raw discriminator, this requires some refactor works.

Differential Revision: https://reviews.llvm.org/D109934

llvm/test/tools/llvm-profgen/inline-noprobe2.test
llvm/tools/llvm-profgen/ProfileGenerator.cpp
llvm/tools/llvm-profgen/ProfileGenerator.h
llvm/tools/llvm-profgen/ProfiledBinary.cpp

index 9ae27d1..8635fee 100644 (file)
 ;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
index 0cfe021..0eb69b3 100644 (file)
@@ -256,12 +256,13 @@ void ProfileGeneratorBase::updateBodySamplesforFunctionProfile(
   if (LeafLoc.Location.LineOffset & 0x80000000)
     return;
   // Use the maximum count of samples with same line location
-  ErrorOr<uint64_t> R = FunctionProfile.findSamplesAt(
-      LeafLoc.Location.LineOffset, LeafLoc.Location.Discriminator);
+  uint32_t Discriminator = getBaseDiscriminator(LeafLoc.Location.Discriminator);
+  ErrorOr<uint64_t> 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());
index 71f4cde..4d334de 100644 (file)
@@ -38,6 +38,16 @@ public:
   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<SampleProfileWriter> Writer,
index b7a18c2..eca1671 100644 (file)
@@ -218,6 +218,12 @@ ProfiledBinary::getExpandedContext(const SmallVectorImpl<uint64_t> &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);