mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-13 23:18:58 +00:00
Add MachineInstr::readsWritesVirtualRegister() to determine if an instruction
reads or writes a register. This takes partial redefines and undef uses into account. Don't actually use it yet. That caused miscompiles. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@104372 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
379fe83dda
commit
18b2c9d3bf
@ -28,6 +28,7 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
template <typename T> class SmallVectorImpl;
|
||||
class AliasAnalysis;
|
||||
class TargetInstrDesc;
|
||||
class TargetInstrInfo;
|
||||
@ -239,7 +240,16 @@ public:
|
||||
/// readsVirtualRegister - Return true if the MachineInstr reads the specified
|
||||
/// virtual register. Take into account that a partial define is a
|
||||
/// 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
|
||||
/// register. If TargetRegisterInfo is passed, then it also checks if there is
|
||||
|
@ -782,27 +782,31 @@ int MachineInstr::findRegisterUseOperandIdx(unsigned Reg, bool isKill,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// readsVirtualRegister - Return true if the MachineInstr reads the specified
|
||||
/// virtual register. Take into account that a partial define is a
|
||||
/// read-modify-write operation.
|
||||
bool MachineInstr::readsVirtualRegister(unsigned Reg) const {
|
||||
bool PartDef = false; // Partial redefine
|
||||
bool FullDef = false; // Full define
|
||||
/// readsWritesVirtualRegister - Return a pair of bools (reads, writes)
|
||||
/// indicating if this instruction reads or writes Reg. This also considers
|
||||
/// partial defines.
|
||||
std::pair<bool,bool>
|
||||
MachineInstr::readsWritesVirtualRegister(unsigned Reg,
|
||||
SmallVectorImpl<unsigned> *Ops) const {
|
||||
bool PartDef = false; // Partial redefine.
|
||||
bool FullDef = false; // Full define.
|
||||
bool Use = false;
|
||||
|
||||
for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
|
||||
const MachineOperand &MO = getOperand(i);
|
||||
if (!MO.isReg() || MO.getReg() != Reg)
|
||||
continue;
|
||||
if (Ops)
|
||||
Ops->push_back(i);
|
||||
if (MO.isUse())
|
||||
return true;
|
||||
if (MO.getSubReg())
|
||||
Use |= !MO.isUndef();
|
||||
else if (MO.getSubReg())
|
||||
PartDef = true;
|
||||
else
|
||||
FullDef = true;
|
||||
}
|
||||
// A partial register definition causes a read unless the full register is
|
||||
// also defined.
|
||||
return PartDef && !FullDef;
|
||||
// A partial redefine uses Reg unless there is also a full define.
|
||||
return std::make_pair(Use || (PartDef && !FullDef), PartDef || FullDef);
|
||||
}
|
||||
|
||||
/// findRegisterDefOperandIdx() - Returns the operand index that is a def of
|
||||
|
Loading…
Reference in New Issue
Block a user