diff options
author | Nick Lewycky <nicholas@mxc.ca> | 2011-04-21 03:18:00 +0000 |
---|---|---|
committer | Nick Lewycky <nicholas@mxc.ca> | 2011-04-21 03:18:00 +0000 |
commit | a4c4c0e1298f4dd9791eff2bae857e7be6d0ab56 (patch) | |
tree | 6bb30d126348fe0f4cfca62d01cd74c1619e2d38 /lib/Transforms/Instrumentation | |
parent | 17df2c3240837b4382898ead8c3ead407a338520 (diff) | |
download | llvm-a4c4c0e1298f4dd9791eff2bae857e7be6d0ab56.tar.gz llvm-a4c4c0e1298f4dd9791eff2bae857e7be6d0ab56.tar.bz2 llvm-a4c4c0e1298f4dd9791eff2bae857e7be6d0ab56.tar.xz |
In gcov profiling, give all functions an extra unified return block. This is
necessary since gcov counts transitions between blocks. It can't see if you've
run every line in a straight-line function, so we add an edge for it to notice.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@129905 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Instrumentation')
-rw-r--r-- | lib/Transforms/Instrumentation/GCOVProfiling.cpp | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/lib/Transforms/Instrumentation/GCOVProfiling.cpp b/lib/Transforms/Instrumentation/GCOVProfiling.cpp index 59538f42ed..236d27cfaf 100644 --- a/lib/Transforms/Instrumentation/GCOVProfiling.cpp +++ b/lib/Transforms/Instrumentation/GCOVProfiling.cpp @@ -244,6 +244,7 @@ namespace { for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { blocks[BB] = new GCOVBlock(i++, os); } + return_block = new GCOVBlock(i++, os); WriteBytes(function_tag, 4); uint32_t block_len = 1 + 1 + 1 + LengthOfGCOVString(SP.getName()) + @@ -259,17 +260,22 @@ namespace { ~GCOVFunction() { DeleteContainerSeconds(blocks); + delete return_block; } GCOVBlock &GetBlock(BasicBlock *BB) { return *blocks[BB]; } + GCOVBlock &GetReturnBlock() { + return *return_block; + } + void WriteOut() { // Emit count of blocks. WriteBytes(block_tag, 4); - Write(blocks.size()); - for (int i = 0, e = blocks.size(); i != e; ++i) { + Write(blocks.size() + 1); + for (int i = 0, e = blocks.size() + 1; i != e; ++i) { Write(0); // No flags on our blocks. } @@ -297,6 +303,7 @@ namespace { private: DenseMap<BasicBlock *, GCOVBlock *> blocks; + GCOVBlock *return_block; }; } @@ -347,6 +354,8 @@ void GCOVProfiler::EmitGCNO(DebugInfoFinder &DIF) { for (int i = 0; i != successors; ++i) { block.AddEdge(function.GetBlock(TI->getSuccessor(i))); } + } else if (isa<ReturnInst>(TI)) { + block.AddEdge(function.GetReturnBlock()); } uint32_t line = 0; @@ -383,11 +392,13 @@ bool GCOVProfiler::EmitProfileArcs(DebugInfoFinder &DIF) { DISubprogram SP(*SPI); Function *F = SP.getFunction(); - // TODO: GCOV format requires a distinct unified exit block. unsigned edges = 0; for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { TerminatorInst *TI = BB->getTerminator(); - edges += TI->getNumSuccessors(); + if (isa<ReturnInst>(TI)) + ++edges; + else + edges += TI->getNumSuccessors(); } const ArrayType *counter_type = @@ -406,7 +417,8 @@ bool GCOVProfiler::EmitProfileArcs(DebugInfoFinder &DIF) { unsigned edge_num = 0; for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { TerminatorInst *TI = BB->getTerminator(); - if (int successors = TI->getNumSuccessors()) { + int successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors(); + if (successors) { IRBuilder<> builder(TI); if (successors == 1) { |