Index: tools/llvm-exegesis/lib/Clustering.cpp =================================================================== --- tools/llvm-exegesis/lib/Clustering.cpp +++ tools/llvm-exegesis/lib/Clustering.cpp @@ -8,7 +8,6 @@ //===----------------------------------------------------------------------===// #include "Clustering.h" -#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallVector.h" #include @@ -93,6 +92,8 @@ void InstructionBenchmarkClustering::dbScan(const size_t MinPts) { std::vector Neighbors; // Persistent buffer to avoid allocs. + std::deque Workqueue(Points_.size()); + std::vector Set(Points_.size(), char(0)); for (size_t P = 0, NumPoints = Points_.size(); P < NumPoints; ++P) { if (!ClusterIdForPoint_[P].isUndef()) continue; // Previously processed in inner loop. @@ -111,12 +112,14 @@ CurrentCluster.PointIndices.push_back(P); // Process P's neighbors. - llvm::SetVector> ToProcess; - ToProcess.insert(Neighbors.begin(), Neighbors.end()); - while (!ToProcess.empty()) { + Workqueue.assign(Neighbors.begin(), Neighbors.end()); + for (size_t Neighbor : Neighbors) + Set[Neighbor] = 1; + while (!Workqueue.empty()) { // Retrieve a point from the set. - const size_t Q = *ToProcess.begin(); - ToProcess.erase(ToProcess.begin()); + const size_t Q = Workqueue.front(); + Workqueue.pop_front(); + Set[Q] = 0; if (ClusterIdForPoint_[Q].isNoise()) { // Change noise point to border point. @@ -133,7 +136,12 @@ // And extend to the neighbors of Q if the region is dense enough. rangeQuery(Q, Neighbors); if (Neighbors.size() + 1 >= MinPts) { - ToProcess.insert(Neighbors.begin(), Neighbors.end()); + for (size_t Neighbor : Neighbors) { + if (Set[Neighbor]) + continue; + Set[Neighbor] = 1; + Workqueue.push_back(Neighbor); + } } } }