| Evan Cheng | 09e8ca8 | 2008-10-20 21:44:59 +0000 | [diff] [blame] | 1 | //===-- PreAllocSplitting.cpp - Pre-allocation Interval Spltting Pass. ----===// | 
 | 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 implements the machine instruction level pre-register allocation | 
 | 11 | // live interval splitting pass. It finds live interval barriers, i.e. | 
 | 12 | // instructions which will kill all physical registers in certain register | 
 | 13 | // classes, and split all live intervals which cross the barrier. | 
 | 14 | // | 
 | 15 | //===----------------------------------------------------------------------===// | 
 | 16 |  | 
 | 17 | #define DEBUG_TYPE "pre-alloc-split" | 
 | 18 | #include "llvm/CodeGen/LiveIntervalAnalysis.h" | 
| Evan Cheng | d0e32c5 | 2008-10-29 05:06:14 +0000 | [diff] [blame] | 19 | #include "llvm/CodeGen/LiveStackAnalysis.h" | 
| Owen Anderson | f1f75b1 | 2008-11-04 22:22:41 +0000 | [diff] [blame] | 20 | #include "llvm/CodeGen/MachineDominators.h" | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 21 | #include "llvm/CodeGen/MachineFrameInfo.h" | 
| Evan Cheng | 09e8ca8 | 2008-10-20 21:44:59 +0000 | [diff] [blame] | 22 | #include "llvm/CodeGen/MachineFunctionPass.h" | 
 | 23 | #include "llvm/CodeGen/MachineLoopInfo.h" | 
 | 24 | #include "llvm/CodeGen/MachineRegisterInfo.h" | 
 | 25 | #include "llvm/CodeGen/Passes.h" | 
 | 26 | #include "llvm/CodeGen/RegisterCoalescer.h" | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 27 | #include "llvm/Target/TargetInstrInfo.h" | 
| Evan Cheng | 09e8ca8 | 2008-10-20 21:44:59 +0000 | [diff] [blame] | 28 | #include "llvm/Target/TargetMachine.h" | 
 | 29 | #include "llvm/Target/TargetOptions.h" | 
 | 30 | #include "llvm/Target/TargetRegisterInfo.h" | 
 | 31 | #include "llvm/Support/CommandLine.h" | 
 | 32 | #include "llvm/Support/Debug.h" | 
| Evan Cheng | d0e32c5 | 2008-10-29 05:06:14 +0000 | [diff] [blame] | 33 | #include "llvm/ADT/DenseMap.h" | 
| Evan Cheng | 5489893 | 2008-10-29 08:39:34 +0000 | [diff] [blame] | 34 | #include "llvm/ADT/DepthFirstIterator.h" | 
| Evan Cheng | 09e8ca8 | 2008-10-20 21:44:59 +0000 | [diff] [blame] | 35 | #include "llvm/ADT/SmallPtrSet.h" | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 36 | #include "llvm/ADT/Statistic.h" | 
| Evan Cheng | 09e8ca8 | 2008-10-20 21:44:59 +0000 | [diff] [blame] | 37 | using namespace llvm; | 
 | 38 |  | 
| Evan Cheng | ae7fa5b | 2008-10-28 01:48:24 +0000 | [diff] [blame] | 39 | static cl::opt<int> PreSplitLimit("pre-split-limit", cl::init(-1), cl::Hidden); | 
 | 40 |  | 
