GCOVProfiling.cpp revision 39c41c3c93e0d223792acb093adce21a714b01c6
1//===- GCOVProfiling.cpp - Insert edge counters for gcov profiling --------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This pass implements GCOV-style profiling. When this pass is run it emits 11// "gcno" files next to the existing source, and instruments the code that runs 12// to records the edges between blocks that run and emit a complementary "gcda" 13// file on exit. 14// 15//===----------------------------------------------------------------------===// 16 17#define DEBUG_TYPE "insert-gcov-profiling" 18 19#include "llvm/Transforms/Instrumentation.h" 20#include "ProfilingUtils.h" 21#include "llvm/ADT/DenseMap.h" 22#include "llvm/ADT/STLExtras.h" 23#include "llvm/ADT/Statistic.h" 24#include "llvm/ADT/StringExtras.h" 25#include "llvm/ADT/StringMap.h" 26#include "llvm/ADT/UniqueVector.h" 27#include "llvm/DebugInfo.h" 28#include "llvm/IR/IRBuilder.h" 29#include "llvm/IR/Instructions.h" 30#include "llvm/IR/Module.h" 31#include "llvm/Pass.h" 32#include "llvm/Support/CommandLine.h" 33#include "llvm/Support/Debug.h" 34#include "llvm/Support/DebugLoc.h" 35#include "llvm/Support/FileSystem.h" 36#include "llvm/Support/InstIterator.h" 37#include "llvm/Support/PathV2.h" 38#include "llvm/Support/raw_ostream.h" 39#include "llvm/Transforms/Utils/ModuleUtils.h" 40#include <string> 41#include <utility> 42using namespace llvm; 43 44static cl::opt<std::string> 45DefaultGCOVVersion("default-gcov-version", cl::init("402*"), cl::Hidden, 46 cl::ValueRequired); 47 48GCOVOptions GCOVOptions::getDefault() { 49 GCOVOptions Options; 50 Options.EmitNotes = true; 51 Options.EmitData = true; 52 Options.UseCfgChecksum = false; 53 Options.NoRedZone = false; 54 Options.FunctionNamesInData = true; 55 56 if (DefaultGCOVVersion.size() != 4) { 57 llvm::report_fatal_error(std::string("Invalid -default-gcov-version: ") + 58 DefaultGCOVVersion); 59 } 60 memcpy(Options.Version, DefaultGCOVVersion.c_str(), 4); 61 return Options; 62} 63 64namespace { 65 class GCOVProfiler : public ModulePass { 66 public: 67 static char ID; 68 GCOVProfiler() : ModulePass(ID), Options(GCOVOptions::getDefault()) { 69 ReversedVersion[0] = Options.Version[3]; 70 ReversedVersion[1] = Options.Version[2]; 71 ReversedVersion[2] = Options.Version[1]; 72 ReversedVersion[3] = Options.Version[0]; 73 ReversedVersion[4] = '\0'; 74 initializeGCOVProfilerPass(*PassRegistry::getPassRegistry()); 75 } 76 GCOVProfiler(const GCOVOptions &Options) : ModulePass(ID), Options(Options){ 77 assert((Options.EmitNotes || Options.EmitData) && 78 "GCOVProfiler asked to do nothing?"); 79 ReversedVersion[0] = Options.Version[3]; 80 ReversedVersion[1] = Options.Version[2]; 81 ReversedVersion[2] = Options.Version[1]; 82 ReversedVersion[3] = Options.Version[0]; 83 ReversedVersion[4] = '\0'; 84 initializeGCOVProfilerPass(*PassRegistry::getPassRegistry()); 85 } 86 virtual const char *getPassName() const { 87 return "GCOV Profiler"; 88 } 89 90 private: 91 bool runOnModule(Module &M); 92 93 // Create the .gcno files for the Module based on DebugInfo. 94 void emitProfileNotes(); 95 96 // Modify the program to track transitions along edges and call into the 97 // profiling runtime to emit .gcda files when run. 98 bool emitProfileArcs(); 99 100 // Get pointers to the functions in the runtime library. 101 Constant *getStartFileFunc(); 102 Constant *getIncrementIndirectCounterFunc(); 103 Constant *getEmitFunctionFunc(); 104 Constant *getEmitArcsFunc(); 105 Constant *getDeleteWriteoutFunctionListFunc(); 106 Constant *getDeleteFlushFunctionListFunc(); 107 Constant *getEndFileFunc(); 108 109 // Create or retrieve an i32 state value that is used to represent the 110 // pred block number for certain non-trivial edges. 111 GlobalVariable *getEdgeStateValue(); 112 113 // Produce a table of pointers to counters, by predecessor and successor 114 // block number. 115 GlobalVariable *buildEdgeLookupTable(Function *F, 116 GlobalVariable *Counter, 117 const UniqueVector<BasicBlock *>&Preds, 118 const UniqueVector<BasicBlock*>&Succs); 119 120 // Add the function to write out all our counters to the global destructor 121 // list. 122 Function *insertCounterWriteout(ArrayRef<std::pair<GlobalVariable*, 123 MDNode*> >); 124 Function *insertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> >); 125 void insertIndirectCounterIncrement(); 126 127 std::string mangleName(DICompileUnit CU, const char *NewStem, 128 bool FullPath); 129 130 GCOVOptions Options; 131 132 // Reversed, NUL-terminated copy of Options.Version. 133 char ReversedVersion[5]; 134 135 Module *M; 136 LLVMContext *Ctx; 137 }; 138} 139 140char GCOVProfiler::ID = 0; 141INITIALIZE_PASS(GCOVProfiler, "insert-gcov-profiling", 142 "Insert instrumentation for GCOV profiling", false, false) 143 144ModulePass *llvm::createGCOVProfilerPass(const GCOVOptions &Options) { 145 return new GCOVProfiler(Options); 146} 147 148static std::string getFunctionName(DISubprogram SP) { 149 if (!SP.getLinkageName().empty()) 150 return SP.getLinkageName(); 151 return SP.getName(); 152} 153 154namespace { 155 class GCOVRecord { 156 protected: 157 static const char *LinesTag; 158 static const char *FunctionTag; 159 static const char *BlockTag; 160 static const char *EdgeTag; 161 162 GCOVRecord() {} 163 164 void writeBytes(const char *Bytes, int Size) { 165 os->write(Bytes, Size); 166 } 167 168 void write(uint32_t i) { 169 writeBytes(reinterpret_cast<char*>(&i), 4); 170 } 171 172 // Returns the length measured in 4-byte blocks that will be used to 173 // represent this string in a GCOV file 174 unsigned lengthOfGCOVString(StringRef s) { 175 // A GCOV string is a length, followed by a NUL, then between 0 and 3 NULs 176 // padding out to the next 4-byte word. The length is measured in 4-byte 177 // words including padding, not bytes of actual string. 178 return (s.size() / 4) + 1; 179 } 180 181 void writeGCOVString(StringRef s) { 182 uint32_t Len = lengthOfGCOVString(s); 183 write(Len); 184 writeBytes(s.data(), s.size()); 185 186 // Write 1 to 4 bytes of NUL padding. 187 assert((unsigned)(4 - (s.size() % 4)) > 0); 188 assert((unsigned)(4 - (s.size() % 4)) <= 4); 189 writeBytes("\0\0\0\0", 4 - (s.size() % 4)); 190 } 191 192 raw_ostream *os; 193 }; 194 const char *GCOVRecord::LinesTag = "\0\0\x45\x01"; 195 const char *GCOVRecord::FunctionTag = "\0\0\0\1"; 196 const char *GCOVRecord::BlockTag = "\0\0\x41\x01"; 197 const char *GCOVRecord::EdgeTag = "\0\0\x43\x01"; 198 199 class GCOVFunction; 200 class GCOVBlock; 201 202 // Constructed only by requesting it from a GCOVBlock, this object stores a 203 // list of line numbers and a single filename, representing lines that belong 204 // to the block. 205 class GCOVLines : public GCOVRecord { 206 public: 207 void addLine(uint32_t Line) { 208 Lines.push_back(Line); 209 } 210 211 uint32_t length() { 212 // Here 2 = 1 for string length + 1 for '0' id#. 213 return lengthOfGCOVString(Filename) + 2 + Lines.size(); 214 } 215 216 void writeOut() { 217 write(0); 218 writeGCOVString(Filename); 219 for (int i = 0, e = Lines.size(); i != e; ++i) 220 write(Lines[i]); 221 } 222 223 GCOVLines(StringRef F, raw_ostream *os) 224 : Filename(F) { 225 this->os = os; 226 } 227 228 private: 229 StringRef Filename; 230 SmallVector<uint32_t, 32> Lines; 231 }; 232 233 // Represent a basic block in GCOV. Each block has a unique number in the 234 // function, number of lines belonging to each block, and a set of edges to 235 // other blocks. 236 class GCOVBlock : public GCOVRecord { 237 public: 238 GCOVLines &getFile(StringRef Filename) { 239 GCOVLines *&Lines = LinesByFile[Filename]; 240 if (!Lines) { 241 Lines = new GCOVLines(Filename, os); 242 } 243 return *Lines; 244 } 245 246 void addEdge(GCOVBlock &Successor) { 247 OutEdges.push_back(&Successor); 248 } 249 250 void writeOut() { 251 uint32_t Len = 3; 252 for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(), 253 E = LinesByFile.end(); I != E; ++I) { 254 Len += I->second->length(); 255 } 256 257 writeBytes(LinesTag, 4); 258 write(Len); 259 write(Number); 260 for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(), 261 E = LinesByFile.end(); I != E; ++I) 262 I->second->writeOut(); 263 write(0); 264 write(0); 265 } 266 267 ~GCOVBlock() { 268 DeleteContainerSeconds(LinesByFile); 269 } 270 271 private: 272 friend class GCOVFunction; 273 274 GCOVBlock(uint32_t Number, raw_ostream *os) 275 : Number(Number) { 276 this->os = os; 277 } 278 279 uint32_t Number; 280 StringMap<GCOVLines *> LinesByFile; 281 SmallVector<GCOVBlock *, 4> OutEdges; 282 }; 283 284 // A function has a unique identifier, a checksum (we leave as zero) and a 285 // set of blocks and a map of edges between blocks. This is the only GCOV 286 // object users can construct, the blocks and lines will be rooted here. 287 class GCOVFunction : public GCOVRecord { 288 public: 289 GCOVFunction(DISubprogram SP, raw_ostream *os, uint32_t Ident, 290 bool UseCfgChecksum) { 291 this->os = os; 292 293 Function *F = SP.getFunction(); 294 DEBUG(dbgs() << "Function: " << F->getName() << "\n"); 295 uint32_t i = 0; 296 for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 297 Blocks[BB] = new GCOVBlock(i++, os); 298 } 299 ReturnBlock = new GCOVBlock(i++, os); 300 301 writeBytes(FunctionTag, 4); 302 uint32_t BlockLen = 1 + 1 + 1 + lengthOfGCOVString(getFunctionName(SP)) + 303 1 + lengthOfGCOVString(SP.getFilename()) + 1; 304 if (UseCfgChecksum) 305 ++BlockLen; 306 write(BlockLen); 307 write(Ident); 308 write(0); // lineno checksum 309 if (UseCfgChecksum) 310 write(0); // cfg checksum 311 writeGCOVString(getFunctionName(SP)); 312 writeGCOVString(SP.getFilename()); 313 write(SP.getLineNumber()); 314 } 315 316 ~GCOVFunction() { 317 DeleteContainerSeconds(Blocks); 318 delete ReturnBlock; 319 } 320 321 GCOVBlock &getBlock(BasicBlock *BB) { 322 return *Blocks[BB]; 323 } 324 325 GCOVBlock &getReturnBlock() { 326 return *ReturnBlock; 327 } 328 329 void writeOut() { 330 // Emit count of blocks. 331 writeBytes(BlockTag, 4); 332 write(Blocks.size() + 1); 333 for (int i = 0, e = Blocks.size() + 1; i != e; ++i) { 334 write(0); // No flags on our blocks. 335 } 336 DEBUG(dbgs() << Blocks.size() << " blocks.\n"); 337 338 // Emit edges between blocks. 339 for (DenseMap<BasicBlock *, GCOVBlock *>::iterator I = Blocks.begin(), 340 E = Blocks.end(); I != E; ++I) { 341 GCOVBlock &Block = *I->second; 342 if (Block.OutEdges.empty()) continue; 343 344 writeBytes(EdgeTag, 4); 345 write(Block.OutEdges.size() * 2 + 1); 346 write(Block.Number); 347 for (int i = 0, e = Block.OutEdges.size(); i != e; ++i) { 348 DEBUG(dbgs() << Block.Number << " -> " << Block.OutEdges[i]->Number 349 << "\n"); 350 write(Block.OutEdges[i]->Number); 351 write(0); // no flags 352 } 353 } 354 355 // Emit lines for each block. 356 for (DenseMap<BasicBlock *, GCOVBlock *>::iterator I = Blocks.begin(), 357 E = Blocks.end(); I != E; ++I) { 358 I->second->writeOut(); 359 } 360 } 361 362 private: 363 DenseMap<BasicBlock *, GCOVBlock *> Blocks; 364 GCOVBlock *ReturnBlock; 365 }; 366} 367 368std::string GCOVProfiler::mangleName(DICompileUnit CU, const char *NewStem, 369 bool FullPath) { 370 if (NamedMDNode *GCov = M->getNamedMetadata("llvm.gcov")) { 371 for (int i = 0, e = GCov->getNumOperands(); i != e; ++i) { 372 MDNode *N = GCov->getOperand(i); 373 if (N->getNumOperands() != 2) continue; 374 MDString *GCovFile = dyn_cast<MDString>(N->getOperand(0)); 375 MDNode *CompileUnit = dyn_cast<MDNode>(N->getOperand(1)); 376 if (!GCovFile || !CompileUnit) continue; 377 if (CompileUnit == CU) { 378 SmallString<128> Filename = GCovFile->getString(); 379 sys::path::replace_extension(Filename, NewStem); 380 return Filename.str(); 381 } 382 } 383 } 384 385 SmallString<128> Filename = CU.getFilename(); 386 sys::path::replace_extension(Filename, NewStem); 387 StringRef FName = sys::path::filename(Filename); 388 if (!FullPath) 389 return FName; 390 SmallString<128> CurPath; 391 if (sys::fs::current_path(CurPath)) return FName; 392 sys::path::append(CurPath, FName.str()); 393 return CurPath.str(); 394} 395 396bool GCOVProfiler::runOnModule(Module &M) { 397 this->M = &M; 398 Ctx = &M.getContext(); 399 400 if (Options.EmitNotes) emitProfileNotes(); 401 if (Options.EmitData) return emitProfileArcs(); 402 return false; 403} 404 405void GCOVProfiler::emitProfileNotes() { 406 NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); 407 if (!CU_Nodes) return; 408 409 for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { 410 // Each compile unit gets its own .gcno file. This means that whether we run 411 // this pass over the original .o's as they're produced, or run it after 412 // LTO, we'll generate the same .gcno files. 413 414 DICompileUnit CU(CU_Nodes->getOperand(i)); 415 std::string ErrorInfo; 416 raw_fd_ostream out(mangleName(CU, "gcno", false).c_str(), ErrorInfo, 417 raw_fd_ostream::F_Binary); 418 out.write("oncg", 4); 419 out.write(ReversedVersion, 4); 420 out.write("MVLL", 4); 421 422 DIArray SPs = CU.getSubprograms(); 423 for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) { 424 DISubprogram SP(SPs.getElement(i)); 425 if (!SP.Verify()) continue; 426 427 Function *F = SP.getFunction(); 428 if (!F) continue; 429 GCOVFunction Func(SP, &out, i, Options.UseCfgChecksum); 430 431 for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 432 GCOVBlock &Block = Func.getBlock(BB); 433 TerminatorInst *TI = BB->getTerminator(); 434 if (int successors = TI->getNumSuccessors()) { 435 for (int i = 0; i != successors; ++i) { 436 Block.addEdge(Func.getBlock(TI->getSuccessor(i))); 437 } 438 } else if (isa<ReturnInst>(TI)) { 439 Block.addEdge(Func.getReturnBlock()); 440 } 441 442 uint32_t Line = 0; 443 for (BasicBlock::iterator I = BB->begin(), IE = BB->end(); 444 I != IE; ++I) { 445 const DebugLoc &Loc = I->getDebugLoc(); 446 if (Loc.isUnknown()) continue; 447 if (Line == Loc.getLine()) continue; 448 Line = Loc.getLine(); 449 if (SP != getDISubprogram(Loc.getScope(*Ctx))) continue; 450 451 GCOVLines &Lines = Block.getFile(SP.getFilename()); 452 Lines.addLine(Loc.getLine()); 453 } 454 } 455 Func.writeOut(); 456 } 457 out.write("\0\0\0\0\0\0\0\0", 8); // EOF 458 out.close(); 459 } 460} 461 462bool GCOVProfiler::emitProfileArcs() { 463 NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); 464 if (!CU_Nodes) return false; 465 466 bool Result = false; 467 bool InsertIndCounterIncrCode = false; 468 for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { 469 DICompileUnit CU(CU_Nodes->getOperand(i)); 470 DIArray SPs = CU.getSubprograms(); 471 SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> CountersBySP; 472 for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) { 473 DISubprogram SP(SPs.getElement(i)); 474 if (!SP.Verify()) continue; 475 Function *F = SP.getFunction(); 476 if (!F) continue; 477 if (!Result) Result = true; 478 unsigned Edges = 0; 479 for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 480 TerminatorInst *TI = BB->getTerminator(); 481 if (isa<ReturnInst>(TI)) 482 ++Edges; 483 else 484 Edges += TI->getNumSuccessors(); 485 } 486 487 ArrayType *CounterTy = 488 ArrayType::get(Type::getInt64Ty(*Ctx), Edges); 489 GlobalVariable *Counters = 490 new GlobalVariable(*M, CounterTy, false, 491 GlobalValue::InternalLinkage, 492 Constant::getNullValue(CounterTy), 493 "__llvm_gcov_ctr"); 494 CountersBySP.push_back(std::make_pair(Counters, (MDNode*)SP)); 495 496 UniqueVector<BasicBlock *> ComplexEdgePreds; 497 UniqueVector<BasicBlock *> ComplexEdgeSuccs; 498 499 unsigned Edge = 0; 500 for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 501 TerminatorInst *TI = BB->getTerminator(); 502 int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors(); 503 if (Successors) { 504 IRBuilder<> Builder(TI); 505 506 if (Successors == 1) { 507 Value *Counter = Builder.CreateConstInBoundsGEP2_64(Counters, 0, 508 Edge); 509 Value *Count = Builder.CreateLoad(Counter); 510 Count = Builder.CreateAdd(Count, Builder.getInt64(1)); 511 Builder.CreateStore(Count, Counter); 512 } else if (BranchInst *BI = dyn_cast<BranchInst>(TI)) { 513 Value *Sel = Builder.CreateSelect(BI->getCondition(), 514 Builder.getInt64(Edge), 515 Builder.getInt64(Edge + 1)); 516 SmallVector<Value *, 2> Idx; 517 Idx.push_back(Builder.getInt64(0)); 518 Idx.push_back(Sel); 519 Value *Counter = Builder.CreateInBoundsGEP(Counters, Idx); 520 Value *Count = Builder.CreateLoad(Counter); 521 Count = Builder.CreateAdd(Count, Builder.getInt64(1)); 522 Builder.CreateStore(Count, Counter); 523 } else { 524 ComplexEdgePreds.insert(BB); 525 for (int i = 0; i != Successors; ++i) 526 ComplexEdgeSuccs.insert(TI->getSuccessor(i)); 527 } 528 Edge += Successors; 529 } 530 } 531 532 if (!ComplexEdgePreds.empty()) { 533 GlobalVariable *EdgeTable = 534 buildEdgeLookupTable(F, Counters, 535 ComplexEdgePreds, ComplexEdgeSuccs); 536 GlobalVariable *EdgeState = getEdgeStateValue(); 537 538 for (int i = 0, e = ComplexEdgePreds.size(); i != e; ++i) { 539 IRBuilder<> Builder(ComplexEdgePreds[i+1]->getTerminator()); 540 Builder.CreateStore(Builder.getInt32(i), EdgeState); 541 } 542 for (int i = 0, e = ComplexEdgeSuccs.size(); i != e; ++i) { 543 // call runtime to perform increment 544 BasicBlock::iterator InsertPt = 545 ComplexEdgeSuccs[i+1]->getFirstInsertionPt(); 546 IRBuilder<> Builder(InsertPt); 547 Value *CounterPtrArray = 548 Builder.CreateConstInBoundsGEP2_64(EdgeTable, 0, 549 i * ComplexEdgePreds.size()); 550 551 // Build code to increment the counter. 552 InsertIndCounterIncrCode = true; 553 Builder.CreateCall2(getIncrementIndirectCounterFunc(), 554 EdgeState, CounterPtrArray); 555 } 556 } 557 } 558 559 Function *WriteoutF = insertCounterWriteout(CountersBySP); 560 Function *FlushF = insertFlush(CountersBySP); 561 562 // Create a small bit of code that registers the "__llvm_gcov_writeout" to 563 // be executed at exit and the "__llvm_gcov_flush" function to be executed 564 // when "__gcov_flush" is called. 565 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 566 Function *F = Function::Create(FTy, GlobalValue::InternalLinkage, 567 "__llvm_gcov_init", M); 568 F->setUnnamedAddr(true); 569 F->setLinkage(GlobalValue::InternalLinkage); 570 F->addFnAttr(Attribute::NoInline); 571 if (Options.NoRedZone) 572 F->addFnAttr(Attribute::NoRedZone); 573 574 BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", F); 575 IRBuilder<> Builder(BB); 576 577 FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 578 Type *Params[] = { 579 PointerType::get(FTy, 0), 580 PointerType::get(FTy, 0) 581 }; 582 FTy = FunctionType::get(Builder.getVoidTy(), Params, false); 583 584 // Inialize the environment and register the local writeout and flush 585 // functions. 586 Constant *GCOVInit = M->getOrInsertFunction("llvm_gcov_init", FTy); 587 Builder.CreateCall2(GCOVInit, WriteoutF, FlushF); 588 Builder.CreateRetVoid(); 589 590 appendToGlobalCtors(*M, F, 0); 591 } 592 593 if (InsertIndCounterIncrCode) 594 insertIndirectCounterIncrement(); 595 596 return Result; 597} 598 599// All edges with successors that aren't branches are "complex", because it 600// requires complex logic to pick which counter to update. 601GlobalVariable *GCOVProfiler::buildEdgeLookupTable( 602 Function *F, 603 GlobalVariable *Counters, 604 const UniqueVector<BasicBlock *> &Preds, 605 const UniqueVector<BasicBlock *> &Succs) { 606 // TODO: support invoke, threads. We rely on the fact that nothing can modify 607 // the whole-Module pred edge# between the time we set it and the time we next 608 // read it. Threads and invoke make this untrue. 609 610 // emit [(succs * preds) x i64*], logically [succ x [pred x i64*]]. 611 size_t TableSize = Succs.size() * Preds.size(); 612 Type *Int64PtrTy = Type::getInt64PtrTy(*Ctx); 613 ArrayType *EdgeTableTy = ArrayType::get(Int64PtrTy, TableSize); 614 615 OwningArrayPtr<Constant *> EdgeTable(new Constant*[TableSize]); 616 Constant *NullValue = Constant::getNullValue(Int64PtrTy); 617 for (size_t i = 0; i != TableSize; ++i) 618 EdgeTable[i] = NullValue; 619 620 unsigned Edge = 0; 621 for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 622 TerminatorInst *TI = BB->getTerminator(); 623 int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors(); 624 if (Successors > 1 && !isa<BranchInst>(TI) && !isa<ReturnInst>(TI)) { 625 for (int i = 0; i != Successors; ++i) { 626 BasicBlock *Succ = TI->getSuccessor(i); 627 IRBuilder<> Builder(Succ); 628 Value *Counter = Builder.CreateConstInBoundsGEP2_64(Counters, 0, 629 Edge + i); 630 EdgeTable[((Succs.idFor(Succ)-1) * Preds.size()) + 631 (Preds.idFor(BB)-1)] = cast<Constant>(Counter); 632 } 633 } 634 Edge += Successors; 635 } 636 637 ArrayRef<Constant*> V(&EdgeTable[0], TableSize); 638 GlobalVariable *EdgeTableGV = 639 new GlobalVariable( 640 *M, EdgeTableTy, true, GlobalValue::InternalLinkage, 641 ConstantArray::get(EdgeTableTy, V), 642 "__llvm_gcda_edge_table"); 643 EdgeTableGV->setUnnamedAddr(true); 644 return EdgeTableGV; 645} 646 647Constant *GCOVProfiler::getStartFileFunc() { 648 Type *Args[] = { 649 Type::getInt8PtrTy(*Ctx), // const char *orig_filename 650 Type::getInt8PtrTy(*Ctx), // const char version[4] 651 }; 652 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false); 653 return M->getOrInsertFunction("llvm_gcda_start_file", FTy); 654} 655 656Constant *GCOVProfiler::getIncrementIndirectCounterFunc() { 657 Type *Int32Ty = Type::getInt32Ty(*Ctx); 658 Type *Int64Ty = Type::getInt64Ty(*Ctx); 659 Type *Args[] = { 660 Int32Ty->getPointerTo(), // uint32_t *predecessor 661 Int64Ty->getPointerTo()->getPointerTo() // uint64_t **counters 662 }; 663 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false); 664 return M->getOrInsertFunction("__llvm_gcov_indirect_counter_increment", FTy); 665} 666 667Constant *GCOVProfiler::getEmitFunctionFunc() { 668 Type *Args[3] = { 669 Type::getInt32Ty(*Ctx), // uint32_t ident 670 Type::getInt8PtrTy(*Ctx), // const char *function_name 671 Type::getInt8Ty(*Ctx), // uint8_t use_extra_checksum 672 }; 673 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false); 674 return M->getOrInsertFunction("llvm_gcda_emit_function", FTy); 675} 676 677Constant *GCOVProfiler::getEmitArcsFunc() { 678 Type *Args[] = { 679 Type::getInt32Ty(*Ctx), // uint32_t num_counters 680 Type::getInt64PtrTy(*Ctx), // uint64_t *counters 681 }; 682 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false); 683 return M->getOrInsertFunction("llvm_gcda_emit_arcs", FTy); 684} 685 686Constant *GCOVProfiler::getDeleteWriteoutFunctionListFunc() { 687 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 688 return M->getOrInsertFunction("llvm_delete_writeout_function_list", FTy); 689} 690 691Constant *GCOVProfiler::getDeleteFlushFunctionListFunc() { 692 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 693 return M->getOrInsertFunction("llvm_delete_flush_function_list", FTy); 694} 695 696Constant *GCOVProfiler::getEndFileFunc() { 697 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 698 return M->getOrInsertFunction("llvm_gcda_end_file", FTy); 699} 700 701GlobalVariable *GCOVProfiler::getEdgeStateValue() { 702 GlobalVariable *GV = M->getGlobalVariable("__llvm_gcov_global_state_pred"); 703 if (!GV) { 704 GV = new GlobalVariable(*M, Type::getInt32Ty(*Ctx), false, 705 GlobalValue::InternalLinkage, 706 ConstantInt::get(Type::getInt32Ty(*Ctx), 707 0xffffffff), 708 "__llvm_gcov_global_state_pred"); 709 GV->setUnnamedAddr(true); 710 } 711 return GV; 712} 713 714Function *GCOVProfiler::insertCounterWriteout( 715 ArrayRef<std::pair<GlobalVariable *, MDNode *> > CountersBySP) { 716 FunctionType *WriteoutFTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 717 Function *WriteoutF = M->getFunction("__llvm_gcov_writeout"); 718 if (!WriteoutF) 719 WriteoutF = Function::Create(WriteoutFTy, GlobalValue::InternalLinkage, 720 "__llvm_gcov_writeout", M); 721 WriteoutF->setUnnamedAddr(true); 722 WriteoutF->addFnAttr(Attribute::NoInline); 723 if (Options.NoRedZone) 724 WriteoutF->addFnAttr(Attribute::NoRedZone); 725 726 BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", WriteoutF); 727 IRBuilder<> Builder(BB); 728 729 Constant *StartFile = getStartFileFunc(); 730 Constant *EmitFunction = getEmitFunctionFunc(); 731 Constant *EmitArcs = getEmitArcsFunc(); 732 Constant *EndFile = getEndFileFunc(); 733 734 NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); 735 if (CU_Nodes) { 736 for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { 737 DICompileUnit CU(CU_Nodes->getOperand(i)); 738 std::string FilenameGcda = mangleName(CU, "gcda", true); 739 Builder.CreateCall2(StartFile, 740 Builder.CreateGlobalStringPtr(FilenameGcda), 741 Builder.CreateGlobalStringPtr(ReversedVersion)); 742 for (unsigned j = 0, e = CountersBySP.size(); j != e; ++j) { 743 DISubprogram SP(CountersBySP[j].second); 744 Builder.CreateCall3( 745 EmitFunction, Builder.getInt32(j), 746 Options.FunctionNamesInData ? 747 Builder.CreateGlobalStringPtr(getFunctionName(SP)) : 748 Constant::getNullValue(Builder.getInt8PtrTy()), 749 Builder.getInt8(Options.UseCfgChecksum)); 750 751 GlobalVariable *GV = CountersBySP[j].first; 752 unsigned Arcs = 753 cast<ArrayType>(GV->getType()->getElementType())->getNumElements(); 754 Builder.CreateCall2(EmitArcs, 755 Builder.getInt32(Arcs), 756 Builder.CreateConstGEP2_64(GV, 0, 0)); 757 } 758 Builder.CreateCall(EndFile); 759 } 760 } 761 762 Builder.CreateRetVoid(); 763 return WriteoutF; 764} 765 766void GCOVProfiler::insertIndirectCounterIncrement() { 767 Function *Fn = 768 cast<Function>(GCOVProfiler::getIncrementIndirectCounterFunc()); 769 Fn->setUnnamedAddr(true); 770 Fn->setLinkage(GlobalValue::InternalLinkage); 771 Fn->addFnAttr(Attribute::NoInline); 772 if (Options.NoRedZone) 773 Fn->addFnAttr(Attribute::NoRedZone); 774 775 // Create basic blocks for function. 776 BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", Fn); 777 IRBuilder<> Builder(BB); 778 779 BasicBlock *PredNotNegOne = BasicBlock::Create(*Ctx, "", Fn); 780 BasicBlock *CounterEnd = BasicBlock::Create(*Ctx, "", Fn); 781 BasicBlock *Exit = BasicBlock::Create(*Ctx, "exit", Fn); 782 783 // uint32_t pred = *predecessor; 784 // if (pred == 0xffffffff) return; 785 Argument *Arg = Fn->arg_begin(); 786 Arg->setName("predecessor"); 787 Value *Pred = Builder.CreateLoad(Arg, "pred"); 788 Value *Cond = Builder.CreateICmpEQ(Pred, Builder.getInt32(0xffffffff)); 789 BranchInst::Create(Exit, PredNotNegOne, Cond, BB); 790 791 Builder.SetInsertPoint(PredNotNegOne); 792 793 // uint64_t *counter = counters[pred]; 794 // if (!counter) return; 795 Value *ZExtPred = Builder.CreateZExt(Pred, Builder.getInt64Ty()); 796 Arg = llvm::next(Fn->arg_begin()); 797 Arg->setName("counters"); 798 Value *GEP = Builder.CreateGEP(Arg, ZExtPred); 799 Value *Counter = Builder.CreateLoad(GEP, "counter"); 800 Cond = Builder.CreateICmpEQ(Counter, 801 Constant::getNullValue( 802 Builder.getInt64Ty()->getPointerTo())); 803 Builder.CreateCondBr(Cond, Exit, CounterEnd); 804 805 // ++*counter; 806 Builder.SetInsertPoint(CounterEnd); 807 Value *Add = Builder.CreateAdd(Builder.CreateLoad(Counter), 808 Builder.getInt64(1)); 809 Builder.CreateStore(Add, Counter); 810 Builder.CreateBr(Exit); 811 812 // Fill in the exit block. 813 Builder.SetInsertPoint(Exit); 814 Builder.CreateRetVoid(); 815} 816 817Function *GCOVProfiler:: 818insertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> > CountersBySP) { 819 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 820 Function *FlushF = M->getFunction("__llvm_gcov_flush"); 821 if (!FlushF) 822 FlushF = Function::Create(FTy, GlobalValue::InternalLinkage, 823 "__llvm_gcov_flush", M); 824 else 825 FlushF->setLinkage(GlobalValue::InternalLinkage); 826 FlushF->setUnnamedAddr(true); 827 FlushF->addFnAttr(Attribute::NoInline); 828 if (Options.NoRedZone) 829 FlushF->addFnAttr(Attribute::NoRedZone); 830 831 BasicBlock *Entry = BasicBlock::Create(*Ctx, "entry", FlushF); 832 833 // Write out the current counters. 834 Constant *WriteoutF = M->getFunction("__llvm_gcov_writeout"); 835 assert(WriteoutF && "Need to create the writeout function first!"); 836 837 IRBuilder<> Builder(Entry); 838 Builder.CreateCall(WriteoutF); 839 840 // Zero out the counters. 841 for (ArrayRef<std::pair<GlobalVariable *, MDNode *> >::iterator 842 I = CountersBySP.begin(), E = CountersBySP.end(); 843 I != E; ++I) { 844 GlobalVariable *GV = I->first; 845 Constant *Null = Constant::getNullValue(GV->getType()->getElementType()); 846 Builder.CreateStore(Null, GV); 847 } 848 849 Type *RetTy = FlushF->getReturnType(); 850 if (RetTy == Type::getVoidTy(*Ctx)) 851 Builder.CreateRetVoid(); 852 else if (RetTy->isIntegerTy()) 853 // Used if __llvm_gcov_flush was implicitly declared. 854 Builder.CreateRet(ConstantInt::get(RetTy, 0)); 855 else 856 report_fatal_error("invalid return type for __llvm_gcov_flush"); 857 858 return FlushF; 859} 860