16 #ifndef LLVM_CODEGEN_REGALLOCPBQP_H
17 #define LLVM_CODEGEN_REGALLOCPBQP_H
45 : WorstRow(0), WorstCol(0),
46 UnsafeRows(new
bool[M.getRows() - 1]()),
47 UnsafeCols(new
bool[M.getCols() - 1]()) {
49 unsigned* ColCounts =
new unsigned[M.
getCols() - 1]();
52 unsigned RowCount = 0;
53 for (
unsigned j = 1; j < M.
getCols(); ++j) {
54 if (M[
i][j] == std::numeric_limits<PBQPNum>::infinity()) {
57 UnsafeRows[
i - 1] =
true;
58 UnsafeCols[j - 1] =
true;
61 WorstRow = std::max(WorstRow, RowCount);
63 unsigned WorstColCountForCurRow =
64 *std::max_element(ColCounts, ColCounts + M.
getCols() - 1);
65 WorstCol = std::max(WorstCol, WorstColCountForCurRow);
75 unsigned WorstRow, WorstCol;
76 std::unique_ptr<bool[]> UnsafeRows;
77 std::unique_ptr<bool[]> UnsafeCols;
89 std::copy(OptVec.begin(), OptVec.end(), Opts.get());
94 unsigned size()
const {
return NumOpts; }
98 if (NumOpts != Other.NumOpts)
100 return std::equal(Opts.get(), Opts.get() + NumOpts, Other.Opts.get());
104 return !(*
this == Other);
109 std::unique_ptr<unsigned[]> Opts;
113 unsigned *OStart = OptRegs.Opts.get();
114 unsigned *OEnd = OptRegs.Opts.get() + OptRegs.NumOpts;
130 : MF(MF), LIS(LIS), MBFI(MBFI) {}
137 VRegToNodeId[VReg] = NId;
141 auto VRegItr = VRegToNodeId.find(VReg);
142 if (VRegItr == VRegToNodeId.end())
144 return VRegItr->second;
148 return AllowedRegVecs.
getValue(std::move(Allowed));
153 AllowedRegVecPool AllowedRegVecs;
172 : RS(
Unprocessed), NumOpts(0), DeniedOpts(0), OptUnsafeEdges(nullptr),
175 , everConservativelyAllocatable(
false)
180 : RS(Other.RS), NumOpts(Other.NumOpts), DeniedOpts(Other.DeniedOpts),
181 OptUnsafeEdges(new
unsigned[NumOpts]), VReg(Other.VReg),
182 AllowedRegs(Other.AllowedRegs)
184 , everConservativelyAllocatable(Other.everConservativelyAllocatable)
188 std::copy(&Other.OptUnsafeEdges[0], &Other.OptUnsafeEdges[NumOpts],
197 void setVReg(
unsigned VReg) { this->VReg = VReg; }
201 this->AllowedRegs = std::move(AllowedRegs);
207 OptUnsafeEdges = std::unique_ptr<unsigned[]>(
new unsigned[NumOpts]());
212 assert(RS >= this->RS &&
"A node's reduction state can not be downgraded");
219 everConservativelyAllocatable =
true;
225 const bool* UnsafeOpts =
227 for (
unsigned i = 0;
i < NumOpts; ++
i)
228 OptUnsafeEdges[
i] += UnsafeOpts[
i];
233 const bool* UnsafeOpts =
235 for (
unsigned i = 0;
i < NumOpts; ++
i)
236 OptUnsafeEdges[
i] -= UnsafeOpts[
i];
240 return (DeniedOpts < NumOpts) ||
241 (
std::find(&OptUnsafeEdges[0], &OptUnsafeEdges[NumOpts], 0) !=
242 &OptUnsafeEdges[NumOpts]);
247 return everConservativelyAllocatable;
255 std::unique_ptr<unsigned[]> OptUnsafeEdges;
260 bool everConservativelyAllocatable;
296 "PBQP Graph should not contain single or zero-option nodes");
349 moveToOptimallyReducibleNodes(NId);
354 moveToConservativelyAllocatableNodes(NId);
358 void removeFromCurrentSet(
NodeId NId) {
362 assert(OptimallyReducibleNodes.find(NId) !=
363 OptimallyReducibleNodes.end() &&
364 "Node not in optimally reducible set.");
365 OptimallyReducibleNodes.erase(NId);
368 assert(ConservativelyAllocatableNodes.find(NId) !=
369 ConservativelyAllocatableNodes.end() &&
370 "Node not in conservatively allocatable set.");
371 ConservativelyAllocatableNodes.erase(NId);
374 assert(NotProvablyAllocatableNodes.find(NId) !=
375 NotProvablyAllocatableNodes.end() &&
376 "Node not in not-provably-allocatable set.");
377 NotProvablyAllocatableNodes.erase(NId);
382 void moveToOptimallyReducibleNodes(
NodeId NId) {
383 removeFromCurrentSet(NId);
384 OptimallyReducibleNodes.insert(NId);
389 void moveToConservativelyAllocatableNodes(
NodeId NId) {
390 removeFromCurrentSet(NId);
391 ConservativelyAllocatableNodes.insert(NId);
396 void moveToNotProvablyAllocatableNodes(
NodeId NId) {
397 removeFromCurrentSet(NId);
398 NotProvablyAllocatableNodes.insert(NId);
407 moveToOptimallyReducibleNodes(NId);
409 moveToConservativelyAllocatableNodes(NId);
411 moveToNotProvablyAllocatableNodes(NId);
421 std::vector<GraphBase::NodeId> reduce() {
422 assert(!G.
empty() &&
"Cannot reduce empty graph.");
425 std::vector<NodeId> NodeStack;
429 if (!OptimallyReducibleNodes.empty()) {
430 NodeSet::iterator NItr = OptimallyReducibleNodes.begin();
432 OptimallyReducibleNodes.erase(NItr);
433 NodeStack.push_back(NId);
445 }
else if (!ConservativelyAllocatableNodes.empty()) {
452 NodeSet::iterator NItr = ConservativelyAllocatableNodes.begin();
454 ConservativelyAllocatableNodes.erase(NItr);
455 NodeStack.push_back(NId);
458 }
else if (!NotProvablyAllocatableNodes.empty()) {
459 NodeSet::iterator NItr =
460 std::min_element(NotProvablyAllocatableNodes.begin(),
461 NotProvablyAllocatableNodes.end(),
462 SpillCostComparator(G));
464 NotProvablyAllocatableNodes.erase(NItr);
465 NodeStack.push_back(NId);
474 class SpillCostComparator {
476 SpillCostComparator(
const Graph& G) : G(G) {}
477 bool operator()(NodeId N1Id, NodeId N2Id) {
478 PBQPNum N1SC =
G.getNodeCosts(N1Id)[0];
479 PBQPNum N2SC =
G.getNodeCosts(N2Id)[0];
481 return G.getNodeDegree(N1Id) <
G.getNodeDegree(N2Id);
489 typedef std::set<NodeId> NodeSet;
490 NodeSet OptimallyReducibleNodes;
491 NodeSet ConservativelyAllocatableNodes;
492 NodeSet NotProvablyAllocatableNodes;
517 return RegAllocSolver.
solve();
PBQP::Graph< RegAllocSolverImpl > Graph
unsigned getCols() const
Return the number of cols in this matrix.
Represents a solution to a PBQP problem.
NodeId getEdgeNode1Id(EdgeId EId) const
Get the first node connected to this edge.
Holds a vector of the allowed physical regs for a vreg.
void handleSetNodeCosts(NodeId NId, const Vector &newCosts)
bool operator!=(const AllowedRegVector &Other) const
static NodeId invalidNodeId()
Returns a value representing an invalid (non-existent) node.
NodeId getEdgeNode2Id(EdgeId EId) const
Get the second node connected to this edge.
PoolRef getValue(ValueKeyT ValueKey)
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
RegAllocSolverImpl::GraphMetadata GraphMetadata
const Vector & getNodeCosts(NodeId NId) const
Get a node's cost vector.
RegAllocSolverImpl(Graph &G)
FunctionPass * createPBQPRegisterAllocator(char *customPassID=nullptr)
Create a PBQP register allocator instance.
void dump() const
Dump this graph to dbgs().
NodeMetadata & getNodeMetadata(NodeId NId)
friend hash_code hash_value(const AllowedRegVector &)
bool operator==(const AllowedRegVector &Other) const
void printDot(raw_ostream &OS) const
Print a representation of this graph in DOT format.
Function Alias Analysis false
void applyR1(GraphT &G, typename GraphT::NodeId NId)
Reduce a node of degree one.
void handleDisconnectEdge(EdgeId EId, NodeId NId)
NodeEntry::AdjEdgeList::size_type getNodeDegree(NodeId NId) const
NodeIdSet nodeIds() const
PBQPRAGraph(GraphMetadata Metadata)
AllowedRegVector(const std::vector< unsigned > &OptVec)
void setSolver(SolverT &S)
Lock this graph to the given solver instance in preparation for running the solver.
unsigned getLength() const
Return the length of the vector.
const Metadata & getMetadata() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void unsetSolver()
Release from solver instance.
auto find(R &&Range, const T &Val) -> decltype(std::begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
unsigned operator[](size_t I) const
Solution backpropagate(GraphT &G, StackT stack)
const Matrix & getEdgeCosts(EdgeId EId) const
Get an edge's cost matrix.
std::shared_ptr< const AllowedRegVector > PoolRef
bool empty() const
Returns true if the graph is empty.
RegAlloc::NodeMetadata NodeMetadata
RegAlloc::GraphMetadata GraphMetadata
void handleUpdateCosts(EdgeId EId, const Matrix &NewCosts)
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
hash_code hash_combine_range(InputIteratorT first, InputIteratorT last)
Compute a hash_code for a sequence of values.
An opaque object representing a hash code.
static cl::opt< RegisterRegAlloc::FunctionPassCtor, false, RegisterPassParser< RegisterRegAlloc > > RegAlloc("regalloc", cl::init(&useDefaultRegisterAllocator), cl::desc("Register allocator to use"))
-regalloc=... command line option.
void disconnectAllNeighborsFromNode(NodeId NId)
Convenience method to disconnect all neighbours from the given node.
unsigned getRows() const
Return the number of rows in this matrix.
void handleReconnectEdge(EdgeId EId, NodeId NId)
hash_code hash_value(const AllowedRegVector &OptRegs)
Solution solve(PBQPRAGraph &G)
unsigned getSpillOptionIdx()
Spill option index.
void handleAddEdge(EdgeId EId)
void applyR2(GraphT &G, typename GraphT::NodeId NId)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This class implements an extremely fast bulk output stream that can only output to a stream...
PBQP::PoolCostAllocator< Vector, Matrix > CostAllocator
void handleAddNode(NodeId NId)
void handleRemoveNode(NodeId NId)