LiveRangeEdit.cpp revision b80e973c95034e5754d888140497a9658a7c1ded
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" 16#include "llvm/CodeGen/LiveIntervalAnalysis.h" 17#include "llvm/CodeGen/MachineRegisterInfo.h" 18#include "llvm/Target/TargetInstrInfo.h" 19 20using namespace llvm; 21 22LiveInterval &LiveRangeEdit::create(MachineRegisterInfo &mri, 23 LiveIntervals &lis, 24 VirtRegMap &vrm) { 25 const TargetRegisterClass *RC = mri.getRegClass(parent_.reg); 26 unsigned VReg = mri.createVirtualRegister(RC); 27 vrm.grow(); 28 LiveInterval &li = lis.getOrCreateInterval(VReg); 29 newRegs_.push_back(&li); 30 return li; 31} 32 33void LiveRangeEdit::scanRemattable(LiveIntervals &lis, 34 const TargetInstrInfo &tii, 35 AliasAnalysis *aa) { 36 for (LiveInterval::vni_iterator I = parent_.vni_begin(), 37 E = parent_.vni_end(); I != E; ++I) { 38 VNInfo *VNI = *I; 39 if (VNI->isUnused()) 40 continue; 41 MachineInstr *DefMI = lis.getInstructionFromIndex(VNI->def); 42 if (!DefMI) 43 continue; 44 if (tii.isTriviallyReMaterializable(DefMI, aa)) 45 remattable_.insert(VNI); 46 } 47 scannedRemattable_ = true; 48} 49 50bool LiveRangeEdit::anyRematerializable(LiveIntervals &lis, 51 const TargetInstrInfo &tii, 52 AliasAnalysis *aa) { 53 if (!scannedRemattable_) 54 scanRemattable(lis, tii, aa); 55 return !remattable_.empty(); 56} 57 58/// allUsesAvailableAt - Return true if all registers used by OrigMI at 59/// OrigIdx are also available with the same value at UseIdx. 60bool LiveRangeEdit::allUsesAvailableAt(const MachineInstr *OrigMI, 61 SlotIndex OrigIdx, 62 SlotIndex UseIdx, 63 LiveIntervals &lis) { 64 OrigIdx = OrigIdx.getUseIndex(); 65 UseIdx = UseIdx.getUseIndex(); 66 for (unsigned i = 0, e = OrigMI->getNumOperands(); i != e; ++i) { 67 const MachineOperand &MO = OrigMI->getOperand(i); 68 if (!MO.isReg() || !MO.getReg() || MO.getReg() == getReg()) 69 continue; 70 // Reserved registers are OK. 71 if (MO.isUndef() || !lis.hasInterval(MO.getReg())) 72 continue; 73 // We don't want to move any defs. 74 if (MO.isDef()) 75 return false; 76 // We cannot depend on virtual registers in uselessRegs_. 77 for (unsigned ui = 0, ue = uselessRegs_.size(); ui != ue; ++ui) 78 if (uselessRegs_[ui]->reg == MO.getReg()) 79 return false; 80 81 LiveInterval &li = lis.getInterval(MO.getReg()); 82 const VNInfo *OVNI = li.getVNInfoAt(OrigIdx); 83 if (!OVNI) 84 continue; 85 if (OVNI != li.getVNInfoAt(UseIdx)) 86 return false; 87 } 88 return true; 89} 90 91bool LiveRangeEdit::canRematerializeAt(Remat &RM, 92 SlotIndex UseIdx, 93 bool cheapAsAMove, 94 LiveIntervals &lis) { 95 assert(scannedRemattable_ && "Call anyRematerializable first"); 96 97 // Use scanRemattable info. 98 if (!remattable_.count(RM.ParentVNI)) 99 return false; 100 101 // No defining instruction. 102 RM.OrigMI = lis.getInstructionFromIndex(RM.ParentVNI->def); 103 assert(RM.OrigMI && "Defining instruction for remattable value disappeared"); 104 105 // If only cheap remats were requested, bail out early. 106 if (cheapAsAMove && !RM.OrigMI->getDesc().isAsCheapAsAMove()) 107 return false; 108 109 // Verify that all used registers are available with the same values. 110 if (!allUsesAvailableAt(RM.OrigMI, RM.ParentVNI->def, UseIdx, lis)) 111 return false; 112 113 return true; 114} 115 116SlotIndex LiveRangeEdit::rematerializeAt(MachineBasicBlock &MBB, 117 MachineBasicBlock::iterator MI, 118 unsigned DestReg, 119 const Remat &RM, 120 LiveIntervals &lis, 121 const TargetInstrInfo &tii, 122 const TargetRegisterInfo &tri) { 123 assert(RM.OrigMI && "Invalid remat"); 124 tii.reMaterialize(MBB, MI, DestReg, 0, RM.OrigMI, tri); 125 rematted_.insert(RM.ParentVNI); 126 return lis.InsertMachineInstrInMaps(--MI).getDefIndex(); 127} 128 129