Revert "Use MachineInstr::readsWritesVirtualRegister to determine if a register is read."

This reverts r104322. I think it was causing miscompilations.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@104323 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jakob Stoklund Olesen 2010-05-21 17:36:32 +00:00
parent 00c53caa33
commit 19f5f71bba
3 changed files with 58 additions and 34 deletions

View File

@ -28,7 +28,6 @@
namespace llvm { namespace llvm {
template <typename T> class SmallVectorImpl;
class AliasAnalysis; class AliasAnalysis;
class TargetInstrDesc; class TargetInstrDesc;
class TargetInstrInfo; class TargetInstrInfo;
@ -240,16 +239,7 @@ public:
/// readsVirtualRegister - Return true if the MachineInstr reads the specified /// readsVirtualRegister - Return true if the MachineInstr reads the specified
/// virtual register. Take into account that a partial define is a /// virtual register. Take into account that a partial define is a
/// read-modify-write operation. /// read-modify-write operation.
bool readsVirtualRegister(unsigned Reg) const { bool readsVirtualRegister(unsigned Reg) const;
return readsWritesVirtualRegister(Reg).first;
}
/// readsWritesVirtualRegister - Return a pair of bools (reads, writes)
/// indicating if this instruction reads or writes Reg. This also considers
/// partial defines.
/// If Ops is not null, all operand indices for Reg are added.
std::pair<bool,bool> readsWritesVirtualRegister(unsigned Reg,
SmallVectorImpl<unsigned> *Ops = 0) const;
/// killsRegister - Return true if the MachineInstr kills the specified /// killsRegister - Return true if the MachineInstr kills the specified
/// register. If TargetRegisterInfo is passed, then it also checks if there is /// register. If TargetRegisterInfo is passed, then it also checks if there is

View File

@ -1098,6 +1098,7 @@ rewriteInstructionForSpills(const LiveInterval &li, const VNInfo *VNI,
if (!mop.isReg()) if (!mop.isReg())
continue; continue;
unsigned Reg = mop.getReg(); unsigned Reg = mop.getReg();
unsigned RegI = Reg;
if (Reg == 0 || TargetRegisterInfo::isPhysicalRegister(Reg)) if (Reg == 0 || TargetRegisterInfo::isPhysicalRegister(Reg))
continue; continue;
if (Reg != li.reg) if (Reg != li.reg)
@ -1139,8 +1140,26 @@ rewriteInstructionForSpills(const LiveInterval &li, const VNInfo *VNI,
// //
// Keep track of whether we replace a use and/or def so that we can // Keep track of whether we replace a use and/or def so that we can
// create the spill interval with the appropriate range. // create the spill interval with the appropriate range.
HasUse = mop.isUse();
HasDef = mop.isDef();
SmallVector<unsigned, 2> Ops; SmallVector<unsigned, 2> Ops;
tie(HasUse, HasDef) = MI->readsWritesVirtualRegister(Reg, &Ops); Ops.push_back(i);
for (unsigned j = i+1, e = MI->getNumOperands(); j != e; ++j) {
const MachineOperand &MOj = MI->getOperand(j);
if (!MOj.isReg())
continue;
unsigned RegJ = MOj.getReg();
if (RegJ == 0 || TargetRegisterInfo::isPhysicalRegister(RegJ))
continue;
if (RegJ == RegI) {
Ops.push_back(j);
if (!MOj.isUndef()) {
HasUse |= MOj.isUse();
HasDef |= MOj.isDef();
}
}
}
// Create a new virtual register for the spill interval. // Create a new virtual register for the spill interval.
// Create the new register now so we can map the fold instruction // Create the new register now so we can map the fold instruction
@ -1293,7 +1312,10 @@ namespace {
struct RewriteInfo { struct RewriteInfo {
SlotIndex Index; SlotIndex Index;
MachineInstr *MI; MachineInstr *MI;
RewriteInfo(SlotIndex i, MachineInstr *mi) : Index(i), MI(mi) {} bool HasUse;
bool HasDef;
RewriteInfo(SlotIndex i, MachineInstr *mi, bool u, bool d)
: Index(i), MI(mi), HasUse(u), HasDef(d) {}
}; };
struct RewriteInfoCompare { struct RewriteInfoCompare {
@ -1372,7 +1394,7 @@ rewriteInstructionsForSpills(const LiveInterval &li, bool TrySplit,
// easily see a situation where both registers are reloaded before // easily see a situation where both registers are reloaded before
// the INSERT_SUBREG and both target registers that would overlap. // the INSERT_SUBREG and both target registers that would overlap.
continue; continue;
RewriteMIs.push_back(RewriteInfo(index, MI)); RewriteMIs.push_back(RewriteInfo(index, MI, O.isUse(), O.isDef()));
} }
std::sort(RewriteMIs.begin(), RewriteMIs.end(), RewriteInfoCompare()); std::sort(RewriteMIs.begin(), RewriteMIs.end(), RewriteInfoCompare());
@ -1382,11 +1404,18 @@ rewriteInstructionsForSpills(const LiveInterval &li, bool TrySplit,
RewriteInfo &rwi = RewriteMIs[i]; RewriteInfo &rwi = RewriteMIs[i];
++i; ++i;
SlotIndex index = rwi.Index; SlotIndex index = rwi.Index;
bool MIHasUse = rwi.HasUse;
bool MIHasDef = rwi.HasDef;
MachineInstr *MI = rwi.MI; MachineInstr *MI = rwi.MI;
// If MI def and/or use the same register multiple times, then there // If MI def and/or use the same register multiple times, then there
// are multiple entries. // are multiple entries.
unsigned NumUses = MIHasUse;
while (i != e && RewriteMIs[i].MI == MI) { while (i != e && RewriteMIs[i].MI == MI) {
assert(RewriteMIs[i].Index == index); assert(RewriteMIs[i].Index == index);
bool isUse = RewriteMIs[i].HasUse;
if (isUse) ++NumUses;
MIHasUse |= isUse;
MIHasDef |= RewriteMIs[i].HasDef;
++i; ++i;
} }
MachineBasicBlock *MBB = MI->getParent(); MachineBasicBlock *MBB = MI->getParent();
@ -1411,8 +1440,7 @@ rewriteInstructionsForSpills(const LiveInterval &li, bool TrySplit,
// = use // = use
// It's better to start a new interval to avoid artifically // It's better to start a new interval to avoid artifically
// extend the new interval. // extend the new interval.
if (MI->readsWritesVirtualRegister(li.reg) == if (MIHasDef && !MIHasUse) {
std::make_pair(false,true)) {
MBBVRegsMap.erase(MBB->getNumber()); MBBVRegsMap.erase(MBB->getNumber());
ThisVReg = 0; ThisVReg = 0;
} }
@ -1646,8 +1674,18 @@ addIntervalsForSpillsFast(const LiveInterval &li,
MachineInstr* MI = &*RI; MachineInstr* MI = &*RI;
SmallVector<unsigned, 2> Indices; SmallVector<unsigned, 2> Indices;
bool HasUse, HasDef; bool HasUse = false;
tie(HasUse, HasDef) = MI->readsWritesVirtualRegister(li.reg, &Indices); bool HasDef = false;
for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
MachineOperand& mop = MI->getOperand(i);
if (!mop.isReg() || mop.getReg() != li.reg) continue;
HasUse |= MI->getOperand(i).isUse();
HasDef |= MI->getOperand(i).isDef();
Indices.push_back(i);
}
if (!tryFoldMemoryOperand(MI, vrm, NULL, getInstructionIndex(MI), if (!tryFoldMemoryOperand(MI, vrm, NULL, getInstructionIndex(MI),
Indices, true, slot, li.reg)) { Indices, true, slot, li.reg)) {

View File

@ -782,31 +782,27 @@ int MachineInstr::findRegisterUseOperandIdx(unsigned Reg, bool isKill,
return -1; return -1;
} }
/// readsWritesVirtualRegister - Return a pair of bools (reads, writes) /// readsVirtualRegister - Return true if the MachineInstr reads the specified
/// indicating if this instruction reads or writes Reg. This also considers /// virtual register. Take into account that a partial define is a
/// partial defines. /// read-modify-write operation.
std::pair<bool,bool> bool MachineInstr::readsVirtualRegister(unsigned Reg) const {
MachineInstr::readsWritesVirtualRegister(unsigned Reg, bool PartDef = false; // Partial redefine
SmallVectorImpl<unsigned> *Ops) const { bool FullDef = false; // Full define
bool PartDef = false; // Partial redefine.
bool FullDef = false; // Full define.
bool Use = false;
for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
const MachineOperand &MO = getOperand(i); const MachineOperand &MO = getOperand(i);
if (!MO.isReg() || MO.getReg() != Reg) if (!MO.isReg() || MO.getReg() != Reg)
continue; continue;
if (Ops)
Ops->push_back(i);
if (MO.isUse()) if (MO.isUse())
Use |= !MO.isUndef(); return true;
else if (MO.getSubReg()) if (MO.getSubReg())
PartDef = true; PartDef = true;
else else
FullDef = true; FullDef = true;
} }
// A partial redefine uses Reg unless there is also a full define. // A partial register definition causes a read unless the full register is
return std::make_pair(Use || (PartDef && !FullDef), PartDef || FullDef); // also defined.
return PartDef && !FullDef;
} }
/// findRegisterDefOperandIdx() - Returns the operand index that is a def of /// findRegisterDefOperandIdx() - Returns the operand index that is a def of