When an instruction like: A += B had both A and B virtual registers

spilled, A was loaded from its stack location twice. This fixes the bug.

llvm-svn: 11093
This commit is contained in:
Alkis Evlogimenos 2004-02-03 01:13:07 +00:00
parent e128cb3295
commit 5e78d4bd75
3 changed files with 30 additions and 10 deletions

View File

@ -207,6 +207,10 @@ public:
return *this;
}
bool operator==(const MachineOperand& rhs) const {
return regNum == rhs.regNum && opType == rhs.opType;
}
// Accessor methods. Caller is responsible for checking the
// operand type before invoking the corresponding accessor.
//
@ -282,8 +286,10 @@ public:
}
bool isUse () const { return flags & USEFLAG; }
bool isEverUsed (const MachineInstr&) const;
bool isDef () const { return flags & DEFFLAG; }
bool isHiBits32 () const { return flags & HIFLAG32; }
bool isEverDefined (const MachineInstr&) const;
bool isLoBits32 () const { return flags & LOFLAG32; }
bool isHiBits64 () const { return flags & HIFLAG64; }
bool isLoBits64 () const { return flags & LOFLAG64; }

View File

@ -27,6 +27,24 @@ namespace llvm {
//
extern const TargetInstrDescriptor *TargetInstrDescriptors;
bool MachineOperand::isEverUsed(const MachineInstr& mi) const
{
for (int i = 0, e = mi.getNumOperands(); i != e; ++i) {
if (*this == mi.getOperand(i) && mi.getOperand(i).isUse())
return true;
}
return false;
}
bool MachineOperand::isEverDefined(const MachineInstr& mi) const
{
for (int i = 0, e = mi.getNumOperands(); i != e; ++i) {
if (*this == mi.getOperand(i) && mi.getOperand(i).isDef())
return true;
}
return false;
}
// Constructor for instructions with variable #operands
MachineInstr::MachineInstr(MachineOpCode OpCode, unsigned numOperands)
: opCode(OpCode),

View File

@ -470,7 +470,8 @@ bool RA::runOnMachineFunction(MachineFunction &fn) {
for (unsigned i = 0, e = (*currentInstr_)->getNumOperands();
i != e; ++i) {
MachineOperand& op = (*currentInstr_)->getOperand(i);
if (op.isVirtualRegister() && op.isUse() && !op.isDef()) {
if (op.isVirtualRegister() && op.isUse() &&
!op.isEverDefined(**currentInstr_)) {
unsigned virtReg = op.getAllocatedRegNum();
unsigned physReg = 0;
Virt2PhysMap::const_iterator it = v2pMap_.find(virtReg);
@ -497,7 +498,9 @@ bool RA::runOnMachineFunction(MachineFunction &fn) {
for (unsigned i = 0, e = (*currentInstr_)->getNumOperands();
i != e; ++i) {
MachineOperand& op = (*currentInstr_)->getOperand(i);
if (op.isVirtualRegister() && op.isDef()) {
if (op.isVirtualRegister()) {
assert(op.isEverDefined(**currentInstr_) &&
"operand should be defined by this instruction");
unsigned virtReg = op.getAllocatedRegNum();
unsigned physReg = 0;
Virt2PhysMap::const_iterator it = v2pMap_.find(virtReg);
@ -506,14 +509,9 @@ bool RA::runOnMachineFunction(MachineFunction &fn) {
}
else {
physReg = getFreeTempPhysReg(virtReg);
}
if (op.isUse()) { // def and use
loadVirt2PhysReg(virtReg, physReg);
}
else {
assignVirt2PhysReg(virtReg, physReg);
tempDefOperands_.push_back(virtReg);
}
tempDefOperands_.push_back(virtReg);
(*currentInstr_)->SetMachineOperandReg(i, physReg);
}
}
@ -815,8 +813,6 @@ void RA::assignVirt2StackSlot(unsigned virtReg)
int RA::getStackSlot(unsigned virtReg)
{
// use lower_bound so that we can do a possibly O(1) insert later
// if necessary
Virt2StackSlotMap::iterator it = v2ssMap_.find(virtReg);
assert(it != v2ssMap_.end() &&
"attempt to get stack slot on register that does not live on the stack");