mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-11-02 07:17:36 +00:00
When dead code elimination removes all but one use, try to fold the single def into the remaining use.
Rematerialization can leave single-use loads behind that we might as well fold whenever possible. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@128918 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -149,6 +149,54 @@ void LiveRangeEdit::eraseVirtReg(unsigned Reg, LiveIntervals &LIS) {
|
|||||||
LIS.removeInterval(Reg);
|
LIS.removeInterval(Reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LiveRangeEdit::foldAsLoad(LiveInterval *LI,
|
||||||
|
SmallVectorImpl<MachineInstr*> &Dead,
|
||||||
|
MachineRegisterInfo &MRI,
|
||||||
|
LiveIntervals &LIS,
|
||||||
|
const TargetInstrInfo &TII) {
|
||||||
|
MachineInstr *DefMI = 0, *UseMI = 0;
|
||||||
|
|
||||||
|
// Check that there is a single def and a single use.
|
||||||
|
for (MachineRegisterInfo::reg_nodbg_iterator I = MRI.reg_nodbg_begin(LI->reg),
|
||||||
|
E = MRI.reg_nodbg_end(); I != E; ++I) {
|
||||||
|
MachineOperand &MO = I.getOperand();
|
||||||
|
MachineInstr *MI = MO.getParent();
|
||||||
|
if (MO.isDef()) {
|
||||||
|
if (DefMI && DefMI != MI)
|
||||||
|
return false;
|
||||||
|
if (!MI->getDesc().canFoldAsLoad())
|
||||||
|
return false;
|
||||||
|
DefMI = MI;
|
||||||
|
} else if (!MO.isUndef()) {
|
||||||
|
if (UseMI && UseMI != MI)
|
||||||
|
return false;
|
||||||
|
// FIXME: Targets don't know how to fold subreg uses.
|
||||||
|
if (MO.getSubReg())
|
||||||
|
return false;
|
||||||
|
UseMI = MI;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!DefMI || !UseMI)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
DEBUG(dbgs() << "Try to fold single def: " << *DefMI
|
||||||
|
<< " into single use: " << *UseMI);
|
||||||
|
|
||||||
|
SmallVector<unsigned, 8> Ops;
|
||||||
|
if (UseMI->readsWritesVirtualRegister(LI->reg, &Ops).second)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MachineInstr *FoldMI = TII.foldMemoryOperand(UseMI, Ops, DefMI);
|
||||||
|
if (!FoldMI)
|
||||||
|
return false;
|
||||||
|
DEBUG(dbgs() << " folded: " << *FoldMI);
|
||||||
|
LIS.ReplaceMachineInstrInMaps(UseMI, FoldMI);
|
||||||
|
UseMI->eraseFromParent();
|
||||||
|
DefMI->addRegisterDead(LI->reg, 0);
|
||||||
|
Dead.push_back(DefMI);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
|
void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
|
||||||
LiveIntervals &LIS, VirtRegMap &VRM,
|
LiveIntervals &LIS, VirtRegMap &VRM,
|
||||||
const TargetInstrInfo &TII) {
|
const TargetInstrInfo &TII) {
|
||||||
@@ -218,6 +266,8 @@ void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
|
|||||||
// Shrink just one live interval. Then delete new dead defs.
|
// Shrink just one live interval. Then delete new dead defs.
|
||||||
LiveInterval *LI = ToShrink.back();
|
LiveInterval *LI = ToShrink.back();
|
||||||
ToShrink.pop_back();
|
ToShrink.pop_back();
|
||||||
|
if (foldAsLoad(LI, Dead, VRM.getRegInfo(), LIS, TII))
|
||||||
|
continue;
|
||||||
if (delegate_)
|
if (delegate_)
|
||||||
delegate_->LRE_WillShrinkVirtReg(LI->reg);
|
delegate_->LRE_WillShrinkVirtReg(LI->reg);
|
||||||
if (!LIS.shrinkToUses(LI, &Dead))
|
if (!LIS.shrinkToUses(LI, &Dead))
|
||||||
|
|||||||
@@ -80,6 +80,11 @@ private:
|
|||||||
bool allUsesAvailableAt(const MachineInstr *OrigMI, SlotIndex OrigIdx,
|
bool allUsesAvailableAt(const MachineInstr *OrigMI, SlotIndex OrigIdx,
|
||||||
SlotIndex UseIdx, LiveIntervals &lis);
|
SlotIndex UseIdx, LiveIntervals &lis);
|
||||||
|
|
||||||
|
/// foldAsLoad - If LI has a single use and a single def that can be folded as
|
||||||
|
/// a load, eliminate the register by folding the def into the use.
|
||||||
|
bool foldAsLoad(LiveInterval *LI, SmallVectorImpl<MachineInstr*> &Dead,
|
||||||
|
MachineRegisterInfo&, LiveIntervals&, const TargetInstrInfo&);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Create a LiveRangeEdit for breaking down parent into smaller pieces.
|
/// Create a LiveRangeEdit for breaking down parent into smaller pieces.
|
||||||
/// @param parent The register being spilled or split.
|
/// @param parent The register being spilled or split.
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s
|
; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s
|
||||||
|
; RUN: llc < %s -mtriple=x86_64-linux -regalloc=greedy | FileCheck %s
|
||||||
; RUN: llc < %s -march=x86 -mattr=+sse2 | FileCheck %s
|
; RUN: llc < %s -march=x86 -mattr=+sse2 | FileCheck %s
|
||||||
; CHECK: LCPI
|
; CHECK: LCPI
|
||||||
; CHECK: LCPI
|
; CHECK: LCPI
|
||||||
|
|||||||
Reference in New Issue
Block a user