[PATCH] D46228: [ELF] Use union-find set in Call-Chain Clustering (C³) heuristic to improve worst-case time complexity.
Fangrui Song via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sat Apr 28 14:50:13 PDT 2018
MaskRay created this revision.
MaskRay added reviewers: Bigcheese, ruiu.
Herald added subscribers: llvm-commits, arichardson, emaste.
Herald added a reviewer: espindola.
Repository:
rLLD LLVM Linker
https://reviews.llvm.org/D46228
Files:
ELF/CallGraphSort.cpp
Index: ELF/CallGraphSort.cpp
===================================================================
--- ELF/CallGraphSort.cpp
+++ ELF/CallGraphSort.cpp
@@ -46,6 +46,9 @@
#include "SymbolTable.h"
#include "Symbols.h"
+#include <list>
+#include <numeric>
+
using namespace llvm;
using namespace lld;
using namespace lld::elf;
@@ -68,7 +71,7 @@
return double(Weight) / double(Size);
}
- std::vector<int> Sections;
+ std::list<int> Sections;
size_t Size = 0;
uint64_t Weight = 0;
uint64_t InitialWeight = 0;
@@ -151,35 +154,39 @@
return false;
}
+static int findLeader(std::vector<int> &Leaders, int V) {
+ while (Leaders[V] != V) {
+ Leaders[V] = Leaders[Leaders[V]];
+ V = Leaders[V];
+ }
+ return V;
+}
+
static void mergeClusters(Cluster &Into, Cluster &From) {
- Into.Sections.insert(Into.Sections.end(), From.Sections.begin(),
- From.Sections.end());
+ Into.Sections.splice(Into.Sections.end(), From.Sections);
Into.Size += From.Size;
Into.Weight += From.Weight;
- From.Sections.clear();
From.Size = 0;
From.Weight = 0;
}
// Group InputSections into clusters using the Call-Chain Clustering heuristic
// then sort the clusters by density.
void CallGraphSort::groupClusters() {
std::vector<int> SortedSecs(Clusters.size());
- std::vector<Cluster *> SecToCluster(Clusters.size());
-
- for (int SI = 0, SE = Clusters.size(); SI != SE; ++SI) {
- SortedSecs[SI] = SI;
- SecToCluster[SI] = &Clusters[SI];
- }
+ std::vector<int> Leaders(Clusters.size());
+ std::iota(Leaders.begin(), Leaders.end(), 0);
+ std::iota(SortedSecs.begin(), SortedSecs.end(), 0);
std::stable_sort(SortedSecs.begin(), SortedSecs.end(), [&](int A, int B) {
return Clusters[B].getDensity() < Clusters[A].getDensity();
});
for (int SI : SortedSecs) {
// Clusters[SI] is the same as SecToClusters[SI] here because it has not
// been merged into another cluster yet.
- Cluster &C = Clusters[SI];
+ int L = findLeader(Leaders, SI);
+ Cluster &C = Clusters[L];
int BestPred = -1;
uint64_t BestWeight = 0;
@@ -195,21 +202,18 @@
if (BestWeight * 10 <= C.InitialWeight)
continue;
- Cluster *PredC = SecToCluster[BestPred];
- if (PredC == &C)
+ int PredL = findLeader(Leaders, BestPred);
+ if (L == PredL)
continue;
+ Cluster *PredC = &Clusters[PredL];
if (C.Size + PredC->Size > MAX_CLUSTER_SIZE)
continue;
if (isNewDensityBad(*PredC, C))
continue;
- // NOTE: Consider using a disjoint-set to track section -> cluster mapping
- // if this is ever slow.
- for (int SI : C.Sections)
- SecToCluster[SI] = PredC;
-
+ Leaders[L] = PredL;
mergeClusters(*PredC, C);
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D46228.144461.patch
Type: text/x-patch
Size: 2763 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180428/2dfdde95/attachment.bin>
More information about the llvm-commits
mailing list