]> git.ipfire.org Git - thirdparty/vectorscan.git/commitdiff
deterministic assembleProgramBlocks()
authorAlex Coyte <a.coyte@intel.com>
Mon, 8 May 2017 00:51:19 +0000 (10:51 +1000)
committerMatthew Barr <matthew.barr@intel.com>
Tue, 30 May 2017 03:59:00 +0000 (13:59 +1000)
src/rose/rose_build_bytecode.cpp
src/rose/rose_build_program.cpp

index 02304ae22877ddc7e58ce30a11d47bf40c51507f..4d0793bfeab6d4d45e4419ec0ae5a7317d81553d 100644 (file)
@@ -2819,7 +2819,6 @@ vector<LitFragment> 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());
index eb9db5a6a351f666496f80cd9a420846e2bf8c87..23a8b959bfec799030dc8d9ac52e25937b502334 100644 (file)
@@ -1923,17 +1923,37 @@ void makeGroupSquashInstruction(const RoseBuildImpl &build, u32 lit_id,
     prog.add_before_end(make_unique<RoseInstrSquashGroups>(~info.group_mask));
 }
 
-RoseProgram assembleProgramBlocks(vector<RoseProgram> &&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);
+    }
+
+    friend size_t hash_value(const ProgKey &a) {
+        return RoseProgramHash()(*a.prog);
+    }
+private:
+    const RoseProgram *prog;
+};
+}
+
+RoseProgram assembleProgramBlocks(vector<RoseProgram> &&blocks_in) {
+    DEBUG_PRINTF("%zu blocks before dedupe\n", blocks_in.size());
 
-    blocks.erase(unique(blocks.begin(), blocks.end(), RoseProgramEquivalence()),
-                 blocks.end());
+    vector<RoseProgram> blocks;
+    blocks.reserve(blocks_in.size()); /* to ensure stable reference for seen */
+
+    unordered_set<ProgKey> 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());