summaryrefslogtreecommitdiff
path: root/lib/Transforms/Instrumentation/GCOVProfiling.cpp
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2013-06-18 06:38:21 +0000
committerNick Lewycky <nicholas@mxc.ca>2013-06-18 06:38:21 +0000
commitc4e6b540f05932eea37ca10b6c1fded522777954 (patch)
treeeea0ac03e78efd4fa014375204a420e12c004a06 /lib/Transforms/Instrumentation/GCOVProfiling.cpp
parentb44193dde11836b2f1bfb00bc99f899f0de757e4 (diff)
downloadllvm-c4e6b540f05932eea37ca10b6c1fded522777954.tar.gz
llvm-c4e6b540f05932eea37ca10b6c1fded522777954.tar.bz2
llvm-c4e6b540f05932eea37ca10b6c1fded522777954.tar.xz
Fix nondeterminism in .gcno file generation.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@184174 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Instrumentation/GCOVProfiling.cpp')
-rw-r--r--lib/Transforms/Instrumentation/GCOVProfiling.cpp34
1 files changed, 25 insertions, 9 deletions
diff --git a/lib/Transforms/Instrumentation/GCOVProfiling.cpp b/lib/Transforms/Instrumentation/GCOVProfiling.cpp
index 3ce9cf6c3a..ef66bf8e11 100644
--- a/lib/Transforms/Instrumentation/GCOVProfiling.cpp
+++ b/lib/Transforms/Instrumentation/GCOVProfiling.cpp
@@ -37,6 +37,7 @@
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"
+#include <algorithm>
#include <string>
#include <utility>
using namespace llvm;
@@ -229,6 +230,15 @@ namespace {
SmallVector<uint32_t, 32> Lines;
};
+
+ // Sorting function for deterministic behaviour in GCOVBlock::writeOut.
+ struct StringKeySort {
+ bool operator()(StringMapEntry<GCOVLines *> *LHS,
+ StringMapEntry<GCOVLines *> *RHS) const {
+ return LHS->getKey() < RHS->getKey();
+ }
+ };
+
// Represent a basic block in GCOV. Each block has a unique number in the
// function, number of lines belonging to each block, and a set of edges to
// other blocks.
@@ -248,17 +258,23 @@ namespace {
void writeOut() {
uint32_t Len = 3;
+ SmallVector<StringMapEntry<GCOVLines *> *, 32> SortedLinesByFile;
for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(),
E = LinesByFile.end(); I != E; ++I) {
Len += I->second->length();
+ SortedLinesByFile.push_back(&*I);
}
writeBytes(LinesTag, 4);
write(Len);
write(Number);
- for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(),
- E = LinesByFile.end(); I != E; ++I)
- I->second->writeOut();
+
+ StringKeySort Sorter;
+ std::sort(SortedLinesByFile.begin(), SortedLinesByFile.end(), Sorter);
+ for (SmallVector<StringMapEntry<GCOVLines *> *, 32>::iterator
+ I = SortedLinesByFile.begin(), E = SortedLinesByFile.end();
+ I != E; ++I)
+ (*I)->getValue()->writeOut();
write(0);
write(0);
}
@@ -335,9 +351,10 @@ namespace {
DEBUG(dbgs() << Blocks.size() << " blocks.\n");
// Emit edges between blocks.
- for (DenseMap<BasicBlock *, GCOVBlock *>::iterator I = Blocks.begin(),
- E = Blocks.end(); I != E; ++I) {
- GCOVBlock &Block = *I->second;
+ if (Blocks.empty()) return;
+ Function *F = Blocks.begin()->first->getParent();
+ for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
+ GCOVBlock &Block = *Blocks[I];
if (Block.OutEdges.empty()) continue;
writeBytes(EdgeTag, 4);
@@ -352,9 +369,8 @@ namespace {
}
// Emit lines for each block.
- for (DenseMap<BasicBlock *, GCOVBlock *>::iterator I = Blocks.begin(),
- E = Blocks.end(); I != E; ++I) {
- I->second->writeOut();
+ for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
+ Blocks[I]->writeOut();
}
}