| Owen Anderson | 26562de | 2009-01-27 05:01:15 +0000 | [diff] [blame] | 41 | STATISTIC(NumTotalSplits, "Number of intervals split"); | 
| Owen Anderson | 75fa96b | 2008-11-19 04:28:29 +0000 | [diff] [blame] | 42 | STATISTIC(NumRemats, "Number of intervals split by rematerialization"); | 
| Owen Anderson | 7b9d67c | 2008-12-02 18:53:47 +0000 | [diff] [blame] | 43 | STATISTIC(NumFolds, "Number of intervals split with spill folding"); | 
| Owen Anderson | 2ebf63f | 2008-12-18 01:27:19 +0000 | [diff] [blame] | 44 | STATISTIC(NumRenumbers, "Number of intervals renumbered into new registers"); | 
| Owen Anderson | 956ec27 | 2009-01-23 00:23:32 +0000 | [diff] [blame] | 45 | STATISTIC(NumDeadSpills, "Number of dead spills removed"); | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 46 |  | 
| Evan Cheng | 09e8ca8 | 2008-10-20 21:44:59 +0000 | [diff] [blame] | 47 | namespace { | 
 | 48 |   class VISIBILITY_HIDDEN PreAllocSplitting : public MachineFunctionPass { | 
| Evan Cheng | d0e32c5 | 2008-10-29 05:06:14 +0000 | [diff] [blame] | 49 |     MachineFunction       *CurrMF; | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 50 |     const TargetMachine   *TM; | 
 | 51 |     const TargetInstrInfo *TII; | 
 | 52 |     MachineFrameInfo      *MFI; | 
 | 53 |     MachineRegisterInfo   *MRI; | 
 | 54 |     LiveIntervals         *LIs; | 
| Evan Cheng | d0e32c5 | 2008-10-29 05:06:14 +0000 | [diff] [blame] | 55 |     LiveStacks            *LSs; | 
| Evan Cheng | 09e8ca8 | 2008-10-20 21:44:59 +0000 | [diff] [blame] | 56 |  | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 57 |     // Barrier - Current barrier being processed. | 
 | 58 |     MachineInstr          *Barrier; | 
 | 59 |  | 
 | 60 |     // BarrierMBB - Basic block where the barrier resides in. | 
 | 61 |     MachineBasicBlock     *BarrierMBB; | 
 | 62 |  | 
 | 63 |     // Barrier - Current barrier index. | 
 | 64 |     unsigned              BarrierIdx; | 
 | 65 |  | 
 | 66 |     // CurrLI - Current live interval being split. | 
 | 67 |     LiveInterval          *CurrLI; | 
 | 68 |  | 
| Evan Cheng | d0e32c5 | 2008-10-29 05:06:14 +0000 | [diff] [blame] | 69 |     // CurrSLI - Current stack slot live interval. | 
 | 70 |     LiveInterval          *CurrSLI; | 
 | 71 |  | 
 | 72 |     // CurrSValNo - Current val# for the stack slot live interval. | 
 | 73 |     VNInfo                *CurrSValNo; | 
 | 74 |  | 
 | 75 |     // IntervalSSMap - A map from live interval to spill slots. | 
 | 76 |     DenseMap<unsigned, int> IntervalSSMap; | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 77 |  | 
| Evan Cheng | 5489893 | 2008-10-29 08:39:34 +0000 | [diff] [blame] | 78 |     // Def2SpillMap - A map from a def instruction index to spill index. | 
 | 79 |     DenseMap<unsigned, unsigned> Def2SpillMap; | 
| Owen Anderson | 26562de | 2009-01-27 05:01:15 +0000 | [diff] [blame] | 80 |      | 
 | 81 |     unsigned NumSplits; | 
| Evan Cheng | 0658749 | 2008-10-24 02:05:00 +0000 | [diff] [blame] | 82 |  | 
| Evan Cheng | 09e8ca8 | 2008-10-20 21:44:59 +0000 | [diff] [blame] | 83 |   public: | 
 | 84 |     static char ID; | 
 | 85 |     PreAllocSplitting() : MachineFunctionPass(&ID) {} | 
 | 86 |  | 
 | 87 |     virtual bool runOnMachineFunction(MachineFunction &MF); | 
 | 88 |  | 
 | 89 |     virtual void getAnalysisUsage(AnalysisUsage &AU) const { | 
 | 90 |       AU.addRequired<LiveIntervals>(); | 
 | 91 |       AU.addPreserved<LiveIntervals>(); | 
| Evan Cheng | d0e32c5 | 2008-10-29 05:06:14 +0000 | [diff] [blame] | 92 |       AU.addRequired<LiveStacks>(); | 
 | 93 |       AU.addPreserved<LiveStacks>(); | 
| Evan Cheng | 09e8ca8 | 2008-10-20 21:44:59 +0000 | [diff] [blame] | 94 |       AU.addPreserved<RegisterCoalescer>(); | 
 | 95 |       if (StrongPHIElim) | 
 | 96 |         AU.addPreservedID(StrongPHIEliminationID); | 
 | 97 |       else | 
 | 98 |         AU.addPreservedID(PHIEliminationID); | 
| Owen Anderson | f1f75b1 | 2008-11-04 22:22:41 +0000 | [diff] [blame] | 99 |       AU.addRequired<MachineDominatorTree>(); | 
 | 100 |       AU.addRequired<MachineLoopInfo>(); | 
 | 101 |       AU.addPreserved<MachineDominatorTree>(); | 
 | 102 |       AU.addPreserved<MachineLoopInfo>(); | 
| Evan Cheng | 09e8ca8 | 2008-10-20 21:44:59 +0000 | [diff] [blame] | 103 |       MachineFunctionPass::getAnalysisUsage(AU); | 
 | 104 |     } | 
 | 105 |      | 
 | 106 |     virtual void releaseMemory() { | 
| Evan Cheng | d0e32c5 | 2008-10-29 05:06:14 +0000 | [diff] [blame] | 107 |       IntervalSSMap.clear(); | 
| Evan Cheng | 5489893 | 2008-10-29 08:39:34 +0000 | [diff] [blame] | 108 |       Def2SpillMap.clear(); | 
| Evan Cheng | 09e8ca8 | 2008-10-20 21:44:59 +0000 | [diff] [blame] | 109 |     } | 
 | 110 |  | 
 | 111 |     virtual const char *getPassName() const { | 
 | 112 |       return "Pre-Register Allocaton Live Interval Splitting"; | 
 | 113 |     } | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 114 |  | 
 | 115 |     /// print - Implement the dump method. | 
 | 116 |     virtual void print(std::ostream &O, const Module* M = 0) const { | 
 | 117 |       LIs->print(O, M); | 
 | 118 |     } | 
 | 119 |  | 
 | 120 |     void print(std::ostream *O, const Module* M = 0) const { | 
 | 121 |       if (O) print(*O, M); | 
 | 122 |     } | 
 | 123 |  | 
 | 124 |   private: | 
 | 125 |     MachineBasicBlock::iterator | 
 | 126 |       findNextEmptySlot(MachineBasicBlock*, MachineInstr*, | 
 | 127 |                         unsigned&); | 
 | 128 |  | 
 | 129 |     MachineBasicBlock::iterator | 
| Evan Cheng | 1f08cc2 | 2008-10-28 05:28:21 +0000 | [diff] [blame] | 130 |       findSpillPoint(MachineBasicBlock*, MachineInstr*, MachineInstr*, | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 131 |                      SmallPtrSet<MachineInstr*, 4>&, unsigned&); | 
 | 132 |  | 
 | 133 |     MachineBasicBlock::iterator | 
| Evan Cheng | f62ce37 | 2008-10-28 00:47:49 +0000 | [diff] [blame] | 134 |       findRestorePoint(MachineBasicBlock*, MachineInstr*, unsigned, | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 135 |                      SmallPtrSet<MachineInstr*, 4>&, unsigned&); | 
 | 136 |  | 
| Evan Cheng | d0e32c5 | 2008-10-29 05:06:14 +0000 | [diff] [blame] | 137 |     int CreateSpillStackSlot(unsigned, const TargetRegisterClass *); | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 138 |  | 
| Evan Cheng | 5489893 | 2008-10-29 08:39:34 +0000 | [diff] [blame] | 139 |     bool IsAvailableInStack(MachineBasicBlock*, unsigned, unsigned, unsigned, | 
 | 140 |                             unsigned&, int&) const; | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 141 |  | 
| Evan Cheng | d0e32c5 | 2008-10-29 05:06:14 +0000 | [diff] [blame] | 142 |     void UpdateSpillSlotInterval(VNInfo*, unsigned, unsigned); | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 143 |  | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 144 |     bool SplitRegLiveInterval(LiveInterval*); | 
 | 145 |  | 
| Owen Anderson | 956ec27 | 2009-01-23 00:23:32 +0000 | [diff] [blame] | 146 |     bool SplitRegLiveIntervals(const TargetRegisterClass **, | 
 | 147 |                                SmallPtrSet<LiveInterval*, 8>&); | 
| Owen Anderson | f1f75b1 | 2008-11-04 22:22:41 +0000 | [diff] [blame] | 148 |      | 
 | 149 |     bool createsNewJoin(LiveRange* LR, MachineBasicBlock* DefMBB, | 
 | 150 |                         MachineBasicBlock* BarrierMBB); | 
| Owen Anderson | 75fa96b | 2008-11-19 04:28:29 +0000 | [diff] [blame] | 151 |     bool Rematerialize(unsigned vreg, VNInfo* ValNo, | 
 | 152 |                        MachineInstr* DefMI, | 
 | 153 |                        MachineBasicBlock::iterator RestorePt, | 
 | 154 |                        unsigned RestoreIdx, | 
 | 155 |                        SmallPtrSet<MachineInstr*, 4>& RefsInMBB); | 
| Owen Anderson | 7b9d67c | 2008-12-02 18:53:47 +0000 | [diff] [blame] | 156 |     MachineInstr* FoldSpill(unsigned vreg, const TargetRegisterClass* RC, | 
 | 157 |                             MachineInstr* DefMI, | 
 | 158 |                             MachineInstr* Barrier, | 
 | 159 |                             MachineBasicBlock* MBB, | 
 | 160 |                             int& SS, | 
 | 161 |                             SmallPtrSet<MachineInstr*, 4>& RefsInMBB); | 
| Owen Anderson | d0b6a0d | 2008-12-16 21:35:08 +0000 | [diff] [blame] | 162 |     void RenumberValno(VNInfo* VN); | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 163 |     void ReconstructLiveInterval(LiveInterval* LI); | 
| Owen Anderson | 956ec27 | 2009-01-23 00:23:32 +0000 | [diff] [blame] | 164 |     bool removeDeadSpills(SmallPtrSet<LiveInterval*, 8>& split); | 
| Owen Anderson | 32ca865 | 2009-01-24 10:07:43 +0000 | [diff] [blame] | 165 |     unsigned getNumberOfSpills(SmallPtrSet<MachineInstr*, 4>& MIs, | 
 | 166 |                                unsigned Reg, int FrameIndex); | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 167 |     VNInfo* PerformPHIConstruction(MachineBasicBlock::iterator use, | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 168 |                                    MachineBasicBlock* MBB, | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 169 |                                    LiveInterval* LI, | 
| Owen Anderson | 200ee7f | 2009-01-06 07:53:32 +0000 | [diff] [blame] | 170 |                                    SmallPtrSet<MachineInstr*, 4>& Visited, | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 171 |             DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 2> >& Defs, | 
 | 172 |             DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 2> >& Uses, | 
 | 173 |                                       DenseMap<MachineInstr*, VNInfo*>& NewVNs, | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 174 |                                 DenseMap<MachineBasicBlock*, VNInfo*>& LiveOut, | 
 | 175 |                                 DenseMap<MachineBasicBlock*, VNInfo*>& Phis, | 
 | 176 |                                         bool toplevel, bool intrablock); | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 177 | }; | 
| Evan Cheng | 09e8ca8 | 2008-10-20 21:44:59 +0000 | [diff] [blame] | 178 | } // end anonymous namespace | 
 | 179 |  | 
 | 180 | char PreAllocSplitting::ID = 0; | 
 | 181 |  | 
 | 182 | static RegisterPass<PreAllocSplitting> | 
 | 183 | X("pre-alloc-splitting", "Pre-Register Allocation Live Interval Splitting"); | 
 | 184 |  | 
 | 185 | const PassInfo *const llvm::PreAllocSplittingID = &X; | 
 | 186 |  | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 187 |  | 
 | 188 | /// findNextEmptySlot - Find a gap after the given machine instruction in the | 
 | 189 | /// instruction index map. If there isn't one, return end(). | 
 | 190 | MachineBasicBlock::iterator | 
 | 191 | PreAllocSplitting::findNextEmptySlot(MachineBasicBlock *MBB, MachineInstr *MI, | 
 | 192 |                                      unsigned &SpotIndex) { | 
 | 193 |   MachineBasicBlock::iterator MII = MI; | 
 | 194 |   if (++MII != MBB->end()) { | 
 | 195 |     unsigned Index = LIs->findGapBeforeInstr(LIs->getInstructionIndex(MII)); | 
 | 196 |     if (Index) { | 
 | 197 |       SpotIndex = Index; | 
 | 198 |       return MII; | 
 | 199 |     } | 
 | 200 |   } | 
 | 201 |   return MBB->end(); | 
 | 202 | } | 
 | 203 |  | 
 | 204 | /// findSpillPoint - Find a gap as far away from the given MI that's suitable | 
 | 205 | /// for spilling the current live interval. The index must be before any | 
 | 206 | /// defs and uses of the live interval register in the mbb. Return begin() if | 
 | 207 | /// none is found. | 
 | 208 | MachineBasicBlock::iterator | 
 | 209 | PreAllocSplitting::findSpillPoint(MachineBasicBlock *MBB, MachineInstr *MI, | 
| Evan Cheng | 1f08cc2 | 2008-10-28 05:28:21 +0000 | [diff] [blame] | 210 |                                   MachineInstr *DefMI, | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 211 |                                   SmallPtrSet<MachineInstr*, 4> &RefsInMBB, | 
 | 212 |                                   unsigned &SpillIndex) { | 
 | 213 |   MachineBasicBlock::iterator Pt = MBB->begin(); | 
 | 214 |  | 
 | 215 |   // Go top down if RefsInMBB is empty. | 
| Evan Cheng | 1f08cc2 | 2008-10-28 05:28:21 +0000 | [diff] [blame] | 216 |   if (RefsInMBB.empty() && !DefMI) { | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 217 |     MachineBasicBlock::iterator MII = MBB->begin(); | 
 | 218 |     MachineBasicBlock::iterator EndPt = MI; | 
 | 219 |     do { | 
 | 220 |       ++MII; | 
 | 221 |       unsigned Index = LIs->getInstructionIndex(MII); | 
 | 222 |       unsigned Gap = LIs->findGapBeforeInstr(Index); | 
 | 223 |       if (Gap) { | 
 | 224 |         Pt = MII; | 
 | 225 |         SpillIndex = Gap; | 
 | 226 |         break; | 
 | 227 |       } | 
 | 228 |     } while (MII != EndPt); | 
 | 229 |   } else { | 
 | 230 |     MachineBasicBlock::iterator MII = MI; | 
| Evan Cheng | 1f08cc2 | 2008-10-28 05:28:21 +0000 | [diff] [blame] | 231 |     MachineBasicBlock::iterator EndPt = DefMI | 
 | 232 |       ? MachineBasicBlock::iterator(DefMI) : MBB->begin(); | 
 | 233 |     while (MII != EndPt && !RefsInMBB.count(MII)) { | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 234 |       unsigned Index = LIs->getInstructionIndex(MII); | 
 | 235 |       if (LIs->hasGapBeforeInstr(Index)) { | 
 | 236 |         Pt = MII; | 
 | 237 |         SpillIndex = LIs->findGapBeforeInstr(Index, true); | 
 | 238 |       } | 
 | 239 |       --MII; | 
 | 240 |     } | 
 | 241 |   } | 
 | 242 |  | 
 | 243 |   return Pt; | 
 | 244 | } | 
 | 245 |  | 
 | 246 | /// findRestorePoint - Find a gap in the instruction index map that's suitable | 
 | 247 | /// for restoring the current live interval value. The index must be before any | 
 | 248 | /// uses of the live interval register in the mbb. Return end() if none is | 
 | 249 | /// found. | 
 | 250 | MachineBasicBlock::iterator | 
 | 251 | PreAllocSplitting::findRestorePoint(MachineBasicBlock *MBB, MachineInstr *MI, | 
| Evan Cheng | f62ce37 | 2008-10-28 00:47:49 +0000 | [diff] [blame] | 252 |                                     unsigned LastIdx, | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 253 |                                     SmallPtrSet<MachineInstr*, 4> &RefsInMBB, | 
 | 254 |                                     unsigned &RestoreIndex) { | 
| Evan Cheng | 5489893 | 2008-10-29 08:39:34 +0000 | [diff] [blame] | 255 |   // FIXME: Allow spill to be inserted to the beginning of the mbb. Update mbb | 
 | 256 |   // begin index accordingly. | 
| Owen Anderson | 5a92d4e | 2008-11-18 20:53:59 +0000 | [diff] [blame] | 257 |   MachineBasicBlock::iterator Pt = MBB->end(); | 
| Evan Cheng | f62ce37 | 2008-10-28 00:47:49 +0000 | [diff] [blame] | 258 |   unsigned EndIdx = LIs->getMBBEndIdx(MBB); | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 259 |  | 
| Evan Cheng | f62ce37 | 2008-10-28 00:47:49 +0000 | [diff] [blame] | 260 |   // Go bottom up if RefsInMBB is empty and the end of the mbb isn't beyond | 
 | 261 |   // the last index in the live range. | 
 | 262 |   if (RefsInMBB.empty() && LastIdx >= EndIdx) { | 
| Owen Anderson | 711fd3d | 2008-11-13 21:53:14 +0000 | [diff] [blame] | 263 |     MachineBasicBlock::iterator MII = MBB->getFirstTerminator(); | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 264 |     MachineBasicBlock::iterator EndPt = MI; | 
| Evan Cheng | 5489893 | 2008-10-29 08:39:34 +0000 | [diff] [blame] | 265 |     --MII; | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 266 |     do { | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 267 |       unsigned Index = LIs->getInstructionIndex(MII); | 
| Evan Cheng | 56ab0de | 2008-10-24 18:46:44 +0000 | [diff] [blame] | 268 |       unsigned Gap = LIs->findGapBeforeInstr(Index); | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 269 |       if (Gap) { | 
 | 270 |         Pt = MII; | 
 | 271 |         RestoreIndex = Gap; | 
 | 272 |         break; | 
 | 273 |       } | 
| Evan Cheng | 5489893 | 2008-10-29 08:39:34 +0000 | [diff] [blame] | 274 |       --MII; | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 275 |     } while (MII != EndPt); | 
 | 276 |   } else { | 
 | 277 |     MachineBasicBlock::iterator MII = MI; | 
 | 278 |     MII = ++MII; | 
| Evan Cheng | f62ce37 | 2008-10-28 00:47:49 +0000 | [diff] [blame] | 279 |     // FIXME: Limit the number of instructions to examine to reduce | 
 | 280 |     // compile time? | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 281 |     while (MII != MBB->end()) { | 
 | 282 |       unsigned Index = LIs->getInstructionIndex(MII); | 
| Evan Cheng | f62ce37 | 2008-10-28 00:47:49 +0000 | [diff] [blame] | 283 |       if (Index > LastIdx) | 
 | 284 |         break; | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 285 |       unsigned Gap = LIs->findGapBeforeInstr(Index); | 
 | 286 |       if (Gap) { | 
 | 287 |         Pt = MII; | 
 | 288 |         RestoreIndex = Gap; | 
 | 289 |       } | 
 | 290 |       if (RefsInMBB.count(MII)) | 
 | 291 |         break; | 
 | 292 |       ++MII; | 
 | 293 |     } | 
 | 294 |   } | 
 | 295 |  | 
 | 296 |   return Pt; | 
 | 297 | } | 
 | 298 |  | 
