From 2b1a7da188a99657439461c04091c7db3e1f5695 Mon Sep 17 00:00:00 2001 From: Alex Coyte Date: Mon, 8 May 2017 10:51:19 +1000 Subject: [PATCH] deterministic assembleProgramBlocks() --- src/rose/rose_build_bytecode.cpp | 1 - src/rose/rose_build_program.cpp | 38 ++++++++++++++++++++++++-------- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/rose/rose_build_bytecode.cpp b/src/rose/rose_build_bytecode.cpp index 02304ae2..4d0793bf 100644 --- a/src/rose/rose_build_bytecode.cpp +++ b/src/rose/rose_build_bytecode.cpp @@ -2819,7 +2819,6 @@ vector groupByFragment(const RoseBuildImpl &build) { auto &fi = m.second; DEBUG_PRINTF("frag %s -> ids: %s\n", dumpString(m.first.s).c_str(), as_string_list(fi.lit_ids).c_str()); - sort(fi.lit_ids.begin(), fi.lit_ids.end()); /* to match old behaviour */ fragments.emplace_back(frag_id, fi.groups, move(fi.lit_ids)); frag_id++; assert(frag_id == fragments.size()); diff --git a/src/rose/rose_build_program.cpp b/src/rose/rose_build_program.cpp index eb9db5a6..23a8b959 100644 --- a/src/rose/rose_build_program.cpp +++ b/src/rose/rose_build_program.cpp @@ -1923,17 +1923,37 @@ void makeGroupSquashInstruction(const RoseBuildImpl &build, u32 lit_id, prog.add_before_end(make_unique(~info.group_mask)); } -RoseProgram assembleProgramBlocks(vector &&blocks) { - DEBUG_PRINTF("%zu blocks before dedupe\n", blocks.size()); +namespace { +struct ProgKey { + ProgKey(const RoseProgram &p) : prog(&p) { } - sort(blocks.begin(), blocks.end(), - [](const RoseProgram &a, const RoseProgram &b) { - RoseProgramHash hasher; - return hasher(a) < hasher(b); - }); + bool operator==(const ProgKey &b) const { + return RoseProgramEquivalence()(*prog, *b.prog); + } - blocks.erase(unique(blocks.begin(), blocks.end(), RoseProgramEquivalence()), - blocks.end()); + friend size_t hash_value(const ProgKey &a) { + return RoseProgramHash()(*a.prog); + } +private: + const RoseProgram *prog; +}; +} + +RoseProgram assembleProgramBlocks(vector &&blocks_in) { + DEBUG_PRINTF("%zu blocks before dedupe\n", blocks_in.size()); + + vector blocks; + blocks.reserve(blocks_in.size()); /* to ensure stable reference for seen */ + + unordered_set seen; + for (auto &block : blocks_in) { + if (contains(seen, block)) { + continue; + } + + blocks.push_back(move(block)); + seen.emplace(blocks.back()); + } DEBUG_PRINTF("%zu blocks after dedupe\n", blocks.size());