@@ -181,24 +181,52 @@ static cl::opt<bool> SampledInstr("sampled-instrumentation", cl::ZeroOrMore,
181
181
182
182
static cl::opt<unsigned > SampledInstrPeriod (
183
183
" 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 ));
191
192
192
193
static cl::opt<unsigned > SampledInstrBurstDuration (
193
194
" sampled-instr-burst-duration" ,
194
195
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) . "
196
197
" 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 "
199
200
" 'sampled-instr-period' to a prime number." ),
200
201
cl::init(200 ));
201
202
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
+
202
230
using LoadStorePair = std::pair<Instruction *, Instruction *>;
203
231
204
232
static uint64_t getIntModuleFlagOrZero (const Module &M, StringRef Flag) {
@@ -665,7 +693,7 @@ PreservedAnalyses InstrProfilingLoweringPass::run(Module &M,
665
693
// (1) Full burst sampling: We transform:
666
694
// Increment_Instruction;
667
695
// to:
668
- // if (__llvm_profile_sampling__ < SampledInstrBurstDuration) {
696
+ // if (__llvm_profile_sampling__ <= SampledInstrBurstDuration - 1 ) {
669
697
// Increment_Instruction;
670
698
// }
671
699
// __llvm_profile_sampling__ += 1;
@@ -680,14 +708,14 @@ PreservedAnalyses InstrProfilingLoweringPass::run(Module &M,
680
708
// "__llvm_profile_sampling__" variable is an unsigned type, meaning it will
681
709
// wrap around to zero when overflows. In this case, the second check is
682
710
// 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 ) {
685
713
// Increment_Instruction;
686
714
// }
687
715
// __llvm_profile_sampling__ += 1;
688
716
//
689
717
// (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:
691
719
// __llvm_profile_sampling__ += 1;
692
720
// if (__llvm_profile_sampling__ >= SampledInstrPeriod) {
693
721
// __llvm_profile_sampling__ = 0;
@@ -706,27 +734,16 @@ void InstrLowerer::doSampling(Instruction *I) {
706
734
if (!isSamplingEnabled ())
707
735
return ;
708
736
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 )
723
740
return Builder.getInt16 (C);
724
741
else
725
742
return Builder.getInt32 (C);
726
743
};
727
744
728
745
IntegerType *SamplingVarTy;
729
- if (UseShort)
746
+ if (config. UseShort )
730
747
SamplingVarTy = Type::getInt16Ty (M.getContext ());
731
748
else
732
749
SamplingVarTy = Type::getInt32Ty (M.getContext ());
@@ -741,18 +758,18 @@ void InstrLowerer::doSampling(Instruction *I) {
741
758
MDNode *BranchWeight;
742
759
IRBuilder<> CondBuilder (I);
743
760
auto *LoadSamplingVar = CondBuilder.CreateLoad (SamplingVarTy, SamplingVar);
744
- if (IsSimpleSampling) {
761
+ if (config. IsSimpleSampling ) {
745
762
// For the simple sampling, just create the load and increments.
746
763
IRBuilder<> IncBuilder (I);
747
764
NewSamplingVarVal =
748
765
IncBuilder.CreateAdd (LoadSamplingVar, GetConstant (IncBuilder, 1 ));
749
766
SamplingVarIncr = IncBuilder.CreateStore (NewSamplingVarVal, SamplingVar);
750
767
} else {
751
- // For the bust -sampling, create the conditonal update.
768
+ // For the burst -sampling, create the conditional update.
752
769
auto *DurationCond = CondBuilder.CreateICmpULE (
753
- LoadSamplingVar, GetConstant (CondBuilder, SampledBurstDuration ));
770
+ LoadSamplingVar, GetConstant (CondBuilder, config. BurstDuration - 1 ));
754
771
BranchWeight = MDB.createBranchWeights (
755
- SampledBurstDuration, SampledPeriod + 1 - SampledBurstDuration );
772
+ config. BurstDuration , config. Period - config. BurstDuration );
756
773
Instruction *ThenTerm = SplitBlockAndInsertIfThen (
757
774
DurationCond, I, /* Unreachable */ false , BranchWeight);
758
775
IRBuilder<> IncBuilder (I);
@@ -762,20 +779,20 @@ void InstrLowerer::doSampling(Instruction *I) {
762
779
I->moveBefore (ThenTerm);
763
780
}
764
781
765
- if (IsFastSampling)
782
+ if (config. IsFastSampling )
766
783
return ;
767
784
768
- // Create the condtion for checking the period.
785
+ // Create the condition for checking the period.
769
786
Instruction *ThenTerm, *ElseTerm;
770
787
IRBuilder<> PeriodCondBuilder (SamplingVarIncr);
771
788
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 );
774
791
SplitBlockAndInsertIfThenElse (PeriodCond, SamplingVarIncr, &ThenTerm,
775
792
&ElseTerm, BranchWeight);
776
793
777
794
// For the simple sampling, the counter update happens in sampling var reset.
778
- if (IsSimpleSampling)
795
+ if (config. IsSimpleSampling )
779
796
I->moveBefore (ThenTerm);
780
797
781
798
IRBuilder<> ResetBuilder (ThenTerm);
@@ -2138,7 +2155,7 @@ void createProfileSamplingVar(Module &M) {
2138
2155
const StringRef VarName (INSTR_PROF_QUOTE (INSTR_PROF_PROFILE_SAMPLING_VAR));
2139
2156
IntegerType *SamplingVarTy;
2140
2157
Constant *ValueZero;
2141
- if (SampledInstrPeriod. getValue () <= USHRT_MAX ) {
2158
+ if (getSampledInstrumentationConfig (). UseShort ) {
2142
2159
SamplingVarTy = Type::getInt16Ty (M.getContext ());
2143
2160
ValueZero = Constant::getIntegerValue (SamplingVarTy, APInt (16 , 0 ));
2144
2161
} else {
0 commit comments