diff options
author | Bill Wendling <isanbard@gmail.com> | 2008-03-06 23:22:43 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2008-03-06 23:22:43 +0000 |
commit | 7bd225597ac7aca2fde7b9d99173b6b9600603d8 (patch) | |
tree | 06eb1c58fd9cce63d8df5e358bb336cdfd8fde2a /lib/CodeGen/RegisterScavenging.cpp | |
parent | eadaf4495d25535c9fed7d696a5891eb6ad302ce (diff) | |
download | external_llvm-7bd225597ac7aca2fde7b9d99173b6b9600603d8.zip external_llvm-7bd225597ac7aca2fde7b9d99173b6b9600603d8.tar.gz external_llvm-7bd225597ac7aca2fde7b9d99173b6b9600603d8.tar.bz2 |
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
Diffstat (limited to 'lib/CodeGen/RegisterScavenging.cpp')
-rw-r--r-- | lib/CodeGen/RegisterScavenging.cpp | 46 |
1 files changed, 38 insertions, 8 deletions
diff --git a/lib/CodeGen/RegisterScavenging.cpp b/lib/CodeGen/RegisterScavenging.cpp index c074706..635e0cc 100644 --- a/lib/CodeGen/RegisterScavenging.cpp +++ b/lib/CodeGen/RegisterScavenging.cpp @@ -8,9 +8,9 @@ //===----------------------------------------------------------------------===// // // This file implements the machine register scavenger. It can provide -// information such as unused register at any point in a machine basic block. -// It also provides a mechanism to make registers availbale by evicting them -// to spill slots. +// information, such as unused registers, at any point in a machine basic block. +// It also provides a mechanism to make registers available by evicting them to +// spill slots. // //===----------------------------------------------------------------------===// @@ -25,6 +25,28 @@ #include "llvm/ADT/STLExtras.h" 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. void RegScavenger::setUsed(unsigned Reg) { RegsAvailable.reset(Reg); @@ -35,12 +57,13 @@ void RegScavenger::setUsed(unsigned Reg) { } /// 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); for (const unsigned *SubRegs = TRI->getSubRegisters(Reg); unsigned SubReg = *SubRegs; ++SubRegs) - RegsAvailable.set(SubReg); + if (!RedefinesSuperRegPart(MI, Reg, TRI)) + RegsAvailable.set(SubReg); } void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) { @@ -138,9 +161,12 @@ void RegScavenger::forward() { if (MO.isKill() && !isReserved(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); 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 (MO.isDead()) { - setUnused(Reg); + setUnused(Reg, MI); continue; } @@ -169,6 +195,10 @@ void RegScavenger::forward() { continue; } + // Skip is this is merely redefining part of a super-register. + if (RedefinesSuperRegPart(MI, MO, TRI)) + continue; + assert((isUnused(Reg) || isReserved(Reg)) && "Re-defining a live register!"); setUsed(Reg); @@ -194,7 +224,7 @@ void RegScavenger::backward() { unsigned Reg = MO.getReg(); assert(isUsed(Reg)); if (!isReserved(Reg)) - setUnused(Reg); + setUnused(Reg, MI); } // Process uses. |