[gcov] Fix non-determinism (DenseMap iteration order) of checksum computation

... by using MapVector. The issue was caused by 63182c2ac0.

Also use stable_partition instead of partition to get stable results
across different STL implementations.
This commit is contained in:
Fangrui Song 2020-10-05 12:39:19 -07:00
parent 3641d375f6
commit e338f8fe69
1 changed files with 9 additions and 14 deletions

View File

@ -16,6 +16,7 @@
#include "CFGMST.h" #include "CFGMST.h"
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Hashing.h" #include "llvm/ADT/Hashing.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Sequence.h" #include "llvm/ADT/Sequence.h"
#include "llvm/ADT/Statistic.h" #include "llvm/ADT/Statistic.h"
@ -396,7 +397,7 @@ namespace {
} }
GCOVBlock &getBlock(const BasicBlock *BB) { GCOVBlock &getBlock(const BasicBlock *BB) {
return Blocks.find(BB)->second; return Blocks.find(const_cast<BasicBlock *>(BB))->second;
} }
GCOVBlock &getEntryBlock() { return EntryBlock; } GCOVBlock &getEntryBlock() { return EntryBlock; }
@ -462,14 +463,8 @@ namespace {
write(E.second); write(E.second);
} }
} }
std::vector<GCOVBlock *> Sorted; for (auto &It : Blocks) {
Sorted.reserve(Blocks.size()); const GCOVBlock &Block = It.second;
for (auto &It : Blocks)
Sorted.push_back(&It.second);
llvm::sort(Sorted, [](GCOVBlock *x, GCOVBlock *y) {
return x->Number < y->Number;
});
for (GCOVBlock &Block : make_pointee_range(Sorted)) {
if (Block.OutEdges.empty()) continue; if (Block.OutEdges.empty()) continue;
write(GCOV_TAG_ARCS); write(GCOV_TAG_ARCS);
@ -482,8 +477,8 @@ namespace {
} }
// Emit lines for each block. // Emit lines for each block.
for (GCOVBlock &Block : make_pointee_range(Sorted)) for (auto &It : Blocks)
Block.writeOut(); It.second.writeOut();
} }
public: public:
@ -492,7 +487,7 @@ namespace {
uint32_t Ident; uint32_t Ident;
uint32_t FuncChecksum; uint32_t FuncChecksum;
int Version; int Version;
DenseMap<BasicBlock *, GCOVBlock> Blocks; MapVector<BasicBlock *, GCOVBlock> Blocks;
GCOVBlock EntryBlock; GCOVBlock EntryBlock;
GCOVBlock ReturnBlock; GCOVBlock ReturnBlock;
}; };
@ -889,8 +884,8 @@ bool GCOVProfiler::emitProfileNotes(
return E->Removed || (!E->InMST && !E->Place); return E->Removed || (!E->InMST && !E->Place);
}); });
const size_t Measured = const size_t Measured =
llvm::partition(MST.AllEdges, llvm::stable_partition(
[](std::unique_ptr<Edge> &E) { return E->Place; }) - MST.AllEdges, [](std::unique_ptr<Edge> &E) { return E->Place; }) -
MST.AllEdges.begin(); MST.AllEdges.begin();
for (size_t I : llvm::seq<size_t>(0, Measured)) { for (size_t I : llvm::seq<size_t>(0, Measured)) {
Edge &E = *MST.AllEdges[I]; Edge &E = *MST.AllEdges[I];