1dff0c46cSDimitry Andric //===-- RegAllocBasic.cpp - Basic Register Allocator ----------------------===//
22754fe60SDimitry Andric //
32754fe60SDimitry Andric //                     The LLVM Compiler Infrastructure
42754fe60SDimitry Andric //
52754fe60SDimitry Andric // This file is distributed under the University of Illinois Open Source
62754fe60SDimitry Andric // License. See LICENSE.TXT for details.
72754fe60SDimitry Andric //
82754fe60SDimitry Andric //===----------------------------------------------------------------------===//
92754fe60SDimitry Andric //
102754fe60SDimitry Andric // This file defines the RABasic function pass, which provides a minimal
112754fe60SDimitry Andric // implementation of the basic register allocator.
122754fe60SDimitry Andric //
132754fe60SDimitry Andric //===----------------------------------------------------------------------===//
142754fe60SDimitry Andric 
157ae0e2c9SDimitry Andric #include "AllocationOrder.h"
163b0f4066SDimitry Andric #include "LiveDebugVariables.h"
17139f7f9bSDimitry Andric #include "RegAllocBase.h"
182754fe60SDimitry Andric #include "Spiller.h"
192754fe60SDimitry Andric #include "llvm/Analysis/AliasAnalysis.h"
202754fe60SDimitry Andric #include "llvm/CodeGen/CalcSpillWeights.h"
212cab237bSDimitry Andric #include "llvm/CodeGen/LiveIntervals.h"
22dff0c46cSDimitry Andric #include "llvm/CodeGen/LiveRangeEdit.h"
23139f7f9bSDimitry Andric #include "llvm/CodeGen/LiveRegMatrix.h"
24da09e106SDimitry Andric #include "llvm/CodeGen/LiveStacks.h"
25f785676fSDimitry Andric #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
262754fe60SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
272754fe60SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
282754fe60SDimitry Andric #include "llvm/CodeGen/MachineLoopInfo.h"
292754fe60SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
30db17bf38SDimitry Andric #include "llvm/CodeGen/Passes.h"
312754fe60SDimitry Andric #include "llvm/CodeGen/RegAllocRegistry.h"
322cab237bSDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
33139f7f9bSDimitry Andric #include "llvm/CodeGen/VirtRegMap.h"
34139f7f9bSDimitry Andric #include "llvm/PassAnalysisSupport.h"
352754fe60SDimitry Andric #include "llvm/Support/Debug.h"
362754fe60SDimitry Andric #include "llvm/Support/raw_ostream.h"
372754fe60SDimitry Andric #include <cstdlib>
38dd6029ffSDimitry Andric #include <queue>
392754fe60SDimitry Andric 
402754fe60SDimitry Andric using namespace llvm;
412754fe60SDimitry Andric 
4291bc56edSDimitry Andric #define DEBUG_TYPE "regalloc"
4391bc56edSDimitry Andric 
442754fe60SDimitry Andric static RegisterRegAlloc basicRegAlloc("basic", "basic register allocator",
452754fe60SDimitry Andric                                       createBasicRegisterAllocator);
462754fe60SDimitry Andric 
472754fe60SDimitry Andric namespace {
48dd6029ffSDimitry Andric   struct CompSpillWeight {
operator ()__anona346d7640111::CompSpillWeight49dd6029ffSDimitry Andric     bool operator()(LiveInterval *A, LiveInterval *B) const {
50dd6029ffSDimitry Andric       return A->weight < B->weight;
51dd6029ffSDimitry Andric     }
52dd6029ffSDimitry Andric   };
53dd6029ffSDimitry Andric }
54dd6029ffSDimitry Andric 
55dd6029ffSDimitry Andric namespace {
562754fe60SDimitry Andric /// RABasic provides a minimal implementation of the basic register allocation
572754fe60SDimitry Andric /// algorithm. It prioritizes live virtual registers by spill weight and spills
582754fe60SDimitry Andric /// whenever a register is unavailable. This is not practical in production but
592754fe60SDimitry Andric /// provides a useful baseline both for measuring other allocators and comparing
602754fe60SDimitry Andric /// the speed of the basic algorithm against other styles of allocators.
616d97bb29SDimitry Andric class RABasic : public MachineFunctionPass,
626d97bb29SDimitry Andric                 public RegAllocBase,
636d97bb29SDimitry Andric                 private LiveRangeEdit::Delegate {
642754fe60SDimitry Andric   // context
652754fe60SDimitry Andric   MachineFunction *MF;
662754fe60SDimitry Andric 
672754fe60SDimitry Andric   // state
6891bc56edSDimitry Andric   std::unique_ptr<Spiller> SpillerInstance;
69dd6029ffSDimitry Andric   std::priority_queue<LiveInterval*, std::vector<LiveInterval*>,
70dd6029ffSDimitry Andric                       CompSpillWeight> Queue;
71dff0c46cSDimitry Andric 
72dff0c46cSDimitry Andric   // Scratch space.  Allocated here to avoid repeated malloc calls in
73dff0c46cSDimitry Andric   // selectOrSplit().
74dff0c46cSDimitry Andric   BitVector UsableRegs;
75dff0c46cSDimitry Andric 
766d97bb29SDimitry Andric   bool LRE_CanEraseVirtReg(unsigned) override;
776d97bb29SDimitry Andric   void LRE_WillShrinkVirtReg(unsigned) override;
786d97bb29SDimitry Andric 
792754fe60SDimitry Andric public:
802754fe60SDimitry Andric   RABasic();
812754fe60SDimitry Andric 
822754fe60SDimitry Andric   /// Return the pass name.
getPassName() const83d88c1a5aSDimitry Andric   StringRef getPassName() const override { return "Basic Register Allocator"; }
842754fe60SDimitry Andric 
852754fe60SDimitry Andric   /// RABasic analysis usage.
8691bc56edSDimitry Andric   void getAnalysisUsage(AnalysisUsage &AU) const override;
872754fe60SDimitry Andric 
8891bc56edSDimitry Andric   void releaseMemory() override;
892754fe60SDimitry Andric 
spiller()9091bc56edSDimitry Andric   Spiller &spiller() override { return *SpillerInstance; }
912754fe60SDimitry Andric 
enqueue(LiveInterval * LI)9291bc56edSDimitry Andric   void enqueue(LiveInterval *LI) override {
93dd6029ffSDimitry Andric     Queue.push(LI);
94dd6029ffSDimitry Andric   }
95dd6029ffSDimitry Andric 
dequeue()9691bc56edSDimitry Andric   LiveInterval *dequeue() override {
97dd6029ffSDimitry Andric     if (Queue.empty())
9891bc56edSDimitry Andric       return nullptr;
99dd6029ffSDimitry Andric     LiveInterval *LI = Queue.top();
100dd6029ffSDimitry Andric     Queue.pop();
101dd6029ffSDimitry Andric     return LI;
102dd6029ffSDimitry Andric   }
103dd6029ffSDimitry Andric 
10491bc56edSDimitry Andric   unsigned selectOrSplit(LiveInterval &VirtReg,
10591bc56edSDimitry Andric                          SmallVectorImpl<unsigned> &SplitVRegs) override;
1062754fe60SDimitry Andric 
1072754fe60SDimitry Andric   /// Perform register allocation.
10891bc56edSDimitry Andric   bool runOnMachineFunction(MachineFunction &mf) override;
1092754fe60SDimitry Andric 
getRequiredProperties() const110d88c1a5aSDimitry Andric   MachineFunctionProperties getRequiredProperties() const override {
111d88c1a5aSDimitry Andric     return MachineFunctionProperties().set(
112d88c1a5aSDimitry Andric         MachineFunctionProperties::Property::NoPHIs);
113d88c1a5aSDimitry Andric   }
114d88c1a5aSDimitry Andric 
115dff0c46cSDimitry Andric   // Helper for spilling all live virtual registers currently unified under preg
116dff0c46cSDimitry Andric   // that interfere with the most recently queried lvr.  Return true if spilling
117dff0c46cSDimitry Andric   // was successful, and append any new spilled/split intervals to splitLVRs.
118dff0c46cSDimitry Andric   bool spillInterferences(LiveInterval &VirtReg, unsigned PhysReg,
119f785676fSDimitry Andric                           SmallVectorImpl<unsigned> &SplitVRegs);
120dff0c46cSDimitry Andric 
1212754fe60SDimitry Andric   static char ID;
1222754fe60SDimitry Andric };
1232754fe60SDimitry Andric 
1242754fe60SDimitry Andric char RABasic::ID = 0;
1252754fe60SDimitry Andric 
1262754fe60SDimitry Andric } // end anonymous namespace
1272754fe60SDimitry Andric 
1286d97bb29SDimitry Andric char &llvm::RABasicID = RABasic::ID;
1296d97bb29SDimitry Andric 
1306d97bb29SDimitry Andric INITIALIZE_PASS_BEGIN(RABasic, "regallocbasic", "Basic Register Allocator",
1316d97bb29SDimitry Andric                       false, false)
INITIALIZE_PASS_DEPENDENCY(LiveDebugVariables)1326d97bb29SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LiveDebugVariables)
1336d97bb29SDimitry Andric INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
1346d97bb29SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
1356d97bb29SDimitry Andric INITIALIZE_PASS_DEPENDENCY(RegisterCoalescer)
1366d97bb29SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineScheduler)
1376d97bb29SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LiveStacks)
1386d97bb29SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
1396d97bb29SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
1406d97bb29SDimitry Andric INITIALIZE_PASS_DEPENDENCY(VirtRegMap)
1416d97bb29SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LiveRegMatrix)
1426d97bb29SDimitry Andric INITIALIZE_PASS_END(RABasic, "regallocbasic", "Basic Register Allocator", false,
1436d97bb29SDimitry Andric                     false)
1446d97bb29SDimitry Andric 
1456d97bb29SDimitry Andric bool RABasic::LRE_CanEraseVirtReg(unsigned VirtReg) {
1466d97bb29SDimitry Andric   LiveInterval &LI = LIS->getInterval(VirtReg);
1472cab237bSDimitry Andric   if (VRM->hasPhys(VirtReg)) {
1486d97bb29SDimitry Andric     Matrix->unassign(LI);
1496d97bb29SDimitry Andric     aboutToRemoveInterval(LI);
1506d97bb29SDimitry Andric     return true;
1516d97bb29SDimitry Andric   }
1526d97bb29SDimitry Andric   // Unassigned virtreg is probably in the priority queue.
1536d97bb29SDimitry Andric   // RegAllocBase will erase it after dequeueing.
1542cab237bSDimitry Andric   // Nonetheless, clear the live-range so that the debug
1552cab237bSDimitry Andric   // dump will show the right state for that VirtReg.
1562cab237bSDimitry Andric   LI.clear();
1576d97bb29SDimitry Andric   return false;
1586d97bb29SDimitry Andric }
1596d97bb29SDimitry Andric 
LRE_WillShrinkVirtReg(unsigned VirtReg)1606d97bb29SDimitry Andric void RABasic::LRE_WillShrinkVirtReg(unsigned VirtReg) {
1616d97bb29SDimitry Andric   if (!VRM->hasPhys(VirtReg))
1626d97bb29SDimitry Andric     return;
1636d97bb29SDimitry Andric 
1646d97bb29SDimitry Andric   // Register is assigned, put it back on the queue for reassignment.
1656d97bb29SDimitry Andric   LiveInterval &LI = LIS->getInterval(VirtReg);
1666d97bb29SDimitry Andric   Matrix->unassign(LI);
1676d97bb29SDimitry Andric   enqueue(&LI);
1686d97bb29SDimitry Andric }
1696d97bb29SDimitry Andric 
RABasic()1702754fe60SDimitry Andric RABasic::RABasic(): MachineFunctionPass(ID) {
1712754fe60SDimitry Andric }
1722754fe60SDimitry Andric 
getAnalysisUsage(AnalysisUsage & AU) const1732754fe60SDimitry Andric void RABasic::getAnalysisUsage(AnalysisUsage &AU) const {
1742754fe60SDimitry Andric   AU.setPreservesCFG();
1757d523365SDimitry Andric   AU.addRequired<AAResultsWrapperPass>();
1767d523365SDimitry Andric   AU.addPreserved<AAResultsWrapperPass>();
1772754fe60SDimitry Andric   AU.addRequired<LiveIntervals>();
1787ae0e2c9SDimitry Andric   AU.addPreserved<LiveIntervals>();
1792754fe60SDimitry Andric   AU.addPreserved<SlotIndexes>();
1803b0f4066SDimitry Andric   AU.addRequired<LiveDebugVariables>();
1813b0f4066SDimitry Andric   AU.addPreserved<LiveDebugVariables>();
1822754fe60SDimitry Andric   AU.addRequired<LiveStacks>();
1832754fe60SDimitry Andric   AU.addPreserved<LiveStacks>();
184f785676fSDimitry Andric   AU.addRequired<MachineBlockFrequencyInfo>();
185f785676fSDimitry Andric   AU.addPreserved<MachineBlockFrequencyInfo>();
1862754fe60SDimitry Andric   AU.addRequiredID(MachineDominatorsID);
1872754fe60SDimitry Andric   AU.addPreservedID(MachineDominatorsID);
1882754fe60SDimitry Andric   AU.addRequired<MachineLoopInfo>();
1892754fe60SDimitry Andric   AU.addPreserved<MachineLoopInfo>();
1902754fe60SDimitry Andric   AU.addRequired<VirtRegMap>();
1912754fe60SDimitry Andric   AU.addPreserved<VirtRegMap>();
1927ae0e2c9SDimitry Andric   AU.addRequired<LiveRegMatrix>();
1937ae0e2c9SDimitry Andric   AU.addPreserved<LiveRegMatrix>();
1942754fe60SDimitry Andric   MachineFunctionPass::getAnalysisUsage(AU);
1952754fe60SDimitry Andric }
1962754fe60SDimitry Andric 
releaseMemory()1972754fe60SDimitry Andric void RABasic::releaseMemory() {
19891bc56edSDimitry Andric   SpillerInstance.reset();
1992754fe60SDimitry Andric }
2002754fe60SDimitry Andric 
2012754fe60SDimitry Andric 
2022754fe60SDimitry Andric // Spill or split all live virtual registers currently unified under PhysReg
2032754fe60SDimitry Andric // that interfere with VirtReg. The newly spilled or split live intervals are
2042754fe60SDimitry Andric // returned by appending them to SplitVRegs.
spillInterferences(LiveInterval & VirtReg,unsigned PhysReg,SmallVectorImpl<unsigned> & SplitVRegs)205dff0c46cSDimitry Andric bool RABasic::spillInterferences(LiveInterval &VirtReg, unsigned PhysReg,
206f785676fSDimitry Andric                                  SmallVectorImpl<unsigned> &SplitVRegs) {
2072754fe60SDimitry Andric   // Record each interference and determine if all are spillable before mutating
2082754fe60SDimitry Andric   // either the union or live intervals.
2097ae0e2c9SDimitry Andric   SmallVector<LiveInterval*, 8> Intfs;
2107ae0e2c9SDimitry Andric 
2112754fe60SDimitry Andric   // Collect interferences assigned to any alias of the physical register.
2127ae0e2c9SDimitry Andric   for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
2137ae0e2c9SDimitry Andric     LiveIntervalUnion::Query &Q = Matrix->query(VirtReg, *Units);
2147ae0e2c9SDimitry Andric     Q.collectInterferingVRegs();
2157ae0e2c9SDimitry Andric     for (unsigned i = Q.interferingVRegs().size(); i; --i) {
2167ae0e2c9SDimitry Andric       LiveInterval *Intf = Q.interferingVRegs()[i - 1];
2177ae0e2c9SDimitry Andric       if (!Intf->isSpillable() || Intf->weight > VirtReg.weight)
2187ae0e2c9SDimitry Andric         return false;
2197ae0e2c9SDimitry Andric       Intfs.push_back(Intf);
2202754fe60SDimitry Andric     }
2212754fe60SDimitry Andric   }
222*4ba319b5SDimitry Andric   LLVM_DEBUG(dbgs() << "spilling " << printReg(PhysReg, TRI)
2232cab237bSDimitry Andric                     << " interferences with " << VirtReg << "\n");
2247ae0e2c9SDimitry Andric   assert(!Intfs.empty() && "expected interference");
2252754fe60SDimitry Andric 
2262754fe60SDimitry Andric   // Spill each interfering vreg allocated to PhysReg or an alias.
2277ae0e2c9SDimitry Andric   for (unsigned i = 0, e = Intfs.size(); i != e; ++i) {
2287ae0e2c9SDimitry Andric     LiveInterval &Spill = *Intfs[i];
2297ae0e2c9SDimitry Andric 
2307ae0e2c9SDimitry Andric     // Skip duplicates.
2317ae0e2c9SDimitry Andric     if (!VRM->hasPhys(Spill.reg))
2327ae0e2c9SDimitry Andric       continue;
2337ae0e2c9SDimitry Andric 
2347ae0e2c9SDimitry Andric     // Deallocate the interfering vreg by removing it from the union.
2357ae0e2c9SDimitry Andric     // A LiveInterval instance may not be in a union during modification!
2367ae0e2c9SDimitry Andric     Matrix->unassign(Spill);
2377ae0e2c9SDimitry Andric 
2387ae0e2c9SDimitry Andric     // Spill the extracted interval.
2396d97bb29SDimitry Andric     LiveRangeEdit LRE(&Spill, SplitVRegs, *MF, *LIS, VRM, this, &DeadRemats);
2407ae0e2c9SDimitry Andric     spiller().spill(LRE);
2417ae0e2c9SDimitry Andric   }
2422754fe60SDimitry Andric   return true;
2432754fe60SDimitry Andric }
2442754fe60SDimitry Andric 
2452754fe60SDimitry Andric // Driver for the register assignment and splitting heuristics.
2462754fe60SDimitry Andric // Manages iteration over the LiveIntervalUnions.
2472754fe60SDimitry Andric //
2482754fe60SDimitry Andric // This is a minimal implementation of register assignment and splitting that
2492754fe60SDimitry Andric // spills whenever we run out of registers.
2502754fe60SDimitry Andric //
2512754fe60SDimitry Andric // selectOrSplit can only be called once per live virtual register. We then do a
2522754fe60SDimitry Andric // single interference test for each register the correct class until we find an
2532754fe60SDimitry Andric // available register. So, the number of interference tests in the worst case is
2542754fe60SDimitry Andric // |vregs| * |machineregs|. And since the number of interference tests is
2552754fe60SDimitry Andric // minimal, there is no value in caching them outside the scope of
2562754fe60SDimitry Andric // selectOrSplit().
selectOrSplit(LiveInterval & VirtReg,SmallVectorImpl<unsigned> & SplitVRegs)2572754fe60SDimitry Andric unsigned RABasic::selectOrSplit(LiveInterval &VirtReg,
258f785676fSDimitry Andric                                 SmallVectorImpl<unsigned> &SplitVRegs) {
2592754fe60SDimitry Andric   // Populate a list of physical register spill candidates.
2602754fe60SDimitry Andric   SmallVector<unsigned, 8> PhysRegSpillCands;
2612754fe60SDimitry Andric 
2622754fe60SDimitry Andric   // Check for an available register in this class.
2637d523365SDimitry Andric   AllocationOrder Order(VirtReg.reg, *VRM, RegClassInfo, Matrix);
2647ae0e2c9SDimitry Andric   while (unsigned PhysReg = Order.next()) {
2657ae0e2c9SDimitry Andric     // Check for interference in PhysReg
2667ae0e2c9SDimitry Andric     switch (Matrix->checkInterference(VirtReg, PhysReg)) {
2677ae0e2c9SDimitry Andric     case LiveRegMatrix::IK_Free:
2687ae0e2c9SDimitry Andric       // PhysReg is available, allocate it.
2697ae0e2c9SDimitry Andric       return PhysReg;
2702754fe60SDimitry Andric 
2717ae0e2c9SDimitry Andric     case LiveRegMatrix::IK_VirtReg:
2727ae0e2c9SDimitry Andric       // Only virtual registers in the way, we may be able to spill them.
2737ae0e2c9SDimitry Andric       PhysRegSpillCands.push_back(PhysReg);
274dff0c46cSDimitry Andric       continue;
275dff0c46cSDimitry Andric 
2767ae0e2c9SDimitry Andric     default:
2777ae0e2c9SDimitry Andric       // RegMask or RegUnit interference.
2787ae0e2c9SDimitry Andric       continue;
2792754fe60SDimitry Andric     }
2807ae0e2c9SDimitry Andric   }
2812754fe60SDimitry Andric 
2822754fe60SDimitry Andric   // Try to spill another interfering reg with less spill weight.
2832754fe60SDimitry Andric   for (SmallVectorImpl<unsigned>::iterator PhysRegI = PhysRegSpillCands.begin(),
2842754fe60SDimitry Andric        PhysRegE = PhysRegSpillCands.end(); PhysRegI != PhysRegE; ++PhysRegI) {
2857ae0e2c9SDimitry Andric     if (!spillInterferences(VirtReg, *PhysRegI, SplitVRegs))
2867ae0e2c9SDimitry Andric       continue;
2872754fe60SDimitry Andric 
2887ae0e2c9SDimitry Andric     assert(!Matrix->checkInterference(VirtReg, *PhysRegI) &&
2892754fe60SDimitry Andric            "Interference after spill.");
2902754fe60SDimitry Andric     // Tell the caller to allocate to this newly freed physical register.
2912754fe60SDimitry Andric     return *PhysRegI;
2922754fe60SDimitry Andric   }
293bd5abe19SDimitry Andric 
2942754fe60SDimitry Andric   // No other spill candidates were found, so spill the current VirtReg.
295*4ba319b5SDimitry Andric   LLVM_DEBUG(dbgs() << "spilling: " << VirtReg << '\n');
296bd5abe19SDimitry Andric   if (!VirtReg.isSpillable())
297bd5abe19SDimitry Andric     return ~0u;
2986d97bb29SDimitry Andric   LiveRangeEdit LRE(&VirtReg, SplitVRegs, *MF, *LIS, VRM, this, &DeadRemats);
2993b0f4066SDimitry Andric   spiller().spill(LRE);
3002754fe60SDimitry Andric 
3012754fe60SDimitry Andric   // The live virtual register requesting allocation was spilled, so tell
3022754fe60SDimitry Andric   // the caller not to allocate anything during this round.
3032754fe60SDimitry Andric   return 0;
3042754fe60SDimitry Andric }
3052754fe60SDimitry Andric 
runOnMachineFunction(MachineFunction & mf)3062754fe60SDimitry Andric bool RABasic::runOnMachineFunction(MachineFunction &mf) {
307*4ba319b5SDimitry Andric   LLVM_DEBUG(dbgs() << "********** BASIC REGISTER ALLOCATION **********\n"
308*4ba319b5SDimitry Andric                     << "********** Function: " << mf.getName() << '\n');
3092754fe60SDimitry Andric 
3102754fe60SDimitry Andric   MF = &mf;
3117ae0e2c9SDimitry Andric   RegAllocBase::init(getAnalysis<VirtRegMap>(),
3127ae0e2c9SDimitry Andric                      getAnalysis<LiveIntervals>(),
3137ae0e2c9SDimitry Andric                      getAnalysis<LiveRegMatrix>());
314f785676fSDimitry Andric 
3157d523365SDimitry Andric   calculateSpillWeightsAndHints(*LIS, *MF, VRM,
316f785676fSDimitry Andric                                 getAnalysis<MachineLoopInfo>(),
317f785676fSDimitry Andric                                 getAnalysis<MachineBlockFrequencyInfo>());
318f785676fSDimitry Andric 
3193b0f4066SDimitry Andric   SpillerInstance.reset(createInlineSpiller(*this, *MF, *VRM));
3202754fe60SDimitry Andric 
3212754fe60SDimitry Andric   allocatePhysRegs();
3223ca95b02SDimitry Andric   postOptimization();
3232754fe60SDimitry Andric 
3242754fe60SDimitry Andric   // Diagnostic output before rewriting
325*4ba319b5SDimitry Andric   LLVM_DEBUG(dbgs() << "Post alloc VirtRegMap:\n" << *VRM << "\n");
3262754fe60SDimitry Andric 
3272754fe60SDimitry Andric   releaseMemory();
3282754fe60SDimitry Andric   return true;
3292754fe60SDimitry Andric }
3302754fe60SDimitry Andric 
createBasicRegisterAllocator()3312754fe60SDimitry Andric FunctionPass* llvm::createBasicRegisterAllocator()
3322754fe60SDimitry Andric {
3332754fe60SDimitry Andric   return new RABasic();
3342754fe60SDimitry Andric }
335