| Evan Cheng | d0e32c5 | 2008-10-29 05:06:14 +0000 | [diff] [blame] | 299 | /// CreateSpillStackSlot - Create a stack slot for the live interval being | 
 | 300 | /// split. If the live interval was previously split, just reuse the same | 
 | 301 | /// slot. | 
 | 302 | int PreAllocSplitting::CreateSpillStackSlot(unsigned Reg, | 
 | 303 |                                             const TargetRegisterClass *RC) { | 
 | 304 |   int SS; | 
 | 305 |   DenseMap<unsigned, int>::iterator I = IntervalSSMap.find(Reg); | 
 | 306 |   if (I != IntervalSSMap.end()) { | 
 | 307 |     SS = I->second; | 
 | 308 |   } else { | 
 | 309 |     SS = MFI->CreateStackObject(RC->getSize(), RC->getAlignment()); | 
 | 310 |     IntervalSSMap[Reg] = SS; | 
| Evan Cheng | 0658749 | 2008-10-24 02:05:00 +0000 | [diff] [blame] | 311 |   } | 
| Evan Cheng | d0e32c5 | 2008-10-29 05:06:14 +0000 | [diff] [blame] | 312 |  | 
 | 313 |   // Create live interval for stack slot. | 
 | 314 |   CurrSLI = &LSs->getOrCreateInterval(SS); | 
| Evan Cheng | 5489893 | 2008-10-29 08:39:34 +0000 | [diff] [blame] | 315 |   if (CurrSLI->hasAtLeastOneValue()) | 
| Evan Cheng | d0e32c5 | 2008-10-29 05:06:14 +0000 | [diff] [blame] | 316 |     CurrSValNo = CurrSLI->getValNumInfo(0); | 
 | 317 |   else | 
 | 318 |     CurrSValNo = CurrSLI->getNextValue(~0U, 0, LSs->getVNInfoAllocator()); | 
 | 319 |   return SS; | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 320 | } | 
 | 321 |  | 
| Evan Cheng | d0e32c5 | 2008-10-29 05:06:14 +0000 | [diff] [blame] | 322 | /// IsAvailableInStack - Return true if register is available in a split stack | 
 | 323 | /// slot at the specified index. | 
 | 324 | bool | 
| Evan Cheng | 5489893 | 2008-10-29 08:39:34 +0000 | [diff] [blame] | 325 | PreAllocSplitting::IsAvailableInStack(MachineBasicBlock *DefMBB, | 
 | 326 |                                     unsigned Reg, unsigned DefIndex, | 
 | 327 |                                     unsigned RestoreIndex, unsigned &SpillIndex, | 
 | 328 |                                     int& SS) const { | 
 | 329 |   if (!DefMBB) | 
 | 330 |     return false; | 
 | 331 |  | 
| Evan Cheng | d0e32c5 | 2008-10-29 05:06:14 +0000 | [diff] [blame] | 332 |   DenseMap<unsigned, int>::iterator I = IntervalSSMap.find(Reg); | 
 | 333 |   if (I == IntervalSSMap.end()) | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 334 |     return false; | 
| Evan Cheng | 5489893 | 2008-10-29 08:39:34 +0000 | [diff] [blame] | 335 |   DenseMap<unsigned, unsigned>::iterator II = Def2SpillMap.find(DefIndex); | 
 | 336 |   if (II == Def2SpillMap.end()) | 
 | 337 |     return false; | 
 | 338 |  | 
 | 339 |   // If last spill of def is in the same mbb as barrier mbb (where restore will | 
 | 340 |   // be), make sure it's not below the intended restore index. | 
 | 341 |   // FIXME: Undo the previous spill? | 
 | 342 |   assert(LIs->getMBBFromIndex(II->second) == DefMBB); | 
 | 343 |   if (DefMBB == BarrierMBB && II->second >= RestoreIndex) | 
 | 344 |     return false; | 
 | 345 |  | 
 | 346 |   SS = I->second; | 
 | 347 |   SpillIndex = II->second; | 
 | 348 |   return true; | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 349 | } | 
 | 350 |  | 
| Evan Cheng | d0e32c5 | 2008-10-29 05:06:14 +0000 | [diff] [blame] | 351 | /// UpdateSpillSlotInterval - Given the specified val# of the register live | 
 | 352 | /// interval being split, and the spill and restore indicies, update the live | 
 | 353 | /// interval of the spill stack slot. | 
 | 354 | void | 
 | 355 | PreAllocSplitting::UpdateSpillSlotInterval(VNInfo *ValNo, unsigned SpillIndex, | 
 | 356 |                                            unsigned RestoreIndex) { | 
| Evan Cheng | 5489893 | 2008-10-29 08:39:34 +0000 | [diff] [blame] | 357 |   assert(LIs->getMBBFromIndex(RestoreIndex) == BarrierMBB && | 
 | 358 |          "Expect restore in the barrier mbb"); | 
 | 359 |  | 
 | 360 |   MachineBasicBlock *MBB = LIs->getMBBFromIndex(SpillIndex); | 
 | 361 |   if (MBB == BarrierMBB) { | 
 | 362 |     // Intra-block spill + restore. We are done. | 
| Evan Cheng | d0e32c5 | 2008-10-29 05:06:14 +0000 | [diff] [blame] | 363 |     LiveRange SLR(SpillIndex, RestoreIndex, CurrSValNo); | 
 | 364 |     CurrSLI->addRange(SLR); | 
 | 365 |     return; | 
 | 366 |   } | 
 | 367 |  | 
| Evan Cheng | 5489893 | 2008-10-29 08:39:34 +0000 | [diff] [blame] | 368 |   SmallPtrSet<MachineBasicBlock*, 4> Processed; | 
 | 369 |   unsigned EndIdx = LIs->getMBBEndIdx(MBB); | 
 | 370 |   LiveRange SLR(SpillIndex, EndIdx+1, CurrSValNo); | 
| Evan Cheng | d0e32c5 | 2008-10-29 05:06:14 +0000 | [diff] [blame] | 371 |   CurrSLI->addRange(SLR); | 
| Evan Cheng | 5489893 | 2008-10-29 08:39:34 +0000 | [diff] [blame] | 372 |   Processed.insert(MBB); | 
| Evan Cheng | d0e32c5 | 2008-10-29 05:06:14 +0000 | [diff] [blame] | 373 |  | 
 | 374 |   // Start from the spill mbb, figure out the extend of the spill slot's | 
 | 375 |   // live interval. | 
 | 376 |   SmallVector<MachineBasicBlock*, 4> WorkList; | 
| Evan Cheng | 5489893 | 2008-10-29 08:39:34 +0000 | [diff] [blame] | 377 |   const LiveRange *LR = CurrLI->getLiveRangeContaining(SpillIndex); | 
 | 378 |   if (LR->end > EndIdx) | 
| Evan Cheng | d0e32c5 | 2008-10-29 05:06:14 +0000 | [diff] [blame] | 379 |     // If live range extend beyond end of mbb, add successors to work list. | 
 | 380 |     for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(), | 
 | 381 |            SE = MBB->succ_end(); SI != SE; ++SI) | 
 | 382 |       WorkList.push_back(*SI); | 
