Use of implicit_def is not part of live interval. Create empty intervals for the uses when the live interval is being spilled.

llvm-svn: 49542
This commit is contained in:
Evan Cheng 2008-04-11 17:53:36 +00:00
parent bde1bbed16
commit 499ffa9055
4 changed files with 58 additions and 15 deletions

View File

@ -394,9 +394,11 @@ namespace llvm {
BitVector &RestoreMBBs,
std::map<unsigned,std::vector<SRInfo> >&RestoreIdxes);
/// removeSpilledImpDefs - Remove IMPLICIT_DEF instructions which are being
/// spilled.
void removeSpilledImpDefs(const LiveInterval &li, VirtRegMap &vrm);
/// handleSpilledImpDefs - Remove IMPLICIT_DEF instructions which are being
/// spilled and create empty intervals for their uses.
void handleSpilledImpDefs(const LiveInterval &li, VirtRegMap &vrm,
const TargetRegisterClass* rc,
std::vector<LiveInterval*> &NewLIs);
/// rewriteImplicitOps - Rewrite implicit use operands of MI (i.e. uses of
/// interval on to-be re-materialized operands of MI) with new register.

View File

@ -1319,19 +1319,37 @@ void LiveIntervals::eraseRestoreInfo(int Id, int index, unsigned vr,
Restores[i].index = -1;
}
/// removeSpilledImpDefs - Remove IMPLICIT_DEF instructions which are being
/// spilled.
void LiveIntervals::removeSpilledImpDefs(const LiveInterval &li,
VirtRegMap &vrm) {
/// handleSpilledImpDefs - Remove IMPLICIT_DEF instructions which are being
/// spilled and create empty intervals for their uses.
void
LiveIntervals::handleSpilledImpDefs(const LiveInterval &li, VirtRegMap &vrm,
const TargetRegisterClass* rc,
std::vector<LiveInterval*> &NewLIs) {
for (MachineRegisterInfo::reg_iterator ri = mri_->reg_begin(li.reg),
re = mri_->reg_end(); ri != re; ) {
MachineOperand &O = ri.getOperand();
MachineInstr *MI = &*ri;
++ri;
if (MI->getOpcode() != TargetInstrInfo::IMPLICIT_DEF)
continue;
RemoveMachineInstrFromMaps(MI);
vrm.RemoveMachineInstrFromMaps(MI);
MI->eraseFromParent();
if (O.isDef()) {
assert(MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF &&
"Register def was not rewritten?");
RemoveMachineInstrFromMaps(MI);
vrm.RemoveMachineInstrFromMaps(MI);
MI->eraseFromParent();
} else {
// This must be an use of an implicit_def so it's not part of the live
// interval. Create a new empty live interval for it.
// FIXME: Can we simply erase some of the instructions? e.g. Stores?
unsigned NewVReg = mri_->createVirtualRegister(rc);
vrm.grow();
vrm.setIsImplicitlyDefined(NewVReg);
NewLIs.push_back(&getOrCreateInterval(NewVReg));
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i);
if (MO.isReg() && MO.getReg() == li.reg)
MO.setReg(NewVReg);
}
}
}
}
@ -1415,7 +1433,7 @@ addIntervalsForSpills(const LiveInterval &li,
IsFirstRange = false;
}
removeSpilledImpDefs(li, vrm);
handleSpilledImpDefs(li, vrm, rc, NewLIs);
return NewLIs;
}
@ -1485,7 +1503,7 @@ addIntervalsForSpills(const LiveInterval &li,
// Insert spills / restores if we are splitting.
if (!TrySplit) {
removeSpilledImpDefs(li, vrm);
handleSpilledImpDefs(li, vrm, rc, NewLIs);
return NewLIs;
}
@ -1640,7 +1658,7 @@ addIntervalsForSpills(const LiveInterval &li,
}
}
removeSpilledImpDefs(li, vrm);
handleSpilledImpDefs(li, vrm, rc, RetNewLIs);
return RetNewLIs;
}

View File

@ -21,6 +21,7 @@
#include "llvm/Function.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetInstrInfo.h"
@ -69,6 +70,8 @@ VirtRegMap::VirtRegMap(MachineFunction &mf)
Virt2SplitKillMap(0), ReMatMap(NULL), ReMatId(MAX_STACK_SLOT+1),
LowSpillSlot(NO_STACK_SLOT), HighSpillSlot(NO_STACK_SLOT) {
SpillSlotToUsesMap.resize(8);
ImplicitDefed.resize(MF.getRegInfo().getLastVirtReg()+1-
TargetRegisterInfo::FirstVirtualRegister);
grow();
}
@ -80,6 +83,7 @@ void VirtRegMap::grow() {
Virt2SplitMap.grow(LastVirtReg);
Virt2SplitKillMap.grow(LastVirtReg);
ReMatMap.grow(LastVirtReg);
ImplicitDefed.resize(LastVirtReg-TargetRegisterInfo::FirstVirtualRegister+1);
}
int VirtRegMap::assignVirt2StackSlot(unsigned virtReg) {
@ -1155,6 +1159,8 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
// We want to process implicit virtual register uses first.
if (MO.isImplicit())
// If the virtual register is implicitly defined, emit a implicit_def
// before so scavenger knows it's "defined".
VirtUseOps.insert(VirtUseOps.begin(), i);
else
VirtUseOps.push_back(i);
@ -1177,6 +1183,8 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
ReusedOperands.markClobbered(Phys);
unsigned RReg = SubIdx ? TRI->getSubReg(Phys, SubIdx) : Phys;
MI.getOperand(i).setReg(RReg);
if (VRM.isImplicitlyDefined(VirtReg))
BuildMI(MBB, MI, TII->get(TargetInstrInfo::IMPLICIT_DEF), RReg);
continue;
}

View File

@ -18,6 +18,7 @@
#define LLVM_CODEGEN_VIRTREGMAP_H
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/SmallPtrSet.h"
@ -116,6 +117,10 @@ namespace llvm {
/// SpillSlotToUsesMap - Records uses for each register spill slot.
SmallVector<SmallPtrSet<MachineInstr*, 4>, 8> SpillSlotToUsesMap;
/// ImplicitDefed - One bit for each virtual register. If set it indicates
/// the register is implicitly defined.
BitVector ImplicitDefed;
VirtRegMap(const VirtRegMap&); // DO NOT IMPLEMENT
void operator=(const VirtRegMap&); // DO NOT IMPLEMENT
@ -382,6 +387,16 @@ namespace llvm {
return !SpillSlotToUsesMap[FrameIndex-LowSpillSlot].empty();
}
/// @brief Mark the specified register as being implicitly defined.
void setIsImplicitlyDefined(unsigned VirtReg) {
ImplicitDefed.set(VirtReg-TargetRegisterInfo::FirstVirtualRegister);
}
/// @brief Returns true if the virtual register is implicitly defined.
bool isImplicitlyDefined(unsigned VirtReg) const {
return ImplicitDefed[VirtReg-TargetRegisterInfo::FirstVirtualRegister];
}
/// @brief Updates information about the specified virtual register's value
/// folded into newMI machine instruction.
void virtFolded(unsigned VirtReg, MachineInstr *OldMI, MachineInstr *NewMI,