| Jakob Stoklund Olesen | cba2e06 | 2010-12-08 03:26:16 +0000 | [diff] [blame] | 1 | //===-- RegAllocGreedy.cpp - greedy register allocator --------------------===// | 
|  | 2 | // | 
|  | 3 | //                     The LLVM Compiler Infrastructure | 
|  | 4 | // | 
|  | 5 | // This file is distributed under the University of Illinois Open Source | 
|  | 6 | // License. See LICENSE.TXT for details. | 
|  | 7 | // | 
|  | 8 | //===----------------------------------------------------------------------===// | 
|  | 9 | // | 
|  | 10 | // This file defines the RAGreedy function pass for register allocation in | 
|  | 11 | // optimized builds. | 
|  | 12 | // | 
|  | 13 | //===----------------------------------------------------------------------===// | 
|  | 14 |  | 
|  | 15 | #define DEBUG_TYPE "regalloc" | 
| Jakob Stoklund Olesen | dd479e9 | 2010-12-10 22:21:05 +0000 | [diff] [blame] | 16 | #include "AllocationOrder.h" | 
| Jakob Stoklund Olesen | cba2e06 | 2010-12-08 03:26:16 +0000 | [diff] [blame] | 17 | #include "LiveIntervalUnion.h" | 
|  | 18 | #include "RegAllocBase.h" | 
|  | 19 | #include "Spiller.h" | 
| Jakob Stoklund Olesen | d0bb5e2 | 2010-12-15 23:46:13 +0000 | [diff] [blame^] | 20 | #include "SplitKit.h" | 
| Jakob Stoklund Olesen | cba2e06 | 2010-12-08 03:26:16 +0000 | [diff] [blame] | 21 | #include "VirtRegMap.h" | 
|  | 22 | #include "VirtRegRewriter.h" | 
| Jakob Stoklund Olesen | cba2e06 | 2010-12-08 03:26:16 +0000 | [diff] [blame] | 23 | #include "llvm/Analysis/AliasAnalysis.h" | 
|  | 24 | #include "llvm/Function.h" | 
|  | 25 | #include "llvm/PassAnalysisSupport.h" | 
|  | 26 | #include "llvm/CodeGen/CalcSpillWeights.h" | 
|  | 27 | #include "llvm/CodeGen/LiveIntervalAnalysis.h" | 
|  | 28 | #include "llvm/CodeGen/LiveStackAnalysis.h" | 
|  | 29 | #include "llvm/CodeGen/MachineFunctionPass.h" | 
| Jakob Stoklund Olesen | cba2e06 | 2010-12-08 03:26:16 +0000 | [diff] [blame] | 30 | #include "llvm/CodeGen/MachineLoopInfo.h" | 
| Jakob Stoklund Olesen | d0bb5e2 | 2010-12-15 23:46:13 +0000 | [diff] [blame^] | 31 | #include "llvm/CodeGen/MachineLoopRanges.h" | 
| Jakob Stoklund Olesen | cba2e06 | 2010-12-08 03:26:16 +0000 | [diff] [blame] | 32 | #include "llvm/CodeGen/MachineRegisterInfo.h" | 
|  | 33 | #include "llvm/CodeGen/Passes.h" | 
|  | 34 | #include "llvm/CodeGen/RegAllocRegistry.h" | 
|  | 35 | #include "llvm/CodeGen/RegisterCoalescer.h" | 
| Jakob Stoklund Olesen | cba2e06 | 2010-12-08 03:26:16 +0000 | [diff] [blame] | 36 | #include "llvm/Target/TargetOptions.h" | 
| Jakob Stoklund Olesen | cba2e06 | 2010-12-08 03:26:16 +0000 | [diff] [blame] | 37 | #include "llvm/Support/Debug.h" | 
|  | 38 | #include "llvm/Support/ErrorHandling.h" | 
|  | 39 | #include "llvm/Support/raw_ostream.h" | 
| Jakob Stoklund Olesen | 533f58e | 2010-12-11 00:19:56 +0000 | [diff] [blame] | 40 | #include "llvm/Support/Timer.h" | 
| Jakob Stoklund Olesen | cba2e06 | 2010-12-08 03:26:16 +0000 | [diff] [blame] | 41 |  | 
|  | 42 | using namespace llvm; | 
|  | 43 |  | 
|  | 44 | static RegisterRegAlloc greedyRegAlloc("greedy", "greedy register allocator", | 
|  | 45 | createGreedyRegisterAllocator); | 
|  | 46 |  | 
|  | 47 | namespace { | 
|  | 48 | class RAGreedy : public MachineFunctionPass, public RegAllocBase { | 
|  | 49 | // context | 
|  | 50 | MachineFunction *MF; | 
| Jakob Stoklund Olesen | cba2e06 | 2010-12-08 03:26:16 +0000 | [diff] [blame] | 51 | BitVector ReservedRegs; | 
|  | 52 |  | 
|  | 53 | // analyses | 
|  | 54 | LiveStacks *LS; | 
| Jakob Stoklund Olesen | d0bb5e2 | 2010-12-15 23:46:13 +0000 | [diff] [blame^] | 55 | MachineLoopInfo *Loops; | 
|  | 56 | MachineLoopRanges *LoopRanges; | 
| Jakob Stoklund Olesen | cba2e06 | 2010-12-08 03:26:16 +0000 | [diff] [blame] | 57 | // state | 
|  | 58 | std::auto_ptr<Spiller> SpillerInstance; | 
| Jakob Stoklund Olesen | d0bb5e2 | 2010-12-15 23:46:13 +0000 | [diff] [blame^] | 59 | std::auto_ptr<SplitAnalysis> SA; | 
| Jakob Stoklund Olesen | cba2e06 | 2010-12-08 03:26:16 +0000 | [diff] [blame] | 60 |  | 
|  | 61 | public: | 
|  | 62 | RAGreedy(); | 
|  | 63 |  | 
|  | 64 | /// Return the pass name. | 
|  | 65 | virtual const char* getPassName() const { | 
| Jakob Stoklund Olesen | 533f58e | 2010-12-11 00:19:56 +0000 | [diff] [blame] | 66 | return "Greedy Register Allocator"; | 
| Jakob Stoklund Olesen | cba2e06 | 2010-12-08 03:26:16 +0000 | [diff] [blame] | 67 | } | 
|  | 68 |  | 
|  | 69 | /// RAGreedy analysis usage. | 
|  | 70 | virtual void getAnalysisUsage(AnalysisUsage &AU) const; | 
|  | 71 |  | 
|  | 72 | virtual void releaseMemory(); | 
|  | 73 |  | 
|  | 74 | virtual Spiller &spiller() { return *SpillerInstance; } | 
|  | 75 |  | 
| Jakob Stoklund Olesen | 90c1d7d | 2010-12-08 22:57:16 +0000 | [diff] [blame] | 76 | virtual float getPriority(LiveInterval *LI); | 
| Jakob Stoklund Olesen | d0bec3e | 2010-12-08 22:22:41 +0000 | [diff] [blame] | 77 |  | 
| Jakob Stoklund Olesen | cba2e06 | 2010-12-08 03:26:16 +0000 | [diff] [blame] | 78 | virtual unsigned selectOrSplit(LiveInterval &VirtReg, | 
|  | 79 | SmallVectorImpl<LiveInterval*> &SplitVRegs); | 
|  | 80 |  | 
|  | 81 | /// Perform register allocation. | 
|  | 82 | virtual bool runOnMachineFunction(MachineFunction &mf); | 
|  | 83 |  | 
|  | 84 | static char ID; | 
| Andrew Trick | b853e6c | 2010-12-09 18:15:21 +0000 | [diff] [blame] | 85 |  | 
|  | 86 | private: | 
| Jakob Stoklund Olesen | 46c83c8 | 2010-12-14 00:37:49 +0000 | [diff] [blame] | 87 | bool checkUncachedInterference(LiveInterval&, unsigned); | 
|  | 88 | LiveInterval *getSingleInterference(LiveInterval&, unsigned); | 
| Andrew Trick | b853e6c | 2010-12-09 18:15:21 +0000 | [diff] [blame] | 89 | bool reassignVReg(LiveInterval &InterferingVReg, unsigned OldPhysReg); | 
|  | 90 | bool reassignInterferences(LiveInterval &VirtReg, unsigned PhysReg); | 
| Jakob Stoklund Olesen | b64d92e | 2010-12-14 00:37:44 +0000 | [diff] [blame] | 91 |  | 
| Jakob Stoklund Olesen | 46c83c8 | 2010-12-14 00:37:49 +0000 | [diff] [blame] | 92 | unsigned tryReassign(LiveInterval&, AllocationOrder&); | 
| Jakob Stoklund Olesen | b64d92e | 2010-12-14 00:37:44 +0000 | [diff] [blame] | 93 | unsigned trySplit(LiveInterval&, AllocationOrder&, | 
|  | 94 | SmallVectorImpl<LiveInterval*>&); | 
| Jakob Stoklund Olesen | cba2e06 | 2010-12-08 03:26:16 +0000 | [diff] [blame] | 95 | }; | 
|  | 96 | } // end anonymous namespace | 
|  | 97 |  | 
|  | 98 | char RAGreedy::ID = 0; | 
|  | 99 |  | 
|  | 100 | FunctionPass* llvm::createGreedyRegisterAllocator() { | 
|  | 101 | return new RAGreedy(); | 
|  | 102 | } | 
|  | 103 |  | 
|  | 104 | RAGreedy::RAGreedy(): MachineFunctionPass(ID) { | 
|  | 105 | initializeLiveIntervalsPass(*PassRegistry::getPassRegistry()); | 
|  | 106 | initializeSlotIndexesPass(*PassRegistry::getPassRegistry()); | 
|  | 107 | initializeStrongPHIEliminationPass(*PassRegistry::getPassRegistry()); | 
|  | 108 | initializeRegisterCoalescerAnalysisGroup(*PassRegistry::getPassRegistry()); | 
|  | 109 | initializeCalculateSpillWeightsPass(*PassRegistry::getPassRegistry()); | 
|  | 110 | initializeLiveStacksPass(*PassRegistry::getPassRegistry()); | 
|  | 111 | initializeMachineDominatorTreePass(*PassRegistry::getPassRegistry()); | 
|  | 112 | initializeMachineLoopInfoPass(*PassRegistry::getPassRegistry()); | 
| Jakob Stoklund Olesen | d0bb5e2 | 2010-12-15 23:46:13 +0000 | [diff] [blame^] | 113 | initializeMachineLoopRangesPass(*PassRegistry::getPassRegistry()); | 
| Jakob Stoklund Olesen | cba2e06 | 2010-12-08 03:26:16 +0000 | [diff] [blame] | 114 | initializeVirtRegMapPass(*PassRegistry::getPassRegistry()); | 
|  | 115 | } | 
|  | 116 |  | 
|  | 117 | void RAGreedy::getAnalysisUsage(AnalysisUsage &AU) const { | 
|  | 118 | AU.setPreservesCFG(); | 
|  | 119 | AU.addRequired<AliasAnalysis>(); | 
|  | 120 | AU.addPreserved<AliasAnalysis>(); | 
|  | 121 | AU.addRequired<LiveIntervals>(); | 
|  | 122 | AU.addPreserved<SlotIndexes>(); | 
|  | 123 | if (StrongPHIElim) | 
|  | 124 | AU.addRequiredID(StrongPHIEliminationID); | 
|  | 125 | AU.addRequiredTransitive<RegisterCoalescer>(); | 
|  | 126 | AU.addRequired<CalculateSpillWeights>(); | 
|  | 127 | AU.addRequired<LiveStacks>(); | 
|  | 128 | AU.addPreserved<LiveStacks>(); | 
|  | 129 | AU.addRequiredID(MachineDominatorsID); | 
|  | 130 | AU.addPreservedID(MachineDominatorsID); | 
|  | 131 | AU.addRequired<MachineLoopInfo>(); | 
|  | 132 | AU.addPreserved<MachineLoopInfo>(); | 
| Jakob Stoklund Olesen | d0bb5e2 | 2010-12-15 23:46:13 +0000 | [diff] [blame^] | 133 | AU.addRequired<MachineLoopRanges>(); | 
|  | 134 | AU.addPreserved<MachineLoopRanges>(); | 
| Jakob Stoklund Olesen | cba2e06 | 2010-12-08 03:26:16 +0000 | [diff] [blame] | 135 | AU.addRequired<VirtRegMap>(); | 
|  | 136 | AU.addPreserved<VirtRegMap>(); | 
|  | 137 | MachineFunctionPass::getAnalysisUsage(AU); | 
|  | 138 | } | 
|  | 139 |  | 
|  | 140 | void RAGreedy::releaseMemory() { | 
|  | 141 | SpillerInstance.reset(0); | 
|  | 142 | RegAllocBase::releaseMemory(); | 
|  | 143 | } | 
|  | 144 |  | 
| Jakob Stoklund Olesen | 90c1d7d | 2010-12-08 22:57:16 +0000 | [diff] [blame] | 145 | float RAGreedy::getPriority(LiveInterval *LI) { | 
|  | 146 | float Priority = LI->weight; | 
|  | 147 |  | 
|  | 148 | // Prioritize hinted registers so they are allocated first. | 
|  | 149 | std::pair<unsigned, unsigned> Hint; | 
|  | 150 | if (Hint.first || Hint.second) { | 
|  | 151 | // The hint can be target specific, a virtual register, or a physreg. | 
|  | 152 | Priority *= 2; | 
|  | 153 |  | 
|  | 154 | // Prefer physreg hints above anything else. | 
|  | 155 | if (Hint.first == 0 && TargetRegisterInfo::isPhysicalRegister(Hint.second)) | 
|  | 156 | Priority *= 2; | 
|  | 157 | } | 
|  | 158 | return Priority; | 
|  | 159 | } | 
|  | 160 |  | 
| Jakob Stoklund Olesen | 6ce219e | 2010-12-10 20:45:04 +0000 | [diff] [blame] | 161 | // Check interference without using the cache. | 
|  | 162 | bool RAGreedy::checkUncachedInterference(LiveInterval &VirtReg, | 
|  | 163 | unsigned PhysReg) { | 
| Jakob Stoklund Olesen | 257c556 | 2010-12-14 23:38:19 +0000 | [diff] [blame] | 164 | for (const unsigned *AliasI = TRI->getOverlaps(PhysReg); *AliasI; ++AliasI) { | 
|  | 165 | LiveIntervalUnion::Query subQ(&VirtReg, &PhysReg2LiveUnion[*AliasI]); | 
| Jakob Stoklund Olesen | 6ce219e | 2010-12-10 20:45:04 +0000 | [diff] [blame] | 166 | if (subQ.checkInterference()) | 
|  | 167 | return true; | 
|  | 168 | } | 
|  | 169 | return false; | 
|  | 170 | } | 
|  | 171 |  | 
| Jakob Stoklund Olesen | 46c83c8 | 2010-12-14 00:37:49 +0000 | [diff] [blame] | 172 | /// getSingleInterference - Return the single interfering virtual register | 
|  | 173 | /// assigned to PhysReg. Return 0 if more than one virtual register is | 
|  | 174 | /// interfering. | 
|  | 175 | LiveInterval *RAGreedy::getSingleInterference(LiveInterval &VirtReg, | 
|  | 176 | unsigned PhysReg) { | 
| Jakob Stoklund Olesen | 257c556 | 2010-12-14 23:38:19 +0000 | [diff] [blame] | 177 | // Check physreg and aliases. | 
| Jakob Stoklund Olesen | 46c83c8 | 2010-12-14 00:37:49 +0000 | [diff] [blame] | 178 | LiveInterval *Interference = 0; | 
| Jakob Stoklund Olesen | 257c556 | 2010-12-14 23:38:19 +0000 | [diff] [blame] | 179 | for (const unsigned *AliasI = TRI->getOverlaps(PhysReg); *AliasI; ++AliasI) { | 
| Jakob Stoklund Olesen | 46c83c8 | 2010-12-14 00:37:49 +0000 | [diff] [blame] | 180 | LiveIntervalUnion::Query &Q = query(VirtReg, *AliasI); | 
|  | 181 | if (Q.checkInterference()) { | 
| Jakob Stoklund Olesen | d84de8c | 2010-12-14 17:47:36 +0000 | [diff] [blame] | 182 | if (Interference) | 
| Jakob Stoklund Olesen | 46c83c8 | 2010-12-14 00:37:49 +0000 | [diff] [blame] | 183 | return 0; | 
|  | 184 | Q.collectInterferingVRegs(1); | 
| Jakob Stoklund Olesen | d84de8c | 2010-12-14 17:47:36 +0000 | [diff] [blame] | 185 | if (!Q.seenAllInterferences()) | 
|  | 186 | return 0; | 
| Jakob Stoklund Olesen | 46c83c8 | 2010-12-14 00:37:49 +0000 | [diff] [blame] | 187 | Interference = Q.interferingVRegs().front(); | 
|  | 188 | } | 
|  | 189 | } | 
|  | 190 | return Interference; | 
|  | 191 | } | 
|  | 192 |  | 
| Andrew Trick | b853e6c | 2010-12-09 18:15:21 +0000 | [diff] [blame] | 193 | // Attempt to reassign this virtual register to a different physical register. | 
|  | 194 | // | 
|  | 195 | // FIXME: we are not yet caching these "second-level" interferences discovered | 
|  | 196 | // in the sub-queries. These interferences can change with each call to | 
|  | 197 | // selectOrSplit. However, we could implement a "may-interfere" cache that | 
|  | 198 | // could be conservatively dirtied when we reassign or split. | 
|  | 199 | // | 
|  | 200 | // FIXME: This may result in a lot of alias queries. We could summarize alias | 
|  | 201 | // live intervals in their parent register's live union, but it's messy. | 
|  | 202 | bool RAGreedy::reassignVReg(LiveInterval &InterferingVReg, | 
| Jakob Stoklund Olesen | 46c83c8 | 2010-12-14 00:37:49 +0000 | [diff] [blame] | 203 | unsigned WantedPhysReg) { | 
|  | 204 | assert(TargetRegisterInfo::isVirtualRegister(InterferingVReg.reg) && | 
|  | 205 | "Can only reassign virtual registers"); | 
|  | 206 | assert(TRI->regsOverlap(WantedPhysReg, VRM->getPhys(InterferingVReg.reg)) && | 
| Andrew Trick | b853e6c | 2010-12-09 18:15:21 +0000 | [diff] [blame] | 207 | "inconsistent phys reg assigment"); | 
|  | 208 |  | 
| Jakob Stoklund Olesen | dd479e9 | 2010-12-10 22:21:05 +0000 | [diff] [blame] | 209 | AllocationOrder Order(InterferingVReg.reg, *VRM, ReservedRegs); | 
|  | 210 | while (unsigned PhysReg = Order.next()) { | 
| Jakob Stoklund Olesen | 46c83c8 | 2010-12-14 00:37:49 +0000 | [diff] [blame] | 211 | // Don't reassign to a WantedPhysReg alias. | 
|  | 212 | if (TRI->regsOverlap(PhysReg, WantedPhysReg)) | 
| Andrew Trick | b853e6c | 2010-12-09 18:15:21 +0000 | [diff] [blame] | 213 | continue; | 
|  | 214 |  | 
| Jakob Stoklund Olesen | 6ce219e | 2010-12-10 20:45:04 +0000 | [diff] [blame] | 215 | if (checkUncachedInterference(InterferingVReg, PhysReg)) | 
| Andrew Trick | b853e6c | 2010-12-09 18:15:21 +0000 | [diff] [blame] | 216 | continue; | 
|  | 217 |  | 
| Andrew Trick | b853e6c | 2010-12-09 18:15:21 +0000 | [diff] [blame] | 218 | // Reassign the interfering virtual reg to this physical reg. | 
| Jakob Stoklund Olesen | 46c83c8 | 2010-12-14 00:37:49 +0000 | [diff] [blame] | 219 | unsigned OldAssign = VRM->getPhys(InterferingVReg.reg); | 
|  | 220 | DEBUG(dbgs() << "reassigning: " << InterferingVReg << " from " << | 
|  | 221 | TRI->getName(OldAssign) << " to " << TRI->getName(PhysReg) << '\n'); | 
|  | 222 | PhysReg2LiveUnion[OldAssign].extract(InterferingVReg); | 
| Andrew Trick | b853e6c | 2010-12-09 18:15:21 +0000 | [diff] [blame] | 223 | VRM->clearVirt(InterferingVReg.reg); | 
|  | 224 | VRM->assignVirt2Phys(InterferingVReg.reg, PhysReg); | 
|  | 225 | PhysReg2LiveUnion[PhysReg].unify(InterferingVReg); | 
|  | 226 |  | 
|  | 227 | return true; | 
|  | 228 | } | 
|  | 229 | return false; | 
|  | 230 | } | 
|  | 231 |  | 
| Jakob Stoklund Olesen | 46c83c8 | 2010-12-14 00:37:49 +0000 | [diff] [blame] | 232 | /// reassignInterferences - Reassign all interferences to different physical | 
|  | 233 | /// registers such that Virtreg can be assigned to PhysReg. | 
|  | 234 | /// Currently this only works with a single interference. | 
|  | 235 | /// @param  VirtReg Currently unassigned virtual register. | 
|  | 236 | /// @param  PhysReg Physical register to be cleared. | 
|  | 237 | /// @return True on success, false if nothing was changed. | 
| Andrew Trick | b853e6c | 2010-12-09 18:15:21 +0000 | [diff] [blame] | 238 | bool RAGreedy::reassignInterferences(LiveInterval &VirtReg, unsigned PhysReg) { | 
| Jakob Stoklund Olesen | 46c83c8 | 2010-12-14 00:37:49 +0000 | [diff] [blame] | 239 | LiveInterval *InterferingVReg = getSingleInterference(VirtReg, PhysReg); | 
|  | 240 | if (!InterferingVReg) | 
| Andrew Trick | b853e6c | 2010-12-09 18:15:21 +0000 | [diff] [blame] | 241 | return false; | 
| Jakob Stoklund Olesen | 46c83c8 | 2010-12-14 00:37:49 +0000 | [diff] [blame] | 242 | if (TargetRegisterInfo::isPhysicalRegister(InterferingVReg->reg)) | 
|  | 243 | return false; | 
|  | 244 | return reassignVReg(*InterferingVReg, PhysReg); | 
|  | 245 | } | 
| Andrew Trick | b853e6c | 2010-12-09 18:15:21 +0000 | [diff] [blame] | 246 |  | 
| Jakob Stoklund Olesen | 46c83c8 | 2010-12-14 00:37:49 +0000 | [diff] [blame] | 247 | /// tryReassign - Try to reassign interferences to different physregs. | 
|  | 248 | /// @param  VirtReg Currently unassigned virtual register. | 
|  | 249 | /// @param  Order   Physregs to try. | 
|  | 250 | /// @return         Physreg to assign VirtReg, or 0. | 
|  | 251 | unsigned RAGreedy::tryReassign(LiveInterval &VirtReg, AllocationOrder &Order) { | 
|  | 252 | NamedRegionTimer T("Reassign", TimerGroupName, TimePassesIsEnabled); | 
|  | 253 | Order.rewind(); | 
|  | 254 | while (unsigned PhysReg = Order.next()) | 
|  | 255 | if (reassignInterferences(VirtReg, PhysReg)) | 
|  | 256 | return PhysReg; | 
|  | 257 | return 0; | 
| Andrew Trick | b853e6c | 2010-12-09 18:15:21 +0000 | [diff] [blame] | 258 | } | 
|  | 259 |  | 
| Jakob Stoklund Olesen | b64d92e | 2010-12-14 00:37:44 +0000 | [diff] [blame] | 260 | /// trySplit - Try to split VirtReg or one of its interferences, making it | 
|  | 261 | /// assignable. | 
|  | 262 | /// @return Physreg when VirtReg may be assigned and/or new SplitVRegs. | 
|  | 263 | unsigned RAGreedy::trySplit(LiveInterval &VirtReg, AllocationOrder &Order, | 
|  | 264 | SmallVectorImpl<LiveInterval*>&SplitVRegs) { | 
|  | 265 | NamedRegionTimer T("Splitter", TimerGroupName, TimePassesIsEnabled); | 
| Jakob Stoklund Olesen | d0bb5e2 | 2010-12-15 23:46:13 +0000 | [diff] [blame^] | 266 | SA->analyze(&VirtReg); | 
|  | 267 |  | 
|  | 268 | // Get the set of loops that have VirtReg uses and are splittable. | 
|  | 269 | SplitAnalysis::LoopPtrSet SplitLoops; | 
|  | 270 | SA->getSplitLoops(SplitLoops); | 
|  | 271 |  | 
|  | 272 | Order.rewind(); | 
|  | 273 | while (unsigned PhysReg = Order.next()) { | 
|  | 274 | for (const unsigned *AI = TRI->getOverlaps(PhysReg); *AI; ++AI) { | 
|  | 275 | LiveIntervalUnion::Query &Q = query(VirtReg, *AI); | 
|  | 276 | if (!Q.checkInterference()) | 
|  | 277 | continue; | 
|  | 278 | LiveIntervalUnion::InterferenceResult IR = Q.firstInterference(); | 
|  | 279 | do { | 
|  | 280 | DEBUG({dbgs() << "  "; IR.print(dbgs(), TRI);}); | 
|  | 281 | for (SplitAnalysis::LoopPtrSet::iterator I = SplitLoops.begin(), | 
|  | 282 | E = SplitLoops.end(); I != E; ++I) { | 
|  | 283 | MachineLoopRange *Range = LoopRanges->getLoopRange(*I); | 
|  | 284 | if (!Range->overlaps(IR.start(), IR.stop())) | 
|  | 285 | continue; | 
|  | 286 | DEBUG(dbgs() << ", overlaps " << *Range); | 
|  | 287 | } | 
|  | 288 | DEBUG(dbgs() << '\n'); | 
|  | 289 | } while (Q.nextInterference(IR)); | 
| Matt Beaumont-Gay | 3ef9f3d | 2010-12-14 21:14:55 +0000 | [diff] [blame] | 290 | } | 
| Jakob Stoklund Olesen | d0bb5e2 | 2010-12-15 23:46:13 +0000 | [diff] [blame^] | 291 | } | 
| Jakob Stoklund Olesen | b64d92e | 2010-12-14 00:37:44 +0000 | [diff] [blame] | 292 | return 0; | 
|  | 293 | } | 
|  | 294 |  | 
| Jakob Stoklund Olesen | cba2e06 | 2010-12-08 03:26:16 +0000 | [diff] [blame] | 295 | unsigned RAGreedy::selectOrSplit(LiveInterval &VirtReg, | 
|  | 296 | SmallVectorImpl<LiveInterval*> &SplitVRegs) { | 
|  | 297 | // Populate a list of physical register spill candidates. | 
| Jakob Stoklund Olesen | 885b328 | 2010-12-14 00:58:47 +0000 | [diff] [blame] | 298 | SmallVector<unsigned, 8> PhysRegSpillCands; | 
| Jakob Stoklund Olesen | cba2e06 | 2010-12-08 03:26:16 +0000 | [diff] [blame] | 299 |  | 
|  | 300 | // Check for an available register in this class. | 
| Jakob Stoklund Olesen | dd479e9 | 2010-12-10 22:21:05 +0000 | [diff] [blame] | 301 | AllocationOrder Order(VirtReg.reg, *VRM, ReservedRegs); | 
|  | 302 | while (unsigned PhysReg = Order.next()) { | 
| Jakob Stoklund Olesen | cba2e06 | 2010-12-08 03:26:16 +0000 | [diff] [blame] | 303 | // Check interference and as a side effect, intialize queries for this | 
|  | 304 | // VirtReg and its aliases. | 
| Andrew Trick | b853e6c | 2010-12-09 18:15:21 +0000 | [diff] [blame] | 305 | unsigned InterfReg = checkPhysRegInterference(VirtReg, PhysReg); | 
|  | 306 | if (InterfReg == 0) { | 
| Jakob Stoklund Olesen | cba2e06 | 2010-12-08 03:26:16 +0000 | [diff] [blame] | 307 | // Found an available register. | 
|  | 308 | return PhysReg; | 
|  | 309 | } | 
| Jakob Stoklund Olesen | 9b0c4f8 | 2010-12-08 23:51:35 +0000 | [diff] [blame] | 310 | assert(!VirtReg.empty() && "Empty VirtReg has interference"); | 
| Andrew Trick | b853e6c | 2010-12-09 18:15:21 +0000 | [diff] [blame] | 311 | LiveInterval *InterferingVirtReg = | 
|  | 312 | Queries[InterfReg].firstInterference().liveUnionPos().value(); | 
| Jakob Stoklund Olesen | cba2e06 | 2010-12-08 03:26:16 +0000 | [diff] [blame] | 313 |  | 
| Andrew Trick | b853e6c | 2010-12-09 18:15:21 +0000 | [diff] [blame] | 314 | // The current VirtReg must either be spillable, or one of its interferences | 
| Jakob Stoklund Olesen | cba2e06 | 2010-12-08 03:26:16 +0000 | [diff] [blame] | 315 | // must have less spill weight. | 
| Jakob Stoklund Olesen | 46c83c8 | 2010-12-14 00:37:49 +0000 | [diff] [blame] | 316 | if (InterferingVirtReg->weight < VirtReg.weight ) | 
|  | 317 | PhysRegSpillCands.push_back(PhysReg); | 
| Jakob Stoklund Olesen | cba2e06 | 2010-12-08 03:26:16 +0000 | [diff] [blame] | 318 | } | 
| Andrew Trick | b853e6c | 2010-12-09 18:15:21 +0000 | [diff] [blame] | 319 |  | 
| Jakob Stoklund Olesen | 46c83c8 | 2010-12-14 00:37:49 +0000 | [diff] [blame] | 320 | // Try to reassign interferences. | 
|  | 321 | if (unsigned PhysReg = tryReassign(VirtReg, Order)) | 
|  | 322 | return PhysReg; | 
| Andrew Trick | b853e6c | 2010-12-09 18:15:21 +0000 | [diff] [blame] | 323 |  | 
| Jakob Stoklund Olesen | 46c83c8 | 2010-12-14 00:37:49 +0000 | [diff] [blame] | 324 | // Try splitting VirtReg or interferences. | 
| Jakob Stoklund Olesen | b64d92e | 2010-12-14 00:37:44 +0000 | [diff] [blame] | 325 | unsigned PhysReg = trySplit(VirtReg, Order, SplitVRegs); | 
|  | 326 | if (PhysReg || !SplitVRegs.empty()) | 
|  | 327 | return PhysReg; | 
|  | 328 |  | 
| Jakob Stoklund Olesen | cba2e06 | 2010-12-08 03:26:16 +0000 | [diff] [blame] | 329 | // Try to spill another interfering reg with less spill weight. | 
| Jakob Stoklund Olesen | 533f58e | 2010-12-11 00:19:56 +0000 | [diff] [blame] | 330 | NamedRegionTimer T("Spiller", TimerGroupName, TimePassesIsEnabled); | 
| Jakob Stoklund Olesen | cba2e06 | 2010-12-08 03:26:16 +0000 | [diff] [blame] | 331 | // | 
| Andrew Trick | b853e6c | 2010-12-09 18:15:21 +0000 | [diff] [blame] | 332 | // FIXME: do this in two steps: (1) check for unspillable interferences while | 
|  | 333 | // accumulating spill weight; (2) spill the interferences with lowest | 
|  | 334 | // aggregate spill weight. | 
| Jakob Stoklund Olesen | cba2e06 | 2010-12-08 03:26:16 +0000 | [diff] [blame] | 335 | for (SmallVectorImpl<unsigned>::iterator PhysRegI = PhysRegSpillCands.begin(), | 
|  | 336 | PhysRegE = PhysRegSpillCands.end(); PhysRegI != PhysRegE; ++PhysRegI) { | 
|  | 337 |  | 
|  | 338 | if (!spillInterferences(VirtReg, *PhysRegI, SplitVRegs)) continue; | 
|  | 339 |  | 
|  | 340 | assert(checkPhysRegInterference(VirtReg, *PhysRegI) == 0 && | 
|  | 341 | "Interference after spill."); | 
|  | 342 | // Tell the caller to allocate to this newly freed physical register. | 
|  | 343 | return *PhysRegI; | 
|  | 344 | } | 
| Andrew Trick | b853e6c | 2010-12-09 18:15:21 +0000 | [diff] [blame] | 345 |  | 
| Jakob Stoklund Olesen | cba2e06 | 2010-12-08 03:26:16 +0000 | [diff] [blame] | 346 | // No other spill candidates were found, so spill the current VirtReg. | 
|  | 347 | DEBUG(dbgs() << "spilling: " << VirtReg << '\n'); | 
|  | 348 | SmallVector<LiveInterval*, 1> pendingSpills; | 
|  | 349 |  | 
|  | 350 | spiller().spill(&VirtReg, SplitVRegs, pendingSpills); | 
|  | 351 |  | 
|  | 352 | // The live virtual register requesting allocation was spilled, so tell | 
|  | 353 | // the caller not to allocate anything during this round. | 
|  | 354 | return 0; | 
|  | 355 | } | 
|  | 356 |  | 
|  | 357 | bool RAGreedy::runOnMachineFunction(MachineFunction &mf) { | 
|  | 358 | DEBUG(dbgs() << "********** GREEDY REGISTER ALLOCATION **********\n" | 
|  | 359 | << "********** Function: " | 
|  | 360 | << ((Value*)mf.getFunction())->getName() << '\n'); | 
|  | 361 |  | 
|  | 362 | MF = &mf; | 
| Jakob Stoklund Olesen | 4680dec | 2010-12-10 23:49:00 +0000 | [diff] [blame] | 363 | RegAllocBase::init(getAnalysis<VirtRegMap>(), getAnalysis<LiveIntervals>()); | 
| Jakob Stoklund Olesen | cba2e06 | 2010-12-08 03:26:16 +0000 | [diff] [blame] | 364 | ReservedRegs = TRI->getReservedRegs(*MF); | 
| Jakob Stoklund Olesen | f6dff84 | 2010-12-10 22:54:44 +0000 | [diff] [blame] | 365 | SpillerInstance.reset(createInlineSpiller(*this, *MF, *VRM)); | 
| Jakob Stoklund Olesen | d0bb5e2 | 2010-12-15 23:46:13 +0000 | [diff] [blame^] | 366 | Loops = &getAnalysis<MachineLoopInfo>(); | 
|  | 367 | LoopRanges = &getAnalysis<MachineLoopRanges>(); | 
|  | 368 | SA.reset(new SplitAnalysis(*MF, *LIS, *Loops)); | 
|  | 369 |  | 
| Jakob Stoklund Olesen | cba2e06 | 2010-12-08 03:26:16 +0000 | [diff] [blame] | 370 | allocatePhysRegs(); | 
|  | 371 | addMBBLiveIns(MF); | 
|  | 372 |  | 
|  | 373 | // Run rewriter | 
| Jakob Stoklund Olesen | 533f58e | 2010-12-11 00:19:56 +0000 | [diff] [blame] | 374 | { | 
|  | 375 | NamedRegionTimer T("Rewriter", TimerGroupName, TimePassesIsEnabled); | 
|  | 376 | std::auto_ptr<VirtRegRewriter> rewriter(createVirtRegRewriter()); | 
|  | 377 | rewriter->runOnMachineFunction(*MF, *VRM, LIS); | 
|  | 378 | } | 
| Jakob Stoklund Olesen | cba2e06 | 2010-12-08 03:26:16 +0000 | [diff] [blame] | 379 |  | 
|  | 380 | // The pass output is in VirtRegMap. Release all the transient data. | 
|  | 381 | releaseMemory(); | 
|  | 382 |  | 
|  | 383 | return true; | 
|  | 384 | } |