| Evan Cheng | d0e32c5 | 2008-10-29 05:06:14 +0000 | [diff] [blame] | 383 |  | 
 | 384 |   while (!WorkList.empty()) { | 
 | 385 |     MachineBasicBlock *MBB = WorkList.back(); | 
 | 386 |     WorkList.pop_back(); | 
| Evan Cheng | 5489893 | 2008-10-29 08:39:34 +0000 | [diff] [blame] | 387 |     if (Processed.count(MBB)) | 
 | 388 |       continue; | 
| Evan Cheng | d0e32c5 | 2008-10-29 05:06:14 +0000 | [diff] [blame] | 389 |     unsigned Idx = LIs->getMBBStartIdx(MBB); | 
 | 390 |     LR = CurrLI->getLiveRangeContaining(Idx); | 
| Evan Cheng | 5489893 | 2008-10-29 08:39:34 +0000 | [diff] [blame] | 391 |     if (LR && LR->valno == ValNo) { | 
 | 392 |       EndIdx = LIs->getMBBEndIdx(MBB); | 
 | 393 |       if (Idx <= RestoreIndex && RestoreIndex < EndIdx) { | 
| Evan Cheng | d0e32c5 | 2008-10-29 05:06:14 +0000 | [diff] [blame] | 394 |         // Spill slot live interval stops at the restore. | 
| Evan Cheng | 5489893 | 2008-10-29 08:39:34 +0000 | [diff] [blame] | 395 |         LiveRange SLR(Idx, RestoreIndex, CurrSValNo); | 
| Evan Cheng | d0e32c5 | 2008-10-29 05:06:14 +0000 | [diff] [blame] | 396 |         CurrSLI->addRange(SLR); | 
| Evan Cheng | 5489893 | 2008-10-29 08:39:34 +0000 | [diff] [blame] | 397 |       } else if (LR->end > EndIdx) { | 
 | 398 |         // Live range extends beyond end of mbb, process successors. | 
 | 399 |         LiveRange SLR(Idx, EndIdx+1, CurrSValNo); | 
 | 400 |         CurrSLI->addRange(SLR); | 
 | 401 |         for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(), | 
 | 402 |                SE = MBB->succ_end(); SI != SE; ++SI) | 
 | 403 |           WorkList.push_back(*SI); | 
| Evan Cheng | d0e32c5 | 2008-10-29 05:06:14 +0000 | [diff] [blame] | 404 |       } else { | 
| Evan Cheng | 5489893 | 2008-10-29 08:39:34 +0000 | [diff] [blame] | 405 |         LiveRange SLR(Idx, LR->end, CurrSValNo); | 
| Evan Cheng | d0e32c5 | 2008-10-29 05:06:14 +0000 | [diff] [blame] | 406 |         CurrSLI->addRange(SLR); | 
| Evan Cheng | d0e32c5 | 2008-10-29 05:06:14 +0000 | [diff] [blame] | 407 |       } | 
| Evan Cheng | 5489893 | 2008-10-29 08:39:34 +0000 | [diff] [blame] | 408 |       Processed.insert(MBB); | 
| Evan Cheng | d0e32c5 | 2008-10-29 05:06:14 +0000 | [diff] [blame] | 409 |     } | 
 | 410 |   } | 
 | 411 | } | 
 | 412 |  | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 413 | /// PerformPHIConstruction - From properly set up use and def lists, use a PHI | 
 | 414 | /// construction algorithm to compute the ranges and valnos for an interval. | 
 | 415 | VNInfo* PreAllocSplitting::PerformPHIConstruction( | 
 | 416 |                                                 MachineBasicBlock::iterator use, | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 417 |                                                          MachineBasicBlock* MBB, | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 418 |                                                                LiveInterval* LI, | 
| Owen Anderson | 200ee7f | 2009-01-06 07:53:32 +0000 | [diff] [blame] | 419 |                                        SmallPtrSet<MachineInstr*, 4>& Visited, | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 420 |              DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 2> >& Defs, | 
 | 421 |              DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 2> >& Uses, | 
 | 422 |                                        DenseMap<MachineInstr*, VNInfo*>& NewVNs, | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 423 |                                  DenseMap<MachineBasicBlock*, VNInfo*>& LiveOut, | 
 | 424 |                                  DenseMap<MachineBasicBlock*, VNInfo*>& Phis, | 
 | 425 |                                               bool toplevel, bool intrablock) { | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 426 |   // Return memoized result if it's available. | 
| Owen Anderson | 200ee7f | 2009-01-06 07:53:32 +0000 | [diff] [blame] | 427 |   if (toplevel && Visited.count(use) && NewVNs.count(use)) | 
 | 428 |     return NewVNs[use]; | 
 | 429 |   else if (!toplevel && intrablock && NewVNs.count(use)) | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 430 |     return NewVNs[use]; | 
 | 431 |   else if (!intrablock && LiveOut.count(MBB)) | 
 | 432 |     return LiveOut[MBB]; | 
 | 433 |    | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 434 |   typedef DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 2> > RegMap; | 
 | 435 |    | 
 | 436 |   // Check if our block contains any uses or defs. | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 437 |   bool ContainsDefs = Defs.count(MBB); | 
 | 438 |   bool ContainsUses = Uses.count(MBB); | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 439 |    | 
 | 440 |   VNInfo* ret = 0; | 
 | 441 |    | 
 | 442 |   // Enumerate the cases of use/def contaning blocks. | 
 | 443 |   if (!ContainsDefs && !ContainsUses) { | 
 | 444 |   Fallback: | 
 | 445 |     // NOTE: Because this is the fallback case from other cases, we do NOT | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 446 |     // assume that we are not intrablock here. | 
 | 447 |     if (Phis.count(MBB)) return Phis[MBB]; | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 448 |      | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 449 |     unsigned StartIndex = LIs->getMBBStartIdx(MBB); | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 450 |      | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 451 |     if (MBB->pred_size() == 1) { | 
 | 452 |       Phis[MBB] = ret = PerformPHIConstruction((*MBB->pred_begin())->end(), | 
| Owen Anderson | 200ee7f | 2009-01-06 07:53:32 +0000 | [diff] [blame] | 453 |                                           *(MBB->pred_begin()), LI, Visited, | 
 | 454 |                                           Defs, Uses, NewVNs, LiveOut, Phis, | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 455 |                                           false, false); | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 456 |       unsigned EndIndex = 0; | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 457 |       if (intrablock) { | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 458 |         EndIndex = LIs->getInstructionIndex(use); | 
 | 459 |         EndIndex = LiveIntervals::getUseIndex(EndIndex); | 
 | 460 |       } else | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 461 |         EndIndex = LIs->getMBBEndIdx(MBB); | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 462 |        | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 463 |       LI->addRange(LiveRange(StartIndex, EndIndex+1, ret)); | 
| Owen Anderson | e1762c9 | 2009-01-12 03:10:40 +0000 | [diff] [blame] | 464 |       if (intrablock) | 
 | 465 |         LI->addKill(ret, EndIndex); | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 466 |     } else { | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 467 |       Phis[MBB] = ret = LI->getNextValue(~0U, /*FIXME*/ 0, | 
 | 468 |                                           LIs->getVNInfoAllocator()); | 
 | 469 |       if (!intrablock) LiveOut[MBB] = ret; | 
 | 470 |      | 
 | 471 |       // If there are no uses or defs between our starting point and the | 
 | 472 |       // beginning of the block, then recursive perform phi construction | 
 | 473 |       // on our predecessors. | 
 | 474 |       DenseMap<MachineBasicBlock*, VNInfo*> IncomingVNs; | 
 | 475 |       for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(), | 
 | 476 |            PE = MBB->pred_end(); PI != PE; ++PI) { | 
| Owen Anderson | 200ee7f | 2009-01-06 07:53:32 +0000 | [diff] [blame] | 477 |         VNInfo* Incoming = PerformPHIConstruction((*PI)->end(), *PI, LI,  | 
 | 478 |                                             Visited, Defs, Uses, NewVNs, | 
 | 479 |                                             LiveOut, Phis, false, false); | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 480 |         if (Incoming != 0) | 
 | 481 |           IncomingVNs[*PI] = Incoming; | 
 | 482 |       } | 
 | 483 |      | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 484 |       // Otherwise, merge the incoming VNInfos with a phi join.  Create a new | 
 | 485 |       // VNInfo to represent the joined value. | 
 | 486 |       for (DenseMap<MachineBasicBlock*, VNInfo*>::iterator I = | 
 | 487 |            IncomingVNs.begin(), E = IncomingVNs.end(); I != E; ++I) { | 
 | 488 |         I->second->hasPHIKill = true; | 
 | 489 |         unsigned KillIndex = LIs->getMBBEndIdx(I->first); | 
 | 490 |         LI->addKill(I->second, KillIndex); | 
 | 491 |       } | 
 | 492 |        | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 493 |       unsigned EndIndex = 0; | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 494 |       if (intrablock) { | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 495 |         EndIndex = LIs->getInstructionIndex(use); | 
 | 496 |         EndIndex = LiveIntervals::getUseIndex(EndIndex); | 
 | 497 |       } else | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 498 |         EndIndex = LIs->getMBBEndIdx(MBB); | 
 | 499 |       LI->addRange(LiveRange(StartIndex, EndIndex+1, ret)); | 
| Owen Anderson | e1762c9 | 2009-01-12 03:10:40 +0000 | [diff] [blame] | 500 |       if (intrablock) | 
 | 501 |         LI->addKill(ret, EndIndex); | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 502 |     } | 
 | 503 |   } else if (ContainsDefs && !ContainsUses) { | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 504 |     SmallPtrSet<MachineInstr*, 2>& BlockDefs = Defs[MBB]; | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 505 |  | 
 | 506 |     // Search for the def in this block.  If we don't find it before the | 
 | 507 |     // instruction we care about, go to the fallback case.  Note that that | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 508 |     // should never happen: this cannot be intrablock, so use should | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 509 |     // always be an end() iterator. | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 510 |     assert(use == MBB->end() && "No use marked in intrablock"); | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 511 |      | 
 | 512 |     MachineBasicBlock::iterator walker = use; | 
 | 513 |     --walker; | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 514 |     while (walker != MBB->begin()) | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 515 |       if (BlockDefs.count(walker)) { | 
 | 516 |         break; | 
 | 517 |       } else | 
 | 518 |         --walker; | 
 | 519 |      | 
 | 520 |     // Once we've found it, extend its VNInfo to our instruction. | 
 | 521 |     unsigned DefIndex = LIs->getInstructionIndex(walker); | 
 | 522 |     DefIndex = LiveIntervals::getDefIndex(DefIndex); | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 523 |     unsigned EndIndex = LIs->getMBBEndIdx(MBB); | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 524 |      | 
 | 525 |     ret = NewVNs[walker]; | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 526 |     LI->addRange(LiveRange(DefIndex, EndIndex+1, ret)); | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 527 |   } else if (!ContainsDefs && ContainsUses) { | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 528 |     SmallPtrSet<MachineInstr*, 2>& BlockUses = Uses[MBB]; | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 529 |      | 
 | 530 |     // Search for the use in this block that precedes the instruction we care  | 
 | 531 |     // about, going to the fallback case if we don't find it. | 
 | 532 |      | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 533 |     if (use == MBB->begin()) | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 534 |       goto Fallback; | 
 | 535 |      | 
 | 536 |     MachineBasicBlock::iterator walker = use; | 
 | 537 |     --walker; | 
 | 538 |     bool found = false; | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 539 |     while (walker != MBB->begin()) | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 540 |       if (BlockUses.count(walker)) { | 
 | 541 |         found = true; | 
 | 542 |         break; | 
 | 543 |       } else | 
 | 544 |         --walker; | 
 | 545 |          | 
 | 546 |     // Must check begin() too. | 
| Duncan Sands | 2b7fc1e | 2008-12-29 08:05:02 +0000 | [diff] [blame] | 547 |     if (!found) { | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 548 |       if (BlockUses.count(walker)) | 
 | 549 |         found = true; | 
 | 550 |       else | 
 | 551 |         goto Fallback; | 
| Duncan Sands | 2b7fc1e | 2008-12-29 08:05:02 +0000 | [diff] [blame] | 552 |     } | 
 | 553 |  | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 554 |     unsigned UseIndex = LIs->getInstructionIndex(walker); | 
 | 555 |     UseIndex = LiveIntervals::getUseIndex(UseIndex); | 
 | 556 |     unsigned EndIndex = 0; | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 557 |     if (intrablock) { | 
 | 558 |       EndIndex = LIs->getInstructionIndex(use); | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 559 |       EndIndex = LiveIntervals::getUseIndex(EndIndex); | 
 | 560 |     } else | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 561 |       EndIndex = LIs->getMBBEndIdx(MBB); | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 562 |  | 
 | 563 |     // Now, recursively phi construct the VNInfo for the use we found, | 
 | 564 |     // and then extend it to include the instruction we care about | 
| Owen Anderson | 200ee7f | 2009-01-06 07:53:32 +0000 | [diff] [blame] | 565 |     ret = PerformPHIConstruction(walker, MBB, LI, Visited, Defs, Uses, | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 566 |                                  NewVNs, LiveOut, Phis, false, true); | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 567 |      | 
| Owen Anderson | b4b8436 | 2009-01-26 21:57:31 +0000 | [diff] [blame] | 568 |     LI->addRange(LiveRange(UseIndex, EndIndex+1, ret)); | 
 | 569 |      | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 570 |     // FIXME: Need to set kills properly for inter-block stuff. | 
| Owen Anderson | d4f6fe5 | 2008-12-28 23:35:13 +0000 | [diff] [blame] | 571 |     if (LI->isKill(ret, UseIndex)) LI->removeKill(ret, UseIndex); | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 572 |     if (intrablock) | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 573 |       LI->addKill(ret, EndIndex); | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 574 |   } else if (ContainsDefs && ContainsUses){ | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 575 |     SmallPtrSet<MachineInstr*, 2>& BlockDefs = Defs[MBB]; | 
 | 576 |     SmallPtrSet<MachineInstr*, 2>& BlockUses = Uses[MBB]; | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 577 |      | 
 | 578 |     // This case is basically a merging of the two preceding case, with the | 
 | 579 |     // special note that checking for defs must take precedence over checking | 
 | 580 |     // for uses, because of two-address instructions. | 
 | 581 |      | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 582 |     if (use == MBB->begin()) | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 583 |       goto Fallback; | 
 | 584 |      | 
 | 585 |     MachineBasicBlock::iterator walker = use; | 
 | 586 |     --walker; | 
 | 587 |     bool foundDef = false; | 
 | 588 |     bool foundUse = false; | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 589 |     while (walker != MBB->begin()) | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 590 |       if (BlockDefs.count(walker)) { | 
 | 591 |         foundDef = true; | 
 | 592 |         break; | 
 | 593 |       } else if (BlockUses.count(walker)) { | 
 | 594 |         foundUse = true; | 
 | 595 |         break; | 
 | 596 |       } else | 
 | 597 |         --walker; | 
 | 598 |          | 
 | 599 |     // Must check begin() too. | 
| Duncan Sands | 2b7fc1e | 2008-12-29 08:05:02 +0000 | [diff] [blame] | 600 |     if (!foundDef && !foundUse) { | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 601 |       if (BlockDefs.count(walker)) | 
 | 602 |         foundDef = true; | 
 | 603 |       else if (BlockUses.count(walker)) | 
 | 604 |         foundUse = true; | 
 | 605 |       else | 
 | 606 |         goto Fallback; | 
| Duncan Sands | 2b7fc1e | 2008-12-29 08:05:02 +0000 | [diff] [blame] | 607 |     } | 
 | 608 |  | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 609 |     unsigned StartIndex = LIs->getInstructionIndex(walker); | 
 | 610 |     StartIndex = foundDef ? LiveIntervals::getDefIndex(StartIndex) : | 
 | 611 |                             LiveIntervals::getUseIndex(StartIndex); | 
 | 612 |     unsigned EndIndex = 0; | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 613 |     if (intrablock) { | 
 | 614 |       EndIndex = LIs->getInstructionIndex(use); | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 615 |       EndIndex = LiveIntervals::getUseIndex(EndIndex); | 
 | 616 |     } else | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 617 |       EndIndex = LIs->getMBBEndIdx(MBB); | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 618 |  | 
 | 619 |     if (foundDef) | 
 | 620 |       ret = NewVNs[walker]; | 
 | 621 |     else | 
| Owen Anderson | 200ee7f | 2009-01-06 07:53:32 +0000 | [diff] [blame] | 622 |       ret = PerformPHIConstruction(walker, MBB, LI, Visited, Defs, Uses, | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 623 |                                    NewVNs, LiveOut, Phis, false, true); | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 624 |  | 
| Owen Anderson | b4b8436 | 2009-01-26 21:57:31 +0000 | [diff] [blame] | 625 |     LI->addRange(LiveRange(StartIndex, EndIndex+1, ret)); | 
 | 626 |      | 
| Owen Anderson | d4f6fe5 | 2008-12-28 23:35:13 +0000 | [diff] [blame] | 627 |     if (foundUse && LI->isKill(ret, StartIndex)) | 
 | 628 |       LI->removeKill(ret, StartIndex); | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 629 |     if (intrablock) { | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 630 |       LI->addKill(ret, EndIndex); | 
 | 631 |     } | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 632 |   } | 
 | 633 |    | 
 | 634 |   // Memoize results so we don't have to recompute them. | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 635 |   if (!intrablock) LiveOut[MBB] = ret; | 
