void BBCloner::CreateFastPath(Function &F) { CloneMap.clear(); for (Function::arg_iterator AI = F.arg_begin(); AI != F.arg_end(); ++AI) CloneMap[AI] = AI; BBSet OldBBs; for (Function::iterator B = F.begin(); B != F.end(); ++B) OldBBs.insert(B); for (BBSet::iterator I = OldBBs.begin(); I != OldBBs.end(); ++I) { BasicBlock *B = *I; // Skip the back edge blocks inserted by CheckInserter. if (IsBackEdgeBlock(*B)) { CloneMap[B] = B; continue; } BasicBlock *B2 = CloneBasicBlock(B, CloneMap, ".fast", &F, NULL); // Strip DebugLoc from all cloned instructions; otherwise, the code // generator would assert fail. TODO: Figure out why it would fail. for (BasicBlock::iterator Ins = B2->begin(); Ins != B2->end(); ++Ins) { if (!Ins->getDebugLoc().isUnknown()) Ins->setDebugLoc(DebugLoc()); } CloneMap[B] = B2; } for (Function::iterator B2 = F.begin(); B2 != F.end(); ++B2) { if (OldBBs.count(B2)) continue; for (BasicBlock::iterator I = B2->begin(); I != B2->end(); ++I) RemapInstruction(I, CloneMap); } }
void GCOVProfiler::emitGCNO() { NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); if (!CU_Nodes) return; for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { // Each compile unit gets its own .gcno file. This means that whether we run // this pass over the original .o's as they're produced, or run it after // LTO, we'll generate the same .gcno files. DICompileUnit CU(CU_Nodes->getOperand(i)); std::string ErrorInfo; raw_fd_ostream out(mangleName(CU, "gcno").c_str(), ErrorInfo, raw_fd_ostream::F_Binary); if (!Use402Format) out.write("oncg*404MVLL", 12); else out.write("oncg*204MVLL", 12); DIArray SPs = CU.getSubprograms(); for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) { DISubprogram SP(SPs.getElement(i)); if (!SP.Verify()) continue; Function *F = SP.getFunction(); if (!F) continue; GCOVFunction Func(SP, &out, Use402Format, UseExtraChecksum); for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { GCOVBlock &Block = Func.getBlock(BB); TerminatorInst *TI = BB->getTerminator(); if (int successors = TI->getNumSuccessors()) { for (int i = 0; i != successors; ++i) { Block.addEdge(Func.getBlock(TI->getSuccessor(i))); } } else if (isa<ReturnInst>(TI)) { Block.addEdge(Func.getReturnBlock()); } uint32_t Line = 0; for (BasicBlock::iterator I = BB->begin(), IE = BB->end(); I != IE; ++I) { const DebugLoc &Loc = I->getDebugLoc(); if (Loc.isUnknown()) continue; if (Line == Loc.getLine()) continue; Line = Loc.getLine(); if (SP != getDISubprogram(Loc.getScope(*Ctx))) continue; GCOVLines &Lines = Block.getFile(SP.getFilename()); Lines.addLine(Loc.getLine()); } } Func.writeOut(); } out.write("\0\0\0\0\0\0\0\0", 8); // EOF out.close(); } }
void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F, BasicBlock &BB) { BasicBlock::iterator IP = BB.getFirstInsertionPt(), BE = BB.end(); // Skip static allocas at the top of the entry block so they don't become // dynamic when we split the block. If we used our optimized stack layout, // then there will only be one alloca and it will come first. for (; IP != BE; ++IP) { AllocaInst *AI = dyn_cast<AllocaInst>(IP); if (!AI || !AI->isStaticAlloca()) break; } bool IsEntryBB = &BB == &F.getEntryBlock(); DebugLoc EntryLoc = IsEntryBB ? IP->getDebugLoc().getFnDebugLoc(*C) : IP->getDebugLoc(); IRBuilder<> IRB(IP); IRB.SetCurrentDebugLocation(EntryLoc); SmallVector<Value *, 1> Indices; Value *GuardP = IRB.CreateAdd( IRB.CreatePointerCast(GuardArray, IntptrTy), ConstantInt::get(IntptrTy, (1 + SanCovFunction->getNumUses()) * 4)); Type *Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty()); GuardP = IRB.CreateIntToPtr(GuardP, Int32PtrTy); LoadInst *Load = IRB.CreateLoad(GuardP); Load->setAtomic(Monotonic); Load->setAlignment(4); Load->setMetadata(F.getParent()->getMDKindID("nosanitize"), MDNode::get(*C, None)); Value *Cmp = IRB.CreateICmpSGE(Constant::getNullValue(Load->getType()), Load); Instruction *Ins = SplitBlockAndInsertIfThen( Cmp, IP, false, MDBuilder(*C).createBranchWeights(1, 100000)); IRB.SetInsertPoint(Ins); IRB.SetCurrentDebugLocation(EntryLoc); // __sanitizer_cov gets the PC of the instruction using GET_CALLER_PC. IRB.CreateCall(SanCovFunction, GuardP); IRB.CreateCall(EmptyAsm); // Avoids callback merge. if (ClExperimentalTracing) { // Experimental support for tracing. // Insert a callback with the same guard variable as used for coverage. IRB.SetInsertPoint(IP); IRB.CreateCall(IsEntryBB ? SanCovTraceEnter : SanCovTraceBB, GuardP); } }
/// fixupLineNumbers - Update inlined instructions' line numbers to /// to encode location where these instructions are inlined. static void fixupLineNumbers(Function *Fn, Function::iterator FI, Instruction *TheCall) { DebugLoc TheCallDL = TheCall->getDebugLoc(); if (TheCallDL.isUnknown()) return; for (; FI != Fn->end(); ++FI) { for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; ++BI) { DebugLoc DL = BI->getDebugLoc(); if (!DL.isUnknown()) { BI->setDebugLoc(updateInlinedAtInfo(DL, TheCallDL, BI->getContext())); if (DbgValueInst *DVI = dyn_cast<DbgValueInst>(BI)) { LLVMContext &Ctx = BI->getContext(); MDNode *InlinedAt = BI->getDebugLoc().getInlinedAt(Ctx); DVI->setOperand(2, createInlinedVariable(DVI->getVariable(), InlinedAt, Ctx)); } } } } }
// StripDebugInfo - Strip debug info in the module if it exists. // To do this, we remove llvm.dbg.func.start, llvm.dbg.stoppoint, and // llvm.dbg.region.end calls, and any globals they point to if now dead. static bool StripDebugInfo(Module &M) { bool Changed = false; // Remove all of the calls to the debugger intrinsics, and remove them from // the module. if (Function *Declare = M.getFunction("llvm.dbg.declare")) { while (!Declare->use_empty()) { CallInst *CI = cast<CallInst>(Declare->use_back()); CI->eraseFromParent(); } Declare->eraseFromParent(); Changed = true; } if (Function *DbgVal = M.getFunction("llvm.dbg.value")) { while (!DbgVal->use_empty()) { CallInst *CI = cast<CallInst>(DbgVal->use_back()); CI->eraseFromParent(); } DbgVal->eraseFromParent(); Changed = true; } for (Module::named_metadata_iterator NMI = M.named_metadata_begin(), NME = M.named_metadata_end(); NMI != NME;) { NamedMDNode *NMD = NMI; ++NMI; if (NMD->getName().startswith("llvm.dbg.")) { NMD->eraseFromParent(); Changed = true; } } for (Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI) for (Function::iterator FI = MI->begin(), FE = MI->end(); FI != FE; ++FI) for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; ++BI) { if (!BI->getDebugLoc().isUnknown()) { Changed = true; BI->setDebugLoc(DebugLoc()); } } return Changed; }
/// processModule - Process entire module and collect debug info. void DebugInfoFinder::processModule(Module &M) { if (NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu")) for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) addCompileUnit(DICompileUnit(CU_Nodes->getOperand(i))); for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) for (Function::iterator FI = (*I).begin(), FE = (*I).end(); FI != FE; ++FI) for (BasicBlock::iterator BI = (*FI).begin(), BE = (*FI).end(); BI != BE; ++BI) { if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(BI)) processDeclare(DDI); DebugLoc Loc = BI->getDebugLoc(); if (Loc.isUnknown()) continue; LLVMContext &Ctx = BI->getContext(); DIDescriptor Scope(Loc.getScope(Ctx)); if (Scope.isCompileUnit()) addCompileUnit(DICompileUnit(Scope)); else if (Scope.isSubprogram()) processSubprogram(DISubprogram(Scope)); else if (Scope.isLexicalBlock()) processLexicalBlock(DILexicalBlock(Scope)); if (MDNode *IA = Loc.getInlinedAt(Ctx)) processLocation(DILocation(IA)); } if (NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.gv")) { for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { DIGlobalVariable DIG(cast<MDNode>(NMD->getOperand(i))); if (addGlobalVariable(DIG)) { if (DIG.getVersion() <= LLVMDebugVersion10) addCompileUnit(DIG.getCompileUnit()); processType(DIG.getType()); } } } if (NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.sp")) for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) processSubprogram(DISubprogram(NMD->getOperand(i))); }
void Matcher::processInst(Function *F) { for (Function::iterator FI = F->begin(), FE = F->end(); FI != FE; FI++) { /** Get each instruction's scope information **/ for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; BI++) { DebugLoc Loc = BI->getDebugLoc(); if (Loc.isUnknown()) continue; LLVMContext & Ctx = BI->getContext(); DIDescriptor Scope(Loc.getScope(Ctx)); if (Scope.isLexicalBlock()) { DILexicalBlock DILB(Scope); errs() << "Block :" << DILB.getLineNumber() << ", " << DILB.getColumnNumber() << "\n"; } } } }
void llvm::ReplaceInstWithInst(BasicBlock::InstListType &BIL, BasicBlock::iterator &BI, Instruction *I) { assert(I->getParent() == nullptr && "ReplaceInstWithInst: Instruction already inserted into basic block!"); // Copy debug location to newly added instruction, if it wasn't already set // by the caller. if (!I->getDebugLoc()) I->setDebugLoc(BI->getDebugLoc()); // Insert the new instruction into the basic block... BasicBlock::iterator New = BIL.insert(BI, I); // Replace all uses of the old instruction, and delete it. ReplaceInstWithValue(BIL, BI, I); // Move BI back to point to the newly inserted instruction BI = New; }
static bool functionHasLines(Function *F) { // Check whether this function actually has any source lines. Not only // do these waste space, they also can crash gcov. for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { for (BasicBlock::iterator I = BB->begin(), IE = BB->end(); I != IE; ++I) { // Debug intrinsic locations correspond to the location of the // declaration, not necessarily any statements or expressions. if (isa<DbgInfoIntrinsic>(I)) continue; const DebugLoc &Loc = I->getDebugLoc(); if (Loc.isUnknown()) continue; // Artificial lines such as calls to the global constructors. if (Loc.getLine() == 0) continue; return true; } } return false; }
void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F, BasicBlock &BB, size_t Idx, bool UseCalls) { BasicBlock::iterator IP = BB.getFirstInsertionPt(); bool IsEntryBB = &BB == &F.getEntryBlock(); DebugLoc EntryLoc; if (IsEntryBB) { if (auto SP = F.getSubprogram()) EntryLoc = DebugLoc::get(SP->getScopeLine(), 0, SP); // Keep static allocas and llvm.localescape calls in the entry block. Even // if we aren't splitting the block, it's nice for allocas to be before // calls. IP = PrepareToSplitEntryBlock(BB, IP); } else { EntryLoc = IP->getDebugLoc(); } IRBuilder<> IRB(&*IP); IRB.SetCurrentDebugLocation(EntryLoc); if (Options.TracePC) { IRB.CreateCall(SanCovTracePC); // gets the PC using GET_CALLER_PC. IRB.CreateCall(EmptyAsm, {}); // Avoids callback merge. } else if (Options.TracePCGuard) { //auto GuardVar = new GlobalVariable( // *F.getParent(), Int64Ty, false, GlobalVariable::LinkOnceODRLinkage, // Constant::getNullValue(Int64Ty), "__sancov_guard." + F.getName()); // if (auto Comdat = F.getComdat()) // GuardVar->setComdat(Comdat); // TODO: add debug into to GuardVar. // GuardVar->setSection(SanCovTracePCGuardSection); // auto GuardPtr = IRB.CreatePointerCast(GuardVar, IntptrPtrTy); auto GuardPtr = IRB.CreateIntToPtr( IRB.CreateAdd(IRB.CreatePointerCast(FunctionGuardArray, IntptrTy), ConstantInt::get(IntptrTy, Idx * 4)), Int32PtrTy); if (!UseCalls) { auto GuardLoad = IRB.CreateLoad(GuardPtr); GuardLoad->setAtomic(AtomicOrdering::Monotonic); GuardLoad->setAlignment(8); SetNoSanitizeMetadata(GuardLoad); // Don't instrument with e.g. asan. auto Cmp = IRB.CreateICmpNE( GuardLoad, Constant::getNullValue(GuardLoad->getType())); auto Ins = SplitBlockAndInsertIfThen( Cmp, &*IP, false, MDBuilder(*C).createBranchWeights(1, 100000)); IRB.SetCurrentDebugLocation(EntryLoc); IRB.SetInsertPoint(Ins); } IRB.CreateCall(SanCovTracePCGuard, GuardPtr); IRB.CreateCall(EmptyAsm, {}); // Avoids callback merge. } else { Value *GuardP = IRB.CreateAdd( IRB.CreatePointerCast(GuardArray, IntptrTy), ConstantInt::get(IntptrTy, (1 + NumberOfInstrumentedBlocks()) * 4)); GuardP = IRB.CreateIntToPtr(GuardP, Int32PtrTy); if (Options.TraceBB) { IRB.CreateCall(IsEntryBB ? SanCovTraceEnter : SanCovTraceBB, GuardP); } else if (UseCalls) { IRB.CreateCall(SanCovWithCheckFunction, GuardP); } else { LoadInst *Load = IRB.CreateLoad(GuardP); Load->setAtomic(AtomicOrdering::Monotonic); Load->setAlignment(4); SetNoSanitizeMetadata(Load); Value *Cmp = IRB.CreateICmpSGE(Constant::getNullValue(Load->getType()), Load); Instruction *Ins = SplitBlockAndInsertIfThen( Cmp, &*IP, false, MDBuilder(*C).createBranchWeights(1, 100000)); IRB.SetInsertPoint(Ins); IRB.SetCurrentDebugLocation(EntryLoc); // __sanitizer_cov gets the PC of the instruction using GET_CALLER_PC. IRB.CreateCall(SanCovFunction, GuardP); IRB.CreateCall(EmptyAsm, {}); // Avoids callback merge. } } if (Options.Use8bitCounters) { IRB.SetInsertPoint(&*IP); Value *P = IRB.CreateAdd( IRB.CreatePointerCast(EightBitCounterArray, IntptrTy), ConstantInt::get(IntptrTy, NumberOfInstrumentedBlocks() - 1)); P = IRB.CreateIntToPtr(P, IRB.getInt8PtrTy()); LoadInst *LI = IRB.CreateLoad(P); Value *Inc = IRB.CreateAdd(LI, ConstantInt::get(IRB.getInt8Ty(), 1)); StoreInst *SI = IRB.CreateStore(Inc, P); SetNoSanitizeMetadata(LI); SetNoSanitizeMetadata(SI); } }
void GCOVProfiler::emitProfileNotes() { NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); if (!CU_Nodes) return; for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { // Each compile unit gets its own .gcno file. This means that whether we run // this pass over the original .o's as they're produced, or run it after // LTO, we'll generate the same .gcno files. auto *CU = cast<DICompileUnit>(CU_Nodes->getOperand(i)); std::error_code EC; raw_fd_ostream out(mangleName(CU, "gcno"), EC, sys::fs::F_None); std::string EdgeDestinations; unsigned FunctionIdent = 0; for (auto *SP : CU->getSubprograms()) { Function *F = FnMap[SP]; if (!F) continue; if (!functionHasLines(F)) continue; // gcov expects every function to start with an entry block that has a // single successor, so split the entry block to make sure of that. BasicBlock &EntryBlock = F->getEntryBlock(); BasicBlock::iterator It = EntryBlock.begin(); while (isa<AllocaInst>(*It) || isa<DbgInfoIntrinsic>(*It)) ++It; EntryBlock.splitBasicBlock(It); Funcs.push_back(make_unique<GCOVFunction>(SP, F, &out, FunctionIdent++, Options.UseCfgChecksum, Options.ExitBlockBeforeBody)); GCOVFunction &Func = *Funcs.back(); for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { GCOVBlock &Block = Func.getBlock(&*BB); TerminatorInst *TI = BB->getTerminator(); if (int successors = TI->getNumSuccessors()) { for (int i = 0; i != successors; ++i) { Block.addEdge(Func.getBlock(TI->getSuccessor(i))); } } else if (isa<ReturnInst>(TI)) { Block.addEdge(Func.getReturnBlock()); } uint32_t Line = 0; for (BasicBlock::iterator I = BB->begin(), IE = BB->end(); I != IE; ++I) { // Debug intrinsic locations correspond to the location of the // declaration, not necessarily any statements or expressions. if (isa<DbgInfoIntrinsic>(I)) continue; const DebugLoc &Loc = I->getDebugLoc(); if (!Loc) continue; // Artificial lines such as calls to the global constructors. if (Loc.getLine() == 0) continue; if (Line == Loc.getLine()) continue; Line = Loc.getLine(); if (SP != getDISubprogram(Loc.getScope())) continue; GCOVLines &Lines = Block.getFile(SP->getFilename()); Lines.addLine(Loc.getLine()); } } EdgeDestinations += Func.getEdgeDestinations(); } FileChecksums.push_back(hash_value(EdgeDestinations)); out.write("oncg", 4); out.write(ReversedVersion, 4); out.write(reinterpret_cast<char*>(&FileChecksums.back()), 4); for (auto &Func : Funcs) { Func->setCfgChecksum(FileChecksums.back()); Func->writeOut(); } out.write("\0\0\0\0\0\0\0\0", 8); // EOF out.close(); } }
void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F, BasicBlock &BB, bool UseCalls) { // Don't insert coverage for unreachable blocks: we will never call // __sanitizer_cov() for them, so counting them in // NumberOfInstrumentedBlocks() might complicate calculation of code coverage // percentage. Also, unreachable instructions frequently have no debug // locations. if (isa<UnreachableInst>(BB.getTerminator())) return; BasicBlock::iterator IP = BB.getFirstInsertionPt(); bool IsEntryBB = &BB == &F.getEntryBlock(); DebugLoc EntryLoc; if (IsEntryBB) { if (auto SP = getDISubprogram(&F)) EntryLoc = DebugLoc::get(SP->getScopeLine(), 0, SP); // Keep static allocas and llvm.localescape calls in the entry block. Even // if we aren't splitting the block, it's nice for allocas to be before // calls. IP = PrepareToSplitEntryBlock(BB, IP); } else { EntryLoc = IP->getDebugLoc(); } IRBuilder<> IRB(&*IP); IRB.SetCurrentDebugLocation(EntryLoc); Value *GuardP = IRB.CreateAdd( IRB.CreatePointerCast(GuardArray, IntptrTy), ConstantInt::get(IntptrTy, (1 + NumberOfInstrumentedBlocks()) * 4)); Type *Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty()); GuardP = IRB.CreateIntToPtr(GuardP, Int32PtrTy); if (Options.TracePC) { IRB.CreateCall(SanCovTracePC); } else if (Options.TraceBB) { IRB.CreateCall(IsEntryBB ? SanCovTraceEnter : SanCovTraceBB, GuardP); } else if (UseCalls) { IRB.CreateCall(SanCovWithCheckFunction, GuardP); } else { LoadInst *Load = IRB.CreateLoad(GuardP); Load->setAtomic(Monotonic); Load->setAlignment(4); SetNoSanitizeMetadata(Load); Value *Cmp = IRB.CreateICmpSGE(Constant::getNullValue(Load->getType()), Load); Instruction *Ins = SplitBlockAndInsertIfThen( Cmp, &*IP, false, MDBuilder(*C).createBranchWeights(1, 100000)); IRB.SetInsertPoint(Ins); IRB.SetCurrentDebugLocation(EntryLoc); // __sanitizer_cov gets the PC of the instruction using GET_CALLER_PC. IRB.CreateCall(SanCovFunction, GuardP); IRB.CreateCall(EmptyAsm, {}); // Avoids callback merge. } if (Options.Use8bitCounters) { IRB.SetInsertPoint(&*IP); Value *P = IRB.CreateAdd( IRB.CreatePointerCast(EightBitCounterArray, IntptrTy), ConstantInt::get(IntptrTy, NumberOfInstrumentedBlocks() - 1)); P = IRB.CreateIntToPtr(P, IRB.getInt8PtrTy()); LoadInst *LI = IRB.CreateLoad(P); Value *Inc = IRB.CreateAdd(LI, ConstantInt::get(IRB.getInt8Ty(), 1)); StoreInst *SI = IRB.CreateStore(Inc, P); SetNoSanitizeMetadata(LI); SetNoSanitizeMetadata(SI); } }
void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F, BasicBlock &BB, bool UseCalls) { // Don't insert coverage for unreachable blocks: we will never call // __sanitizer_cov() for them, so counting them in // NumberOfInstrumentedBlocks() might complicate calculation of code coverage // percentage. Also, unreachable instructions frequently have no debug // locations. if (isa<UnreachableInst>(BB.getTerminator())) return; BasicBlock::iterator IP = BB.getFirstInsertionPt(), BE = BB.end(); // Skip static allocas at the top of the entry block so they don't become // dynamic when we split the block. If we used our optimized stack layout, // then there will only be one alloca and it will come first. for (; IP != BE; ++IP) { AllocaInst *AI = dyn_cast<AllocaInst>(IP); if (!AI || !AI->isStaticAlloca()) break; } bool IsEntryBB = &BB == &F.getEntryBlock(); DebugLoc EntryLoc; if (IsEntryBB) { if (auto SP = getDISubprogram(&F)) EntryLoc = DebugLoc::get(SP->getScopeLine(), 0, SP); } else { EntryLoc = IP->getDebugLoc(); } IRBuilder<> IRB(IP); IRB.SetCurrentDebugLocation(EntryLoc); SmallVector<Value *, 1> Indices; Value *GuardP = IRB.CreateAdd( IRB.CreatePointerCast(GuardArray, IntptrTy), ConstantInt::get(IntptrTy, (1 + NumberOfInstrumentedBlocks()) * 4)); Type *Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty()); GuardP = IRB.CreateIntToPtr(GuardP, Int32PtrTy); if (UseCalls) { IRB.CreateCall(SanCovWithCheckFunction, GuardP); } else { LoadInst *Load = IRB.CreateLoad(GuardP); Load->setAtomic(Monotonic); Load->setAlignment(4); SetNoSanitizeMetadata(Load); Value *Cmp = IRB.CreateICmpSGE(Constant::getNullValue(Load->getType()), Load); Instruction *Ins = SplitBlockAndInsertIfThen( Cmp, IP, false, MDBuilder(*C).createBranchWeights(1, 100000)); IRB.SetInsertPoint(Ins); IRB.SetCurrentDebugLocation(EntryLoc); // __sanitizer_cov gets the PC of the instruction using GET_CALLER_PC. IRB.CreateCall(SanCovFunction, GuardP); IRB.CreateCall(EmptyAsm, {}); // Avoids callback merge. } if (Options.Use8bitCounters) { IRB.SetInsertPoint(IP); Value *P = IRB.CreateAdd( IRB.CreatePointerCast(EightBitCounterArray, IntptrTy), ConstantInt::get(IntptrTy, NumberOfInstrumentedBlocks() - 1)); P = IRB.CreateIntToPtr(P, IRB.getInt8PtrTy()); LoadInst *LI = IRB.CreateLoad(P); Value *Inc = IRB.CreateAdd(LI, ConstantInt::get(IRB.getInt8Ty(), 1)); StoreInst *SI = IRB.CreateStore(Inc, P); SetNoSanitizeMetadata(LI); SetNoSanitizeMetadata(SI); } if (Options.TraceBB) { // Experimental support for tracing. // Insert a callback with the same guard variable as used for coverage. IRB.SetInsertPoint(IP); IRB.CreateCall(IsEntryBB ? SanCovTraceEnter : SanCovTraceBB, GuardP); } }