xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/RegAllocBasic.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===-- RegAllocBasic.cpp - Basic Register Allocator ----------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file defines the RABasic function pass, which provides a minimal
100b57cec5SDimitry Andric // implementation of the basic register allocator.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "AllocationOrder.h"
150b57cec5SDimitry Andric #include "RegAllocBase.h"
160b57cec5SDimitry Andric #include "llvm/Analysis/AliasAnalysis.h"
170b57cec5SDimitry Andric #include "llvm/CodeGen/CalcSpillWeights.h"
18*0fca6ea1SDimitry Andric #include "llvm/CodeGen/LiveDebugVariables.h"
190b57cec5SDimitry Andric #include "llvm/CodeGen/LiveIntervals.h"
200b57cec5SDimitry Andric #include "llvm/CodeGen/LiveRangeEdit.h"
210b57cec5SDimitry Andric #include "llvm/CodeGen/LiveRegMatrix.h"
220b57cec5SDimitry Andric #include "llvm/CodeGen/LiveStacks.h"
230b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
240b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
250b57cec5SDimitry Andric #include "llvm/CodeGen/MachineLoopInfo.h"
260b57cec5SDimitry Andric #include "llvm/CodeGen/Passes.h"
270b57cec5SDimitry Andric #include "llvm/CodeGen/RegAllocRegistry.h"
285ffd83dbSDimitry Andric #include "llvm/CodeGen/Spiller.h"
290b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
300b57cec5SDimitry Andric #include "llvm/CodeGen/VirtRegMap.h"
315ffd83dbSDimitry Andric #include "llvm/Pass.h"
320b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
330b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
340b57cec5SDimitry Andric #include <queue>
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric using namespace llvm;
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric #define DEBUG_TYPE "regalloc"
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric static RegisterRegAlloc basicRegAlloc("basic", "basic register allocator",
410b57cec5SDimitry Andric                                       createBasicRegisterAllocator);
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric namespace {
440b57cec5SDimitry Andric   struct CompSpillWeight {
4581ad6265SDimitry Andric     bool operator()(const LiveInterval *A, const LiveInterval *B) const {
46e8d8bef9SDimitry Andric       return A->weight() < B->weight();
470b57cec5SDimitry Andric     }
480b57cec5SDimitry Andric   };
490b57cec5SDimitry Andric }
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric namespace {
520b57cec5SDimitry Andric /// RABasic provides a minimal implementation of the basic register allocation
530b57cec5SDimitry Andric /// algorithm. It prioritizes live virtual registers by spill weight and spills
540b57cec5SDimitry Andric /// whenever a register is unavailable. This is not practical in production but
550b57cec5SDimitry Andric /// provides a useful baseline both for measuring other allocators and comparing
560b57cec5SDimitry Andric /// the speed of the basic algorithm against other styles of allocators.
570b57cec5SDimitry Andric class RABasic : public MachineFunctionPass,
580b57cec5SDimitry Andric                 public RegAllocBase,
590b57cec5SDimitry Andric                 private LiveRangeEdit::Delegate {
600b57cec5SDimitry Andric   // context
6106c3fb27SDimitry Andric   MachineFunction *MF = nullptr;
620b57cec5SDimitry Andric 
630b57cec5SDimitry Andric   // state
640b57cec5SDimitry Andric   std::unique_ptr<Spiller> SpillerInstance;
6581ad6265SDimitry Andric   std::priority_queue<const LiveInterval *, std::vector<const LiveInterval *>,
6681ad6265SDimitry Andric                       CompSpillWeight>
6781ad6265SDimitry Andric       Queue;
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric   // Scratch space.  Allocated here to avoid repeated malloc calls in
700b57cec5SDimitry Andric   // selectOrSplit().
710b57cec5SDimitry Andric   BitVector UsableRegs;
720b57cec5SDimitry Andric 
73e8d8bef9SDimitry Andric   bool LRE_CanEraseVirtReg(Register) override;
74e8d8bef9SDimitry Andric   void LRE_WillShrinkVirtReg(Register) override;
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric public:
77*0fca6ea1SDimitry Andric   RABasic(const RegAllocFilterFunc F = nullptr);
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric   /// Return the pass name.
800b57cec5SDimitry Andric   StringRef getPassName() const override { return "Basic Register Allocator"; }
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric   /// RABasic analysis usage.
830b57cec5SDimitry Andric   void getAnalysisUsage(AnalysisUsage &AU) const override;
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric   void releaseMemory() override;
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric   Spiller &spiller() override { return *SpillerInstance; }
880b57cec5SDimitry Andric 
8981ad6265SDimitry Andric   void enqueueImpl(const LiveInterval *LI) override { Queue.push(LI); }
900b57cec5SDimitry Andric 
9181ad6265SDimitry Andric   const LiveInterval *dequeue() override {
920b57cec5SDimitry Andric     if (Queue.empty())
930b57cec5SDimitry Andric       return nullptr;
9481ad6265SDimitry Andric     const LiveInterval *LI = Queue.top();
950b57cec5SDimitry Andric     Queue.pop();
960b57cec5SDimitry Andric     return LI;
970b57cec5SDimitry Andric   }
980b57cec5SDimitry Andric 
9981ad6265SDimitry Andric   MCRegister selectOrSplit(const LiveInterval &VirtReg,
1005ffd83dbSDimitry Andric                            SmallVectorImpl<Register> &SplitVRegs) override;
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric   /// Perform register allocation.
1030b57cec5SDimitry Andric   bool runOnMachineFunction(MachineFunction &mf) override;
1040b57cec5SDimitry Andric 
1050b57cec5SDimitry Andric   MachineFunctionProperties getRequiredProperties() const override {
1060b57cec5SDimitry Andric     return MachineFunctionProperties().set(
1070b57cec5SDimitry Andric         MachineFunctionProperties::Property::NoPHIs);
1080b57cec5SDimitry Andric   }
1090b57cec5SDimitry Andric 
110e8d8bef9SDimitry Andric   MachineFunctionProperties getClearedProperties() const override {
111e8d8bef9SDimitry Andric     return MachineFunctionProperties().set(
112e8d8bef9SDimitry Andric       MachineFunctionProperties::Property::IsSSA);
113e8d8bef9SDimitry Andric   }
114e8d8bef9SDimitry Andric 
1150b57cec5SDimitry Andric   // Helper for spilling all live virtual registers currently unified under preg
1160b57cec5SDimitry Andric   // that interfere with the most recently queried lvr.  Return true if spilling
1170b57cec5SDimitry Andric   // was successful, and append any new spilled/split intervals to splitLVRs.
11881ad6265SDimitry Andric   bool spillInterferences(const LiveInterval &VirtReg, MCRegister PhysReg,
1195ffd83dbSDimitry Andric                           SmallVectorImpl<Register> &SplitVRegs);
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric   static char ID;
1220b57cec5SDimitry Andric };
1230b57cec5SDimitry Andric 
1240b57cec5SDimitry Andric char RABasic::ID = 0;
1250b57cec5SDimitry Andric 
1260b57cec5SDimitry Andric } // end anonymous namespace
1270b57cec5SDimitry Andric 
1280b57cec5SDimitry Andric char &llvm::RABasicID = RABasic::ID;
1290b57cec5SDimitry Andric 
1300b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(RABasic, "regallocbasic", "Basic Register Allocator",
1310b57cec5SDimitry Andric                       false, false)
1320b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LiveDebugVariables)
133*0fca6ea1SDimitry Andric INITIALIZE_PASS_DEPENDENCY(SlotIndexesWrapperPass)
134*0fca6ea1SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
1350b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(RegisterCoalescer)
1360b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineScheduler)
1370b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LiveStacks)
138fcaf7f86SDimitry Andric INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
139*0fca6ea1SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
140*0fca6ea1SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass)
1410b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(VirtRegMap)
1420b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LiveRegMatrix)
1430b57cec5SDimitry Andric INITIALIZE_PASS_END(RABasic, "regallocbasic", "Basic Register Allocator", false,
1440b57cec5SDimitry Andric                     false)
1450b57cec5SDimitry Andric 
146e8d8bef9SDimitry Andric bool RABasic::LRE_CanEraseVirtReg(Register VirtReg) {
1470b57cec5SDimitry Andric   LiveInterval &LI = LIS->getInterval(VirtReg);
1480b57cec5SDimitry Andric   if (VRM->hasPhys(VirtReg)) {
1490b57cec5SDimitry Andric     Matrix->unassign(LI);
1500b57cec5SDimitry Andric     aboutToRemoveInterval(LI);
1510b57cec5SDimitry Andric     return true;
1520b57cec5SDimitry Andric   }
1530b57cec5SDimitry Andric   // Unassigned virtreg is probably in the priority queue.
1540b57cec5SDimitry Andric   // RegAllocBase will erase it after dequeueing.
1550b57cec5SDimitry Andric   // Nonetheless, clear the live-range so that the debug
1560b57cec5SDimitry Andric   // dump will show the right state for that VirtReg.
1570b57cec5SDimitry Andric   LI.clear();
1580b57cec5SDimitry Andric   return false;
1590b57cec5SDimitry Andric }
1600b57cec5SDimitry Andric 
161e8d8bef9SDimitry Andric void RABasic::LRE_WillShrinkVirtReg(Register VirtReg) {
1620b57cec5SDimitry Andric   if (!VRM->hasPhys(VirtReg))
1630b57cec5SDimitry Andric     return;
1640b57cec5SDimitry Andric 
1650b57cec5SDimitry Andric   // Register is assigned, put it back on the queue for reassignment.
1660b57cec5SDimitry Andric   LiveInterval &LI = LIS->getInterval(VirtReg);
1670b57cec5SDimitry Andric   Matrix->unassign(LI);
1680b57cec5SDimitry Andric   enqueue(&LI);
1690b57cec5SDimitry Andric }
1700b57cec5SDimitry Andric 
171*0fca6ea1SDimitry Andric RABasic::RABasic(RegAllocFilterFunc F)
172*0fca6ea1SDimitry Andric     : MachineFunctionPass(ID), RegAllocBase(F) {}
1730b57cec5SDimitry Andric 
1740b57cec5SDimitry Andric void RABasic::getAnalysisUsage(AnalysisUsage &AU) const {
1750b57cec5SDimitry Andric   AU.setPreservesCFG();
1760b57cec5SDimitry Andric   AU.addRequired<AAResultsWrapperPass>();
1770b57cec5SDimitry Andric   AU.addPreserved<AAResultsWrapperPass>();
178*0fca6ea1SDimitry Andric   AU.addRequired<LiveIntervalsWrapperPass>();
179*0fca6ea1SDimitry Andric   AU.addPreserved<LiveIntervalsWrapperPass>();
180*0fca6ea1SDimitry Andric   AU.addPreserved<SlotIndexesWrapperPass>();
1810b57cec5SDimitry Andric   AU.addRequired<LiveDebugVariables>();
1820b57cec5SDimitry Andric   AU.addPreserved<LiveDebugVariables>();
1830b57cec5SDimitry Andric   AU.addRequired<LiveStacks>();
1840b57cec5SDimitry Andric   AU.addPreserved<LiveStacks>();
185*0fca6ea1SDimitry Andric   AU.addRequired<MachineBlockFrequencyInfoWrapperPass>();
186*0fca6ea1SDimitry Andric   AU.addPreserved<MachineBlockFrequencyInfoWrapperPass>();
1870b57cec5SDimitry Andric   AU.addRequiredID(MachineDominatorsID);
1880b57cec5SDimitry Andric   AU.addPreservedID(MachineDominatorsID);
189*0fca6ea1SDimitry Andric   AU.addRequired<MachineLoopInfoWrapperPass>();
190*0fca6ea1SDimitry Andric   AU.addPreserved<MachineLoopInfoWrapperPass>();
1910b57cec5SDimitry Andric   AU.addRequired<VirtRegMap>();
1920b57cec5SDimitry Andric   AU.addPreserved<VirtRegMap>();
1930b57cec5SDimitry Andric   AU.addRequired<LiveRegMatrix>();
1940b57cec5SDimitry Andric   AU.addPreserved<LiveRegMatrix>();
1950b57cec5SDimitry Andric   MachineFunctionPass::getAnalysisUsage(AU);
1960b57cec5SDimitry Andric }
1970b57cec5SDimitry Andric 
1980b57cec5SDimitry Andric void RABasic::releaseMemory() {
1990b57cec5SDimitry Andric   SpillerInstance.reset();
2000b57cec5SDimitry Andric }
2010b57cec5SDimitry Andric 
2020b57cec5SDimitry Andric 
2030b57cec5SDimitry Andric // Spill or split all live virtual registers currently unified under PhysReg
2040b57cec5SDimitry Andric // that interfere with VirtReg. The newly spilled or split live intervals are
2050b57cec5SDimitry Andric // returned by appending them to SplitVRegs.
20681ad6265SDimitry Andric bool RABasic::spillInterferences(const LiveInterval &VirtReg,
20781ad6265SDimitry Andric                                  MCRegister PhysReg,
2085ffd83dbSDimitry Andric                                  SmallVectorImpl<Register> &SplitVRegs) {
2090b57cec5SDimitry Andric   // Record each interference and determine if all are spillable before mutating
2100b57cec5SDimitry Andric   // either the union or live intervals.
21181ad6265SDimitry Andric   SmallVector<const LiveInterval *, 8> Intfs;
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric   // Collect interferences assigned to any alias of the physical register.
21406c3fb27SDimitry Andric   for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
21506c3fb27SDimitry Andric     LiveIntervalUnion::Query &Q = Matrix->query(VirtReg, Unit);
21681ad6265SDimitry Andric     for (const auto *Intf : reverse(Q.interferingVRegs())) {
217e8d8bef9SDimitry Andric       if (!Intf->isSpillable() || Intf->weight() > VirtReg.weight())
2180b57cec5SDimitry Andric         return false;
2190b57cec5SDimitry Andric       Intfs.push_back(Intf);
2200b57cec5SDimitry Andric     }
2210b57cec5SDimitry Andric   }
2220b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "spilling " << printReg(PhysReg, TRI)
2230b57cec5SDimitry Andric                     << " interferences with " << VirtReg << "\n");
2240b57cec5SDimitry Andric   assert(!Intfs.empty() && "expected interference");
2250b57cec5SDimitry Andric 
2260b57cec5SDimitry Andric   // Spill each interfering vreg allocated to PhysReg or an alias.
227*0fca6ea1SDimitry Andric   for (const LiveInterval *Spill : Intfs) {
2280b57cec5SDimitry Andric     // Skip duplicates.
229*0fca6ea1SDimitry Andric     if (!VRM->hasPhys(Spill->reg()))
2300b57cec5SDimitry Andric       continue;
2310b57cec5SDimitry Andric 
2320b57cec5SDimitry Andric     // Deallocate the interfering vreg by removing it from the union.
2330b57cec5SDimitry Andric     // A LiveInterval instance may not be in a union during modification!
234*0fca6ea1SDimitry Andric     Matrix->unassign(*Spill);
2350b57cec5SDimitry Andric 
2360b57cec5SDimitry Andric     // Spill the extracted interval.
237*0fca6ea1SDimitry Andric     LiveRangeEdit LRE(Spill, SplitVRegs, *MF, *LIS, VRM, this, &DeadRemats);
2380b57cec5SDimitry Andric     spiller().spill(LRE);
2390b57cec5SDimitry Andric   }
2400b57cec5SDimitry Andric   return true;
2410b57cec5SDimitry Andric }
2420b57cec5SDimitry Andric 
2430b57cec5SDimitry Andric // Driver for the register assignment and splitting heuristics.
2440b57cec5SDimitry Andric // Manages iteration over the LiveIntervalUnions.
2450b57cec5SDimitry Andric //
2460b57cec5SDimitry Andric // This is a minimal implementation of register assignment and splitting that
2470b57cec5SDimitry Andric // spills whenever we run out of registers.
2480b57cec5SDimitry Andric //
2490b57cec5SDimitry Andric // selectOrSplit can only be called once per live virtual register. We then do a
2500b57cec5SDimitry Andric // single interference test for each register the correct class until we find an
2510b57cec5SDimitry Andric // available register. So, the number of interference tests in the worst case is
2520b57cec5SDimitry Andric // |vregs| * |machineregs|. And since the number of interference tests is
2530b57cec5SDimitry Andric // minimal, there is no value in caching them outside the scope of
2540b57cec5SDimitry Andric // selectOrSplit().
25581ad6265SDimitry Andric MCRegister RABasic::selectOrSplit(const LiveInterval &VirtReg,
2565ffd83dbSDimitry Andric                                   SmallVectorImpl<Register> &SplitVRegs) {
2570b57cec5SDimitry Andric   // Populate a list of physical register spill candidates.
258e8d8bef9SDimitry Andric   SmallVector<MCRegister, 8> PhysRegSpillCands;
2590b57cec5SDimitry Andric 
2600b57cec5SDimitry Andric   // Check for an available register in this class.
261e8d8bef9SDimitry Andric   auto Order =
262e8d8bef9SDimitry Andric       AllocationOrder::create(VirtReg.reg(), *VRM, RegClassInfo, Matrix);
263e8d8bef9SDimitry Andric   for (MCRegister PhysReg : Order) {
264e8d8bef9SDimitry Andric     assert(PhysReg.isValid());
2650b57cec5SDimitry Andric     // Check for interference in PhysReg
2660b57cec5SDimitry Andric     switch (Matrix->checkInterference(VirtReg, PhysReg)) {
2670b57cec5SDimitry Andric     case LiveRegMatrix::IK_Free:
2680b57cec5SDimitry Andric       // PhysReg is available, allocate it.
2690b57cec5SDimitry Andric       return PhysReg;
2700b57cec5SDimitry Andric 
2710b57cec5SDimitry Andric     case LiveRegMatrix::IK_VirtReg:
2720b57cec5SDimitry Andric       // Only virtual registers in the way, we may be able to spill them.
2730b57cec5SDimitry Andric       PhysRegSpillCands.push_back(PhysReg);
2740b57cec5SDimitry Andric       continue;
2750b57cec5SDimitry Andric 
2760b57cec5SDimitry Andric     default:
2770b57cec5SDimitry Andric       // RegMask or RegUnit interference.
2780b57cec5SDimitry Andric       continue;
2790b57cec5SDimitry Andric     }
2800b57cec5SDimitry Andric   }
2810b57cec5SDimitry Andric 
2820b57cec5SDimitry Andric   // Try to spill another interfering reg with less spill weight.
283fe6060f1SDimitry Andric   for (MCRegister &PhysReg : PhysRegSpillCands) {
284fe6060f1SDimitry Andric     if (!spillInterferences(VirtReg, PhysReg, SplitVRegs))
2850b57cec5SDimitry Andric       continue;
2860b57cec5SDimitry Andric 
287fe6060f1SDimitry Andric     assert(!Matrix->checkInterference(VirtReg, PhysReg) &&
2880b57cec5SDimitry Andric            "Interference after spill.");
2890b57cec5SDimitry Andric     // Tell the caller to allocate to this newly freed physical register.
290fe6060f1SDimitry Andric     return PhysReg;
2910b57cec5SDimitry Andric   }
2920b57cec5SDimitry Andric 
2930b57cec5SDimitry Andric   // No other spill candidates were found, so spill the current VirtReg.
2940b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "spilling: " << VirtReg << '\n');
2950b57cec5SDimitry Andric   if (!VirtReg.isSpillable())
2960b57cec5SDimitry Andric     return ~0u;
2970b57cec5SDimitry Andric   LiveRangeEdit LRE(&VirtReg, SplitVRegs, *MF, *LIS, VRM, this, &DeadRemats);
2980b57cec5SDimitry Andric   spiller().spill(LRE);
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric   // The live virtual register requesting allocation was spilled, so tell
3010b57cec5SDimitry Andric   // the caller not to allocate anything during this round.
3020b57cec5SDimitry Andric   return 0;
3030b57cec5SDimitry Andric }
3040b57cec5SDimitry Andric 
3050b57cec5SDimitry Andric bool RABasic::runOnMachineFunction(MachineFunction &mf) {
3060b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "********** BASIC REGISTER ALLOCATION **********\n"
3070b57cec5SDimitry Andric                     << "********** Function: " << mf.getName() << '\n');
3080b57cec5SDimitry Andric 
3090b57cec5SDimitry Andric   MF = &mf;
3100b57cec5SDimitry Andric   RegAllocBase::init(getAnalysis<VirtRegMap>(),
311*0fca6ea1SDimitry Andric                      getAnalysis<LiveIntervalsWrapperPass>().getLIS(),
3120b57cec5SDimitry Andric                      getAnalysis<LiveRegMatrix>());
313*0fca6ea1SDimitry Andric   VirtRegAuxInfo VRAI(
314*0fca6ea1SDimitry Andric       *MF, *LIS, *VRM, getAnalysis<MachineLoopInfoWrapperPass>().getLI(),
315*0fca6ea1SDimitry Andric       getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI());
316e8d8bef9SDimitry Andric   VRAI.calculateSpillWeightsAndHints();
3170b57cec5SDimitry Andric 
318fe6060f1SDimitry Andric   SpillerInstance.reset(createInlineSpiller(*this, *MF, *VRM, VRAI));
3190b57cec5SDimitry Andric 
3200b57cec5SDimitry Andric   allocatePhysRegs();
3210b57cec5SDimitry Andric   postOptimization();
3220b57cec5SDimitry Andric 
3230b57cec5SDimitry Andric   // Diagnostic output before rewriting
3240b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "Post alloc VirtRegMap:\n" << *VRM << "\n");
3250b57cec5SDimitry Andric 
3260b57cec5SDimitry Andric   releaseMemory();
3270b57cec5SDimitry Andric   return true;
3280b57cec5SDimitry Andric }
3290b57cec5SDimitry Andric 
330fe6060f1SDimitry Andric FunctionPass* llvm::createBasicRegisterAllocator() {
3310b57cec5SDimitry Andric   return new RABasic();
3320b57cec5SDimitry Andric }
333fe6060f1SDimitry Andric 
334*0fca6ea1SDimitry Andric FunctionPass *llvm::createBasicRegisterAllocator(RegAllocFilterFunc F) {
335fe6060f1SDimitry Andric   return new RABasic(F);
336fe6060f1SDimitry Andric }
337