class NodeEntry {
private:
- Vector costs;
+ Vector costs;
AdjEdgeList adjEdges;
void *data;
NodeEntry() : costs(0, 0) {}
assert(getNodeCosts(n1Id).getLength() == costs.getRows() &&
getNodeCosts(n2Id).getLength() == costs.getCols() &&
"Matrix dimensions mismatch.");
- return addConstructedEdge(EdgeEntry(n1Id, n2Id, costs));
+ return addConstructedEdge(EdgeEntry(n1Id, n2Id, costs));
}
/// \brief Get the number of nodes in the graph.
/// @param nItr Node iterator.
/// @return Pointer to node data.
void* getNodeData(NodeId nId) { return getNode(nId).getData(); }
-
+
/// \brief Get an edge's cost matrix.
/// @param eItr Edge iterator.
/// @return Edge cost matrix.
/// \brief Get an edge's data pointer.
/// @param eItr Edge iterator.
- /// @return Pointer to edge data.
+ /// @return Pointer to edge data.
void* getEdgeData(EdgeId eId) { return getEdge(eId).getData(); }
/// \brief Get a node's degree.
/// \brief Get the first node connected to this edge.
/// @param eItr Edge iterator.
- /// @return The first node connected to the given edge.
+ /// @return The first node connected to the given edge.
NodeId getEdgeNode1(EdgeId eId) {
return getEdge(eId).getNode1();
}
/// \brief Get the second node connected to this edge.
/// @param eItr Edge iterator.
- /// @return The second node connected to the given edge.
+ /// @return The second node connected to the given edge.
NodeId getEdgeNode2(EdgeId eId) {
return getEdge(eId).getNode2();
- }
+ }
/// \brief Get the "other" node connected to this edge.
/// @param eItr Edge iterator.
/// @param nItr Node iterator for the "given" node.
- /// @return The iterator for the "other" node connected to this edge.
+ /// @return The iterator for the "other" node connected to this edge.
NodeId getEdgeOtherNode(EdgeId eId, NodeId nId) {
EdgeEntry &e = getEdge(eId);
if (e.getNode1() == nId) {
NodeEntry &n = getNode(nId);
for (AdjEdgeItr itr = n.edgesBegin(), end = n.edgesEnd(); itr != end; ++itr) {
EdgeId eId = *itr;
- removeEdge(eId);
+ removeEdge(eId);
}
freeNodes.push_back(nId);
}
/// @param os Output stream to print on.
template <typename OStream>
void printDot(OStream &os) {
-
+
os << "graph {\n";
for (NodeItr nodeItr = nodesBegin(), nodeEnd = nodesEnd();
// nEnd = other.nodesEnd();
// nItr != nEnd; ++nItr) {
// nodeMap[nItr] = addNode(other.getNodeCosts(nItr));
-// }
+// }
// }
}
/// <li> void heuristicReduce() : Perform a single heuristic reduction.
/// <li> void preUpdateEdgeCosts(Graph::EdgeItr) : Handle the (imminent)
/// change to the cost matrix on the given edge (by R2).
- /// <li> void postUpdateEdgeCostts(Graph::EdgeItr) : Handle the new
+ /// <li> void postUpdateEdgeCostts(Graph::EdgeItr) : Handle the new
/// costs on the given edge.
/// <li> void handleAddEdge(Graph::EdgeItr) : Handle the addition of a new
/// edge into the PBQP graph (by R2).
///
/// These methods are implemented in this class for documentation purposes,
/// but will assert if called.
- ///
+ ///
/// Note that this class uses the curiously recursive template idiom to
/// forward calls to the derived class. These methods need not be made
/// virtual, and indeed probably shouldn't for performance reasons.
HImpl& impl() { return static_cast<HImpl&>(*this); }
// Add the given node to the optimal reductions list. Keep an iterator to
- // its location for fast removal.
+ // its location for fast removal.
void addToOptimalReductionList(Graph::NodeId nId) {
optimalList.insert(optimalList.end(), nId);
}
/// behaviour.
bool solverRunSimplify() const { return true; }
- /// \brief Decide whether a node should be optimally or heuristically
+ /// \brief Decide whether a node should be optimally or heuristically
/// reduced.
/// @return Whether or not the given node should be listed for optimal
/// reduction (via R0, R1 or R2).
}
/// \brief Prepare a change in the costs on the given edge.
- /// @param eItr Edge iterator.
+ /// @param eItr Edge iterator.
void preUpdateEdgeCosts(Graph::EdgeId eId) {
llvm_unreachable("Must be implemented in derived class.");
}
//
// Heuristic PBQP solver. This solver is able to perform optimal reductions for
// nodes of degree 0, 1 or 2. For nodes of degree >2 a plugable heuristic is
-// used to select a node for reduction.
+// used to select a node for reduction.
//
//===----------------------------------------------------------------------===//
typedef std::list<Graph::EdgeId> SolverEdges;
public:
-
+
/// \brief Iterator type for edges in the solver graph.
typedef SolverEdges::iterator SolverEdgeItr;
unsigned getSolverDegree() const { return solverDegree; }
void clearSolverEdges() {
solverDegree = 0;
- solverEdges.clear();
+ solverEdges.clear();
}
-
+
private:
HeuristicNodeData hData;
unsigned solverDegree;
SolverEdges solverEdges;
};
-
+
class EdgeData {
public:
HeuristicEdgeData& getHeuristicData() { return hData; }
/// \brief Construct a heuristic solver implementation to solve the given
/// graph.
/// @param g The graph representing the problem instance to be solved.
- HeuristicSolverImpl(Graph &g) : g(g), h(*this) {}
+ HeuristicSolverImpl(Graph &g) : g(g), h(*this) {}
/// \brief Get the graph being solved by this solver.
/// @return The graph representing the problem instance being solved by this
/// the solver graph.
/// @param nItr Node iterator.
/// @return Begin iterator for the set of edges adjacent to the given node
- /// in the solver graph.
+ /// in the solver graph.
SolverEdgeItr solverEdgesBegin(Graph::NodeId nId) {
return getSolverNodeData(nId).solverEdgesBegin();
}
/// the solver graph.
/// @param nItr Node iterator.
/// @return End iterator for the set of edges adjacent to the given node in
- /// the solver graph.
+ /// the solver graph.
SolverEdgeItr solverEdgesEnd(Graph::NodeId nId) {
return getSolverNodeData(nId).solverEdgesEnd();
}
const Matrix &eCosts = g.getEdgeCosts(eId);
const Vector &xCosts = g.getNodeCosts(xnId);
-
+
// Duplicate a little to avoid transposing matrices.
if (xnId == g.getEdgeNode1(eId)) {
Graph::NodeId ynId = g.getEdgeNode2(eId);
unsigned xLen = xCosts.getLength(),
yLen = yxeCosts->getRows(),
zLen = zxeCosts->getRows();
-
+
Matrix delta(yLen, zLen);
for (unsigned i = 0; i < yLen; ++i) {
// If we modified the edge costs let the heuristic know.
h.postUpdateEdgeCosts(yzeId);
}
-
+
if (nullCostEdge) {
// If this edge ended up null remove it.
if (!addedEdge) {
/// \brief Record an application of the RN rule.
///
/// For use by the HeuristicBase.
- void recordRN() { s.recordRN(); }
+ void recordRN() { s.recordRN(); }
private:
bool tryToEliminateEdge(Graph::EdgeId eId) {
if (tryNormaliseEdgeMatrix(eId)) {
g.removeEdge(eId);
- return true;
+ return true;
}
return false;
}
/// \brief PBQP Heuristic which applies an allocability test based on
/// Briggs.
- ///
+ ///
/// This heuristic assumes that the elements of cost vectors in the PBQP
/// problem represent storage options, with the first being the spill
/// option and subsequent elements representing legal registers for the
/// solver stack. If no nodes can be proven allocable then the node with
/// the lowest estimated spill cost is selected and push to the solver stack
/// instead.
- ///
- /// This implementation is built on top of HeuristicBase.
+ ///
+ /// This implementation is built on top of HeuristicBase.
class Briggs : public HeuristicBase<Briggs> {
private:
typedef std::list<Graph::NodeId> RNAllocableList;
typedef RNAllocableList::iterator RNAllocableListItr;
- typedef std::list<Graph::NodeId> RNUnallocableList;
+ typedef std::list<Graph::NodeId> RNUnallocableList;
typedef RNUnallocableList::iterator RNUnallocableListItr;
public:
}
/// \brief Prepare a change in the costs on the given edge.
- /// @param eItr Edge iterator.
+ /// @param eItr Edge iterator.
void preUpdateEdgeCosts(Graph::EdgeId eId) {
Graph &g = getGraph();
Graph::NodeId n1Id = g.getEdgeNode1(eId),
numReverseRegs = eCosts.getCols() - 1;
std::vector<unsigned> rowInfCounts(numRegs, 0),
- colInfCounts(numReverseRegs, 0);
+ colInfCounts(numReverseRegs, 0);
ed.worst = 0;
ed.reverseWorst = 0;
ed.isUpToDate = true;
}
- // Add the contributions of the given edge to the given node's
+ // Add the contributions of the given edge to the given node's
// numDenied and safe members. No action is taken other than to update
// these member values. Once updated these numbers can be used by clients
// to update the node's allocability.
NodeData &nd = getHeuristicNodeData(nId);
unsigned numRegs = getGraph().getNodeCosts(nId).getLength() - 1;
-
+
bool nIsNode1 = nId == getGraph().getEdgeNode1(eId);
EdgeData::UnsafeArray &unsafe =
nIsNode1 ? ed.unsafe : ed.reverseUnsafe;
}
}
- // Subtract the contributions of the given edge to the given node's
+ // Subtract the contributions of the given edge to the given node's
// numDenied and safe members. No action is taken other than to update
// these member values. Once updated these numbers can be used by clients
// to update the node's allocability.
NodeData &nd = getHeuristicNodeData(nId);
unsigned numRegs = getGraph().getNodeCosts(nId).getLength() - 1;
-
+
bool nIsNode1 = nId == getGraph().getEdgeNode1(eId);
EdgeData::UnsafeArray &unsafe =
nIsNode1 ? ed.unsafe : ed.reverseUnsafe;
nd.numDenied -= nIsNode1 ? ed.worst : ed.reverseWorst;
for (unsigned r = 0; r < numRegs; ++r) {
- if (unsafe[r]) {
+ if (unsafe[r]) {
if (nd.unsafeDegrees[r] == 1) {
++nd.numSafe;
}
for (SolverEdgeItr aeItr = getSolver().solverEdgesBegin(nId),
aeEnd = getSolver().solverEdgesEnd(nId);
aeItr != aeEnd; ++aeItr) {
-
+
Graph::EdgeId eId = *aeItr;
computeEdgeContributions(eId);
addEdgeContributions(eId, nId);