/// findRegisterUseOperandIdx() - Returns the MachineOperand that is a use of
/// the specific register or -1 if it is not found. It further tightening
/// the search criteria to a use that kills the register if isKill is true.
-int MachineInstr::findRegisterUseOperandIdx(unsigned Reg, bool isKill) const {
+int MachineInstr::findRegisterUseOperandIdx(unsigned Reg, bool isKill,
+ const TargetRegisterInfo *TRI) const {
for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
const MachineOperand &MO = getOperand(i);
- if (MO.isRegister() && MO.isUse() && MO.getReg() == Reg)
+ if (!MO.isRegister() || !MO.isUse())
+ continue;
+ unsigned MOReg = MO.getReg();
+ if (!MOReg)
+ continue;
+ if (MOReg == Reg ||
+ (TRI &&
+ TargetRegisterInfo::isPhysicalRegister(MOReg) &&
+ TargetRegisterInfo::isPhysicalRegister(Reg) &&
+ TRI->isSubRegister(MOReg, Reg)))
if (!isKill || MO.isKill())
return i;
}
return -1;
}
-/// findRegisterDefOperand() - Returns the MachineOperand that is a def of
-/// the specific register or NULL if it is not found.
-MachineOperand *MachineInstr::findRegisterDefOperand(unsigned Reg) {
+/// findRegisterDefOperandIdx() - Returns the operand index that is a def of
+/// the specific register or -1 if it is not found. It further tightening
+ /// the search criteria to a def that is dead the register if isDead is true.
+int MachineInstr::findRegisterDefOperandIdx(unsigned Reg, bool isDead,
+ const TargetRegisterInfo *TRI) const {
for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
- MachineOperand &MO = getOperand(i);
- if (MO.isRegister() && MO.isDef() && MO.getReg() == Reg)
- return &MO;
+ const MachineOperand &MO = getOperand(i);
+ if (!MO.isRegister() || !MO.isDef())
+ continue;
+ unsigned MOReg = MO.getReg();
+ if (MOReg == Reg ||
+ (TRI &&
+ TargetRegisterInfo::isPhysicalRegister(MOReg) &&
+ TargetRegisterInfo::isPhysicalRegister(Reg) &&
+ TRI->isSubRegister(MOReg, Reg)))
+ if (!isDead || MO.isDead())
+ return i;
}
- return NULL;
+ return -1;
}
/// findFirstPredOperandIdx() - Find the index of the first operand in the
bool MachineInstr::addRegisterKilled(unsigned IncomingReg,
const TargetRegisterInfo *RegInfo,
bool AddIfNotFound) {
- bool Found = false;
- for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
+ // Go through the machine instruction's operands to eliminate any potentially
+ // illegal conditions. I.e., a super- and sub-register both marked "kill".
+ for (unsigned i = 0, e = getNumOperands(); i < e;) {
MachineOperand &MO = getOperand(i);
if (MO.isRegister() && MO.isUse()) {
unsigned Reg = MO.getReg();
- if (!Reg)
+
+ if (!Reg || IncomingReg == Reg ||
+ !TargetRegisterInfo::isPhysicalRegister(Reg) ||
+ !TargetRegisterInfo::isPhysicalRegister(IncomingReg)) {
+ ++i;
continue;
+ }
+
+ if (RegInfo->isSuperRegister(IncomingReg, Reg) && MO.isKill())
+ // The kill information is already handled by a super-register. Don't
+ // add this sub-register as a kill.
+ return true;
+
+ if (RegInfo->isSubRegister(IncomingReg, Reg) && MO.isKill()) {
+ if (MO.isImplicit()) {
+ // Remove this implicit use that marks the sub-register
+ // "kill". Let the super-register take care of this
+ // information.
+ RemoveOperand(i);
+ --e;
+ continue;
+ } else {
+ // The super-register is going to take care of this kill
+ // information.
+ MO.setIsKill(false);
+ }
+ }
+ }
+
+ ++i;
+ }
+
+ // If the register already exists, then make sure it or its super-register is
+ // marked "kill".
+ for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
+ MachineOperand &MO = getOperand(i);
+
+ if (MO.isRegister() && MO.isUse()) {
+ unsigned Reg = MO.getReg();
+ if (!Reg) continue;
+
if (Reg == IncomingReg) {
MO.setIsKill();
- Found = true;
- break;
- } else if (TargetRegisterInfo::isPhysicalRegister(Reg) &&
- TargetRegisterInfo::isPhysicalRegister(IncomingReg) &&
- RegInfo->isSuperRegister(IncomingReg, Reg) &&
- MO.isKill())
+ return true;
+ }
+
+ if (TargetRegisterInfo::isPhysicalRegister(Reg) &&
+ TargetRegisterInfo::isPhysicalRegister(IncomingReg) &&
+ RegInfo->isSuperRegister(IncomingReg, Reg) &&
+ MO.isKill())
// A super-register kill already exists.
- Found = true;
+ return true;
}
}
- // If not found, this means an alias of one of the operand is killed. Add a
+ // If not found, this means an alias of one of the operands is killed. Add a
// new implicit operand if required.
- if (!Found && AddIfNotFound) {
- addOperand(MachineOperand::CreateReg(IncomingReg, false/*IsDef*/,
- true/*IsImp*/,true/*IsKill*/));
+ if (AddIfNotFound) {
+ addOperand(MachineOperand::CreateReg(IncomingReg,
+ false /*IsDef*/,
+ true /*IsImp*/,
+ true /*IsKill*/));
return true;
}
- return Found;
+
+ return false;
}
bool MachineInstr::addRegisterDead(unsigned IncomingReg,