mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-26 05:27:43 +00:00
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:
parent
e128cb3295
commit
5e78d4bd75
@ -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; }
|
||||
|
@ -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),
|
||||
|
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user