@@ -181,24 +181,52 @@ static cl::opt<bool> SampledInstr("sampled-instrumentation", cl::ZeroOrMore,
181181
182182static cl::opt<unsigned > SampledInstrPeriod (
183183 " sampled-instr-period" ,
184- cl::desc (" Set the profile instrumentation sample period. For each sample "
185- " period, a fixed number of consecutive samples will be recorded. "
186- " The number is controlled by 'sampled-instr-burst-duration' flag. "
187- " The default sample period of 65535 is optimized for generating "
188- " efficient code that leverages unsigned integer wrapping in "
189- " overflow." ),
190- cl::init(65535 ));
184+ cl::desc (" Set the profile instrumentation sample period. A sample period "
185+ " of 0 is invalid. For each sample period, a fixed number of "
186+ " consecutive samples will be recorded. The number is controlled "
187+ " by 'sampled-instr-burst-duration' flag. The default sample "
188+ " period of 65536 is optimized for generating efficient code that "
189+ " leverages unsigned short integer wrapping in overflow, but this "
190+ " is disabled under simple sampling (burst duration = 1)." ),
191+ cl::init(USHRT_MAX + 1 ));
191192
192193static cl::opt<unsigned > SampledInstrBurstDuration (
193194 " sampled-instr-burst-duration" ,
194195 cl::desc (" Set the profile instrumentation burst duration, which can range "
195- " from 0 to one less than the value of 'sampled-instr-period'. "
196+ " from 1 to the value of 'sampled-instr-period' (0 is invalid) . "
196197 " This number of samples will be recorded for each "
197- " 'sampled-instr-period' count update. Setting to 1 enables "
198- " simple sampling, in which case it is recommended to set "
198+ " 'sampled-instr-period' count update. Setting to 1 enables simple "
199+ " sampling, in which case it is recommended to set "
199200 " 'sampled-instr-period' to a prime number." ),
200201 cl::init(200 ));
201202
203+ struct SampledInstrumentationConfig {
204+ unsigned BurstDuration;
205+ unsigned Period;
206+ bool UseShort;
207+ bool IsSimpleSampling;
208+ bool IsFastSampling;
209+ };
210+
211+ static SampledInstrumentationConfig getSampledInstrumentationConfig () {
212+ SampledInstrumentationConfig config;
213+ config.BurstDuration = SampledInstrBurstDuration.getValue ();
214+ config.Period = SampledInstrPeriod.getValue ();
215+ if (config.BurstDuration > config.Period )
216+ report_fatal_error (
217+ " SampledBurstDuration must be less than or equal to SampledPeriod" );
218+ if (config.Period == 0 || config.BurstDuration == 0 )
219+ report_fatal_error (
220+ " SampledPeriod and SampledBurstDuration must be greater than 0" );
221+ config.IsSimpleSampling = (config.BurstDuration == 1 );
222+ // If (BurstDuration == 1 && Period == 65536), generate the simple sampling
223+ // style code.
224+ config.IsFastSampling =
225+ (!config.IsSimpleSampling && config.Period == USHRT_MAX + 1 );
226+ config.UseShort = (config.Period <= USHRT_MAX) || config.IsFastSampling ;
227+ return config;
228+ }
229+
202230using LoadStorePair = std::pair<Instruction *, Instruction *>;
203231
204232static uint64_t getIntModuleFlagOrZero (const Module &M, StringRef Flag) {
@@ -665,7 +693,7 @@ PreservedAnalyses InstrProfilingLoweringPass::run(Module &M,
665693// (1) Full burst sampling: We transform:
666694// Increment_Instruction;
667695// to:
668- // if (__llvm_profile_sampling__ < SampledInstrBurstDuration) {
696+ // if (__llvm_profile_sampling__ <= SampledInstrBurstDuration - 1 ) {
669697// Increment_Instruction;
670698// }
671699// __llvm_profile_sampling__ += 1;
@@ -680,14 +708,14 @@ PreservedAnalyses InstrProfilingLoweringPass::run(Module &M,
680708// "__llvm_profile_sampling__" variable is an unsigned type, meaning it will
681709// wrap around to zero when overflows. In this case, the second check is
682710// unnecessary, so we won't generate check2 when the SampledInstrPeriod is
683- // set to 65535 (64K - 1 ). The code after:
684- // if (__llvm_profile_sampling__ < SampledInstrBurstDuration) {
711+ // set to 65536 (64K). The code after:
712+ // if (__llvm_profile_sampling__ <= SampledInstrBurstDuration - 1 ) {
685713// Increment_Instruction;
686714// }
687715// __llvm_profile_sampling__ += 1;
688716//
689717// (3) Simple sampling:
690- // When SampledInstrBurstDuration sets to 1, we do a simple sampling:
718+ // When SampledInstrBurstDuration is set to 1, we do a simple sampling:
691719// __llvm_profile_sampling__ += 1;
692720// if (__llvm_profile_sampling__ >= SampledInstrPeriod) {
693721// __llvm_profile_sampling__ = 0;
@@ -706,27 +734,16 @@ void InstrLowerer::doSampling(Instruction *I) {
706734 if (!isSamplingEnabled ())
707735 return ;
708736
709- unsigned SampledBurstDuration = SampledInstrBurstDuration.getValue ();
710- unsigned SampledPeriod = SampledInstrPeriod.getValue ();
711- if (SampledBurstDuration >= SampledPeriod) {
712- report_fatal_error (
713- " SampledPeriod needs to be greater than SampledBurstDuration" );
714- }
715- bool UseShort = (SampledPeriod <= USHRT_MAX);
716- bool IsSimpleSampling = (SampledBurstDuration == 1 );
717- // If (SampledBurstDuration == 1 && SampledPeriod == 65535), generate
718- // the simple sampling style code.
719- bool IsFastSampling = (!IsSimpleSampling && SampledPeriod == 65535 );
720-
721- auto GetConstant = [UseShort](IRBuilder<> &Builder, uint32_t C) {
722- if (UseShort)
737+ SampledInstrumentationConfig config = getSampledInstrumentationConfig ();
738+ auto GetConstant = [&config](IRBuilder<> &Builder, uint32_t C) {
739+ if (config.UseShort )
723740 return Builder.getInt16 (C);
724741 else
725742 return Builder.getInt32 (C);
726743 };
727744
728745 IntegerType *SamplingVarTy;
729- if (UseShort)
746+ if (config. UseShort )
730747 SamplingVarTy = Type::getInt16Ty (M.getContext ());
731748 else
732749 SamplingVarTy = Type::getInt32Ty (M.getContext ());
@@ -741,18 +758,18 @@ void InstrLowerer::doSampling(Instruction *I) {
741758 MDNode *BranchWeight;
742759 IRBuilder<> CondBuilder (I);
743760 auto *LoadSamplingVar = CondBuilder.CreateLoad (SamplingVarTy, SamplingVar);
744- if (IsSimpleSampling) {
761+ if (config. IsSimpleSampling ) {
745762 // For the simple sampling, just create the load and increments.
746763 IRBuilder<> IncBuilder (I);
747764 NewSamplingVarVal =
748765 IncBuilder.CreateAdd (LoadSamplingVar, GetConstant (IncBuilder, 1 ));
749766 SamplingVarIncr = IncBuilder.CreateStore (NewSamplingVarVal, SamplingVar);
750767 } else {
751- // For the bust -sampling, create the conditonal update.
768+ // For the burst -sampling, create the conditional update.
752769 auto *DurationCond = CondBuilder.CreateICmpULE (
753- LoadSamplingVar, GetConstant (CondBuilder, SampledBurstDuration ));
770+ LoadSamplingVar, GetConstant (CondBuilder, config. BurstDuration - 1 ));
754771 BranchWeight = MDB.createBranchWeights (
755- SampledBurstDuration, SampledPeriod + 1 - SampledBurstDuration );
772+ config. BurstDuration , config. Period - config. BurstDuration );
756773 Instruction *ThenTerm = SplitBlockAndInsertIfThen (
757774 DurationCond, I, /* Unreachable */ false , BranchWeight);
758775 IRBuilder<> IncBuilder (I);
@@ -762,20 +779,20 @@ void InstrLowerer::doSampling(Instruction *I) {
762779 I->moveBefore (ThenTerm);
763780 }
764781
765- if (IsFastSampling)
782+ if (config. IsFastSampling )
766783 return ;
767784
768- // Create the condtion for checking the period.
785+ // Create the condition for checking the period.
769786 Instruction *ThenTerm, *ElseTerm;
770787 IRBuilder<> PeriodCondBuilder (SamplingVarIncr);
771788 auto *PeriodCond = PeriodCondBuilder.CreateICmpUGE (
772- NewSamplingVarVal, GetConstant (PeriodCondBuilder, SampledPeriod ));
773- BranchWeight = MDB.createBranchWeights (1 , SampledPeriod );
789+ NewSamplingVarVal, GetConstant (PeriodCondBuilder, config. Period ));
790+ BranchWeight = MDB.createBranchWeights (1 , config. Period - 1 );
774791 SplitBlockAndInsertIfThenElse (PeriodCond, SamplingVarIncr, &ThenTerm,
775792 &ElseTerm, BranchWeight);
776793
777794 // For the simple sampling, the counter update happens in sampling var reset.
778- if (IsSimpleSampling)
795+ if (config. IsSimpleSampling )
779796 I->moveBefore (ThenTerm);
780797
781798 IRBuilder<> ResetBuilder (ThenTerm);
@@ -2138,7 +2155,7 @@ void createProfileSamplingVar(Module &M) {
21382155 const StringRef VarName (INSTR_PROF_QUOTE (INSTR_PROF_PROFILE_SAMPLING_VAR));
21392156 IntegerType *SamplingVarTy;
21402157 Constant *ValueZero;
2141- if (SampledInstrPeriod. getValue () <= USHRT_MAX ) {
2158+ if (getSampledInstrumentationConfig (). UseShort ) {
21422159 SamplingVarTy = Type::getInt16Ty (M.getContext ());
21432160 ValueZero = Constant::getIntegerValue (SamplingVarTy, APInt (16 , 0 ));
21442161 } else {
0 commit comments