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