1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 11:13:28 +01:00

Fix nondeterminism in .gcno file generation.

llvm-svn: 184174
This commit is contained in:
Nick Lewycky 2013-06-18 06:38:21 +00:00
parent 6ec4332633
commit eed4be4827

View File

@ -37,6 +37,7 @@
#include "llvm/Support/Path.h" #include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/ModuleUtils.h" #include "llvm/Transforms/Utils/ModuleUtils.h"
#include <algorithm>
#include <string> #include <string>
#include <utility> #include <utility>
using namespace llvm; using namespace llvm;
@ -229,6 +230,15 @@ namespace {
SmallVector<uint32_t, 32> Lines; 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 // 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 // function, number of lines belonging to each block, and a set of edges to
// other blocks. // other blocks.
@ -248,17 +258,23 @@ namespace {
void writeOut() { void writeOut() {
uint32_t Len = 3; uint32_t Len = 3;
SmallVector<StringMapEntry<GCOVLines *> *, 32> SortedLinesByFile;
for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(), for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(),
E = LinesByFile.end(); I != E; ++I) { E = LinesByFile.end(); I != E; ++I) {
Len += I->second->length(); Len += I->second->length();
SortedLinesByFile.push_back(&*I);
} }
writeBytes(LinesTag, 4); writeBytes(LinesTag, 4);
write(Len); write(Len);
write(Number); write(Number);
for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(),
E = LinesByFile.end(); I != E; ++I) StringKeySort Sorter;
I->second->writeOut(); 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);
write(0); write(0);
} }
@ -335,9 +351,10 @@ namespace {
DEBUG(dbgs() << Blocks.size() << " blocks.\n"); DEBUG(dbgs() << Blocks.size() << " blocks.\n");
// Emit edges between blocks. // Emit edges between blocks.
for (DenseMap<BasicBlock *, GCOVBlock *>::iterator I = Blocks.begin(), if (Blocks.empty()) return;
E = Blocks.end(); I != E; ++I) { Function *F = Blocks.begin()->first->getParent();
GCOVBlock &Block = *I->second; for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
GCOVBlock &Block = *Blocks[I];
if (Block.OutEdges.empty()) continue; if (Block.OutEdges.empty()) continue;
writeBytes(EdgeTag, 4); writeBytes(EdgeTag, 4);
@ -352,9 +369,8 @@ namespace {
} }
// Emit lines for each block. // Emit lines for each block.
for (DenseMap<BasicBlock *, GCOVBlock *>::iterator I = Blocks.begin(), for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
E = Blocks.end(); I != E; ++I) { Blocks[I]->writeOut();
I->second->writeOut();
} }
} }