| Owen Anderson | 200ee7f | 2009-01-06 07:53:32 +0000 | [diff] [blame] | 636 |   else { | 
| Owen Anderson | e1762c9 | 2009-01-12 03:10:40 +0000 | [diff] [blame] | 637 |     if (!NewVNs.count(use)) | 
 | 638 |       NewVNs[use] = ret; | 
| Owen Anderson | 200ee7f | 2009-01-06 07:53:32 +0000 | [diff] [blame] | 639 |     Visited.insert(use); | 
 | 640 |   } | 
 | 641 |  | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 642 |   return ret; | 
 | 643 | } | 
 | 644 |  | 
 | 645 | /// ReconstructLiveInterval - Recompute a live interval from scratch. | 
 | 646 | void PreAllocSplitting::ReconstructLiveInterval(LiveInterval* LI) { | 
 | 647 |   BumpPtrAllocator& Alloc = LIs->getVNInfoAllocator(); | 
 | 648 |    | 
 | 649 |   // Clear the old ranges and valnos; | 
 | 650 |   LI->clear(); | 
 | 651 |    | 
 | 652 |   // Cache the uses and defs of the register | 
 | 653 |   typedef DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 2> > RegMap; | 
 | 654 |   RegMap Defs, Uses; | 
 | 655 |    | 
 | 656 |   // Keep track of the new VNs we're creating. | 
 | 657 |   DenseMap<MachineInstr*, VNInfo*> NewVNs; | 
 | 658 |   SmallPtrSet<VNInfo*, 2> PhiVNs; | 
 | 659 |    | 
 | 660 |   // Cache defs, and create a new VNInfo for each def. | 
 | 661 |   for (MachineRegisterInfo::def_iterator DI = MRI->def_begin(LI->reg), | 
 | 662 |        DE = MRI->def_end(); DI != DE; ++DI) { | 
 | 663 |     Defs[(*DI).getParent()].insert(&*DI); | 
 | 664 |      | 
 | 665 |     unsigned DefIdx = LIs->getInstructionIndex(&*DI); | 
 | 666 |     DefIdx = LiveIntervals::getDefIndex(DefIdx); | 
 | 667 |      | 
| Owen Anderson | 200ee7f | 2009-01-06 07:53:32 +0000 | [diff] [blame] | 668 |     VNInfo* NewVN = LI->getNextValue(DefIdx, 0, Alloc); | 
 | 669 |      | 
 | 670 |     // If the def is a move, set the copy field. | 
| Evan Cheng | 04ee5a1 | 2009-01-20 19:12:24 +0000 | [diff] [blame] | 671 |     unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx; | 
 | 672 |     if (TII->isMoveInstr(*DI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)) | 
 | 673 |       if (DstReg == LI->reg) | 
| Owen Anderson | 200ee7f | 2009-01-06 07:53:32 +0000 | [diff] [blame] | 674 |         NewVN->copy = &*DI; | 
 | 675 |      | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 676 |     NewVNs[&*DI] = NewVN; | 
 | 677 |   } | 
 | 678 |    | 
 | 679 |   // Cache uses as a separate pass from actually processing them. | 
 | 680 |   for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(LI->reg), | 
 | 681 |        UE = MRI->use_end(); UI != UE; ++UI) | 
 | 682 |     Uses[(*UI).getParent()].insert(&*UI); | 
 | 683 |      | 
 | 684 |   // Now, actually process every use and use a phi construction algorithm | 
 | 685 |   // to walk from it to its reaching definitions, building VNInfos along | 
 | 686 |   // the way. | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 687 |   DenseMap<MachineBasicBlock*, VNInfo*> LiveOut; | 
 | 688 |   DenseMap<MachineBasicBlock*, VNInfo*> Phis; | 
| Owen Anderson | 200ee7f | 2009-01-06 07:53:32 +0000 | [diff] [blame] | 689 |   SmallPtrSet<MachineInstr*, 4> Visited; | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 690 |   for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(LI->reg), | 
 | 691 |        UE = MRI->use_end(); UI != UE; ++UI) { | 
| Owen Anderson | 200ee7f | 2009-01-06 07:53:32 +0000 | [diff] [blame] | 692 |     PerformPHIConstruction(&*UI, UI->getParent(), LI, Visited, Defs, | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 693 |                            Uses, NewVNs, LiveOut, Phis, true, true);  | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 694 |   } | 
| Owen Anderson | d4f6fe5 | 2008-12-28 23:35:13 +0000 | [diff] [blame] | 695 |    | 
 | 696 |   // Add ranges for dead defs | 
 | 697 |   for (MachineRegisterInfo::def_iterator DI = MRI->def_begin(LI->reg), | 
 | 698 |        DE = MRI->def_end(); DI != DE; ++DI) { | 
 | 699 |     unsigned DefIdx = LIs->getInstructionIndex(&*DI); | 
 | 700 |     DefIdx = LiveIntervals::getDefIndex(DefIdx); | 
| Owen Anderson | d4f6fe5 | 2008-12-28 23:35:13 +0000 | [diff] [blame] | 701 |      | 
 | 702 |     if (LI->liveAt(DefIdx)) continue; | 
 | 703 |      | 
 | 704 |     VNInfo* DeadVN = NewVNs[&*DI]; | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 705 |     LI->addRange(LiveRange(DefIdx, DefIdx+1, DeadVN)); | 
| Owen Anderson | d4f6fe5 | 2008-12-28 23:35:13 +0000 | [diff] [blame] | 706 |     LI->addKill(DeadVN, DefIdx); | 
 | 707 |   } | 
| Owen Anderson | 60d4f6d | 2008-12-28 21:48:48 +0000 | [diff] [blame] | 708 | } | 
 | 709 |  | 
| Owen Anderson | d0b6a0d | 2008-12-16 21:35:08 +0000 | [diff] [blame] | 710 | /// RenumberValno - Split the given valno out into a new vreg, allowing it to | 
 | 711 | /// be allocated to a different register.  This function creates a new vreg, | 
 | 712 | /// copies the valno and its live ranges over to the new vreg's interval, | 
 | 713 | /// removes them from the old interval, and rewrites all uses and defs of | 
 | 714 | /// the original reg to the new vreg within those ranges. | 
 | 715 | void PreAllocSplitting::RenumberValno(VNInfo* VN) { | 
| Owen Anderson | 2ebf63f | 2008-12-18 01:27:19 +0000 | [diff] [blame] | 716 |   SmallVector<VNInfo*, 4> Stack; | 
 | 717 |   SmallVector<VNInfo*, 4> VNsToCopy; | 
 | 718 |   Stack.push_back(VN); | 
 | 719 |  | 
 | 720 |   // Walk through and copy the valno we care about, and any other valnos | 
 | 721 |   // that are two-address redefinitions of the one we care about.  These | 
 | 722 |   // will need to be rewritten as well.  We also check for safety of the  | 
 | 723 |   // renumbering here, by making sure that none of the valno involved has | 
 | 724 |   // phi kills. | 
 | 725 |   while (!Stack.empty()) { | 
 | 726 |     VNInfo* OldVN = Stack.back(); | 
 | 727 |     Stack.pop_back(); | 
 | 728 |      | 
 | 729 |     // Bail out if we ever encounter a valno that has a PHI kill.  We can't | 
 | 730 |     // renumber these. | 
 | 731 |     if (OldVN->hasPHIKill) return; | 
 | 732 |      | 
 | 733 |     VNsToCopy.push_back(OldVN); | 
 | 734 |      | 
 | 735 |     // Locate two-address redefinitions | 
 | 736 |     for (SmallVector<unsigned, 4>::iterator KI = OldVN->kills.begin(), | 
 | 737 |          KE = OldVN->kills.end(); KI != KE; ++KI) { | 
 | 738 |       MachineInstr* MI = LIs->getInstructionFromIndex(*KI); | 
| Owen Anderson | 2ebf63f | 2008-12-18 01:27:19 +0000 | [diff] [blame] | 739 |       unsigned DefIdx = MI->findRegisterDefOperandIdx(CurrLI->reg); | 
 | 740 |       if (DefIdx == ~0U) continue; | 
 | 741 |       if (MI->isRegReDefinedByTwoAddr(DefIdx)) { | 
 | 742 |         VNInfo* NextVN = | 
 | 743 |                      CurrLI->findDefinedVNInfo(LiveIntervals::getDefIndex(*KI)); | 
| Owen Anderson | b4b8436 | 2009-01-26 21:57:31 +0000 | [diff] [blame] | 744 |         if (NextVN == OldVN) continue; | 
| Owen Anderson | 2ebf63f | 2008-12-18 01:27:19 +0000 | [diff] [blame] | 745 |         Stack.push_back(NextVN); | 
 | 746 |       } | 
 | 747 |     } | 
 | 748 |   } | 
 | 749 |    | 
| Owen Anderson | d0b6a0d | 2008-12-16 21:35:08 +0000 | [diff] [blame] | 750 |   // Create the new vreg | 
 | 751 |   unsigned NewVReg = MRI->createVirtualRegister(MRI->getRegClass(CurrLI->reg)); | 
 | 752 |    | 
| Owen Anderson | 2ebf63f | 2008-12-18 01:27:19 +0000 | [diff] [blame] | 753 |   // Create the new live interval | 
| Owen Anderson | d0b6a0d | 2008-12-16 21:35:08 +0000 | [diff] [blame] | 754 |   LiveInterval& NewLI = LIs->getOrCreateInterval(NewVReg); | 
| Owen Anderson | d0b6a0d | 2008-12-16 21:35:08 +0000 | [diff] [blame] | 755 |    | 
| Owen Anderson | 2ebf63f | 2008-12-18 01:27:19 +0000 | [diff] [blame] | 756 |   for (SmallVector<VNInfo*, 4>::iterator OI = VNsToCopy.begin(), OE =  | 
 | 757 |        VNsToCopy.end(); OI != OE; ++OI) { | 
 | 758 |     VNInfo* OldVN = *OI; | 
 | 759 |      | 
 | 760 |     // Copy the valno over | 
 | 761 |     VNInfo* NewVN = NewLI.getNextValue(OldVN->def, OldVN->copy,  | 
 | 762 |                                        LIs->getVNInfoAllocator()); | 
 | 763 |     NewLI.copyValNumInfo(NewVN, OldVN); | 
 | 764 |     NewLI.MergeValueInAsValue(*CurrLI, OldVN, NewVN); | 
 | 765 |  | 
 | 766 |     // Remove the valno from the old interval | 
 | 767 |     CurrLI->removeValNo(OldVN); | 
 | 768 |   } | 
| Owen Anderson | d0b6a0d | 2008-12-16 21:35:08 +0000 | [diff] [blame] | 769 |    | 
 | 770 |   // Rewrite defs and uses.  This is done in two stages to avoid invalidating | 
 | 771 |   // the reg_iterator. | 
 | 772 |   SmallVector<std::pair<MachineInstr*, unsigned>, 8> OpsToChange; | 
 | 773 |    | 
 | 774 |   for (MachineRegisterInfo::reg_iterator I = MRI->reg_begin(CurrLI->reg), | 
 | 775 |          E = MRI->reg_end(); I != E; ++I) { | 
 | 776 |     MachineOperand& MO = I.getOperand(); | 
 | 777 |     unsigned InstrIdx = LIs->getInstructionIndex(&*I); | 
 | 778 |      | 
 | 779 |     if ((MO.isUse() && NewLI.liveAt(LiveIntervals::getUseIndex(InstrIdx))) || | 
 | 780 |         (MO.isDef() && NewLI.liveAt(LiveIntervals::getDefIndex(InstrIdx)))) | 
 | 781 |       OpsToChange.push_back(std::make_pair(&*I, I.getOperandNo())); | 
 | 782 |   } | 
 | 783 |    | 
 | 784 |   for (SmallVector<std::pair<MachineInstr*, unsigned>, 8>::iterator I = | 
 | 785 |        OpsToChange.begin(), E = OpsToChange.end(); I != E; ++I) { | 
 | 786 |     MachineInstr* Inst = I->first; | 
 | 787 |     unsigned OpIdx = I->second; | 
 | 788 |     MachineOperand& MO = Inst->getOperand(OpIdx); | 
 | 789 |     MO.setReg(NewVReg); | 
 | 790 |   } | 
| Owen Anderson | 2ebf63f | 2008-12-18 01:27:19 +0000 | [diff] [blame] | 791 |    | 
 | 792 |   NumRenumbers++; | 
| Owen Anderson | d0b6a0d | 2008-12-16 21:35:08 +0000 | [diff] [blame] | 793 | } | 
 | 794 |  | 
| Owen Anderson | 6002e99 | 2008-12-04 21:20:30 +0000 | [diff] [blame] | 795 | bool PreAllocSplitting::Rematerialize(unsigned vreg, VNInfo* ValNo, | 
 | 796 |                                       MachineInstr* DefMI, | 
 | 797 |                                       MachineBasicBlock::iterator RestorePt, | 
 | 798 |                                       unsigned RestoreIdx, | 
 | 799 |                                     SmallPtrSet<MachineInstr*, 4>& RefsInMBB) { | 
 | 800 |   MachineBasicBlock& MBB = *RestorePt->getParent(); | 
 | 801 |    | 
 | 802 |   MachineBasicBlock::iterator KillPt = BarrierMBB->end(); | 
 | 803 |   unsigned KillIdx = 0; | 
 | 804 |   if (ValNo->def == ~0U || DefMI->getParent() == BarrierMBB) | 
 | 805 |     KillPt = findSpillPoint(BarrierMBB, Barrier, NULL, RefsInMBB, KillIdx); | 
 | 806 |   else | 
 | 807 |     KillPt = findNextEmptySlot(DefMI->getParent(), DefMI, KillIdx); | 
 | 808 |    | 
 | 809 |   if (KillPt == DefMI->getParent()->end()) | 
 | 810 |     return false; | 
 | 811 |    | 
 | 812 |   TII->reMaterialize(MBB, RestorePt, vreg, DefMI); | 
 | 813 |   LIs->InsertMachineInstrInMaps(prior(RestorePt), RestoreIdx); | 
 | 814 |    | 
| Owen Anderson | b4b8436 | 2009-01-26 21:57:31 +0000 | [diff] [blame] | 815 |   ReconstructLiveInterval(CurrLI); | 
 | 816 |   unsigned RematIdx = LIs->getInstructionIndex(prior(RestorePt)); | 
 | 817 |   RematIdx = LiveIntervals::getDefIndex(RematIdx); | 
 | 818 |   RenumberValno(CurrLI->findDefinedVNInfo(RematIdx)); | 
| Owen Anderson | e1762c9 | 2009-01-12 03:10:40 +0000 | [diff] [blame] | 819 |    | 
| Owen Anderson | 75fa96b | 2008-11-19 04:28:29 +0000 | [diff] [blame] | 820 |   ++NumSplits; | 
 | 821 |   ++NumRemats; | 
| Owen Anderson | 7b9d67c | 2008-12-02 18:53:47 +0000 | [diff] [blame] | 822 |   return true;   | 
 | 823 | } | 
 | 824 |  | 
 | 825 | MachineInstr* PreAllocSplitting::FoldSpill(unsigned vreg,  | 
 | 826 |                                            const TargetRegisterClass* RC, | 
 | 827 |                                            MachineInstr* DefMI, | 
 | 828 |                                            MachineInstr* Barrier, | 
 | 829 |                                            MachineBasicBlock* MBB, | 
 | 830 |                                            int& SS, | 
 | 831 |                                     SmallPtrSet<MachineInstr*, 4>& RefsInMBB) { | 
 | 832 |   MachineBasicBlock::iterator Pt = MBB->begin(); | 
 | 833 |  | 
 | 834 |   // Go top down if RefsInMBB is empty. | 
 | 835 |   if (RefsInMBB.empty()) | 
 | 836 |     return 0; | 
| Owen Anderson | 75fa96b | 2008-11-19 04:28:29 +0000 | [diff] [blame] | 837 |    | 
| Owen Anderson | 7b9d67c | 2008-12-02 18:53:47 +0000 | [diff] [blame] | 838 |   MachineBasicBlock::iterator FoldPt = Barrier; | 
 | 839 |   while (&*FoldPt != DefMI && FoldPt != MBB->begin() && | 
 | 840 |          !RefsInMBB.count(FoldPt)) | 
 | 841 |     --FoldPt; | 
 | 842 |    | 
 | 843 |   int OpIdx = FoldPt->findRegisterDefOperandIdx(vreg, false); | 
 | 844 |   if (OpIdx == -1) | 
 | 845 |     return 0; | 
 | 846 |    | 
 | 847 |   SmallVector<unsigned, 1> Ops; | 
 | 848 |   Ops.push_back(OpIdx); | 
 | 849 |    | 
 | 850 |   if (!TII->canFoldMemoryOperand(FoldPt, Ops)) | 
 | 851 |     return 0; | 
 | 852 |    | 
 | 853 |   DenseMap<unsigned, int>::iterator I = IntervalSSMap.find(vreg); | 
 | 854 |   if (I != IntervalSSMap.end()) { | 
 | 855 |     SS = I->second; | 
 | 856 |   } else { | 
 | 857 |     SS = MFI->CreateStackObject(RC->getSize(), RC->getAlignment()); | 
 | 858 |      | 
 | 859 |   } | 
 | 860 |    | 
 | 861 |   MachineInstr* FMI = TII->foldMemoryOperand(*MBB->getParent(), | 
 | 862 |                                              FoldPt, Ops, SS); | 
 | 863 |    | 
 | 864 |   if (FMI) { | 
 | 865 |     LIs->ReplaceMachineInstrInMaps(FoldPt, FMI); | 
 | 866 |     FMI = MBB->insert(MBB->erase(FoldPt), FMI); | 
 | 867 |     ++NumFolds; | 
 | 868 |      | 
 | 869 |     IntervalSSMap[vreg] = SS; | 
 | 870 |     CurrSLI = &LSs->getOrCreateInterval(SS); | 
 | 871 |     if (CurrSLI->hasAtLeastOneValue()) | 
 | 872 |       CurrSValNo = CurrSLI->getValNumInfo(0); | 
 | 873 |     else | 
 | 874 |       CurrSValNo = CurrSLI->getNextValue(~0U, 0, LSs->getVNInfoAllocator()); | 
 | 875 |   } | 
 | 876 |    | 
 | 877 |   return FMI; | 
| Owen Anderson | 75fa96b | 2008-11-19 04:28:29 +0000 | [diff] [blame] | 878 | } | 
 | 879 |  | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 880 | /// SplitRegLiveInterval - Split (spill and restore) the given live interval | 
 | 881 | /// so it would not cross the barrier that's being processed. Shrink wrap | 
 | 882 | /// (minimize) the live interval to the last uses. | 
 | 883 | bool PreAllocSplitting::SplitRegLiveInterval(LiveInterval *LI) { | 
 | 884 |   CurrLI = LI; | 
 | 885 |  | 
 | 886 |   // Find live range where current interval cross the barrier. | 
 | 887 |   LiveInterval::iterator LR = | 
 | 888 |     CurrLI->FindLiveRangeContaining(LIs->getUseIndex(BarrierIdx)); | 
 | 889 |   VNInfo *ValNo = LR->valno; | 
 | 890 |  | 
 | 891 |   if (ValNo->def == ~1U) { | 
 | 892 |     // Defined by a dead def? How can this be? | 
 | 893 |     assert(0 && "Val# is defined by a dead def?"); | 
 | 894 |     abort(); | 
 | 895 |   } | 
 | 896 |  | 
| Evan Cheng | 0658749 | 2008-10-24 02:05:00 +0000 | [diff] [blame] | 897 |   MachineInstr *DefMI = (ValNo->def != ~0U) | 
 | 898 |     ? LIs->getInstructionFromIndex(ValNo->def) : NULL; | 
| Evan Cheng | 0658749 | 2008-10-24 02:05:00 +0000 | [diff] [blame] | 899 |  | 
| Owen Anderson | d3be462 | 2009-01-21 08:18:03 +0000 | [diff] [blame] | 900 |   // If this would create a new join point, do not split. | 
 | 901 |   if (DefMI && createsNewJoin(LR, DefMI->getParent(), Barrier->getParent())) | 
 | 902 |     return false; | 
 | 903 |  | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 904 |   // Find all references in the barrier mbb. | 
 | 905 |   SmallPtrSet<MachineInstr*, 4> RefsInMBB; | 
 | 906 |   for (MachineRegisterInfo::reg_iterator I = MRI->reg_begin(CurrLI->reg), | 
 | 907 |          E = MRI->reg_end(); I != E; ++I) { | 
 | 908 |     MachineInstr *RefMI = &*I; | 
 | 909 |     if (RefMI->getParent() == BarrierMBB) | 
 | 910 |       RefsInMBB.insert(RefMI); | 
 | 911 |   } | 
 | 912 |  | 
 | 913 |   // Find a point to restore the value after the barrier. | 
| Evan Cheng | b964f33 | 2009-01-26 18:33:51 +0000 | [diff] [blame] | 914 |   unsigned RestoreIndex = 0; | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 915 |   MachineBasicBlock::iterator RestorePt = | 
| Evan Cheng | f62ce37 | 2008-10-28 00:47:49 +0000 | [diff] [blame] | 916 |     findRestorePoint(BarrierMBB, Barrier, LR->end, RefsInMBB, RestoreIndex); | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 917 |   if (RestorePt == BarrierMBB->end()) | 
 | 918 |     return false; | 
 | 919 |  | 
| Owen Anderson | 75fa96b | 2008-11-19 04:28:29 +0000 | [diff] [blame] | 920 |   if (DefMI && LIs->isReMaterializable(*LI, ValNo, DefMI)) | 
 | 921 |     if (Rematerialize(LI->reg, ValNo, DefMI, RestorePt, | 
 | 922 |                       RestoreIndex, RefsInMBB)) | 
 | 923 |     return true; | 
 | 924 |  | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 925 |   // Add a spill either before the barrier or after the definition. | 
| Evan Cheng | 0658749 | 2008-10-24 02:05:00 +0000 | [diff] [blame] | 926 |   MachineBasicBlock *DefMBB = DefMI ? DefMI->getParent() : NULL; | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 927 |   const TargetRegisterClass *RC = MRI->getRegClass(CurrLI->reg); | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 928 |   unsigned SpillIndex = 0; | 
| Evan Cheng | 0658749 | 2008-10-24 02:05:00 +0000 | [diff] [blame] | 929 |   MachineInstr *SpillMI = NULL; | 
| Evan Cheng | 985921e | 2008-10-27 23:29:28 +0000 | [diff] [blame] | 930 |   int SS = -1; | 
| Evan Cheng | 78dfef7 | 2008-10-25 00:52:41 +0000 | [diff] [blame] | 931 |   if (ValNo->def == ~0U) { | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 932 |     // If it's defined by a phi, we must split just before the barrier. | 
| Owen Anderson | 7b9d67c | 2008-12-02 18:53:47 +0000 | [diff] [blame] | 933 |     if ((SpillMI = FoldSpill(LI->reg, RC, 0, Barrier, | 
 | 934 |                             BarrierMBB, SS, RefsInMBB))) { | 
 | 935 |       SpillIndex = LIs->getInstructionIndex(SpillMI); | 
 | 936 |     } else { | 
 | 937 |       MachineBasicBlock::iterator SpillPt =  | 
 | 938 |         findSpillPoint(BarrierMBB, Barrier, NULL, RefsInMBB, SpillIndex); | 
 | 939 |       if (SpillPt == BarrierMBB->begin()) | 
 | 940 |         return false; // No gap to insert spill. | 
 | 941 |       // Add spill. | 
 | 942 |      | 
 | 943 |       SS = CreateSpillStackSlot(CurrLI->reg, RC); | 
 | 944 |       TII->storeRegToStackSlot(*BarrierMBB, SpillPt, CurrLI->reg, true, SS, RC); | 
 | 945 |       SpillMI = prior(SpillPt); | 
 | 946 |       LIs->InsertMachineInstrInMaps(SpillMI, SpillIndex); | 
 | 947 |     } | 
| Evan Cheng | 5489893 | 2008-10-29 08:39:34 +0000 | [diff] [blame] | 948 |   } else if (!IsAvailableInStack(DefMBB, CurrLI->reg, ValNo->def, | 
 | 949 |                                  RestoreIndex, SpillIndex, SS)) { | 
| Evan Cheng | 78dfef7 | 2008-10-25 00:52:41 +0000 | [diff] [blame] | 950 |     // If it's already split, just restore the value. There is no need to spill | 
 | 951 |     // the def again. | 
| Evan Cheng | d0e32c5 | 2008-10-29 05:06:14 +0000 | [diff] [blame] | 952 |     if (!DefMI) | 
 | 953 |       return false; // Def is dead. Do nothing. | 
| Owen Anderson | 7b9d67c | 2008-12-02 18:53:47 +0000 | [diff] [blame] | 954 |      | 
 | 955 |     if ((SpillMI = FoldSpill(LI->reg, RC, DefMI, Barrier, | 
 | 956 |                             BarrierMBB, SS, RefsInMBB))) { | 
 | 957 |       SpillIndex = LIs->getInstructionIndex(SpillMI); | 
| Evan Cheng | 1f08cc2 | 2008-10-28 05:28:21 +0000 | [diff] [blame] | 958 |     } else { | 
| Owen Anderson | 7b9d67c | 2008-12-02 18:53:47 +0000 | [diff] [blame] | 959 |       // Check if it's possible to insert a spill after the def MI. | 
 | 960 |       MachineBasicBlock::iterator SpillPt; | 
 | 961 |       if (DefMBB == BarrierMBB) { | 
 | 962 |         // Add spill after the def and the last use before the barrier. | 
 | 963 |         SpillPt = findSpillPoint(BarrierMBB, Barrier, DefMI, | 
 | 964 |                                  RefsInMBB, SpillIndex); | 
 | 965 |         if (SpillPt == DefMBB->begin()) | 
 | 966 |           return false; // No gap to insert spill. | 
 | 967 |       } else { | 
 | 968 |         SpillPt = findNextEmptySlot(DefMBB, DefMI, SpillIndex); | 
 | 969 |         if (SpillPt == DefMBB->end()) | 
 | 970 |           return false; // No gap to insert spill. | 
 | 971 |       } | 
 | 972 |       // Add spill. The store instruction kills the register if def is before | 
 | 973 |       // the barrier in the barrier block. | 
 | 974 |       SS = CreateSpillStackSlot(CurrLI->reg, RC); | 
 | 975 |       TII->storeRegToStackSlot(*DefMBB, SpillPt, CurrLI->reg, | 
 | 976 |                                DefMBB == BarrierMBB, SS, RC); | 
 | 977 |       SpillMI = prior(SpillPt); | 
 | 978 |       LIs->InsertMachineInstrInMaps(SpillMI, SpillIndex); | 
| Evan Cheng | 1f08cc2 | 2008-10-28 05:28:21 +0000 | [diff] [blame] | 979 |     } | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 980 |   } | 
 | 981 |  | 
| Evan Cheng | 5489893 | 2008-10-29 08:39:34 +0000 | [diff] [blame] | 982 |   // Remember def instruction index to spill index mapping. | 
 | 983 |   if (DefMI && SpillMI) | 
 | 984 |     Def2SpillMap[ValNo->def] = SpillIndex; | 
 | 985 |  | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 986 |   // Add restore. | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 987 |   TII->loadRegFromStackSlot(*BarrierMBB, RestorePt, CurrLI->reg, SS, RC); | 
 | 988 |   MachineInstr *LoadMI = prior(RestorePt); | 
 | 989 |   LIs->InsertMachineInstrInMaps(LoadMI, RestoreIndex); | 
 | 990 |  | 
| Evan Cheng | d0e32c5 | 2008-10-29 05:06:14 +0000 | [diff] [blame] | 991 |   // Update spill stack slot live interval. | 
| Evan Cheng | 5489893 | 2008-10-29 08:39:34 +0000 | [diff] [blame] | 992 |   UpdateSpillSlotInterval(ValNo, LIs->getUseIndex(SpillIndex)+1, | 
 | 993 |                           LIs->getDefIndex(RestoreIndex)); | 
| Evan Cheng | d0e32c5 | 2008-10-29 05:06:14 +0000 | [diff] [blame] | 994 |  | 
| Owen Anderson | b4b8436 | 2009-01-26 21:57:31 +0000 | [diff] [blame] | 995 |   ReconstructLiveInterval(CurrLI); | 
 | 996 |   unsigned RestoreIdx = LIs->getInstructionIndex(prior(RestorePt)); | 
 | 997 |   RestoreIdx = LiveIntervals::getDefIndex(RestoreIdx); | 
 | 998 |   RenumberValno(CurrLI->findDefinedVNInfo(RestoreIdx)); | 
| Owen Anderson | 7d211e2 | 2008-12-31 02:00:25 +0000 | [diff] [blame] | 999 |    | 
| Evan Cheng | ae7fa5b | 2008-10-28 01:48:24 +0000 | [diff] [blame] | 1000 |   ++NumSplits; | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 1001 |   return true; | 
 | 1002 | } | 
 | 1003 |  | 
 | 1004 | /// SplitRegLiveIntervals - Split all register live intervals that cross the | 
 | 1005 | /// barrier that's being processed. | 
 | 1006 | bool | 
