本文整理汇总了C++中basicblock::iterator::getDebugLoc方法的典型用法代码示例。如果您正苦于以下问题:C++ iterator::getDebugLoc方法的具体用法?C++ iterator::getDebugLoc怎么用?C++ iterator::getDebugLoc使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类basicblock::iterator
的用法示例。
在下文中一共展示了iterator::getDebugLoc方法的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: CreateFastPath
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);
}
}
示例2: emitGCNO
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();
}
}
示例3: InjectCoverageAtBlock
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);
}
}
示例4: fixupLineNumbers
/// 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));
}
}
}
}
}
示例5: StripDebugInfo
// 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;
}
示例6: processModule
/// 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)));
}
示例7: processInst
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";
}
}
}
}
示例8: ReplaceInstWithInst
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;
}
示例9: functionHasLines
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;
}
示例10: InjectCoverageAtBlock
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);
}
}
示例11: emitProfileNotes
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();
}
}
示例12: InjectCoverageAtBlock
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);
}
}
示例13: InjectCoverageAtBlock
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);
}
}