mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-10-02 17:55:18 +00:00
When setting the "unused" info, take into account something like this:
%r3<def> = OR %x3<kill>, %x3 We don't want to mark the %r3 as unused even though it's a sub-register of %x3. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48003 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
eb49c4e008
commit
ed1fcd8987
@ -98,7 +98,7 @@ public:
|
|||||||
///
|
///
|
||||||
void setUsed(unsigned Reg);
|
void setUsed(unsigned Reg);
|
||||||
void setUsed(BitVector Regs) { RegsAvailable &= ~Regs; }
|
void setUsed(BitVector Regs) { RegsAvailable &= ~Regs; }
|
||||||
void setUnused(unsigned Reg);
|
void setUnused(unsigned Reg, const MachineInstr *MI);
|
||||||
void setUnused(BitVector Regs) { RegsAvailable |= Regs; }
|
void setUnused(BitVector Regs) { RegsAvailable |= Regs; }
|
||||||
|
|
||||||
/// FindUnusedReg - Find a unused register of the specified register class
|
/// FindUnusedReg - Find a unused register of the specified register class
|
||||||
|
@ -8,9 +8,9 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
//
|
//
|
||||||
// This file implements the machine register scavenger. It can provide
|
// This file implements the machine register scavenger. It can provide
|
||||||
// information such as unused register at any point in a machine basic block.
|
// information, such as unused registers, at any point in a machine basic block.
|
||||||
// It also provides a mechanism to make registers availbale by evicting them
|
// It also provides a mechanism to make registers available by evicting them to
|
||||||
// to spill slots.
|
// spill slots.
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
@ -25,6 +25,28 @@
|
|||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
|
/// RedefinesSuperRegPart - Return true if the specified register is redefining
|
||||||
|
/// part of a super-register.
|
||||||
|
static bool RedefinesSuperRegPart(const MachineInstr *MI, unsigned SubReg,
|
||||||
|
const TargetRegisterInfo *TRI) {
|
||||||
|
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
||||||
|
const MachineOperand &MO = MI->getOperand(i);
|
||||||
|
if (!MO.isRegister() || !MO.isUse())
|
||||||
|
continue;
|
||||||
|
if (TRI->isSuperRegister(SubReg, MO.getReg()))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool RedefinesSuperRegPart(const MachineInstr *MI,
|
||||||
|
const MachineOperand &MO,
|
||||||
|
const TargetRegisterInfo *TRI) {
|
||||||
|
assert(MO.isRegister() && MO.isDef() && "Not a register def!");
|
||||||
|
return RedefinesSuperRegPart(MI, MO.getReg(), TRI);
|
||||||
|
}
|
||||||
|
|
||||||
/// 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) {
|
||||||
RegsAvailable.reset(Reg);
|
RegsAvailable.reset(Reg);
|
||||||
@ -35,12 +57,13 @@ void RegScavenger::setUsed(unsigned Reg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// 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) {
|
void RegScavenger::setUnused(unsigned Reg, const MachineInstr *MI) {
|
||||||
RegsAvailable.set(Reg);
|
RegsAvailable.set(Reg);
|
||||||
|
|
||||||
for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
|
for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
|
||||||
unsigned SubReg = *SubRegs; ++SubRegs)
|
unsigned SubReg = *SubRegs; ++SubRegs)
|
||||||
RegsAvailable.set(SubReg);
|
if (!RedefinesSuperRegPart(MI, Reg, TRI))
|
||||||
|
RegsAvailable.set(SubReg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) {
|
void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) {
|
||||||
@ -138,9 +161,12 @@ void RegScavenger::forward() {
|
|||||||
if (MO.isKill() && !isReserved(Reg)) {
|
if (MO.isKill() && !isReserved(Reg)) {
|
||||||
ChangedRegs.set(Reg);
|
ChangedRegs.set(Reg);
|
||||||
|
|
||||||
|
// Mark sub-registers as changed if they aren't defined in the same
|
||||||
|
// instruction.
|
||||||
for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
|
for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
|
||||||
unsigned SubReg = *SubRegs; ++SubRegs)
|
unsigned SubReg = *SubRegs; ++SubRegs)
|
||||||
ChangedRegs.set(SubReg);
|
if (!RedefinesSuperRegPart(MI, Reg, TRI))
|
||||||
|
ChangedRegs.set(SubReg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +185,7 @@ void RegScavenger::forward() {
|
|||||||
|
|
||||||
// If it's dead upon def, then it is now free.
|
// If it's dead upon def, then it is now free.
|
||||||
if (MO.isDead()) {
|
if (MO.isDead()) {
|
||||||
setUnused(Reg);
|
setUnused(Reg, MI);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,6 +195,10 @@ void RegScavenger::forward() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Skip is this is merely redefining part of a super-register.
|
||||||
|
if (RedefinesSuperRegPart(MI, MO, TRI))
|
||||||
|
continue;
|
||||||
|
|
||||||
assert((isUnused(Reg) || isReserved(Reg)) &&
|
assert((isUnused(Reg) || isReserved(Reg)) &&
|
||||||
"Re-defining a live register!");
|
"Re-defining a live register!");
|
||||||
setUsed(Reg);
|
setUsed(Reg);
|
||||||
@ -194,7 +224,7 @@ void RegScavenger::backward() {
|
|||||||
unsigned Reg = MO.getReg();
|
unsigned Reg = MO.getReg();
|
||||||
assert(isUsed(Reg));
|
assert(isUsed(Reg));
|
||||||
if (!isReserved(Reg))
|
if (!isReserved(Reg))
|
||||||
setUnused(Reg);
|
setUnused(Reg, MI);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process uses.
|
// Process uses.
|
||||||
|
Loading…
Reference in New Issue
Block a user