mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-23 02:32:11 +00:00
[PBQP] Do not add an edge between nodes with totally disjoint allowed registers
Such edges are zero matrix, and they bring no additional info to the allocation problem, apart from contributing to nodes' degree. Removing those edges is expected to improve allocation time. Tune the spill cost comparison, as this gives better average performances now that the nodes' degrees has changed. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@230904 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f5582d938e
commit
e2557d9bd1
@ -544,8 +544,10 @@ private:
|
|||||||
public:
|
public:
|
||||||
SpillCostComparator(const Graph& G) : G(G) {}
|
SpillCostComparator(const Graph& G) : G(G) {}
|
||||||
bool operator()(NodeId N1Id, NodeId N2Id) {
|
bool operator()(NodeId N1Id, NodeId N2Id) {
|
||||||
PBQPNum N1SC = G.getNodeCosts(N1Id)[0] / G.getNodeDegree(N1Id);
|
PBQPNum N1SC = G.getNodeCosts(N1Id)[0];
|
||||||
PBQPNum N2SC = G.getNodeCosts(N2Id)[0] / G.getNodeDegree(N2Id);
|
PBQPNum N2SC = G.getNodeCosts(N2Id)[0];
|
||||||
|
if (N1SC == N2SC)
|
||||||
|
return G.getNodeDegree(N1Id) < G.getNodeDegree(N2Id);
|
||||||
return N1SC < N2SC;
|
return N1SC < N2SC;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
@ -178,8 +178,38 @@ class Interference : public PBQPRAConstraint {
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
typedef const PBQP::RegAlloc::AllowedRegVector* AllowedRegVecPtr;
|
typedef const PBQP::RegAlloc::AllowedRegVector* AllowedRegVecPtr;
|
||||||
typedef std::pair<AllowedRegVecPtr, AllowedRegVecPtr> IMatrixKey;
|
typedef std::pair<AllowedRegVecPtr, AllowedRegVecPtr> IKey;
|
||||||
typedef DenseMap<IMatrixKey, PBQPRAGraph::MatrixPtr> IMatrixCache;
|
typedef DenseMap<IKey, PBQPRAGraph::MatrixPtr> IMatrixCache;
|
||||||
|
typedef DenseSet<IKey> DisjointAllowedRegsCache;
|
||||||
|
|
||||||
|
bool haveDisjointAllowedRegs(const PBQPRAGraph &G, PBQPRAGraph::NodeId NId,
|
||||||
|
PBQPRAGraph::NodeId MId,
|
||||||
|
const DisjointAllowedRegsCache &D) const {
|
||||||
|
const auto *NRegs = &G.getNodeMetadata(NId).getAllowedRegs();
|
||||||
|
const auto *MRegs = &G.getNodeMetadata(MId).getAllowedRegs();
|
||||||
|
|
||||||
|
if (NRegs == MRegs)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (NRegs < MRegs)
|
||||||
|
return D.count(IKey(NRegs, MRegs)) > 0;
|
||||||
|
else
|
||||||
|
return D.count(IKey(MRegs, NRegs)) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDisjointAllowedRegs(const PBQPRAGraph &G, PBQPRAGraph::NodeId NId,
|
||||||
|
PBQPRAGraph::NodeId MId,
|
||||||
|
DisjointAllowedRegsCache &D) {
|
||||||
|
const auto *NRegs = &G.getNodeMetadata(NId).getAllowedRegs();
|
||||||
|
const auto *MRegs = &G.getNodeMetadata(MId).getAllowedRegs();
|
||||||
|
|
||||||
|
assert(NRegs != MRegs && "AllowedRegs can not be disjoint with itself");
|
||||||
|
|
||||||
|
if (NRegs < MRegs)
|
||||||
|
D.insert(IKey(NRegs, MRegs));
|
||||||
|
else
|
||||||
|
D.insert(IKey(MRegs, NRegs));
|
||||||
|
}
|
||||||
|
|
||||||
// Holds (Interval, CurrentSegmentID, and NodeId). The first two are required
|
// Holds (Interval, CurrentSegmentID, and NodeId). The first two are required
|
||||||
// for the fast interference graph construction algorithm. The last is there
|
// for the fast interference graph construction algorithm. The last is there
|
||||||
@ -247,6 +277,9 @@ public:
|
|||||||
// and uniquing them.
|
// and uniquing them.
|
||||||
IMatrixCache C;
|
IMatrixCache C;
|
||||||
|
|
||||||
|
// Cache known disjoint allowed registers pairs
|
||||||
|
DisjointAllowedRegsCache D;
|
||||||
|
|
||||||
typedef std::set<IntervalInfo, decltype(&lowestEndPoint)> IntervalSet;
|
typedef std::set<IntervalInfo, decltype(&lowestEndPoint)> IntervalSet;
|
||||||
typedef std::priority_queue<IntervalInfo, std::vector<IntervalInfo>,
|
typedef std::priority_queue<IntervalInfo, std::vector<IntervalInfo>,
|
||||||
decltype(&lowestStartPoint)> IntervalQueue;
|
decltype(&lowestStartPoint)> IntervalQueue;
|
||||||
@ -290,6 +323,11 @@ public:
|
|||||||
for (const auto &A : Active) {
|
for (const auto &A : Active) {
|
||||||
PBQP::GraphBase::NodeId MId = getNodeId(A);
|
PBQP::GraphBase::NodeId MId = getNodeId(A);
|
||||||
|
|
||||||
|
// Do not add an edge when the nodes' allowed registers do not
|
||||||
|
// intersect: there is obviously no interference.
|
||||||
|
if (haveDisjointAllowedRegs(G, NId, MId, D))
|
||||||
|
continue;
|
||||||
|
|
||||||
// Check that we haven't already added this edge
|
// Check that we haven't already added this edge
|
||||||
// FIXME: findEdge is expensive in the worst case (O(max_clique(G))).
|
// FIXME: findEdge is expensive in the worst case (O(max_clique(G))).
|
||||||
// It might be better to replace this with a local bit-matrix.
|
// It might be better to replace this with a local bit-matrix.
|
||||||
@ -297,7 +335,8 @@ public:
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// This is a new edge - add it to the graph.
|
// This is a new edge - add it to the graph.
|
||||||
createInterferenceEdge(G, NId, MId, C);
|
if (!createInterferenceEdge(G, NId, MId, C))
|
||||||
|
setDisjointAllowedRegs(G, NId, MId, D);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, add Cur to the Active set.
|
// Finally, add Cur to the Active set.
|
||||||
@ -307,35 +346,48 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void createInterferenceEdge(PBQPRAGraph &G, PBQPRAGraph::NodeId NId,
|
// Create an Interference edge and add it to the graph, unless it is
|
||||||
PBQPRAGraph::NodeId MId, IMatrixCache &C) {
|
// a null matrix, meaning the nodes' allowed registers do not have any
|
||||||
|
// interference. This case occurs frequently between integer and floating
|
||||||
|
// point registers for example.
|
||||||
|
// return true iff both nodes interferes.
|
||||||
|
bool createInterferenceEdge(PBQPRAGraph &G,
|
||||||
|
PBQPRAGraph::NodeId NId, PBQPRAGraph::NodeId MId,
|
||||||
|
IMatrixCache &C) {
|
||||||
|
|
||||||
const TargetRegisterInfo &TRI =
|
const TargetRegisterInfo &TRI =
|
||||||
*G.getMetadata().MF.getSubtarget().getRegisterInfo();
|
*G.getMetadata().MF.getSubtarget().getRegisterInfo();
|
||||||
|
|
||||||
const auto &NRegs = G.getNodeMetadata(NId).getAllowedRegs();
|
const auto &NRegs = G.getNodeMetadata(NId).getAllowedRegs();
|
||||||
const auto &MRegs = G.getNodeMetadata(MId).getAllowedRegs();
|
const auto &MRegs = G.getNodeMetadata(MId).getAllowedRegs();
|
||||||
|
|
||||||
// Try looking the edge costs up in the IMatrixCache first.
|
// Try looking the edge costs up in the IMatrixCache first.
|
||||||
IMatrixKey K(&NRegs, &MRegs);
|
IKey K(&NRegs, &MRegs);
|
||||||
IMatrixCache::iterator I = C.find(K);
|
IMatrixCache::iterator I = C.find(K);
|
||||||
if (I != C.end()) {
|
if (I != C.end()) {
|
||||||
G.addEdgeBypassingCostAllocator(NId, MId, I->second);
|
G.addEdgeBypassingCostAllocator(NId, MId, I->second);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
PBQPRAGraph::RawMatrix M(NRegs.size() + 1, MRegs.size() + 1, 0);
|
PBQPRAGraph::RawMatrix M(NRegs.size() + 1, MRegs.size() + 1, 0);
|
||||||
|
bool NodesInterfere = false;
|
||||||
for (unsigned I = 0; I != NRegs.size(); ++I) {
|
for (unsigned I = 0; I != NRegs.size(); ++I) {
|
||||||
unsigned PRegN = NRegs[I];
|
unsigned PRegN = NRegs[I];
|
||||||
for (unsigned J = 0; J != MRegs.size(); ++J) {
|
for (unsigned J = 0; J != MRegs.size(); ++J) {
|
||||||
unsigned PRegM = MRegs[J];
|
unsigned PRegM = MRegs[J];
|
||||||
if (TRI.regsOverlap(PRegN, PRegM))
|
if (TRI.regsOverlap(PRegN, PRegM)) {
|
||||||
M[I + 1][J + 1] = std::numeric_limits<PBQP::PBQPNum>::infinity();
|
M[I + 1][J + 1] = std::numeric_limits<PBQP::PBQPNum>::infinity();
|
||||||
|
NodesInterfere = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!NodesInterfere)
|
||||||
|
return false;
|
||||||
|
|
||||||
PBQPRAGraph::EdgeId EId = G.addEdge(NId, MId, std::move(M));
|
PBQPRAGraph::EdgeId EId = G.addEdge(NId, MId, std::move(M));
|
||||||
C[K] = G.getEdgeCostsPtr(EId);
|
C[K] = G.getEdgeCostsPtr(EId);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user