@@ -244,12 +244,14 @@ class ModuleSanitizerCoverage {
244
244
void InjectTraceForSwitch (Function &F,
245
245
ArrayRef<Instruction *> SwitchTraceTargets);
246
246
bool InjectCoverage (Function &F, ArrayRef<BasicBlock *> AllBlocks,
247
- bool IsLeafFunc = true );
247
+ Value *&FunctionGateCmp, bool IsLeafFunc = true );
248
248
GlobalVariable *CreateFunctionLocalArrayInSection (size_t NumElements,
249
249
Function &F, Type *Ty,
250
250
const char *Section);
251
251
GlobalVariable *CreatePCArray (Function &F, ArrayRef<BasicBlock *> AllBlocks);
252
252
void CreateFunctionLocalArrays (Function &F, ArrayRef<BasicBlock *> AllBlocks);
253
+ Instruction *CreateGateBranch (Function &F, Value *&FunctionGateCmp,
254
+ Instruction *I);
253
255
Value *CreateFunctionLocalGateCmp (IRBuilder<> &IRB);
254
256
void InjectCoverageAtBlock (Function &F, BasicBlock &BB, size_t Idx,
255
257
Value *&FunctionGateCmp, bool IsLeafFunc = true );
@@ -723,7 +725,8 @@ void ModuleSanitizerCoverage::instrumentFunction(Function &F) {
723
725
if (Options.CollectControlFlow )
724
726
createFunctionControlFlow (F);
725
727
726
- InjectCoverage (F, BlocksToInstrument, IsLeafFunc);
728
+ Value *FunctionGateCmp = nullptr ;
729
+ InjectCoverage (F, BlocksToInstrument, FunctionGateCmp, IsLeafFunc);
727
730
InjectCoverageForIndirectCalls (F, IndirCalls);
728
731
InjectTraceForCmp (F, CmpTraceTargets);
729
732
InjectTraceForSwitch (F, SwitchTraceTargets);
@@ -815,12 +818,30 @@ Value *ModuleSanitizerCoverage::CreateFunctionLocalGateCmp(IRBuilder<> &IRB) {
815
818
return Cmp;
816
819
}
817
820
821
+ Instruction *ModuleSanitizerCoverage::CreateGateBranch (Function &F,
822
+ Value *&FunctionGateCmp,
823
+ Instruction *IP) {
824
+ if (!FunctionGateCmp) {
825
+ // Create this in the entry block
826
+ BasicBlock &BB = F.getEntryBlock ();
827
+ BasicBlock::iterator IP = BB.getFirstInsertionPt ();
828
+ IP = PrepareToSplitEntryBlock (BB, IP);
829
+ IRBuilder<> EntryIRB (&*IP);
830
+ FunctionGateCmp = CreateFunctionLocalGateCmp (EntryIRB);
831
+ }
832
+ // Set the branch weights in order to minimize the price paid when the
833
+ // gate is turned off, allowing the default enablement of this
834
+ // instrumentation with as little of a performance cost as possible
835
+ auto Weights = MDBuilder (*C).createBranchWeights (1 , 100000 );
836
+ return SplitBlockAndInsertIfThen (FunctionGateCmp, IP, false , Weights);
837
+ }
838
+
818
839
bool ModuleSanitizerCoverage::InjectCoverage (Function &F,
819
840
ArrayRef<BasicBlock *> AllBlocks,
841
+ Value *&FunctionGateCmp,
820
842
bool IsLeafFunc) {
821
843
if (AllBlocks.empty ()) return false ;
822
844
CreateFunctionLocalArrays (F, AllBlocks);
823
- Value *FunctionGateCmp = nullptr ;
824
845
for (size_t i = 0 , N = AllBlocks.size (); i < N; i++)
825
846
InjectCoverageAtBlock (F, *AllBlocks[i], i, FunctionGateCmp, IsLeafFunc);
826
847
return true ;
0 commit comments