| Jakob Stoklund Olesen | a17768f | 2010-10-14 23:49:52 +0000 | [diff] [blame] | 1 | //===--- LiveRangeEdit.cpp - Basic tools for editing a register live range --===// | 
|  | 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 | // The LiveRangeEdit class represents changes done to a virtual register when it | 
|  | 11 | // is spilled or split. | 
|  | 12 | //===----------------------------------------------------------------------===// | 
|  | 13 |  | 
|  | 14 | #include "LiveRangeEdit.h" | 
|  | 15 | #include "VirtRegMap.h" | 
| Jakob Stoklund Olesen | 5881799 | 2011-03-08 22:46:11 +0000 | [diff] [blame] | 16 | #include "llvm/ADT/SetVector.h" | 
| Jakob Stoklund Olesen | a17768f | 2010-10-14 23:49:52 +0000 | [diff] [blame] | 17 | #include "llvm/CodeGen/LiveIntervalAnalysis.h" | 
|  | 18 | #include "llvm/CodeGen/MachineRegisterInfo.h" | 
| Jakob Stoklund Olesen | 080c316 | 2010-10-20 22:00:51 +0000 | [diff] [blame] | 19 | #include "llvm/Target/TargetInstrInfo.h" | 
| Jakob Stoklund Olesen | 5881799 | 2011-03-08 22:46:11 +0000 | [diff] [blame] | 20 | #include "llvm/Support/Debug.h" | 
|  | 21 | #include "llvm/Support/raw_ostream.h" | 
| Jakob Stoklund Olesen | a17768f | 2010-10-14 23:49:52 +0000 | [diff] [blame] | 22 |  | 
|  | 23 | using namespace llvm; | 
|  | 24 |  | 
|  | 25 | LiveInterval &LiveRangeEdit::create(MachineRegisterInfo &mri, | 
|  | 26 | LiveIntervals &lis, | 
|  | 27 | VirtRegMap &vrm) { | 
| Jakob Stoklund Olesen | e324f6e | 2011-02-18 22:35:20 +0000 | [diff] [blame] | 28 | const TargetRegisterClass *RC = mri.getRegClass(getReg()); | 
| Jakob Stoklund Olesen | a17768f | 2010-10-14 23:49:52 +0000 | [diff] [blame] | 29 | unsigned VReg = mri.createVirtualRegister(RC); | 
|  | 30 | vrm.grow(); | 
| Jakob Stoklund Olesen | fd38917 | 2011-02-19 00:38:43 +0000 | [diff] [blame] | 31 | vrm.setIsSplitFromReg(VReg, vrm.getOriginal(getReg())); | 
| Jakob Stoklund Olesen | a17768f | 2010-10-14 23:49:52 +0000 | [diff] [blame] | 32 | LiveInterval &li = lis.getOrCreateInterval(VReg); | 
|  | 33 | newRegs_.push_back(&li); | 
|  | 34 | return li; | 
|  | 35 | } | 
|  | 36 |  | 
| Jakob Stoklund Olesen | 080c316 | 2010-10-20 22:00:51 +0000 | [diff] [blame] | 37 | void LiveRangeEdit::scanRemattable(LiveIntervals &lis, | 
|  | 38 | const TargetInstrInfo &tii, | 
|  | 39 | AliasAnalysis *aa) { | 
|  | 40 | for (LiveInterval::vni_iterator I = parent_.vni_begin(), | 
|  | 41 | E = parent_.vni_end(); I != E; ++I) { | 
|  | 42 | VNInfo *VNI = *I; | 
|  | 43 | if (VNI->isUnused()) | 
|  | 44 | continue; | 
|  | 45 | MachineInstr *DefMI = lis.getInstructionFromIndex(VNI->def); | 
|  | 46 | if (!DefMI) | 
|  | 47 | continue; | 
|  | 48 | if (tii.isTriviallyReMaterializable(DefMI, aa)) | 
|  | 49 | remattable_.insert(VNI); | 
|  | 50 | } | 
|  | 51 | scannedRemattable_ = true; | 
|  | 52 | } | 
|  | 53 |  | 
|  | 54 | bool LiveRangeEdit::anyRematerializable(LiveIntervals &lis, | 
|  | 55 | const TargetInstrInfo &tii, | 
|  | 56 | AliasAnalysis *aa) { | 
|  | 57 | if (!scannedRemattable_) | 
|  | 58 | scanRemattable(lis, tii, aa); | 
|  | 59 | return !remattable_.empty(); | 
|  | 60 | } | 
|  | 61 |  | 
| Jakob Stoklund Olesen | a17768f | 2010-10-14 23:49:52 +0000 | [diff] [blame] | 62 | /// allUsesAvailableAt - Return true if all registers used by OrigMI at | 
|  | 63 | /// OrigIdx are also available with the same value at UseIdx. | 
|  | 64 | bool LiveRangeEdit::allUsesAvailableAt(const MachineInstr *OrigMI, | 
|  | 65 | SlotIndex OrigIdx, | 
|  | 66 | SlotIndex UseIdx, | 
|  | 67 | LiveIntervals &lis) { | 
|  | 68 | OrigIdx = OrigIdx.getUseIndex(); | 
|  | 69 | UseIdx = UseIdx.getUseIndex(); | 
|  | 70 | for (unsigned i = 0, e = OrigMI->getNumOperands(); i != e; ++i) { | 
|  | 71 | const MachineOperand &MO = OrigMI->getOperand(i); | 
|  | 72 | if (!MO.isReg() || !MO.getReg() || MO.getReg() == getReg()) | 
|  | 73 | continue; | 
|  | 74 | // Reserved registers are OK. | 
|  | 75 | if (MO.isUndef() || !lis.hasInterval(MO.getReg())) | 
|  | 76 | continue; | 
|  | 77 | // We don't want to move any defs. | 
|  | 78 | if (MO.isDef()) | 
|  | 79 | return false; | 
|  | 80 | // We cannot depend on virtual registers in uselessRegs_. | 
| Jakob Stoklund Olesen | 1973b3e | 2011-03-07 22:42:16 +0000 | [diff] [blame] | 81 | if (uselessRegs_) | 
|  | 82 | for (unsigned ui = 0, ue = uselessRegs_->size(); ui != ue; ++ui) | 
|  | 83 | if ((*uselessRegs_)[ui]->reg == MO.getReg()) | 
|  | 84 | return false; | 
| Jakob Stoklund Olesen | a17768f | 2010-10-14 23:49:52 +0000 | [diff] [blame] | 85 |  | 
|  | 86 | LiveInterval &li = lis.getInterval(MO.getReg()); | 
|  | 87 | const VNInfo *OVNI = li.getVNInfoAt(OrigIdx); | 
|  | 88 | if (!OVNI) | 
|  | 89 | continue; | 
|  | 90 | if (OVNI != li.getVNInfoAt(UseIdx)) | 
|  | 91 | return false; | 
|  | 92 | } | 
|  | 93 | return true; | 
|  | 94 | } | 
|  | 95 |  | 
| Jakob Stoklund Olesen | b80e973 | 2010-11-10 01:05:12 +0000 | [diff] [blame] | 96 | bool LiveRangeEdit::canRematerializeAt(Remat &RM, | 
|  | 97 | SlotIndex UseIdx, | 
|  | 98 | bool cheapAsAMove, | 
|  | 99 | LiveIntervals &lis) { | 
| Jakob Stoklund Olesen | 080c316 | 2010-10-20 22:00:51 +0000 | [diff] [blame] | 100 | assert(scannedRemattable_ && "Call anyRematerializable first"); | 
| Jakob Stoklund Olesen | 080c316 | 2010-10-20 22:00:51 +0000 | [diff] [blame] | 101 |  | 
|  | 102 | // Use scanRemattable info. | 
|  | 103 | if (!remattable_.count(RM.ParentVNI)) | 
| Jakob Stoklund Olesen | b80e973 | 2010-11-10 01:05:12 +0000 | [diff] [blame] | 104 | return false; | 
| Jakob Stoklund Olesen | 080c316 | 2010-10-20 22:00:51 +0000 | [diff] [blame] | 105 |  | 
|  | 106 | // No defining instruction. | 
| Jakob Stoklund Olesen | b80e973 | 2010-11-10 01:05:12 +0000 | [diff] [blame] | 107 | RM.OrigMI = lis.getInstructionFromIndex(RM.ParentVNI->def); | 
|  | 108 | assert(RM.OrigMI && "Defining instruction for remattable value disappeared"); | 
| Jakob Stoklund Olesen | 080c316 | 2010-10-20 22:00:51 +0000 | [diff] [blame] | 109 |  | 
|  | 110 | // If only cheap remats were requested, bail out early. | 
| Jakob Stoklund Olesen | b80e973 | 2010-11-10 01:05:12 +0000 | [diff] [blame] | 111 | if (cheapAsAMove && !RM.OrigMI->getDesc().isAsCheapAsAMove()) | 
|  | 112 | return false; | 
| Jakob Stoklund Olesen | 080c316 | 2010-10-20 22:00:51 +0000 | [diff] [blame] | 113 |  | 
|  | 114 | // Verify that all used registers are available with the same values. | 
| Jakob Stoklund Olesen | b80e973 | 2010-11-10 01:05:12 +0000 | [diff] [blame] | 115 | if (!allUsesAvailableAt(RM.OrigMI, RM.ParentVNI->def, UseIdx, lis)) | 
|  | 116 | return false; | 
| Jakob Stoklund Olesen | 080c316 | 2010-10-20 22:00:51 +0000 | [diff] [blame] | 117 |  | 
| Jakob Stoklund Olesen | b80e973 | 2010-11-10 01:05:12 +0000 | [diff] [blame] | 118 | return true; | 
| Jakob Stoklund Olesen | 080c316 | 2010-10-20 22:00:51 +0000 | [diff] [blame] | 119 | } | 
|  | 120 |  | 
|  | 121 | SlotIndex LiveRangeEdit::rematerializeAt(MachineBasicBlock &MBB, | 
|  | 122 | MachineBasicBlock::iterator MI, | 
|  | 123 | unsigned DestReg, | 
|  | 124 | const Remat &RM, | 
|  | 125 | LiveIntervals &lis, | 
|  | 126 | const TargetInstrInfo &tii, | 
|  | 127 | const TargetRegisterInfo &tri) { | 
|  | 128 | assert(RM.OrigMI && "Invalid remat"); | 
|  | 129 | tii.reMaterialize(MBB, MI, DestReg, 0, RM.OrigMI, tri); | 
| Jakob Stoklund Olesen | f1583ae | 2010-10-20 22:50:42 +0000 | [diff] [blame] | 130 | rematted_.insert(RM.ParentVNI); | 
| Jakob Stoklund Olesen | 080c316 | 2010-10-20 22:00:51 +0000 | [diff] [blame] | 131 | return lis.InsertMachineInstrInMaps(--MI).getDefIndex(); | 
|  | 132 | } | 
|  | 133 |  | 
| Jakob Stoklund Olesen | 5881799 | 2011-03-08 22:46:11 +0000 | [diff] [blame] | 134 | void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead, | 
|  | 135 | LiveIntervals &LIS, | 
|  | 136 | const TargetInstrInfo &TII) { | 
|  | 137 | SetVector<LiveInterval*, | 
|  | 138 | SmallVector<LiveInterval*, 8>, | 
|  | 139 | SmallPtrSet<LiveInterval*, 8> > ToShrink; | 
|  | 140 |  | 
|  | 141 | for (;;) { | 
|  | 142 | // Erase all dead defs. | 
|  | 143 | while (!Dead.empty()) { | 
|  | 144 | MachineInstr *MI = Dead.pop_back_val(); | 
|  | 145 | assert(MI->allDefsAreDead() && "Def isn't really dead"); | 
|  | 146 |  | 
|  | 147 | // Never delete inline asm. | 
|  | 148 | if (MI->isInlineAsm()) | 
|  | 149 | continue; | 
|  | 150 |  | 
|  | 151 | // Use the same criteria as DeadMachineInstructionElim. | 
|  | 152 | bool SawStore = false; | 
|  | 153 | if (!MI->isSafeToMove(&TII, 0, SawStore)) | 
|  | 154 | continue; | 
|  | 155 |  | 
|  | 156 | SlotIndex Idx = LIS.getInstructionIndex(MI).getDefIndex(); | 
|  | 157 | DEBUG(dbgs() << "Deleting dead def " << Idx << '\t' << *MI); | 
|  | 158 |  | 
|  | 159 | // Check for live intervals that may shrink | 
|  | 160 | for (MachineInstr::mop_iterator MOI = MI->operands_begin(), | 
|  | 161 | MOE = MI->operands_end(); MOI != MOE; ++MOI) { | 
|  | 162 | if (!MOI->isReg()) | 
|  | 163 | continue; | 
|  | 164 | unsigned Reg = MOI->getReg(); | 
|  | 165 | if (!TargetRegisterInfo::isVirtualRegister(Reg)) | 
|  | 166 | continue; | 
|  | 167 | LiveInterval &LI = LIS.getInterval(Reg); | 
|  | 168 | // Remove defined value. | 
|  | 169 | if (MOI->isDef()) | 
|  | 170 | if (VNInfo *VNI = LI.getVNInfoAt(Idx)) | 
|  | 171 | LI.removeValNo(VNI); | 
|  | 172 | // Shrink read registers. | 
|  | 173 | if (MI->readsVirtualRegister(Reg)) | 
|  | 174 | ToShrink.insert(&LI); | 
|  | 175 | } | 
|  | 176 |  | 
| Jakob Stoklund Olesen | 92a55f4 | 2011-03-09 00:57:29 +0000 | [diff] [blame^] | 177 | if (delegate_) | 
|  | 178 | delegate_->LRE_WillEraseInstruction(MI); | 
| Jakob Stoklund Olesen | 5881799 | 2011-03-08 22:46:11 +0000 | [diff] [blame] | 179 | LIS.RemoveMachineInstrFromMaps(MI); | 
|  | 180 | MI->eraseFromParent(); | 
|  | 181 | } | 
|  | 182 |  | 
|  | 183 | if (ToShrink.empty()) | 
|  | 184 | break; | 
|  | 185 |  | 
|  | 186 | // Shrink just one live interval. Then delete new dead defs. | 
|  | 187 | LIS.shrinkToUses(ToShrink.back(), &Dead); | 
|  | 188 | ToShrink.pop_back(); | 
|  | 189 | } | 
|  | 190 | } | 
|  | 191 |  |