mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-03-15 07:33:18 +00:00
Fix some scavenger performance issues.
- Don't call malloc+free in the very hot forward(). - Don't call isTiedToDefOperand(). - Don't create BitVector temporaries. - Merge DeadRegs into KillRegs. - Eliminate the early clobber checks, they were irrelevant to scavenging. - Remove unnecessary code from -Asserts builds. This speeds up ARM PEI by 3.4x and overall llc -O0 codegen time by 11%. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149189 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
685c23e758
commit
9f946a24d9
@ -68,6 +68,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;
|
||||||
|
|
||||||
|
// These BitVectors are only used internally to forward(). They are members
|
||||||
|
// to avoid frequent reallocations.
|
||||||
|
BitVector KillRegs, DefRegs;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RegScavenger()
|
RegScavenger()
|
||||||
: MBB(NULL), NumPhysRegs(0), Tracking(false),
|
: MBB(NULL), NumPhysRegs(0), Tracking(false),
|
||||||
@ -139,7 +143,7 @@ private:
|
|||||||
/// 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(BitVector &Regs) {
|
void setUsed(BitVector &Regs) {
|
||||||
RegsAvailable &= ~Regs;
|
RegsAvailable.reset(Regs);
|
||||||
}
|
}
|
||||||
void setUnused(BitVector &Regs) {
|
void setUnused(BitVector &Regs) {
|
||||||
RegsAvailable |= Regs;
|
RegsAvailable |= Regs;
|
||||||
@ -148,9 +152,6 @@ private:
|
|||||||
/// Add Reg and all its sub-registers to BV.
|
/// Add Reg and all its sub-registers to BV.
|
||||||
void addRegWithSubRegs(BitVector &BV, unsigned Reg);
|
void addRegWithSubRegs(BitVector &BV, unsigned Reg);
|
||||||
|
|
||||||
/// Add Reg and its aliases to BV.
|
|
||||||
void addRegWithAliases(BitVector &BV, unsigned Reg);
|
|
||||||
|
|
||||||
/// findSurvivorReg - Return the candidate register that is unused for the
|
/// findSurvivorReg - Return the candidate register that is unused for the
|
||||||
/// longest after StartMI. UseMI is set to the instruction where the search
|
/// longest after StartMI. UseMI is set to the instruction where the search
|
||||||
/// stopped.
|
/// stopped.
|
||||||
|
@ -90,6 +90,8 @@ void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) {
|
|||||||
if (!MBB) {
|
if (!MBB) {
|
||||||
NumPhysRegs = TRI->getNumRegs();
|
NumPhysRegs = TRI->getNumRegs();
|
||||||
RegsAvailable.resize(NumPhysRegs);
|
RegsAvailable.resize(NumPhysRegs);
|
||||||
|
KillRegs.resize(NumPhysRegs);
|
||||||
|
DefRegs.resize(NumPhysRegs);
|
||||||
|
|
||||||
// Create reserved registers bitvector.
|
// Create reserved registers bitvector.
|
||||||
ReservedRegs = TRI->getReservedRegs(MF);
|
ReservedRegs = TRI->getReservedRegs(MF);
|
||||||
@ -114,12 +116,6 @@ void RegScavenger::addRegWithSubRegs(BitVector &BV, unsigned Reg) {
|
|||||||
BV.set(*R);
|
BV.set(*R);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegScavenger::addRegWithAliases(BitVector &BV, unsigned Reg) {
|
|
||||||
BV.set(Reg);
|
|
||||||
for (const unsigned *R = TRI->getAliasSet(Reg); *R; R++)
|
|
||||||
BV.set(*R);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RegScavenger::forward() {
|
void RegScavenger::forward() {
|
||||||
// Move ptr forward.
|
// Move ptr forward.
|
||||||
if (!Tracking) {
|
if (!Tracking) {
|
||||||
@ -148,10 +144,8 @@ void RegScavenger::forward() {
|
|||||||
// predicated, conservatively assume "kill" markers do not actually kill the
|
// predicated, conservatively assume "kill" markers do not actually kill the
|
||||||
// register. Similarly ignores "dead" markers.
|
// register. Similarly ignores "dead" markers.
|
||||||
bool isPred = TII->isPredicated(MI);
|
bool isPred = TII->isPredicated(MI);
|
||||||
BitVector EarlyClobberRegs(NumPhysRegs);
|
KillRegs.reset();
|
||||||
BitVector KillRegs(NumPhysRegs);
|
DefRegs.reset();
|
||||||
BitVector DefRegs(NumPhysRegs);
|
|
||||||
BitVector DeadRegs(NumPhysRegs);
|
|
||||||
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);
|
||||||
if (!MO.isReg())
|
if (!MO.isReg())
|
||||||
@ -164,21 +158,19 @@ void RegScavenger::forward() {
|
|||||||
// Ignore undef uses.
|
// Ignore undef uses.
|
||||||
if (MO.isUndef())
|
if (MO.isUndef())
|
||||||
continue;
|
continue;
|
||||||
// Two-address operands implicitly kill.
|
if (!isPred && MO.isKill())
|
||||||
if (!isPred && (MO.isKill() || MI->isRegTiedToDefOperand(i)))
|
|
||||||
addRegWithSubRegs(KillRegs, Reg);
|
addRegWithSubRegs(KillRegs, Reg);
|
||||||
} else {
|
} else {
|
||||||
assert(MO.isDef());
|
assert(MO.isDef());
|
||||||
if (!isPred && MO.isDead())
|
if (!isPred && MO.isDead())
|
||||||
addRegWithSubRegs(DeadRegs, Reg);
|
addRegWithSubRegs(KillRegs, Reg);
|
||||||
else
|
else
|
||||||
addRegWithSubRegs(DefRegs, Reg);
|
addRegWithSubRegs(DefRegs, Reg);
|
||||||
if (MO.isEarlyClobber())
|
|
||||||
addRegWithAliases(EarlyClobberRegs, Reg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify uses and defs.
|
// Verify uses and defs.
|
||||||
|
#ifndef NDEBUG
|
||||||
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);
|
||||||
if (!MO.isReg())
|
if (!MO.isReg())
|
||||||
@ -205,16 +197,12 @@ void RegScavenger::forward() {
|
|||||||
SubUsed = true;
|
SubUsed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifndef NDEBUG
|
|
||||||
if (!SubUsed) {
|
if (!SubUsed) {
|
||||||
MBB->getParent()->verify(NULL, "In Register Scavenger");
|
MBB->getParent()->verify(NULL, "In Register Scavenger");
|
||||||
llvm_unreachable("Using an undefined register!");
|
llvm_unreachable("Using an undefined register!");
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
(void)SubUsed;
|
(void)SubUsed;
|
||||||
}
|
}
|
||||||
assert((!EarlyClobberRegs.test(Reg) || MI->isRegTiedToDefOperand(i)) &&
|
|
||||||
"Using an early clobbered register!");
|
|
||||||
} else {
|
} else {
|
||||||
assert(MO.isDef());
|
assert(MO.isDef());
|
||||||
#if 0
|
#if 0
|
||||||
@ -226,10 +214,10 @@ void RegScavenger::forward() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif // NDEBUG
|
||||||
|
|
||||||
// Commit the changes.
|
// Commit the changes.
|
||||||
setUnused(KillRegs);
|
setUnused(KillRegs);
|
||||||
setUnused(DeadRegs);
|
|
||||||
setUsed(DefRegs);
|
setUsed(DefRegs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user