14 #define DEBUG_TYPE "regalloc"
27 STATISTIC(NumDCEDeleted,
"Number of instructions deleted by DCE");
28 STATISTIC(NumDCEFoldedLoads,
"Number of single use loads folded after DCE");
29 STATISTIC(NumFracRanges,
"Number of live ranges fractured by DCE");
31 void LiveRangeEdit::Delegate::anchor() { }
53 assert(DefMI &&
"Missing instruction");
54 ScannedRemattable =
true;
57 Remattable.insert(VNI);
72 ScannedRemattable =
true;
76 if (!ScannedRemattable)
78 return !Remattable.empty();
83 bool LiveRangeEdit::allUsesAvailableAt(
const MachineInstr *OrigMI,
120 assert(ScannedRemattable &&
"Call anyRematerializable first");
133 assert(RM.
OrigMI &&
"No defining instruction for remattable value");
141 if (!allUsesAvailableAt(RM.
OrigMI, DefIdx, UseIdx))
153 assert(RM.
OrigMI &&
"Invalid remat");
175 if (DefMI && DefMI != MI)
181 if (UseMI && UseMI != MI)
189 if (!DefMI || !UseMI)
194 if (!allUsesAvailableAt(DefMI,
205 DEBUG(
dbgs() <<
"Try to fold single def: " << *DefMI
206 <<
" into single use: " << *UseMI);
209 if (UseMI->readsWritesVirtualRegister(LI->
reg, &Ops).second)
217 UseMI->eraseFromParent();
225 void LiveRangeEdit::eliminateDeadDef(
MachineInstr *MI, ToShrinkSet &ToShrink) {
235 DEBUG(
dbgs() <<
"Won't delete: " << Idx <<
'\t' << *MI);
240 bool SawStore =
false;
242 DEBUG(
dbgs() <<
"Can't delete: " << Idx <<
'\t' << *MI);
246 DEBUG(
dbgs() <<
"Deleting dead def " << Idx <<
'\t' << *MI);
250 bool ReadsPhysRegs =
false;
257 unsigned Reg = MOI->getReg();
260 if (Reg && MOI->readsReg() && !MRI.
isReserved(Reg))
261 ReadsPhysRegs =
true;
262 else if (MOI->isDef()) {
266 if (
VNInfo *VNI = LR->getVNInfoAt(Idx))
267 LR->removeValNo(VNI);
282 ToShrink.insert(&LI);
312 DEBUG(
dbgs() <<
"Converted physregs to:\t" << *MI);
323 for (
unsigned i = 0, e = RegsToErase.
size(); i != e; ++i) {
324 unsigned Reg = RegsToErase[i];
338 while (!Dead.
empty())
341 if (ToShrink.
empty())
347 if (foldAsLoad(LI, Dead))
358 bool BeingSpilled =
false;
359 for (
unsigned i = 0, e = RegsBeingSpilled.
size(); i != e; ++i) {
360 if (LI->
reg == RegsBeingSpilled[i]) {
366 if (BeingSpilled)
continue;
371 unsigned NumComp = ConEQ.
Classify(LI);
376 DEBUG(
dbgs() << NumComp <<
" components: " << *LI <<
'\n');
378 for (
unsigned i = 1; i != NumComp; ++i) {
390 for (
unsigned i = 0; i != NumComp; ++i)
391 dbgs() <<
'\t' << *Dups[i] <<
'\n';
399 LiveRangeEdit::MRI_NoteNewVirtualRegister(
unsigned VReg)
412 for (
unsigned I = 0, Size =
size();
I < Size; ++
I) {
bool isConstantPhysReg(unsigned PhysReg, const MachineFunction &MF) const
void push_back(const T &Elt)
const MachineFunction * getParent() const
mop_iterator operands_end()
Calculate auxiliary information for a virtual register such as its spill weight and allocation hint...
MachineInstr * getParent()
SlotIndex def
The index of the defining instruction.
bool anyRematerializable(AliasAnalysis *)
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
bool addRegisterDead(unsigned Reg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
SlotIndex getInstructionIndex(const MachineInstr *instr) const
Returns the base index of the given instruction.
static bool isVirtualRegister(unsigned Reg)
bool readsVirtualRegister(unsigned Reg) const
virtual void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, unsigned SubIdx, const MachineInstr *Orig, const TargetRegisterInfo &TRI) const
bool canFoldAsLoad(QueryType Type=IgnoreBundle) const
MachineInstr * foldMemoryOperand(MachineBasicBlock::iterator MI, const SmallVectorImpl< unsigned > &Ops, int FrameIndex) const
VNInfo * getVNInfoAt(SlotIndex Idx) const
getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
LoopInfoBase< BlockT, LoopT > * LI
bool allDefsAreDead() const
bool checkRematerializable(VNInfo *VNI, const MachineInstr *DefMI, AliasAnalysis *)
const char * getName() const
const TargetRegisterInfo * getTargetRegisterInfo() const
INITIALIZE_PASS(DeadMachineInstructionElim,"dead-mi-elimination","Remove dead machine instructions", false, false) bool DeadMachineInstructionElim bool SawStore
T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val()
bool isReg() const
isReg - Tests if this is a MO_Register operand.
const TargetRegisterClass * getRegClass(unsigned Reg) const
unsigned Classify(const LiveInterval *LI)
void pop_back()
Remove the last element of the SetVector.
unsigned getNumOperands() const
bool isUnused() const
Returns true if this value is unused.
void Distribute(LiveInterval *LIV[], MachineRegisterInfo &MRI)
void RemoveOperand(unsigned i)
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
void setIsSplitFromReg(unsigned virtReg, unsigned SReg)
records virtReg is a split live interval from SReg.
bool shrinkToUses(LiveInterval *li, SmallVectorImpl< MachineInstr * > *dead=0)
bool empty() const
Determine if the SetVector is empty or not.
size_t size() const
size - Get the array size.
LiveRange * getCachedRegUnit(unsigned Unit)
const MachineBasicBlock * getParent() const
bundle_iterator< MachineInstr, instr_iterator > iterator
void removeValNo(VNInfo *ValNo)
void RemoveMachineInstrFromMaps(MachineInstr *MI)
unsigned createFrom(unsigned OldReg)
createFrom - Create a new virtual register based on OldReg.
SlotIndexes * getSlotIndexes() const
LiveQueryResult Query(SlotIndex Idx) const
void removeInterval(unsigned Reg)
unsigned getOriginal(unsigned VirtReg) const
bool isReserved(unsigned PhysReg) const
bool isAsCheapAsAMove(QueryType Type=AllInBundle) const
const MachineOperand & getOperand(unsigned i) const
virtual bool LRE_CanEraseVirtReg(unsigned)
bool canRematerializeAt(Remat &RM, SlotIndex UseIdx, bool cheapAsAMove)
LiveInterval & getParent() const
virtual void LRE_WillEraseInstruction(MachineInstr *MI)
Called immediately before erasing a dead machine instruction.
unsigned getSubReg() const
const MCInstrDesc & get(unsigned Opcode) const
void setDesc(const MCInstrDesc &tid)
static bool isSameInstr(SlotIndex A, SlotIndex B)
isSameInstr - Return true if A and B refer to the same instruction.
void calculateSpillWeightAndHint(LiveInterval &li)
(re)compute li's spill weight and allocation hint.
LiveInterval & getInterval(unsigned Reg)
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
LiveInterval & createEmptyInterval(unsigned Reg)
virtual void LRE_WillShrinkVirtReg(unsigned)
Called before shrinking the live range of a virtual register.
bool isSafeToMove(const TargetInstrInfo *TII, AliasAnalysis *AA, bool &SawStore) const
void ReplaceMachineInstrInMaps(MachineInstr *MI, MachineInstr *NewMI)
static bool isPhysicalRegister(unsigned Reg)
SlotIndex rematerializeAt(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, const Remat &RM, const TargetRegisterInfo &, bool Late=false)
bool recomputeRegClass(unsigned Reg, const TargetMachine &)
STATISTIC(NumDCEDeleted,"Number of instructions deleted by DCE")
bool hasOneNonDBGUse(unsigned RegNo) const
virtual void LRE_DidCloneVirtReg(unsigned New, unsigned Old)
const TargetMachine & getTarget() const
const T & back() const
Return the last element of the SetVector.
bool hasInterval(unsigned Reg) const
bool isTriviallyReMaterializable(const MachineInstr *MI, AliasAnalysis *AA=0) const
static reg_nodbg_iterator reg_nodbg_end()
Remat - Information needed to rematerialize at a specific location.
SlotIndex getRegSlot(bool EC=false) const
unsigned getReg() const
getReg - Returns the register number.
void eliminateDeadDefs(SmallVectorImpl< MachineInstr * > &Dead, ArrayRef< unsigned > RegsBeingSpilled=None)
mop_iterator operands_begin()
LiveInterval & createEmptyIntervalFrom(unsigned OldReg)
createEmptyIntervalFrom - Create a new empty interval based on OldReg.
A vector that has set insertion semantics.
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction associated with the given index.
void calculateRegClassAndHint(MachineFunction &, const MachineLoopInfo &, const MachineBlockFrequencyInfo &)
void eraseVirtReg(unsigned Reg)
reg_nodbg_iterator reg_nodbg_begin(unsigned RegNo) const
SlotIndex - An opaque wrapper around machine indexes.
SlotIndex insertMachineInstrInMaps(MachineInstr *mi, bool Late=false)
bool reg_nodbg_empty(unsigned RegNo) const