Index: llvm/test/tools/llvm-profdata/Inputs/sample-fs.proftext =================================================================== --- /dev/null +++ llvm/test/tools/llvm-profdata/Inputs/sample-fs.proftext @@ -0,0 +1,7 @@ +main:6436:0 + 4: 534 + 4.2: 534 + 4.738209026: 1068 + 5: 1075 + 5.1: 1075 + 5.738209025: 2150 Index: llvm/test/tools/llvm-profdata/sample-fs.test =================================================================== --- /dev/null +++ llvm/test/tools/llvm-profdata/sample-fs.test @@ -0,0 +1,54 @@ +Basic tests for sample profiles using fs discriminators. + +1- Show command and keep all the discrimiantor bits +RUN: llvm-profdata show --sample %p/Inputs/sample-fs.proftext -profile-isfs | FileCheck %s --check-prefix=SHOW1 +RUN: llvm-profdata show --sample %p/Inputs/sample-fs.proftext -profile-isfs -fs-discriminator-pass=-1 | FileCheck %s --check-prefix=SHOW1 +SHOW1: Function: main: 6436, 0, 6 sampled lines +SHOW1: Samples collected in the function's body { +SHOW1: 4: 534 +SHOW1: 4.2: 534 +SHOW1: 4.738209026: 1068 +SHOW1: 5: 1075 +SHOW1: 5.1: 1075 +SHOW1: 5.738209025: 2150 +SHOW1: } + +2- Show command and keep only the base discriminator bits +RUN: llvm-profdata show --sample %p/Inputs/sample-fs.proftext -profile-isfs -fs-discriminator-pass=0 | FileCheck %s --check-prefix=SHOW2 +SHOW2: Function: main: 6436, 0, 4 sampled lines +SHOW2: Samples collected in the function's body { +SHOW2: 4: 534 +SHOW2: 4.2: 1602 +SHOW2: 5: 1075 +SHOW2: 5.1: 3225 +SHOW2: } + +3- Show command and keep only the base discriminator bits and first pass of FS discriminator +RUN: llvm-profdata show --sample %p/Inputs/sample-fs.proftext -profile-isfs -fs-discriminator-pass=1 | FileCheck %s --check-prefix=SHOW3 +Function: main: 6436, 0, 6 sampled lines +SHOW3: Samples collected in the function's body { +SHOW3: 4: 534 +SHOW3: 4.2: 534 +SHOW3: 4.11522: 1068 +SHOW3: 5: 1075 +SHOW3: 5.1: 1075 +SHOW3: 5.11521: 2150 +SHOW3: } + +4- Merge command and keep all the discrimiantor bits +RUN: llvm-profdata merge --sample %p/Inputs/sample-fs.proftext -profile-isfs -fs-discriminator-pass=-1 --binary -o - | llvm-profdata show --sample - -o %t1-binary_1 +RUN: llvm-profdata merge --sample %p/Inputs/sample-fs.proftext -profile-isfs --binary -o - | llvm-profdata show --sample - -o %t1-binary_2 +RUN: llvm-profdata show --sample %p/Inputs/sample-fs.proftext -profile-isfs -o %t1-text +RUN: diff %t1-binary_1 %t1-text +RUN: diff %t1-binary_2 %t1-text + +2- Merge command and keep only the base discriminator bits +RUN: llvm-profdata merge --sample %p/Inputs/sample-fs.proftext -profile-isfs -fs-discriminator-pass=0 --binary -o - | llvm-profdata show --sample - -o %t2-binary +RUN: llvm-profdata show --sample %p/Inputs/sample-fs.proftext -profile-isfs -fs-discriminator-pass=0 -o %t2-text +RUN: diff %t2-binary %t2-text + +3- Merge command and keep only the base discriminator bits and first pass of FS discriminator +RUN: llvm-profdata merge --sample %p/Inputs/sample-fs.proftext -profile-isfs -fs-discriminator-pass=1 --binary -o - | llvm-profdata show --sample - -o %t3-binary +RUN: llvm-profdata show --sample %p/Inputs/sample-fs.proftext -profile-isfs -fs-discriminator-pass=1 -o %t3-text +RUN: diff %t3-binary %t3-text + Index: llvm/tools/llvm-profdata/llvm-profdata.cpp =================================================================== --- llvm/tools/llvm-profdata/llvm-profdata.cpp +++ llvm/tools/llvm-profdata/llvm-profdata.cpp @@ -20,6 +20,7 @@ #include "llvm/ProfileData/SampleProfReader.h" #include "llvm/ProfileData/SampleProfWriter.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/Discriminator.h" #include "llvm/Support/Errc.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Format.h" @@ -451,6 +452,16 @@ const uint64_t ColdPercentileIdx = 15; const uint64_t HotPercentileIdx = 11; +static sampleprof::FSDiscriminatorPass FSDiscriminatorPassVal; + +static void setDiscriminatorMaskedBit(sampleprof::SampleProfileReader *Reader) { + Reader->setDiscriminatorMaskedBitFrom(FSDiscriminatorPassVal); +} + +static unsigned getDiscriminatorMask() { + return getN1Bits(getFSPassBitEnd(FSDiscriminatorPassVal)); +} + /// Adjust the instr profile in \p WC based on the sample profile in /// \p Reader. static void @@ -547,6 +558,7 @@ if (std::error_code EC = ReaderOrErr.getError()) exitWithErrorCode(EC, SampleFilename); auto Reader = std::move(ReaderOrErr.get()); + setDiscriminatorMaskedBit(Reader.get()); if (std::error_code EC = Reader->read()) exitWithErrorCode(EC, SampleFilename); @@ -573,13 +585,15 @@ Result.setName(Remapper(Samples.getName())); Result.addTotalSamples(Samples.getTotalSamples()); Result.addHeadSamples(Samples.getHeadSamples()); + for (const auto &BodySample : Samples.getBodySamples()) { - Result.addBodySamples(BodySample.first.LineOffset, - BodySample.first.Discriminator, + uint32_t MaskedDiscriminator = + BodySample.first.Discriminator & getDiscriminatorMask(); + Result.addBodySamples(BodySample.first.LineOffset, MaskedDiscriminator, BodySample.second.getSamples()); for (const auto &Target : BodySample.second.getCallTargets()) { Result.addCalledTargetSamples(BodySample.first.LineOffset, - BodySample.first.Discriminator, + MaskedDiscriminator, Remapper(Target.first()), Target.second); } } @@ -689,6 +703,7 @@ // merged profile map. Readers.push_back(std::move(ReaderOrErr.get())); const auto Reader = Readers.back().get(); + setDiscriminatorMaskedBit(Reader); if (std::error_code EC = Reader->read()) { warnOrExitGivenError(FailMode, EC, Input.Filename); Readers.pop_back(); @@ -907,18 +922,30 @@ "sample profile, if the ratio of the number of zero counters " "divided by the the total number of counters is above the " "threshold, the profile of the function will be regarded as " - "being harmful for performance and will be dropped. ")); + "being harmful for performance and will be dropped.")); cl::opt SupplMinSizeThreshold( "suppl-min-size-threshold", cl::init(10), cl::Hidden, cl::desc("If the size of a function is smaller than the threshold, " "assume it can be inlined by PGO early inliner and it won't " - "be adjusted based on sample profile. ")); + "be adjusted based on sample profile.")); cl::opt InstrProfColdThreshold( "instr-prof-cold-threshold", cl::init(0), cl::Hidden, cl::desc("User specified cold threshold for instr profile which will " - "override the cold threshold got from profile summary. ")); + "override the cold threshold got from profile summary.")); + cl::opt FSDiscriminatorPass( + "fs-discriminator-pass", cl::init(-1), cl::Hidden, + cl::desc("Zero out the discriminator bits for the FS discrimiantor " + "pass beyond this value. For exmaple, value 0 will only keep " + "the base discriminators. Default value of -1 will keep all " + "bits for the discrimiantor.")); cl::ParseCommandLineOptions(argc, argv, "LLVM profile data merger\n"); + int Val = FSDiscriminatorPass.getValue(); + if (Val > static_cast(getNumFSPasses())) + exitWithError("FS DiscriminatorPass out of the range."); + if (Val == -1) + Val = getNumFSPasses(); + FSDiscriminatorPassVal = static_cast(Val); WeightedFileVector WeightedInputs; for (StringRef Filename : InputFilenames) @@ -1588,6 +1615,7 @@ using namespace sampleprof; StringMap BaseFuncProf; + const auto &BaseProfiles = BaseReader->getProfiles(); for (const auto &BaseFunc : BaseProfiles) { BaseFuncProf.try_emplace(BaseFunc.second.getNameWithContext(), @@ -1870,6 +1898,9 @@ BaseReader = std::move(BaseReaderOrErr.get()); TestReader = std::move(TestReaderOrErr.get()); + setDiscriminatorMaskedBit(BaseReader.get()); + setDiscriminatorMaskedBit(TestReader.get()); + if (std::error_code EC = BaseReader->read()) exitWithErrorCode(EC, BaseFilename); if (std::error_code EC = TestReader->read()) @@ -2381,6 +2412,8 @@ auto Reader = std::move(ReaderOrErr.get()); + setDiscriminatorMaskedBit(Reader.get()); + if (ShowSectionInfoOnly) { showSectionInfo(Reader.get(), OS); return 0; @@ -2472,8 +2505,20 @@ cl::desc("Show the information of each section in the sample profile. " "The flag is only usable when the sample profile is in " "extbinary format")); + cl::opt FSDiscriminatorPass( + "fs-discriminator-pass", cl::init(-1), cl::Hidden, + cl::desc("Zero out the discriminator bits for the FS discrimiantor " + "pass beyond this value. For exmaple, value 0 will only keep " + "the base discriminators. Default value of -1 will keep all " + "bits for the discrimiantor.")); cl::ParseCommandLineOptions(argc, argv, "LLVM profile data summary\n"); + int Val = FSDiscriminatorPass.getValue(); + if (Val > static_cast(getNumFSPasses())) + exitWithError("FS DiscriminatorPass out of the range."); + if (Val == -1) + Val = getNumFSPasses(); + FSDiscriminatorPassVal = static_cast(Val); if (OutputFilename.empty()) OutputFilename = "-";