64#include "llvm/Config/llvm-config.h"
84#include <system_error>
91#define DEBUG_TYPE "regalloc"
99 cl::desc(
"Attempt coalescing during PBQP register allocation."),
105 cl::desc(
"Dump graphs for each function/round in the compilation unit."),
120 RegAllocPBQP(
char *cPassID =
nullptr)
124 StringRef getPassName()
const override {
return "PBQP Register Allocator"; }
127 void getAnalysisUsage(AnalysisUsage &au)
const override;
130 bool runOnMachineFunction(MachineFunction &MF)
override;
132 MachineFunctionProperties getRequiredProperties()
const override {
133 return MachineFunctionProperties().setNoPHIs();
136 MachineFunctionProperties getClearedProperties()
const override {
137 return MachineFunctionProperties().setIsSSA();
141 using RegSet = std::set<Register>;
145 RegSet VRegsToAlloc, EmptyIntervalVRegs;
151 SmallPtrSet<MachineInstr *, 32> DeadRemats;
154 void findVRegIntervalsToAlloc(
const MachineFunction &MF, LiveIntervals &LIS);
157 void initializeGraph(
PBQPRAGraph &
G, VirtRegMap &VRM, Spiller &VRegSpiller);
160 void spillVReg(
Register VReg, SmallVectorImpl<Register> &NewIntervals,
161 MachineFunction &MF, LiveIntervals &LIS, VirtRegMap &VRM,
162 Spiller &VRegSpiller);
167 const PBQP::Solution &Solution,
169 Spiller &VRegSpiller);
173 void finalizeAlloc(MachineFunction &MF, LiveIntervals &LIS,
174 VirtRegMap &VRM)
const;
176 void postOptimization(Spiller &VRegSpiller, LiveIntervals &LIS);
179char RegAllocPBQP::ID = 0;
185 LiveIntervals &LIS =
G.getMetadata().LIS;
191 for (
auto NId :
G.nodeIds()) {
194 if (SpillCost == 0.0)
195 SpillCost = std::numeric_limits<PBQP::PBQPNum>::min();
197 SpillCost += MinSpillCost;
200 G.setNodeCosts(NId, std::move(NodeCosts));
208 using AllowedRegVecPtr =
const PBQP::RegAlloc::AllowedRegVector *;
209 using IKey = std::pair<AllowedRegVecPtr, AllowedRegVecPtr>;
210 using IMatrixCache = DenseMap<IKey, PBQPRAGraph::MatrixPtr>;
211 using DisjointAllowedRegsCache = DenseSet<IKey>;
212 using IEdgeKey = std::pair<PBQP::GraphBase::NodeId, PBQP::GraphBase::NodeId>;
213 using IEdgeCache = DenseSet<IEdgeKey>;
217 const DisjointAllowedRegsCache &
D)
const {
218 const auto *NRegs = &
G.getNodeMetadata(NId).getAllowedRegs();
219 const auto *MRegs = &
G.getNodeMetadata(MId).getAllowedRegs();
225 return D.contains(IKey(NRegs, MRegs));
227 return D.contains(IKey(MRegs, NRegs));
232 DisjointAllowedRegsCache &
D) {
233 const auto *NRegs = &
G.getNodeMetadata(NId).getAllowedRegs();
234 const auto *MRegs = &
G.getNodeMetadata(MId).getAllowedRegs();
236 assert(NRegs != MRegs &&
"AllowedRegs can not be disjoint with itself");
239 D.insert(IKey(NRegs, MRegs));
241 D.insert(IKey(MRegs, NRegs));
249 std::tuple<LiveInterval*, size_t, PBQP::GraphBase::NodeId>;
251 static SlotIndex getStartPoint(
const IntervalInfo &
I) {
252 return std::get<0>(
I)->segments[std::get<1>(
I)].start;
255 static SlotIndex getEndPoint(
const IntervalInfo &
I) {
256 return std::get<0>(
I)->segments[std::get<1>(
I)].end;
260 return std::get<2>(
I);
263 static bool lowestStartPoint(
const IntervalInfo &I1,
264 const IntervalInfo &I2) {
267 return getStartPoint(I1) > getStartPoint(I2);
270 static bool lowestEndPoint(
const IntervalInfo &I1,
271 const IntervalInfo &I2) {
272 SlotIndex E1 = getEndPoint(I1);
273 SlotIndex E2 = getEndPoint(I2);
284 return std::get<0>(I1)->reg() < std::get<0>(I2)->reg();
287 static bool isAtLastSegment(
const IntervalInfo &
I) {
288 return std::get<1>(
I) == std::get<0>(
I)->size() - 1;
291 static IntervalInfo nextSegment(
const IntervalInfo &
I) {
292 return std::make_tuple(std::get<0>(
I), std::get<1>(
I) + 1, std::get<2>(
I));
302 LiveIntervals &LIS =
G.getMetadata().LIS;
314 DisjointAllowedRegsCache
D;
316 using IntervalSet = std::set<IntervalInfo,
decltype(&lowestEndPoint)>;
317 using IntervalQueue =
318 std::priority_queue<IntervalInfo, std::vector<IntervalInfo>,
319 decltype(&lowestStartPoint)>;
320 IntervalSet
Active(lowestEndPoint);
321 IntervalQueue Inactive(lowestStartPoint);
324 for (
auto NId :
G.nodeIds()) {
325 Register VReg =
G.getNodeMetadata(NId).getVReg();
327 assert(!LI.
empty() &&
"PBQP graph contains node for empty interval");
328 Inactive.push(std::make_tuple(&LI, 0, NId));
331 while (!Inactive.empty()) {
334 IntervalInfo Cur = Inactive.top();
337 IntervalSet::iterator RetireItr =
Active.begin();
338 while (RetireItr !=
Active.end() &&
339 (getEndPoint(*RetireItr) <= getStartPoint(Cur))) {
342 if (!isAtLastSegment(*RetireItr))
343 Inactive.push(nextSegment(*RetireItr));
351 Cur = Inactive.top();
357 for (
const auto &
A : Active) {
362 if (haveDisjointAllowedRegs(
G, NId, MId,
D))
366 IEdgeKey EK(std::min(NId, MId), std::max(NId, MId));
371 if (!createInterferenceEdge(
G, NId, MId,
C))
372 setDisjointAllowedRegs(
G, NId, MId,
D);
391 const TargetRegisterInfo &
TRI =
392 *
G.getMetadata().MF.getSubtarget().getRegisterInfo();
393 const auto &NRegs =
G.getNodeMetadata(NId).getAllowedRegs();
394 const auto &MRegs =
G.getNodeMetadata(MId).getAllowedRegs();
397 IKey
K(&NRegs, &MRegs);
400 G.addEdgeBypassingCostAllocator(NId, MId,
I->second);
405 bool NodesInterfere =
false;
406 for (
unsigned I = 0;
I != NRegs.size(); ++
I) {
407 MCRegister PRegN = NRegs[
I];
408 for (
unsigned J = 0; J != MRegs.size(); ++J) {
409 MCRegister PRegM = MRegs[J];
410 if (
TRI.regsOverlap(PRegN, PRegM)) {
411 M[
I + 1][J + 1] = std::numeric_limits<PBQP::PBQPNum>::infinity();
412 NodesInterfere =
true;
421 C[
K] =
G.getEdgeCostsPtr(EId);
430 MachineFunction &MF =
G.getMetadata().MF;
431 MachineBlockFrequencyInfo &MBFI =
G.getMetadata().MBFI;
436 for (
const auto &
MBB : MF) {
437 for (
const auto &
MI :
MBB) {
439 if (!CP.setRegisters(&
MI) || CP.getSrcReg() == CP.getDstReg())
448 if (!MF.getRegInfo().isAllocatable(DstReg))
453 const PBQPRAGraph::NodeMetadata::AllowedRegVector &
Allowed =
454 G.getNodeMetadata(NId).getAllowedRegs();
456 unsigned PRegOpt = 0;
457 while (PRegOpt <
Allowed.size() && Allowed[PRegOpt].id() != DstReg)
460 if (PRegOpt <
Allowed.size()) {
462 NewCosts[PRegOpt + 1] -= CBenefit;
463 G.setNodeCosts(NId, std::move(NewCosts));
468 const PBQPRAGraph::NodeMetadata::AllowedRegVector *Allowed1 =
469 &
G.getNodeMetadata(N1Id).getAllowedRegs();
470 const PBQPRAGraph::NodeMetadata::AllowedRegVector *Allowed2 =
471 &
G.getNodeMetadata(N2Id).getAllowedRegs();
474 if (EId ==
G.invalidEdgeId()) {
476 Allowed2->size() + 1, 0);
477 addVirtRegCoalesce(Costs, *Allowed1, *Allowed2, CBenefit);
478 G.addEdge(N1Id, N2Id, std::move(Costs));
480 if (
G.getEdgeNode1Id(EId) == N2Id) {
485 addVirtRegCoalesce(Costs, *Allowed1, *Allowed2, CBenefit);
486 G.updateEdgeCosts(EId, std::move(Costs));
494 void addVirtRegCoalesce(
496 const PBQPRAGraph::NodeMetadata::AllowedRegVector &Allowed1,
497 const PBQPRAGraph::NodeMetadata::AllowedRegVector &Allowed2,
499 assert(CostMat.getRows() == Allowed1.size() + 1 &&
"Size mismatch.");
500 assert(CostMat.getCols() == Allowed2.size() + 1 &&
"Size mismatch.");
501 for (
unsigned I = 0;
I != Allowed1.size(); ++
I) {
502 MCRegister PReg1 = Allowed1[
I];
503 for (
unsigned J = 0; J != Allowed2.size(); ++J) {
504 MCRegister PReg2 = Allowed2[J];
506 CostMat[
I + 1][J + 1] -= Benefit;
514 float normalize(
float UseDefFreq,
unsigned Size,
unsigned NumInstr)
override {
521 PBQPVirtRegAuxInfo(MachineFunction &MF, LiveIntervals &LIS, VirtRegMap &VRM,
522 const MachineLoopInfo &
Loops,
523 const MachineBlockFrequencyInfo &MBFI)
524 : VirtRegAuxInfo(MF, LIS, VRM,
Loops, MBFI) {}
531void PBQPRAConstraint::anchor() {}
533void PBQPRAConstraintList::anchor() {}
535void RegAllocPBQP::getAnalysisUsage(
AnalysisUsage &au)
const {
564 for (
unsigned I = 0,
E =
MRI.getNumVirtRegs();
I !=
E; ++
I) {
566 if (
MRI.reg_nodbg_empty(
Reg))
568 VRegsToAlloc.insert(
Reg);
576 for (
unsigned i = 0; CSR[i] != 0; ++i)
577 if (
TRI.regsOverlap(
Reg, CSR[i]))
589 *
G.getMetadata().MF.getSubtarget().getRegisterInfo();
591 std::vector<Register> Worklist(VRegsToAlloc.begin(), VRegsToAlloc.end());
593 std::map<Register, std::vector<MCRegister>> VRegAllowedMap;
595 while (!Worklist.empty()) {
603 if (VRegLI.
empty()) {
604 EmptyIntervalVRegs.insert(VRegLI.
reg());
605 VRegsToAlloc.erase(VRegLI.
reg());
616 std::vector<MCRegister> VRegAllowed;
620 if (
MRI.isReserved(PReg))
624 if (!RegMaskOverlaps.
empty() && !RegMaskOverlaps.
test(PReg))
628 bool Interference =
false;
629 for (MCRegUnit Unit :
TRI.regunits(PReg)) {
639 VRegAllowed.push_back(PReg);
644 if (VRegAllowed.empty()) {
646 spillVReg(VReg, NewVRegs, MF, LIS, VRM, VRegSpiller);
651 VRegAllowedMap[VReg.
id()] = std::move(VRegAllowed);
654 for (
auto &KV : VRegAllowedMap) {
655 auto VReg = KV.first;
659 EmptyIntervalVRegs.insert(VReg);
660 VRegsToAlloc.erase(VReg);
664 auto &VRegAllowed = KV.second;
670 for (
unsigned i = 0; i != VRegAllowed.size(); ++i)
672 NodeCosts[1 + i] += 1.0;
675 G.getNodeMetadata(NId).setVReg(VReg);
676 G.getNodeMetadata(NId).setAllowedRegs(
677 G.getMetadata().getAllowedRegs(std::move(VRegAllowed)));
678 G.getMetadata().setNodeIdForVReg(VReg, NId);
682void RegAllocPBQP::spillVReg(
Register VReg,
686 VRegsToAlloc.erase(VReg);
688 nullptr, &DeadRemats);
689 VRegSpiller.
spill(LRE);
694 << LRE.getParent().weight() <<
", New vregs: ");
702 VRegsToAlloc.insert(LI.
reg());
708bool RegAllocPBQP::mapPBQPToRegAlloc(
const PBQPRAGraph &
G,
718 bool AnotherRoundNeeded =
false;
725 for (
auto NId :
G.nodeIds()) {
726 Register VReg =
G.getNodeMetadata(NId).getVReg();
730 MCRegister PReg =
G.getNodeMetadata(NId).getAllowedRegs()[AllocOpt - 1];
732 <<
TRI.getName(PReg) <<
"\n");
733 assert(PReg != 0 &&
"Invalid preg selected.");
739 spillVReg(VReg, NewVRegs, MF, LIS, VRM, VRegSpiller);
740 AnotherRoundNeeded |= !NewVRegs.
empty();
744 return !AnotherRoundNeeded;
753 for (
const Register &R : EmptyIntervalVRegs) {
761 for (
MCRegister CandidateReg : RawPRegOrder) {
768 "No un-reserved physical registers in this register class");
778 for (
auto *DeadInst : DeadRemats) {
780 DeadInst->eraseFromParent();
786 LiveIntervals &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
788 getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
790 auto &LiveStks = getAnalysis<LiveStacksWrapperLegacy>().getLS();
791 auto &MDT = getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
793 VirtRegMap &VRM = getAnalysis<VirtRegMapWrapperLegacy>().getVRM();
795 PBQPVirtRegAuxInfo VRAI(
796 MF, LIS, VRM, getAnalysis<MachineLoopInfoWrapperPass>().getLI(), MBFI);
797 VRAI.calculateSpillWeightsAndHints();
804 MF, LIS, VRM, getAnalysis<MachineLoopInfoWrapperPass>().getLI(), MBFI);
805 std::unique_ptr<Spiller> VRegSpiller(
822 findVRegIntervalsToAlloc(MF, LIS);
826 std::string FullyQualifiedName =
831 if (!VRegsToAlloc.empty()) {
833 std::unique_ptr<PBQPRAConstraintList> ConstraintsRoot =
834 std::make_unique<PBQPRAConstraintList>();
835 ConstraintsRoot->addConstraint(std::make_unique<SpillCosts>());
836 ConstraintsRoot->addConstraint(std::make_unique<Interference>());
838 ConstraintsRoot->addConstraint(std::make_unique<Coalescing>());
841 bool PBQPAllocComplete =
false;
844 while (!PBQPAllocComplete) {
849 initializeGraph(
G, VRM, *VRegSpiller);
850 ConstraintsRoot->apply(
G);
854 std::ostringstream
RS;
856 std::string GraphFileName = FullyQualifiedName +
"." +
RS.str() +
860 LLVM_DEBUG(
dbgs() <<
"Dumping graph for round " << Round <<
" to \""
861 << GraphFileName <<
"\"\n");
867 PBQPAllocComplete = mapPBQPToRegAlloc(
G, Solution, VRM, *VRegSpiller);
873 finalizeAlloc(MF, LIS, VRM);
874 postOptimization(*VRegSpiller, LIS);
875 VRegsToAlloc.clear();
876 EmptyIntervalVRegs.clear();
889 Register VReg =
G.getNodeMetadata(NId).getVReg();
890 const char *RegClassName =
TRI->getRegClassName(
MRI.getRegClass(VReg));
891 OS << NId <<
" (" << RegClassName <<
':' <<
printReg(VReg,
TRI) <<
')';
895#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
899 assert(Costs.getLength() != 0 &&
"Empty vector in graph.");
907 assert(N1Id != N2Id &&
"PBQP graphs should not have self-edges.");
909 assert(M.getRows() != 0 &&
"No rows in matrix.");
910 assert(M.getCols() != 0 &&
"No cols in matrix.");
911 OS <<
PrintNodeInfo(N1Id, *
this) <<
' ' << M.getRows() <<
" rows / ";
912 OS <<
PrintNodeInfo(N2Id, *
this) <<
' ' << M.getCols() <<
" cols:\n";
925 OS <<
" node" << NId <<
" [ label=\""
930 OS <<
" edge [ len=" <<
nodeIds().size() <<
" ]\n";
936 for (
unsigned i = 0; i < EdgeCosts.getRows(); ++i) {
937 OS << EdgeCosts.getRowAsVector(i) <<
"\\n";
945 return new RegAllocPBQP(customPassID);
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements the BitVector class.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
Module.h This file contains the declarations for the Module class.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static Printable PrintNodeInfo(PBQP::RegAlloc::PBQPRAGraph::NodeId NId, const PBQP::RegAlloc::PBQPRAGraph &G)
Create Printable object for node and register info.
static cl::opt< bool > PBQPDumpGraphs("pbqp-dump-graphs", cl::desc("Dump graphs for each function/round in the compilation unit."), cl::init(false), cl::Hidden)
static cl::opt< bool > PBQPCoalescing("pbqp-coalescing", cl::desc("Attempt coalescing during PBQP register allocation."), cl::init(false), cl::Hidden)
static bool isACalleeSavedRegister(MCRegister Reg, const TargetRegisterInfo &TRI, const MachineFunction &MF)
static RegisterRegAlloc RegisterPBQPRepAlloc("pbqp", "PBQP register allocator", createDefaultPBQPRegisterAllocator)
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
Represent the analysis usage information of a pass.
LLVM_ABI AnalysisUsage & addRequiredID(const void *ID)
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool test(unsigned Idx) const
bool empty() const
empty - Tests whether there are no bits in this bitvector.
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT > iterator
FunctionPass class - This class is used to implement most global optimizations.
Module * getParent()
Get the module that this global value is contained inside of...
LiveInterval - This class represents the liveness of a register, or stack slot.
LLVM_ABI bool checkRegMaskInterference(const LiveInterval &LI, BitVector &UsableRegs)
Test if LI is live across any register mask instructions, and compute a bit mask of physical register...
void RemoveMachineInstrFromMaps(MachineInstr &MI)
LiveInterval & getInterval(Register Reg)
LiveRange & getRegUnit(MCRegUnit Unit)
Return the live range for register unit Unit.
bool overlaps(const LiveRange &other) const
overlaps - Return true if the intersection of the two live ranges is not empty.
Wrapper class representing physical registers. Should be passed by value.
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
double getBlockFreqRelativeToEntryBlock(const MachineBasicBlock *MBB) const
Compute the frequency of the block, relative to the entry block.
Analysis pass which computes a MachineDominatorTree.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI void freezeReservedRegs()
freezeReservedRegs - Called by the register allocator to freeze the set of reserved registers before ...
bool isReserved(MCRegister PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
LLVM_ABI const MCPhysReg * getCalleeSavedRegs() const
Returns list of callee saved registers.
const std::string & getModuleIdentifier() const
Get the module identifier which is, essentially, the name of the module.
Abstract base for classes implementing PBQP register allocation constraints (e.g.
virtual ~PBQPRAConstraint()=0
typename RegAllocSolverImpl::GraphMetadata GraphMetadata
typename RegAllocSolverImpl::Matrix Matrix
NodeId getEdgeNode2Id(EdgeId EId) const
NodeId getEdgeNode1Id(EdgeId EId) const
const Matrix & getEdgeCosts(EdgeId EId) const
typename RegAllocSolverImpl::Vector Vector
NodeIdSet nodeIds() const
typename RegAllocSolverImpl::RawMatrix RawMatrix
typename RegAllocSolverImpl::RawVector RawVector
const Vector & getNodeCosts(NodeId NId) const
EdgeIdSet edgeIds() const
void printDot(raw_ostream &OS) const
Print a representation of this graph in DOT format.
void dump() const
Dump this graph to dbgs().
Represents a solution to a PBQP problem.
unsigned getSelection(GraphBase::NodeId nodeId) const
Get a node's selection.
Simple wrapper around std::function<void(raw_ostream&)>.
Wrapper class representing virtual and physical registers.
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
constexpr unsigned id() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
virtual void postOptimization()
virtual void spill(LiveRangeEdit &LRE, AllocationOrder *Order=nullptr)=0
spill - Spill the LRE.getParent() live interval.
ArrayRef< MCPhysReg > getRawAllocationOrder(const MachineFunction &MF, bool Rev=false) const
Returns the preferred order for allocating registers from this register class in MF.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual std::unique_ptr< PBQPRAConstraint > getCustomPBQPConstraints() const
Return PBQPConstraint(s) for the target.
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
Calculate auxiliary information for a virtual register such as its spill weight and allocation hint.
virtual float normalize(float UseDefFreq, unsigned Size, unsigned NumInstr)
Weight normalization function.
void clearAllVirt()
clears all virtual to physical register mappings
MachineRegisterInfo & getRegInfo() const
LLVM_ABI void assignVirt2Phys(Register virtReg, MCRegister physReg)
creates a mapping for the specified virtual register to the specified physical register
A raw_ostream that writes to a file descriptor.
This class implements an extremely fast bulk output stream that can only output to a stream.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
Solution solve(PBQPRAGraph &G)
unsigned getSpillOptionIdx()
Spill option index.
void apply(Opt *O, const Mod &M, const Mods &... Ms)
initializer< Ty > init(const Ty &Val)
@ OF_TextWithCRLF
The file should be opened in text mode and use a carriage linefeed '\r '.
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
PBQP::RegAlloc::PBQPRAGraph PBQPRAGraph
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI FunctionPass * createDefaultPBQPRegisterAllocator()
PBQPRegisterAllocation Pass - This pass implements the Partitioned Boolean Quadratic Prograaming (PBQ...
FunctionPass * createPBQPRegisterAllocator(char *customPassID=nullptr)
Create a PBQP register allocator instance.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Spiller * createInlineSpiller(const Spiller::RequiredAnalyses &Analyses, MachineFunction &MF, VirtRegMap &VRM, VirtRegAuxInfo &VRAI, LiveRegMatrix *Matrix=nullptr)
Create and return a spiller that will insert spill code directly instead of deferring though VirtRegM...
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.