| Owen Anderson | 956ec27 | 2009-01-23 00:23:32 +0000 | [diff] [blame] | 1007 | PreAllocSplitting::SplitRegLiveIntervals(const TargetRegisterClass **RCs, | 
 | 1008 |                                          SmallPtrSet<LiveInterval*, 8>& Split) { | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 1009 |   // First find all the virtual registers whose live intervals are intercepted | 
 | 1010 |   // by the current barrier. | 
 | 1011 |   SmallVector<LiveInterval*, 8> Intervals; | 
 | 1012 |   for (const TargetRegisterClass **RC = RCs; *RC; ++RC) { | 
| Evan Cheng | 2306628 | 2008-10-27 07:14:50 +0000 | [diff] [blame] | 1013 |     if (TII->IgnoreRegisterClassBarriers(*RC)) | 
 | 1014 |       continue; | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 1015 |     std::vector<unsigned> &VRs = MRI->getRegClassVirtRegs(*RC); | 
 | 1016 |     for (unsigned i = 0, e = VRs.size(); i != e; ++i) { | 
 | 1017 |       unsigned Reg = VRs[i]; | 
 | 1018 |       if (!LIs->hasInterval(Reg)) | 
 | 1019 |         continue; | 
 | 1020 |       LiveInterval *LI = &LIs->getInterval(Reg); | 
 | 1021 |       if (LI->liveAt(BarrierIdx) && !Barrier->readsRegister(Reg)) | 
 | 1022 |         // Virtual register live interval is intercepted by the barrier. We | 
 | 1023 |         // should split and shrink wrap its interval if possible. | 
 | 1024 |         Intervals.push_back(LI); | 
 | 1025 |     } | 
 | 1026 |   } | 
 | 1027 |  | 
 | 1028 |   // Process the affected live intervals. | 
 | 1029 |   bool Change = false; | 
 | 1030 |   while (!Intervals.empty()) { | 
| Evan Cheng | ae7fa5b | 2008-10-28 01:48:24 +0000 | [diff] [blame] | 1031 |     if (PreSplitLimit != -1 && (int)NumSplits == PreSplitLimit) | 
 | 1032 |       break; | 
| Owen Anderson | e1762c9 | 2009-01-12 03:10:40 +0000 | [diff] [blame] | 1033 |     else if (NumSplits == 4) | 
 | 1034 |       Change |= Change; | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 1035 |     LiveInterval *LI = Intervals.back(); | 
 | 1036 |     Intervals.pop_back(); | 
| Owen Anderson | 956ec27 | 2009-01-23 00:23:32 +0000 | [diff] [blame] | 1037 |     bool result = SplitRegLiveInterval(LI); | 
 | 1038 |     if (result) Split.insert(LI); | 
 | 1039 |     Change |= result; | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 1040 |   } | 
 | 1041 |  | 
 | 1042 |   return Change; | 
 | 1043 | } | 
 | 1044 |  | 
| Owen Anderson | 32ca865 | 2009-01-24 10:07:43 +0000 | [diff] [blame] | 1045 | unsigned PreAllocSplitting::getNumberOfSpills( | 
 | 1046 |                                   SmallPtrSet<MachineInstr*, 4>& MIs, | 
 | 1047 |                                   unsigned Reg, int FrameIndex) { | 
 | 1048 |   unsigned Spills = 0; | 
 | 1049 |   for (SmallPtrSet<MachineInstr*, 4>::iterator UI = MIs.begin(), UE = MIs.end(); | 
 | 1050 |        UI != UI; ++UI) { | 
 | 1051 |     int StoreFrameIndex; | 
 | 1052 |     unsigned StoreVReg = TII->isStoreToStackSlot(*UI, StoreFrameIndex); | 
 | 1053 |     if (StoreVReg == Reg && StoreFrameIndex == FrameIndex) | 
 | 1054 |       Spills++; | 
 | 1055 |   } | 
 | 1056 |    | 
 | 1057 |   return Spills; | 
 | 1058 | } | 
 | 1059 |  | 
