forked from OSchip/llvm-project
Allow registers defined by implicit_def to be clobbered.
llvm-svn: 49512
This commit is contained in:
parent
4b77209694
commit
2cb98eb4bb
|
@ -53,6 +53,10 @@ class RegScavenger {
|
||||||
/// available, unset means the register is currently being used.
|
/// available, unset means the register is currently being used.
|
||||||
BitVector RegsAvailable;
|
BitVector RegsAvailable;
|
||||||
|
|
||||||
|
/// ImplicitDefed - If bit is set that means the register is defined by an
|
||||||
|
/// implicit_def instructions. That means it can be clobbered at will.
|
||||||
|
BitVector ImplicitDefed;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RegScavenger()
|
RegScavenger()
|
||||||
: MBB(NULL), NumPhysRegs(0), Tracking(false),
|
: MBB(NULL), NumPhysRegs(0), Tracking(false),
|
||||||
|
@ -92,15 +96,26 @@ public:
|
||||||
bool isUsed(unsigned Reg) const { return !RegsAvailable[Reg]; }
|
bool isUsed(unsigned Reg) const { return !RegsAvailable[Reg]; }
|
||||||
bool isUnused(unsigned Reg) const { return RegsAvailable[Reg]; }
|
bool isUnused(unsigned Reg) const { return RegsAvailable[Reg]; }
|
||||||
|
|
||||||
|
bool isImplicitlyDefined(unsigned Reg) const { return ImplicitDefed[Reg]; }
|
||||||
|
|
||||||
/// getRegsUsed - return all registers currently in use in used.
|
/// getRegsUsed - return all registers currently in use in used.
|
||||||
void getRegsUsed(BitVector &used, bool includeReserved);
|
void getRegsUsed(BitVector &used, bool includeReserved);
|
||||||
|
|
||||||
/// setUsed / setUnused - Mark the state of one or a number of registers.
|
/// setUsed / setUnused - Mark the state of one or a number of registers.
|
||||||
///
|
///
|
||||||
void setUsed(unsigned Reg);
|
void setUsed(unsigned Reg, bool ImpDef = false);
|
||||||
void setUsed(BitVector Regs) { RegsAvailable &= ~Regs; }
|
void setUsed(BitVector Regs, bool ImpDef = false) {
|
||||||
|
RegsAvailable &= ~Regs;
|
||||||
|
if (ImpDef)
|
||||||
|
ImplicitDefed |= Regs;
|
||||||
|
else
|
||||||
|
ImplicitDefed &= ~Regs;
|
||||||
|
}
|
||||||
void setUnused(unsigned Reg, const MachineInstr *MI);
|
void setUnused(unsigned Reg, const MachineInstr *MI);
|
||||||
void setUnused(BitVector Regs) { RegsAvailable |= Regs; }
|
void setUnused(BitVector Regs) {
|
||||||
|
RegsAvailable |= Regs;
|
||||||
|
ImplicitDefed &= ~Regs;
|
||||||
|
}
|
||||||
|
|
||||||
/// FindUnusedReg - Find a unused register of the specified register class
|
/// FindUnusedReg - Find a unused register of the specified register class
|
||||||
/// from the specified set of registers. It return 0 is none is found.
|
/// from the specified set of registers. It return 0 is none is found.
|
||||||
|
|
|
@ -55,22 +55,28 @@ static bool RedefinesSuperRegPart(const MachineInstr *MI,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// setUsed - Set the register and its sub-registers as being used.
|
/// setUsed - Set the register and its sub-registers as being used.
|
||||||
void RegScavenger::setUsed(unsigned Reg) {
|
void RegScavenger::setUsed(unsigned Reg, bool ImpDef) {
|
||||||
RegsAvailable.reset(Reg);
|
RegsAvailable.reset(Reg);
|
||||||
|
ImplicitDefed[Reg] = ImpDef;
|
||||||
|
|
||||||
for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
|
for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
|
||||||
unsigned SubReg = *SubRegs; ++SubRegs)
|
unsigned SubReg = *SubRegs; ++SubRegs) {
|
||||||
RegsAvailable.reset(SubReg);
|
RegsAvailable.reset(SubReg);
|
||||||
|
ImplicitDefed[SubReg] = ImpDef;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// setUnused - Set the register and its sub-registers as being unused.
|
/// setUnused - Set the register and its sub-registers as being unused.
|
||||||
void RegScavenger::setUnused(unsigned Reg, const MachineInstr *MI) {
|
void RegScavenger::setUnused(unsigned Reg, const MachineInstr *MI) {
|
||||||
RegsAvailable.set(Reg);
|
RegsAvailable.set(Reg);
|
||||||
|
ImplicitDefed.reset(Reg);
|
||||||
|
|
||||||
for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
|
for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
|
||||||
unsigned SubReg = *SubRegs; ++SubRegs)
|
unsigned SubReg = *SubRegs; ++SubRegs)
|
||||||
if (!RedefinesSuperRegPart(MI, Reg, TRI))
|
if (!RedefinesSuperRegPart(MI, Reg, TRI)) {
|
||||||
RegsAvailable.set(SubReg);
|
RegsAvailable.set(SubReg);
|
||||||
|
ImplicitDefed.reset(SubReg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) {
|
void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) {
|
||||||
|
@ -86,6 +92,7 @@ void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) {
|
||||||
if (!MBB) {
|
if (!MBB) {
|
||||||
NumPhysRegs = TRI->getNumRegs();
|
NumPhysRegs = TRI->getNumRegs();
|
||||||
RegsAvailable.resize(NumPhysRegs);
|
RegsAvailable.resize(NumPhysRegs);
|
||||||
|
ImplicitDefed.resize(NumPhysRegs);
|
||||||
|
|
||||||
// Create reserved registers bitvector.
|
// Create reserved registers bitvector.
|
||||||
ReservedRegs = TRI->getReservedRegs(MF);
|
ReservedRegs = TRI->getReservedRegs(MF);
|
||||||
|
@ -216,6 +223,7 @@ void RegScavenger::forward() {
|
||||||
setUnused(ChangedRegs);
|
setUnused(ChangedRegs);
|
||||||
|
|
||||||
// Process defs.
|
// Process defs.
|
||||||
|
bool IsImpDef = MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF;
|
||||||
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
||||||
const MachineOperand &MO = MI->getOperand(i);
|
const MachineOperand &MO = MI->getOperand(i);
|
||||||
|
|
||||||
|
@ -240,12 +248,13 @@ void RegScavenger::forward() {
|
||||||
if (RedefinesSuperRegPart(MI, MO, TRI))
|
if (RedefinesSuperRegPart(MI, MO, TRI))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Implicit def is allowed to "re-define" any register.
|
// Implicit def is allowed to "re-define" any register. Similarly,
|
||||||
|
// implicitly defined registers can be clobbered.
|
||||||
assert((isReserved(Reg) || isUnused(Reg) ||
|
assert((isReserved(Reg) || isUnused(Reg) ||
|
||||||
MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF ||
|
IsImpDef || isImplicitlyDefined(Reg) ||
|
||||||
isLiveInButUnusedBefore(Reg, MI, MBB, TRI, MRI)) &&
|
isLiveInButUnusedBefore(Reg, MI, MBB, TRI, MRI)) &&
|
||||||
"Re-defining a live register!");
|
"Re-defining a live register!");
|
||||||
setUsed(Reg);
|
setUsed(Reg, IsImpDef);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue