mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-12 03:32:10 +00:00
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:
parent
00c53caa33
commit
19f5f71bba
@ -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
|
||||||
|
@ -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)) {
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user