| Owen Anderson | 956ec27 | 2009-01-23 00:23:32 +0000 | [diff] [blame] | 1060 | /// removeDeadSpills - After doing splitting, filter through all intervals we've | 
 | 1061 | /// split, and see if any of the spills are unnecessary.  If so, remove them. | 
 | 1062 | bool PreAllocSplitting::removeDeadSpills(SmallPtrSet<LiveInterval*, 8>& split) { | 
 | 1063 |   bool changed = false; | 
 | 1064 |    | 
 | 1065 |   for (SmallPtrSet<LiveInterval*, 8>::iterator LI = split.begin(), | 
 | 1066 |        LE = split.end(); LI != LE; ++LI) { | 
| Owen Anderson | 9ce499a | 2009-01-23 03:28:53 +0000 | [diff] [blame] | 1067 |     DenseMap<VNInfo*, SmallPtrSet<MachineInstr*, 4> > VNUseCount; | 
| Owen Anderson | 956ec27 | 2009-01-23 00:23:32 +0000 | [diff] [blame] | 1068 |      | 
 | 1069 |     for (MachineRegisterInfo::use_iterator UI = MRI->use_begin((*LI)->reg), | 
 | 1070 |          UE = MRI->use_end(); UI != UE; ++UI) { | 
 | 1071 |       unsigned index = LIs->getInstructionIndex(&*UI); | 
 | 1072 |       index = LiveIntervals::getUseIndex(index); | 
 | 1073 |        | 
 | 1074 |       const LiveRange* LR = (*LI)->getLiveRangeContaining(index); | 
| Owen Anderson | 9ce499a | 2009-01-23 03:28:53 +0000 | [diff] [blame] | 1075 |       VNUseCount[LR->valno].insert(&*UI); | 
| Owen Anderson | 956ec27 | 2009-01-23 00:23:32 +0000 | [diff] [blame] | 1076 |     } | 
 | 1077 |      | 
 | 1078 |     for (LiveInterval::vni_iterator VI = (*LI)->vni_begin(), | 
 | 1079 |          VE = (*LI)->vni_end(); VI != VE; ++VI) { | 
 | 1080 |       VNInfo* CurrVN = *VI; | 
 | 1081 |       if (CurrVN->hasPHIKill) continue; | 
| Owen Anderson | 956ec27 | 2009-01-23 00:23:32 +0000 | [diff] [blame] | 1082 |        | 
 | 1083 |       unsigned DefIdx = CurrVN->def; | 
 | 1084 |       if (DefIdx == ~0U || DefIdx == ~1U) continue; | 
| Owen Anderson | 9ce499a | 2009-01-23 03:28:53 +0000 | [diff] [blame] | 1085 |      | 
| Owen Anderson | 956ec27 | 2009-01-23 00:23:32 +0000 | [diff] [blame] | 1086 |       MachineInstr* DefMI = LIs->getInstructionFromIndex(DefIdx); | 
 | 1087 |       int FrameIndex; | 
 | 1088 |       if (!TII->isLoadFromStackSlot(DefMI, FrameIndex)) continue; | 
 | 1089 |        | 
| Owen Anderson | 9ce499a | 2009-01-23 03:28:53 +0000 | [diff] [blame] | 1090 |       if (VNUseCount[CurrVN].size() == 0) { | 
 | 1091 |         LIs->RemoveMachineInstrFromMaps(DefMI); | 
 | 1092 |         (*LI)->removeValNo(CurrVN); | 
 | 1093 |         DefMI->eraseFromParent(); | 
 | 1094 |         NumDeadSpills++; | 
 | 1095 |         changed = true; | 
| Owen Anderson | 32ca865 | 2009-01-24 10:07:43 +0000 | [diff] [blame] | 1096 |         continue; | 
| Owen Anderson | 9ce499a | 2009-01-23 03:28:53 +0000 | [diff] [blame] | 1097 |       } | 
| Owen Anderson | 32ca865 | 2009-01-24 10:07:43 +0000 | [diff] [blame] | 1098 |        | 
 | 1099 |       unsigned SpillCount = getNumberOfSpills(VNUseCount[CurrVN], | 
 | 1100 |                                               (*LI)->reg, FrameIndex); | 
 | 1101 |       if (SpillCount != VNUseCount[CurrVN].size()) continue; | 
 | 1102 |          | 
 | 1103 |       for (SmallPtrSet<MachineInstr*, 4>::iterator UI =  | 
 | 1104 |            VNUseCount[CurrVN].begin(), UE = VNUseCount[CurrVN].end(); | 
 | 1105 |            UI != UI; ++UI) { | 
 | 1106 |         LIs->RemoveMachineInstrFromMaps(*UI); | 
 | 1107 |         (*UI)->eraseFromParent(); | 
 | 1108 |       } | 
 | 1109 |          | 
 | 1110 |       LIs->RemoveMachineInstrFromMaps(DefMI); | 
 | 1111 |       (*LI)->removeValNo(CurrVN); | 
 | 1112 |       DefMI->eraseFromParent(); | 
 | 1113 |       NumDeadSpills++; | 
 | 1114 |       changed = true; | 
| Owen Anderson | 956ec27 | 2009-01-23 00:23:32 +0000 | [diff] [blame] | 1115 |     } | 
 | 1116 |   } | 
 | 1117 |    | 
 | 1118 |   return changed; | 
 | 1119 | } | 
 | 1120 |  | 
| Owen Anderson | f1f75b1 | 2008-11-04 22:22:41 +0000 | [diff] [blame] | 1121 | bool PreAllocSplitting::createsNewJoin(LiveRange* LR, | 
 | 1122 |                                        MachineBasicBlock* DefMBB, | 
 | 1123 |                                        MachineBasicBlock* BarrierMBB) { | 
 | 1124 |   if (DefMBB == BarrierMBB) | 
 | 1125 |     return false; | 
 | 1126 |    | 
 | 1127 |   if (LR->valno->hasPHIKill) | 
 | 1128 |     return false; | 
 | 1129 |    | 
 | 1130 |   unsigned MBBEnd = LIs->getMBBEndIdx(BarrierMBB); | 
 | 1131 |   if (LR->end < MBBEnd) | 
 | 1132 |     return false; | 
 | 1133 |    | 
 | 1134 |   MachineLoopInfo& MLI = getAnalysis<MachineLoopInfo>(); | 
 | 1135 |   if (MLI.getLoopFor(DefMBB) != MLI.getLoopFor(BarrierMBB)) | 
 | 1136 |     return true; | 
 | 1137 |    | 
 | 1138 |   MachineDominatorTree& MDT = getAnalysis<MachineDominatorTree>(); | 
 | 1139 |   SmallPtrSet<MachineBasicBlock*, 4> Visited; | 
 | 1140 |   typedef std::pair<MachineBasicBlock*, | 
 | 1141 |                     MachineBasicBlock::succ_iterator> ItPair; | 
 | 1142 |   SmallVector<ItPair, 4> Stack; | 
 | 1143 |   Stack.push_back(std::make_pair(BarrierMBB, BarrierMBB->succ_begin())); | 
 | 1144 |    | 
 | 1145 |   while (!Stack.empty()) { | 
 | 1146 |     ItPair P = Stack.back(); | 
 | 1147 |     Stack.pop_back(); | 
 | 1148 |      | 
 | 1149 |     MachineBasicBlock* PredMBB = P.first; | 
 | 1150 |     MachineBasicBlock::succ_iterator S = P.second; | 
 | 1151 |      | 
 | 1152 |     if (S == PredMBB->succ_end()) | 
 | 1153 |       continue; | 
 | 1154 |     else if (Visited.count(*S)) { | 
 | 1155 |       Stack.push_back(std::make_pair(PredMBB, ++S)); | 
 | 1156 |       continue; | 
 | 1157 |     } else | 
| Owen Anderson | b214c69 | 2008-11-05 00:32:13 +0000 | [diff] [blame] | 1158 |       Stack.push_back(std::make_pair(PredMBB, S+1)); | 
| Owen Anderson | f1f75b1 | 2008-11-04 22:22:41 +0000 | [diff] [blame] | 1159 |      | 
 | 1160 |     MachineBasicBlock* MBB = *S; | 
 | 1161 |     Visited.insert(MBB); | 
 | 1162 |      | 
 | 1163 |     if (MBB == BarrierMBB) | 
 | 1164 |       return true; | 
 | 1165 |      | 
 | 1166 |     MachineDomTreeNode* DefMDTN = MDT.getNode(DefMBB); | 
 | 1167 |     MachineDomTreeNode* BarrierMDTN = MDT.getNode(BarrierMBB); | 
 | 1168 |     MachineDomTreeNode* MDTN = MDT.getNode(MBB)->getIDom(); | 
 | 1169 |     while (MDTN) { | 
 | 1170 |       if (MDTN == DefMDTN) | 
 | 1171 |         return true; | 
 | 1172 |       else if (MDTN == BarrierMDTN) | 
 | 1173 |         break; | 
 | 1174 |       MDTN = MDTN->getIDom(); | 
 | 1175 |     } | 
 | 1176 |      | 
 | 1177 |     MBBEnd = LIs->getMBBEndIdx(MBB); | 
 | 1178 |     if (LR->end > MBBEnd) | 
 | 1179 |       Stack.push_back(std::make_pair(MBB, MBB->succ_begin())); | 
 | 1180 |   } | 
 | 1181 |    | 
 | 1182 |   return false; | 
 | 1183 | }  | 
 | 1184 |    | 
 | 1185 |  | 
| Evan Cheng | 09e8ca8 | 2008-10-20 21:44:59 +0000 | [diff] [blame] | 1186 | bool PreAllocSplitting::runOnMachineFunction(MachineFunction &MF) { | 
| Evan Cheng | d0e32c5 | 2008-10-29 05:06:14 +0000 | [diff] [blame] | 1187 |   CurrMF = &MF; | 
 | 1188 |   TM     = &MF.getTarget(); | 
 | 1189 |   TII    = TM->getInstrInfo(); | 
 | 1190 |   MFI    = MF.getFrameInfo(); | 
 | 1191 |   MRI    = &MF.getRegInfo(); | 
 | 1192 |   LIs    = &getAnalysis<LiveIntervals>(); | 
 | 1193 |   LSs    = &getAnalysis<LiveStacks>(); | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 1194 |  | 
 | 1195 |   bool MadeChange = false; | 
| Owen Anderson | 26562de | 2009-01-27 05:01:15 +0000 | [diff] [blame] | 1196 |   NumSplits = 0; | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 1197 |  | 
 | 1198 |   // Make sure blocks are numbered in order. | 
 | 1199 |   MF.RenumberBlocks(); | 
 | 1200 |  | 
| Evan Cheng | 5489893 | 2008-10-29 08:39:34 +0000 | [diff] [blame] | 1201 |   MachineBasicBlock *Entry = MF.begin(); | 
 | 1202 |   SmallPtrSet<MachineBasicBlock*,16> Visited; | 
 | 1203 |  | 
| Owen Anderson | 956ec27 | 2009-01-23 00:23:32 +0000 | [diff] [blame] | 1204 |   SmallPtrSet<LiveInterval*, 8> Split; | 
 | 1205 |  | 
| Evan Cheng | 5489893 | 2008-10-29 08:39:34 +0000 | [diff] [blame] | 1206 |   for (df_ext_iterator<MachineBasicBlock*, SmallPtrSet<MachineBasicBlock*,16> > | 
 | 1207 |          DFI = df_ext_begin(Entry, Visited), E = df_ext_end(Entry, Visited); | 
 | 1208 |        DFI != E; ++DFI) { | 
 | 1209 |     BarrierMBB = *DFI; | 
 | 1210 |     for (MachineBasicBlock::iterator I = BarrierMBB->begin(), | 
 | 1211 |            E = BarrierMBB->end(); I != E; ++I) { | 
 | 1212 |       Barrier = &*I; | 
 | 1213 |       const TargetRegisterClass **BarrierRCs = | 
 | 1214 |         Barrier->getDesc().getRegClassBarriers(); | 
 | 1215 |       if (!BarrierRCs) | 
 | 1216 |         continue; | 
 | 1217 |       BarrierIdx = LIs->getInstructionIndex(Barrier); | 
| Owen Anderson | 956ec27 | 2009-01-23 00:23:32 +0000 | [diff] [blame] | 1218 |       MadeChange |= SplitRegLiveIntervals(BarrierRCs, Split); | 
| Evan Cheng | 5489893 | 2008-10-29 08:39:34 +0000 | [diff] [blame] | 1219 |     } | 
 | 1220 |   } | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 1221 |  | 
| Owen Anderson | 956ec27 | 2009-01-23 00:23:32 +0000 | [diff] [blame] | 1222 |   MadeChange |= removeDeadSpills(Split); | 
| Owen Anderson | 26562de | 2009-01-27 05:01:15 +0000 | [diff] [blame] | 1223 |    | 
 | 1224 |   if (NumSplits) | 
 | 1225 |     NumTotalSplits += NumSplits; | 
| Owen Anderson | 956ec27 | 2009-01-23 00:23:32 +0000 | [diff] [blame] | 1226 |  | 
| Evan Cheng | f5cd4f0 | 2008-10-23 20:43:13 +0000 | [diff] [blame] | 1227 |   return MadeChange; | 
| Evan Cheng | 09e8ca8 | 2008-10-20 21:44:59 +0000 | [diff] [blame] | 1228 | } |