summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2010-05-21 20:02:01 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2010-05-21 20:02:01 +0000
commit7d7f6043213a1234addce9acdf70099ce1ef4276 (patch)
tree179b00592338f0617822add21ff22803bc9c3f16
parent71b0bb992257bce0ba6567a7275a2be14663437c (diff)
downloadbcm5719-llvm-7d7f6043213a1234addce9acdf70099ce1ef4276.tar.gz
bcm5719-llvm-7d7f6043213a1234addce9acdf70099ce1ef4276.zip
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. llvm-svn: 104372
-rw-r--r--llvm/include/llvm/CodeGen/MachineInstr.h12
-rw-r--r--llvm/lib/CodeGen/MachineInstr.cpp26
2 files changed, 26 insertions, 12 deletions
diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h
index 5e62f0bcfb8..cd72344dc71 100644
--- a/llvm/include/llvm/CodeGen/MachineInstr.h
+++ b/llvm/include/llvm/CodeGen/MachineInstr.h
@@ -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
diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp
index 595fddda6f6..319059b4bbf 100644
--- a/llvm/lib/CodeGen/MachineInstr.cpp
+++ b/llvm/lib/CodeGen/MachineInstr.cpp
@@ -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
OpenPOWER on IntegriCloud