• Home
  • Raw
  • Download

Lines Matching +full:gcov +full:- +full:4

1 //===- GCOVProfiling.cpp - Insert edge counters for gcov profiling --------===//
8 //===----------------------------------------------------------------------===//
10 // This pass implements GCOV-style profiling. When this pass is run it emits
15 //===----------------------------------------------------------------------===//
46 #define DEBUG_TYPE "insert-gcov-profiling"
49 DefaultGCOVVersion("default-gcov-version", cl::init("402*"), cl::Hidden,
51 static cl::opt<bool> DefaultExitBlockBeforeBody("gcov-exit-block-before-body",
63 if (DefaultGCOVVersion.size() != 4) { in getDefault()
64 llvm::report_fatal_error(std::string("Invalid -default-gcov-version: ") + in getDefault()
67 memcpy(Options.Version, DefaultGCOVVersion.c_str(), 4); in getDefault()
84 ReversedVersion[4] = '\0'; in GCOVProfiler()
105 // pred block number for certain non-trivial edges.
125 // Reversed, NUL-terminated copy of Options.Version.
128 SmallVector<uint32_t, 4> FileChecksums;
144 const char *getPassName() const override { return "GCOV Profiler"; } in getPassName()
154 INITIALIZE_PASS(GCOVProfilerLegacyPass, "insert-gcov-profiling",
155 "Insert instrumentation for GCOV profiling", false, false)
162 if (!SP->getLinkageName().empty()) in getFunctionName()
163 return SP->getLinkageName(); in getFunctionName()
164 return SP->getName(); in getFunctionName()
178 os->write(Bytes, Size); in writeBytes()
182 writeBytes(reinterpret_cast<char*>(&i), 4); in write()
185 // Returns the length measured in 4-byte blocks that will be used to
186 // represent this string in a GCOV file
188 // A GCOV string is a length, followed by a NUL, then between 0 and 3 NULs in lengthOfGCOVString()
189 // padding out to the next 4-byte word. The length is measured in 4-byte in lengthOfGCOVString()
191 return (s.size() / 4) + 1; in lengthOfGCOVString()
199 // Write 1 to 4 bytes of NUL padding. in writeGCOVString()
200 assert((unsigned)(4 - (s.size() % 4)) > 0); in writeGCOVString()
201 assert((unsigned)(4 - (s.size() % 4)) <= 4); in writeGCOVString()
202 writeBytes("\0\0\0\0", 4 - (s.size() % 4)); in writeGCOVString()
239 this->os = os; in GCOVLines()
248 // Represent a basic block in GCOV. Each block has a unique number in the
269 Len += I.second->length(); in writeOut()
273 writeBytes(LinesTag, 4); in writeOut()
280 return LHS->getKey() < RHS->getKey(); in writeOut()
283 I->getValue()->writeOut(); in writeOut()
294 // there are inter-block pointers (eg: edges) that won't take kindly to in GCOVBlock()
305 this->os = os; in GCOVBlock()
310 SmallVector<GCOVBlock *, 4> OutEdges;
314 // set of blocks and a map of edges between blocks. This is the only GCOV
322 this->os = os; in GCOVFunction()
338 FNLOS << getFunctionName(SP) << SP->getLine(); in GCOVFunction()
344 return Blocks.find(BB)->second; in getBlock()
354 Function *F = Blocks.begin()->first->getParent(); in getEdgeDestinations()
358 EDOS << Block.OutEdges[i]->Number; in getEdgeDestinations()
372 writeBytes(FunctionTag, 4); in writeOut()
374 1 + lengthOfGCOVString(SP->getFilename()) + 1; in writeOut()
383 writeGCOVString(SP->getFilename()); in writeOut()
384 write(SP->getLine()); in writeOut()
387 writeBytes(BlockTag, 4); in writeOut()
396 Function *F = Blocks.begin()->first->getParent(); in writeOut()
401 writeBytes(EdgeTag, 4); in writeOut()
405 DEBUG(dbgs() << Block.Number << " -> " << Block.OutEdges[i]->Number in writeOut()
407 write(Block.OutEdges[i]->Number); in writeOut()
430 if (NamedMDNode *GCov = M->getNamedMetadata("llvm.gcov")) { in mangleName() local
431 for (int i = 0, e = GCov->getNumOperands(); i != e; ++i) { in mangleName()
432 MDNode *N = GCov->getOperand(i); in mangleName()
433 if (N->getNumOperands() != 2) continue; in mangleName()
434 MDString *GCovFile = dyn_cast<MDString>(N->getOperand(0)); in mangleName()
435 MDNode *CompileUnit = dyn_cast<MDNode>(N->getOperand(1)); in mangleName()
438 SmallString<128> Filename = GCovFile->getString(); in mangleName()
445 SmallString<128> Filename = CU->getFilename(); in mangleName()
455 this->M = &M; in runOnModule()
476 // do these waste space, they also can crash gcov. in functionHasLines()
497 NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); in emitProfileNotes()
500 for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { in emitProfileNotes()
505 auto *CU = cast<DICompileUnit>(CU_Nodes->getOperand(i)); in emitProfileNotes()
508 if (CU->getDWOId()) in emitProfileNotes()
516 for (auto &F : M->functions()) { in emitProfileNotes()
521 // gcov expects every function to start with an entry block that has a in emitProfileNotes()
537 if (int successors = TI->getNumSuccessors()) { in emitProfileNotes()
539 Block.addEdge(Func.getBlock(TI->getSuccessor(i))); in emitProfileNotes()
563 GCOVLines &Lines = Block.getFile(SP->getFilename()); in emitProfileNotes()
571 out.write("oncg", 4); in emitProfileNotes()
572 out.write(ReversedVersion, 4); in emitProfileNotes()
573 out.write(reinterpret_cast<char*>(&FileChecksums.back()), 4); in emitProfileNotes()
576 Func->setCfgChecksum(FileChecksums.back()); in emitProfileNotes()
577 Func->writeOut(); in emitProfileNotes()
586 NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); in emitProfileArcs()
591 for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { in emitProfileArcs()
593 for (auto &F : M->functions()) { in emitProfileArcs()
604 Edges += TI->getNumSuccessors(); in emitProfileArcs()
622 int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors(); in emitProfileArcs()
633 Value *Sel = Builder.CreateSelect(BI->getCondition(), in emitProfileArcs()
637 Counters->getValueType(), Counters, {Builder.getInt64(0), Sel}); in emitProfileArcs()
644 ComplexEdgeSuccs.insert(TI->getSuccessor(i)); in emitProfileArcs()
658 IRBuilder<> Builder(&*ComplexEdgePreds[i + 1]->getFirstInsertionPt()); in emitProfileArcs()
664 IRBuilder<> Builder(&*ComplexEdgeSuccs[i + 1]->getFirstInsertionPt()); in emitProfileArcs()
686 F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); in emitProfileArcs()
687 F->setLinkage(GlobalValue::InternalLinkage); in emitProfileArcs()
688 F->addFnAttr(Attribute::NoInline); in emitProfileArcs()
690 F->addFnAttr(Attribute::NoRedZone); in emitProfileArcs()
704 Constant *GCOVInit = M->getOrInsertFunction("llvm_gcov_init", FTy); in emitProfileArcs()
725 // the whole-Module pred edge# between the time we set it and the time we next in buildEdgeLookupTable()
741 int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors(); in buildEdgeLookupTable()
744 BasicBlock *Succ = TI->getSuccessor(i); in buildEdgeLookupTable()
748 EdgeTable[((Succs.idFor(Succ) - 1) * Preds.size()) + in buildEdgeLookupTable()
749 (Preds.idFor(&BB) - 1)] = cast<Constant>(Counter); in buildEdgeLookupTable()
761 EdgeTableGV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); in buildEdgeLookupTable()
768 Type::getInt8PtrTy(*Ctx), // const char version[4] in getStartFileFunc()
772 return M->getOrInsertFunction("llvm_gcda_start_file", FTy); in getStartFileFunc()
779 Int32Ty->getPointerTo(), // uint32_t *predecessor in getIncrementIndirectCounterFunc()
780 Int64Ty->getPointerTo()->getPointerTo() // uint64_t **counters in getIncrementIndirectCounterFunc()
783 return M->getOrInsertFunction("__llvm_gcov_indirect_counter_increment", FTy); in getIncrementIndirectCounterFunc()
795 return M->getOrInsertFunction("llvm_gcda_emit_function", FTy); in getEmitFunctionFunc()
804 return M->getOrInsertFunction("llvm_gcda_emit_arcs", FTy); in getEmitArcsFunc()
809 return M->getOrInsertFunction("llvm_gcda_summary_info", FTy); in getSummaryInfoFunc()
814 return M->getOrInsertFunction("llvm_gcda_end_file", FTy); in getEndFileFunc()
818 GlobalVariable *GV = M->getGlobalVariable("__llvm_gcov_global_state_pred"); in getEdgeStateValue()
825 GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); in getEdgeStateValue()
833 Function *WriteoutF = M->getFunction("__llvm_gcov_writeout"); in insertCounterWriteout()
837 WriteoutF->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); in insertCounterWriteout()
838 WriteoutF->addFnAttr(Attribute::NoInline); in insertCounterWriteout()
840 WriteoutF->addFnAttr(Attribute::NoRedZone); in insertCounterWriteout()
851 NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); in insertCounterWriteout()
853 for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { in insertCounterWriteout()
854 auto *CU = cast<DICompileUnit>(CU_Nodes->getOperand(i)); in insertCounterWriteout()
857 if (CU->getDWOId()) in insertCounterWriteout()
868 uint32_t FuncChecksum = Funcs.empty() ? 0 : Funcs[j]->getFuncChecksum(); in insertCounterWriteout()
881 cast<ArrayType>(GV->getValueType())->getNumElements(); in insertCounterWriteout()
897 Fn->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); in insertIndirectCounterIncrement()
898 Fn->setLinkage(GlobalValue::InternalLinkage); in insertIndirectCounterIncrement()
899 Fn->addFnAttr(Attribute::NoInline); in insertIndirectCounterIncrement()
901 Fn->addFnAttr(Attribute::NoRedZone); in insertIndirectCounterIncrement()
913 Argument *Arg = &*Fn->arg_begin(); in insertIndirectCounterIncrement()
914 Arg->setName("predecessor"); in insertIndirectCounterIncrement()
924 Arg = &*std::next(Fn->arg_begin()); in insertIndirectCounterIncrement()
925 Arg->setName("counters"); in insertIndirectCounterIncrement()
930 Builder.getInt64Ty()->getPointerTo())); in insertIndirectCounterIncrement()
948 Function *FlushF = M->getFunction("__llvm_gcov_flush"); in insertFlush()
953 FlushF->setLinkage(GlobalValue::InternalLinkage); in insertFlush()
954 FlushF->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); in insertFlush()
955 FlushF->addFnAttr(Attribute::NoInline); in insertFlush()
957 FlushF->addFnAttr(Attribute::NoRedZone); in insertFlush()
962 Constant *WriteoutF = M->getFunction("__llvm_gcov_writeout"); in insertFlush()
971 Constant *Null = Constant::getNullValue(GV->getValueType()); in insertFlush()
975 Type *RetTy = FlushF->getReturnType(); in insertFlush()
978 else if (RetTy->isIntegerTy()) in insertFlush()