@@ -244,12 +244,14 @@ class ModuleSanitizerCoverage {
244244 void InjectTraceForSwitch (Function &F,
245245 ArrayRef<Instruction *> SwitchTraceTargets);
246246 bool InjectCoverage (Function &F, ArrayRef<BasicBlock *> AllBlocks,
247- bool IsLeafFunc = true );
247+ Value *&FunctionGateCmp, bool IsLeafFunc = true );
248248 GlobalVariable *CreateFunctionLocalArrayInSection (size_t NumElements,
249249 Function &F, Type *Ty,
250250 const char *Section);
251251 GlobalVariable *CreatePCArray (Function &F, ArrayRef<BasicBlock *> AllBlocks);
252252 void CreateFunctionLocalArrays (Function &F, ArrayRef<BasicBlock *> AllBlocks);
253+ Instruction *CreateGateBranch (Function &F, Value *&FunctionGateCmp,
254+ Instruction *I);
253255 Value *CreateFunctionLocalGateCmp (IRBuilder<> &IRB);
254256 void InjectCoverageAtBlock (Function &F, BasicBlock &BB, size_t Idx,
255257 Value *&FunctionGateCmp, bool IsLeafFunc = true );
@@ -723,7 +725,8 @@ void ModuleSanitizerCoverage::instrumentFunction(Function &F) {
723725 if (Options.CollectControlFlow )
724726 createFunctionControlFlow (F);
725727
726- InjectCoverage (F, BlocksToInstrument, IsLeafFunc);
728+ Value *FunctionGateCmp = nullptr ;
729+ InjectCoverage (F, BlocksToInstrument, FunctionGateCmp, IsLeafFunc);
727730 InjectCoverageForIndirectCalls (F, IndirCalls);
728731 InjectTraceForCmp (F, CmpTraceTargets);
729732 InjectTraceForSwitch (F, SwitchTraceTargets);
@@ -815,12 +818,30 @@ Value *ModuleSanitizerCoverage::CreateFunctionLocalGateCmp(IRBuilder<> &IRB) {
815818 return Cmp;
816819}
817820
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+
818839bool ModuleSanitizerCoverage::InjectCoverage (Function &F,
819840 ArrayRef<BasicBlock *> AllBlocks,
841+ Value *&FunctionGateCmp,
820842 bool IsLeafFunc) {
821843 if (AllBlocks.empty ()) return false ;
822844 CreateFunctionLocalArrays (F, AllBlocks);
823- Value *FunctionGateCmp = nullptr ;
824845 for (size_t i = 0 , N = AllBlocks.size (); i < N; i++)
825846 InjectCoverageAtBlock (F, *AllBlocks[i], i, FunctionGateCmp, IsLeafFunc);
826847 return true ;
0 commit comments