diff options
author | James Molloy <james.molloy@arm.com> | 2012-09-12 10:03:31 +0000 |
---|---|---|
committer | James Molloy <james.molloy@arm.com> | 2012-09-12 10:03:31 +0000 |
commit | 381fab93d5cb3dbb227e22109c987bb9f375708e (patch) | |
tree | 1ec68eea149dbe5a6e636eb9da5ce0a35ad4d80e /llvm/lib/CodeGen/MachineInstrBundle.cpp | |
parent | 66fc0e63a0fc2b79fe968c0aaccbcde5518798f7 (diff) | |
download | llvm-381fab93d5cb3dbb227e22109c987bb9f375708e.zip llvm-381fab93d5cb3dbb227e22109c987bb9f375708e.tar.gz llvm-381fab93d5cb3dbb227e22109c987bb9f375708e.tar.bz2 |
Add an analyzePhysReg() function to MachineOperandIteratorBase that analyses an instruction's use of a physical register, analogous to analyzeVirtReg.
Rename RegInfo to VirtRegInfo so as not to be confused with the new PhysRegInfo.
llvm-svn: 163694
Diffstat (limited to 'llvm/lib/CodeGen/MachineInstrBundle.cpp')
-rw-r--r-- | llvm/lib/CodeGen/MachineInstrBundle.cpp | 54 |
1 files changed, 52 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/MachineInstrBundle.cpp b/llvm/lib/CodeGen/MachineInstrBundle.cpp index b7de7bf..ff7ad03 100644 --- a/llvm/lib/CodeGen/MachineInstrBundle.cpp +++ b/llvm/lib/CodeGen/MachineInstrBundle.cpp @@ -248,10 +248,10 @@ bool llvm::finalizeBundles(MachineFunction &MF) { // MachineOperand iterator //===----------------------------------------------------------------------===// -MachineOperandIteratorBase::RegInfo +MachineOperandIteratorBase::VirtRegInfo MachineOperandIteratorBase::analyzeVirtReg(unsigned Reg, SmallVectorImpl<std::pair<MachineInstr*, unsigned> > *Ops) { - RegInfo RI = { false, false, false }; + VirtRegInfo RI = { false, false, false }; for(; isValid(); ++*this) { MachineOperand &MO = deref(); if (!MO.isReg() || MO.getReg() != Reg) @@ -276,3 +276,53 @@ MachineOperandIteratorBase::analyzeVirtReg(unsigned Reg, } return RI; } + +MachineOperandIteratorBase::PhysRegInfo +MachineOperandIteratorBase::analyzePhysReg(unsigned Reg, + const TargetRegisterInfo *TRI) { + bool AllDefsDead = true; + PhysRegInfo PRI = {false, false, false, false, false, false, false}; + + assert(TargetRegisterInfo::isPhysicalRegister(Reg) && + "analyzePhysReg not given a physical register!"); + for (; isValid(); ++*this) { + MachineOperand &MO = deref(); + + if (MO.isRegMask() && MO.clobbersPhysReg(Reg)) + PRI.Clobbers = true; // Regmask clobbers Reg. + + if (!MO.isReg()) + continue; + + unsigned MOReg = MO.getReg(); + if (!MOReg || !TargetRegisterInfo::isPhysicalRegister(MOReg)) + continue; + + bool IsRegOrSuperReg = MOReg == Reg || TRI->isSubRegister(MOReg, Reg); + bool IsRegOrOverlapping = MOReg == Reg || TRI->regsOverlap(MOReg, Reg); + + if (IsRegOrSuperReg && MO.readsReg()) { + // Reg or a super-reg is read, and perhaps killed also. + PRI.Reads = true; + PRI.Kills = MO.isKill(); + } if (IsRegOrOverlapping && MO.readsReg()) { + PRI.ReadsOverlap = true;// Reg or an overlapping register is read. + } + + if (!MO.isDef()) + continue; + + if (IsRegOrSuperReg) { + PRI.Defines = true; // Reg or a super-register is defined. + if (!MO.isDead()) + AllDefsDead = false; + } + if (IsRegOrOverlapping) + PRI.Clobbers = true; // Reg or an overlapping reg is defined. + } + + if (AllDefsDead && PRI.Defines) + PRI.DefinesDead = true; // Reg or super-register was defined and was dead. + + return PRI; +} |