summaryrefslogtreecommitdiff
path: root/lib/Transforms/Instrumentation
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2011-04-21 03:18:00 +0000
committerNick Lewycky <nicholas@mxc.ca>2011-04-21 03:18:00 +0000
commita4c4c0e1298f4dd9791eff2bae857e7be6d0ab56 (patch)
tree6bb30d126348fe0f4cfca62d01cd74c1619e2d38 /lib/Transforms/Instrumentation
parent17df2c3240837b4382898ead8c3ead407a338520 (diff)
downloadllvm-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.cpp22
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) {