summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/passes/DuplicateFunctionElimination.cpp33
1 files changed, 16 insertions, 17 deletions
diff --git a/src/passes/DuplicateFunctionElimination.cpp b/src/passes/DuplicateFunctionElimination.cpp
index c7852237b..027d16b4a 100644
--- a/src/passes/DuplicateFunctionElimination.cpp
+++ b/src/passes/DuplicateFunctionElimination.cpp
@@ -102,23 +102,22 @@ struct DuplicateFunctionElimination : public Pass {
std::set<Name> duplicates;
for (auto& pair : hashGroups) {
auto& group = pair.second;
- if (group.size() == 1) continue;
- // pick a base for each group, and try to replace everyone else to it. TODO: multiple bases per hash group, for collisions
-#if 0
- // for comparison purposes, pick in a deterministic way based on the names
- Function* base = nullptr;
- for (auto* func : group) {
- if (!base || strcmp(func->name.str, base->name.str) < 0) {
- base = func;
- }
- }
-#else
- Function* base = group[0];
-#endif
- for (auto* func : group) {
- if (func != base && equal(func, base)) {
- replacements[func->name] = base->name;
- duplicates.insert(func->name);
+ Index size = group.size();
+ if (size == 1) continue;
+ // The groups should be fairly small, and even if a group is large we should
+ // have almost all of them identical, so we should not hit actual O(N^2)
+ // here unless the hash is quite poor.
+ for (Index i = 0; i < size - 1; i++) {
+ auto* first = group[i];
+ if (duplicates.count(first->name)) continue;
+ for (Index j = i + 1; j < size; j++) {
+ auto* second = group[j];
+ if (duplicates.count(second->name)) continue;
+ if (equal(first, second)) {
+ // great, we can replace the second with the first!
+ replacements[second->name] = first->name;
+ duplicates.insert(second->name);
+ }
}
}
}