mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2026-04-26 12:20:42 +00:00
[PBQP] Unique allowed-sets for nodes in the PBQP graph and use pairs of these
sets as keys into a cache of interference matrice values in the Interference constraint adder. Creating interference matrices was one of the large remaining time-sinks in PBQP. Caching them reduces the total compile time (when using PBQP) on the nightly test suite by ~10%. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@220688 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -166,6 +166,12 @@ public:
|
||||
class Interference : public PBQPRAConstraint {
|
||||
private:
|
||||
|
||||
private:
|
||||
|
||||
typedef const PBQP::RegAlloc::AllowedRegVector* AllowedRegVecPtr;
|
||||
typedef std::pair<AllowedRegVecPtr, AllowedRegVecPtr> IMatrixKey;
|
||||
typedef DenseMap<IMatrixKey, PBQPRAGraph::MatrixPtr> IMatrixCache;
|
||||
|
||||
// Holds (Interval, CurrentSegmentID, and NodeId). The first two are required
|
||||
// for the fast interference graph construction algorithm. The last is there
|
||||
// to save us from looking up node ids via the VRegToNode map in the graph
|
||||
@@ -226,8 +232,11 @@ public:
|
||||
// number of registers, but rather the size of the largest clique in the
|
||||
// graph. Still, we expect this to be better than N^2.
|
||||
LiveIntervals &LIS = G.getMetadata().LIS;
|
||||
const TargetRegisterInfo &TRI =
|
||||
*G.getMetadata().MF.getTarget().getSubtargetImpl()->getRegisterInfo();
|
||||
|
||||
// Interferenc matrices are incredibly regular - they're only a function of
|
||||
// the allowed sets, so we cache them to avoid the overhead of constructing
|
||||
// and uniquing them.
|
||||
IMatrixCache C;
|
||||
|
||||
typedef std::set<IntervalInfo, decltype(&lowestEndPoint)> IntervalSet;
|
||||
typedef std::priority_queue<IntervalInfo, std::vector<IntervalInfo>,
|
||||
@@ -275,13 +284,11 @@ public:
|
||||
// Check that we haven't already added this edge
|
||||
// FIXME: findEdge is expensive in the worst case (O(max_clique(G))).
|
||||
// It might be better to replace this with a local bit-matrix.
|
||||
if (G.findEdge(NId, MId) != PBQP::GraphBase::invalidEdgeId())
|
||||
if (G.findEdge(NId, MId) != PBQPRAGraph::invalidEdgeId())
|
||||
continue;
|
||||
|
||||
// This is a new edge - add it to the graph.
|
||||
const auto &NOpts = G.getNodeMetadata(NId).getOptionRegs();
|
||||
const auto &MOpts = G.getNodeMetadata(MId).getOptionRegs();
|
||||
G.addEdge(NId, MId, createInterferenceMatrix(TRI, NOpts, MOpts));
|
||||
createInterferenceEdge(G, NId, MId, C);
|
||||
}
|
||||
|
||||
// Finally, add Cur to the Active set.
|
||||
@@ -291,21 +298,35 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
PBQPRAGraph::RawMatrix createInterferenceMatrix(
|
||||
const TargetRegisterInfo &TRI,
|
||||
const PBQPRAGraph::NodeMetadata::OptionToRegMap &NOpts,
|
||||
const PBQPRAGraph::NodeMetadata::OptionToRegMap &MOpts) {
|
||||
PBQPRAGraph::RawMatrix M(NOpts.size() + 1, MOpts.size() + 1, 0);
|
||||
for (unsigned I = 0; I != NOpts.size(); ++I) {
|
||||
unsigned PRegN = NOpts[I];
|
||||
for (unsigned J = 0; J != MOpts.size(); ++J) {
|
||||
unsigned PRegM = MOpts[J];
|
||||
void createInterferenceEdge(PBQPRAGraph &G, PBQPRAGraph::NodeId NId,
|
||||
PBQPRAGraph::NodeId MId, IMatrixCache &C) {
|
||||
|
||||
const TargetRegisterInfo &TRI =
|
||||
*G.getMetadata().MF.getTarget().getSubtargetImpl()->getRegisterInfo();
|
||||
|
||||
const auto &NRegs = G.getNodeMetadata(NId).getAllowedRegs();
|
||||
const auto &MRegs = G.getNodeMetadata(MId).getAllowedRegs();
|
||||
|
||||
// Try looking the edge costs up in the IMatrixCache first.
|
||||
IMatrixKey K(&NRegs, &MRegs);
|
||||
IMatrixCache::iterator I = C.find(K);
|
||||
if (I != C.end()) {
|
||||
G.addEdgeBypassingCostAllocator(NId, MId, I->second);
|
||||
return;
|
||||
}
|
||||
|
||||
PBQPRAGraph::RawMatrix M(NRegs.size() + 1, MRegs.size() + 1, 0);
|
||||
for (unsigned I = 0; I != NRegs.size(); ++I) {
|
||||
unsigned PRegN = NRegs[I];
|
||||
for (unsigned J = 0; J != MRegs.size(); ++J) {
|
||||
unsigned PRegM = MRegs[J];
|
||||
if (TRI.regsOverlap(PRegN, PRegM))
|
||||
M[I + 1][J + 1] = std::numeric_limits<PBQP::PBQPNum>::infinity();
|
||||
}
|
||||
}
|
||||
|
||||
return M;
|
||||
PBQPRAGraph::EdgeId EId = G.addEdge(NId, MId, std::move(M));
|
||||
C[K] = G.getEdgeCostsPtr(EId);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -341,8 +362,8 @@ public:
|
||||
|
||||
PBQPRAGraph::NodeId NId = G.getMetadata().getNodeIdForVReg(SrcReg);
|
||||
|
||||
const PBQPRAGraph::NodeMetadata::OptionToRegMap &Allowed =
|
||||
G.getNodeMetadata(NId).getOptionRegs();
|
||||
const PBQPRAGraph::NodeMetadata::AllowedRegVector &Allowed =
|
||||
G.getNodeMetadata(NId).getAllowedRegs();
|
||||
|
||||
unsigned PRegOpt = 0;
|
||||
while (PRegOpt < Allowed.size() && Allowed[PRegOpt] != DstReg)
|
||||
@@ -356,10 +377,10 @@ public:
|
||||
} else {
|
||||
PBQPRAGraph::NodeId N1Id = G.getMetadata().getNodeIdForVReg(DstReg);
|
||||
PBQPRAGraph::NodeId N2Id = G.getMetadata().getNodeIdForVReg(SrcReg);
|
||||
const PBQPRAGraph::NodeMetadata::OptionToRegMap *Allowed1 =
|
||||
&G.getNodeMetadata(N1Id).getOptionRegs();
|
||||
const PBQPRAGraph::NodeMetadata::OptionToRegMap *Allowed2 =
|
||||
&G.getNodeMetadata(N2Id).getOptionRegs();
|
||||
const PBQPRAGraph::NodeMetadata::AllowedRegVector *Allowed1 =
|
||||
&G.getNodeMetadata(N1Id).getAllowedRegs();
|
||||
const PBQPRAGraph::NodeMetadata::AllowedRegVector *Allowed2 =
|
||||
&G.getNodeMetadata(N2Id).getAllowedRegs();
|
||||
|
||||
PBQPRAGraph::EdgeId EId = G.findEdge(N1Id, N2Id);
|
||||
if (EId == G.invalidEdgeId()) {
|
||||
@@ -384,10 +405,10 @@ public:
|
||||
private:
|
||||
|
||||
void addVirtRegCoalesce(
|
||||
PBQPRAGraph::RawMatrix &CostMat,
|
||||
const PBQPRAGraph::NodeMetadata::OptionToRegMap &Allowed1,
|
||||
const PBQPRAGraph::NodeMetadata::OptionToRegMap &Allowed2,
|
||||
PBQP::PBQPNum Benefit) {
|
||||
PBQPRAGraph::RawMatrix &CostMat,
|
||||
const PBQPRAGraph::NodeMetadata::AllowedRegVector &Allowed1,
|
||||
const PBQPRAGraph::NodeMetadata::AllowedRegVector &Allowed2,
|
||||
PBQP::PBQPNum Benefit) {
|
||||
assert(CostMat.getRows() == Allowed1.size() + 1 && "Size mismatch.");
|
||||
assert(CostMat.getCols() == Allowed2.size() + 1 && "Size mismatch.");
|
||||
for (unsigned I = 0; I != Allowed1.size(); ++I) {
|
||||
@@ -501,7 +522,8 @@ void RegAllocPBQP::initializeGraph(PBQPRAGraph &G) {
|
||||
PBQPRAGraph::RawVector NodeCosts(VRegAllowed.size() + 1, 0);
|
||||
PBQPRAGraph::NodeId NId = G.addNode(std::move(NodeCosts));
|
||||
G.getNodeMetadata(NId).setVReg(VReg);
|
||||
G.getNodeMetadata(NId).setOptionRegs(std::move(VRegAllowed));
|
||||
G.getNodeMetadata(NId).setAllowedRegs(
|
||||
G.getMetadata().getAllowedRegs(std::move(VRegAllowed)));
|
||||
G.getMetadata().setNodeIdForVReg(VReg, NId);
|
||||
}
|
||||
}
|
||||
@@ -529,7 +551,7 @@ bool RegAllocPBQP::mapPBQPToRegAlloc(const PBQPRAGraph &G,
|
||||
unsigned AllocOption = Solution.getSelection(NId);
|
||||
|
||||
if (AllocOption != PBQP::RegAlloc::getSpillOptionIdx()) {
|
||||
unsigned PReg = G.getNodeMetadata(NId).getOptionRegs()[AllocOption - 1];
|
||||
unsigned PReg = G.getNodeMetadata(NId).getAllowedRegs()[AllocOption - 1];
|
||||
DEBUG(dbgs() << "VREG " << PrintReg(VReg, &TRI) << " -> "
|
||||
<< TRI.getName(PReg) << "\n");
|
||||
assert(PReg != 0 && "Invalid preg selected.");
|
||||
@@ -563,7 +585,6 @@ bool RegAllocPBQP::mapPBQPToRegAlloc(const PBQPRAGraph &G,
|
||||
return !AnotherRoundNeeded;
|
||||
}
|
||||
|
||||
|
||||
void RegAllocPBQP::finalizeAlloc(MachineFunction &MF,
|
||||
LiveIntervals &LIS,
|
||||
VirtRegMap &VRM) const {
|
||||
|
||||
Reference in New Issue
Block a user