summaryrefslogtreecommitdiff
path: root/lib/CodeGen/RegAllocPBQP.cpp
diff options
context:
space:
mode:
authorLang Hames <lhames@gmail.com>2013-11-09 00:14:07 +0000
committerLang Hames <lhames@gmail.com>2013-11-09 00:14:07 +0000
commitfc93ae629e49b00fc1cc536d93f1b106bcd0937d (patch)
treebdf5d1b14e8c4b800482b0f778e0b4e8eac0799f /lib/CodeGen/RegAllocPBQP.cpp
parent623d2e618f4e672c47edff9ec63ed6d733ac81d3 (diff)
downloadllvm-fc93ae629e49b00fc1cc536d93f1b106bcd0937d.tar.gz
llvm-fc93ae629e49b00fc1cc536d93f1b106bcd0937d.tar.bz2
llvm-fc93ae629e49b00fc1cc536d93f1b106bcd0937d.tar.xz
Rewrite the PBQP graph data structure.
The new graph structure replaces the node and edge linked lists with vectors. Free lists (well, free vectors) are used for fast insertion/deletion. The ultimate aim is to make PBQP graphs cheap to clone. The motivation is that the PBQP solver destructively consumes input graphs while computing a solution, forcing the graph to be fully reconstructed for each round of PBQP. This imposes a high cost on large functions, which often require several rounds of solving/spilling to find a final register allocation. If we can cheaply clone the PBQP graph and incrementally update it between rounds then hopefully we can reduce this cost. Further, once we begin pooling matrix/vector values (future work), we can cache some PBQP solver metadata and share it between cloned graphs, allowing the PBQP solver to re-use some of the computation done in earlier rounds. For now this is just a data structure update. The allocator and solver still use the graph the same way as before, fully reconstructing it between each round. I expect no material change from this update, although it may change the iteration order of the nodes, causing ties in the solver to break in different directions, and this could perturb the generated allocations (hopefully in a completely benign way). Thanks very much to Arnaud Allard de Grandmaison for encouraging me to get back to work on this, and for a lot of discussion and many useful PBQP test cases. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194300 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/RegAllocPBQP.cpp')
-rw-r--r--lib/CodeGen/RegAllocPBQP.cpp28
1 files changed, 14 insertions, 14 deletions
diff --git a/lib/CodeGen/RegAllocPBQP.cpp b/lib/CodeGen/RegAllocPBQP.cpp
index 7786ecdf37..38738536e5 100644
--- a/lib/CodeGen/RegAllocPBQP.cpp
+++ b/lib/CodeGen/RegAllocPBQP.cpp
@@ -158,13 +158,13 @@ char RegAllocPBQP::ID = 0;
} // End anonymous namespace.
-unsigned PBQPRAProblem::getVRegForNode(PBQP::Graph::ConstNodeItr node) const {
+unsigned PBQPRAProblem::getVRegForNode(PBQP::Graph::NodeId node) const {
Node2VReg::const_iterator vregItr = node2VReg.find(node);
assert(vregItr != node2VReg.end() && "No vreg for node.");
return vregItr->second;
}
-PBQP::Graph::NodeItr PBQPRAProblem::getNodeForVReg(unsigned vreg) const {
+PBQP::Graph::NodeId PBQPRAProblem::getNodeForVReg(unsigned vreg) const {
VReg2Node::const_iterator nodeItr = vreg2Node.find(vreg);
assert(nodeItr != vreg2Node.end() && "No node for vreg.");
return nodeItr->second;
@@ -247,7 +247,7 @@ PBQPRAProblem *PBQPBuilder::build(MachineFunction *mf, const LiveIntervals *lis,
}
// Construct the node.
- PBQP::Graph::NodeItr node =
+ PBQP::Graph::NodeId node =
g.addNode(PBQP::Vector(vrAllowed.size() + 1, 0));
// Record the mapping and allowed set in the problem.
@@ -273,7 +273,7 @@ PBQPRAProblem *PBQPBuilder::build(MachineFunction *mf, const LiveIntervals *lis,
assert(!l2.empty() && "Empty interval in vreg set?");
if (l1.overlaps(l2)) {
- PBQP::Graph::EdgeItr edge =
+ PBQP::Graph::EdgeId edge =
g.addEdge(p->getNodeForVReg(vr1), p->getNodeForVReg(vr2),
PBQP::Matrix(vr1Allowed.size()+1, vr2Allowed.size()+1, 0));
@@ -364,16 +364,16 @@ PBQPRAProblem *PBQPBuilderWithCoalescing::build(MachineFunction *mf,
}
if (pregOpt < allowed.size()) {
++pregOpt; // +1 to account for spill option.
- PBQP::Graph::NodeItr node = p->getNodeForVReg(src);
+ PBQP::Graph::NodeId node = p->getNodeForVReg(src);
addPhysRegCoalesce(g.getNodeCosts(node), pregOpt, cBenefit);
}
} else {
const PBQPRAProblem::AllowedSet *allowed1 = &p->getAllowedSet(dst);
const PBQPRAProblem::AllowedSet *allowed2 = &p->getAllowedSet(src);
- PBQP::Graph::NodeItr node1 = p->getNodeForVReg(dst);
- PBQP::Graph::NodeItr node2 = p->getNodeForVReg(src);
- PBQP::Graph::EdgeItr edge = g.findEdge(node1, node2);
- if (edge == g.edgesEnd()) {
+ PBQP::Graph::NodeId node1 = p->getNodeForVReg(dst);
+ PBQP::Graph::NodeId node2 = p->getNodeForVReg(src);
+ PBQP::Graph::EdgeId edge = g.findEdge(node1, node2);
+ if (edge == g.invalidEdgeId()) {
edge = g.addEdge(node1, node2, PBQP::Matrix(allowed1->size() + 1,
allowed2->size() + 1,
0));
@@ -477,11 +477,11 @@ bool RegAllocPBQP::mapPBQPToRegAlloc(const PBQPRAProblem &problem,
const PBQP::Graph &g = problem.getGraph();
// Iterate over the nodes mapping the PBQP solution to a register
// assignment.
- for (PBQP::Graph::ConstNodeItr node = g.nodesBegin(),
- nodeEnd = g.nodesEnd();
- node != nodeEnd; ++node) {
- unsigned vreg = problem.getVRegForNode(node);
- unsigned alloc = solution.getSelection(node);
+ for (PBQP::Graph::NodeItr nodeItr = g.nodesBegin(),
+ nodeEnd = g.nodesEnd();
+ nodeItr != nodeEnd; ++nodeItr) {
+ unsigned vreg = problem.getVRegForNode(*nodeItr);
+ unsigned alloc = solution.getSelection(*nodeItr);
if (problem.isPRegOption(vreg, alloc)) {
unsigned preg = problem.getPRegForOption(vreg, alloc);