Index: llvm/include/llvm/Support/Discriminator.h =================================================================== --- llvm/include/llvm/Support/Discriminator.h +++ llvm/include/llvm/Support/Discriminator.h @@ -54,7 +54,7 @@ // namespace llvm { namespace sampleprof { -enum class FSDiscriminatorPass : unsigned { +enum FSDiscriminatorPass { Base = 0, Pass0 = 0, Pass1 = 1, 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=PassLast | 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=Base | 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=Pass1 | 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=PassLast --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=Base --binary -o - | llvm-profdata show --sample - -o %t2-binary +RUN: llvm-profdata show --sample %p/Inputs/sample-fs.proftext -profile-isfs -fs-discriminator-pass=Base -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=Pass1 --binary -o - | llvm-profdata show --sample - -o %t3-binary +RUN: llvm-profdata show --sample %p/Inputs/sample-fs.proftext -profile-isfs -fs-discriminator-pass=Pass1 -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,27 @@ const uint64_t ColdPercentileIdx = 15; const uint64_t HotPercentileIdx = 11; +using sampleprof::FSDiscriminatorPass; +// Internal options to set FSDiscriminatorPass. Used in merge and show +// commands. +static cl::opt FSDiscriminatorPassOption( + "fs-discriminator-pass", cl::init(PassLast), cl::Hidden, + cl::desc("Zero out the discriminator bits for the FS discrimiantor " + "pass beyond this value. The enum values are defined in " + "Support/Discriminator.h"), + cl::values(clEnumVal(Base, "Use base discriminators only"), + clEnumVal(Pass1, "Use base and pass 1 discriminators"), + clEnumVal(Pass2, "Use base and pass 1-2 discriminators"), + clEnumVal(Pass3, "Use base and pass 1-3 discriminators"), + clEnumVal(PassLast, "Use all discriminator bits (default)"))); +static void setDiscriminatorMaskedBit(sampleprof::SampleProfileReader *Reader) { + Reader->setDiscriminatorMaskedBitFrom(FSDiscriminatorPassOption.getValue()); +} + +static unsigned getDiscriminatorMask() { + return getN1Bits(getFSPassBitEnd(FSDiscriminatorPassOption.getValue())); +} + /// Adjust the instr profile in \p WC based on the sample profile in /// \p Reader. static void @@ -547,6 +569,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); @@ -574,12 +597,13 @@ 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 +713,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,16 +932,16 @@ "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::ParseCommandLineOptions(argc, argv, "LLVM profile data merger\n"); @@ -1870,6 +1895,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()) @@ -2380,7 +2408,7 @@ exitWithErrorCode(EC, Filename); auto Reader = std::move(ReaderOrErr.get()); - + setDiscriminatorMaskedBit(Reader.get()); if (ShowSectionInfoOnly) { showSectionInfo(Reader.get(), OS); return 0;