mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2026-04-27 04:18:42 +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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@11093 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
1 parent
9fe7602862
commit
4e7854407c
3 files changed
+30
-10
No files matched your search
@@ -207,6 +207,10 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator==(const MachineOperand& rhs) const {
|
||||||
|
return regNum == rhs.regNum && opType == rhs.opType;
|
||||||
|
}
|
||||||
|
|
||||||
// Accessor methods. Caller is responsible for checking the
|
// Accessor methods. Caller is responsible for checking the
|
||||||
// operand type before invoking the corresponding accessor.
|
// operand type before invoking the corresponding accessor.
|
||||||
//
|
//
|
||||||
@@ -282,8 +286,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool isUse () const { return flags & USEFLAG; }
|
bool isUse () const { return flags & USEFLAG; }
|
||||||
|
bool isEverUsed (const MachineInstr&) const;
|
||||||
bool isDef () const { return flags & DEFFLAG; }
|
bool isDef () const { return flags & DEFFLAG; }
|
||||||
bool isHiBits32 () const { return flags & HIFLAG32; }
|
bool isHiBits32 () const { return flags & HIFLAG32; }
|
||||||
|
bool isEverDefined (const MachineInstr&) const;
|
||||||
bool isLoBits32 () const { return flags & LOFLAG32; }
|
bool isLoBits32 () const { return flags & LOFLAG32; }
|
||||||
bool isHiBits64 () const { return flags & HIFLAG64; }
|
bool isHiBits64 () const { return flags & HIFLAG64; }
|
||||||
bool isLoBits64 () const { return flags & LOFLAG64; }
|
bool isLoBits64 () const { return flags & LOFLAG64; }
|
||||||
|
|||||||
@@ -27,6 +27,24 @@ namespace llvm {
|
|||||||
//
|
//
|
||||||
extern const TargetInstrDescriptor *TargetInstrDescriptors;
|
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
|
// Constructor for instructions with variable #operands
|
||||||
MachineInstr::MachineInstr(MachineOpCode OpCode, unsigned numOperands)
|
MachineInstr::MachineInstr(MachineOpCode OpCode, unsigned numOperands)
|
||||||
: opCode(OpCode),
|
: opCode(OpCode),
|
||||||
|
|||||||
@@ -470,7 +470,8 @@ bool RA::runOnMachineFunction(MachineFunction &fn) {
|
|||||||
for (unsigned i = 0, e = (*currentInstr_)->getNumOperands();
|
for (unsigned i = 0, e = (*currentInstr_)->getNumOperands();
|
||||||
i != e; ++i) {
|
i != e; ++i) {
|
||||||
MachineOperand& op = (*currentInstr_)->getOperand(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 virtReg = op.getAllocatedRegNum();
|
||||||
unsigned physReg = 0;
|
unsigned physReg = 0;
|
||||||
Virt2PhysMap::const_iterator it = v2pMap_.find(virtReg);
|
Virt2PhysMap::const_iterator it = v2pMap_.find(virtReg);
|
||||||
@@ -497,7 +498,9 @@ bool RA::runOnMachineFunction(MachineFunction &fn) {
|
|||||||
for (unsigned i = 0, e = (*currentInstr_)->getNumOperands();
|
for (unsigned i = 0, e = (*currentInstr_)->getNumOperands();
|
||||||
i != e; ++i) {
|
i != e; ++i) {
|
||||||
MachineOperand& op = (*currentInstr_)->getOperand(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 virtReg = op.getAllocatedRegNum();
|
||||||
unsigned physReg = 0;
|
unsigned physReg = 0;
|
||||||
Virt2PhysMap::const_iterator it = v2pMap_.find(virtReg);
|
Virt2PhysMap::const_iterator it = v2pMap_.find(virtReg);
|
||||||
@@ -506,14 +509,9 @@ bool RA::runOnMachineFunction(MachineFunction &fn) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
physReg = getFreeTempPhysReg(virtReg);
|
physReg = getFreeTempPhysReg(virtReg);
|
||||||
}
|
|
||||||
if (op.isUse()) { // def and use
|
|
||||||
loadVirt2PhysReg(virtReg, physReg);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
assignVirt2PhysReg(virtReg, physReg);
|
assignVirt2PhysReg(virtReg, physReg);
|
||||||
|
tempDefOperands_.push_back(virtReg);
|
||||||
}
|
}
|
||||||
tempDefOperands_.push_back(virtReg);
|
|
||||||
(*currentInstr_)->SetMachineOperandReg(i, physReg);
|
(*currentInstr_)->SetMachineOperandReg(i, physReg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -815,8 +813,6 @@ void RA::assignVirt2StackSlot(unsigned virtReg)
|
|||||||
|
|
||||||
int RA::getStackSlot(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);
|
Virt2StackSlotMap::iterator it = v2ssMap_.find(virtReg);
|
||||||
assert(it != v2ssMap_.end() &&
|
assert(it != v2ssMap_.end() &&
|
||||||
"attempt to get stack slot on register that does not live on the stack");
|
"attempt to get stack slot on register that does not live on the stack");
|
||||||
|
|||||||
Reference in new issue
Block a user