aboutsummaryrefslogtreecommitdiff
path: root/lib
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
parent17df2c3240837b4382898ead8c3ead407a338520 (diff)
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')
-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) {