#include "llvm/Target/TargetInstrDesc.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Analysis/DebugInfo.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/LeakDetector.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Streams.h"
/// the specified value. If an operand is known to be an register already,
/// the setReg method should be used.
void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp,
- bool isKill, bool isDead) {
+ bool isKill, bool isDead, bool isUndef) {
// If this operand is already a register operand, use setReg to update the
// register's use/def lists.
if (isReg()) {
IsImp = isImp;
IsKill = isKill;
IsDead = isDead;
+ IsUndef = isUndef;
IsEarlyClobber = false;
SubReg = 0;
}
return false;
switch (getType()) {
- default: assert(0 && "Unrecognized operand type");
+ default: llvm_unreachable("Unrecognized operand type");
case MachineOperand::MO_Register:
return getReg() == Other.getReg() && isDef() == Other.isDef() &&
getSubReg() == Other.getSubReg();
OS << "%mreg" << getReg();
}
- if (getSubReg() != 0) {
+ if (getSubReg() != 0)
OS << ':' << getSubReg();
- }
- if (isDef() || isKill() || isDead() || isImplicit() || isEarlyClobber()) {
+ if (isDef() || isKill() || isDead() || isImplicit() || isUndef() ||
+ isEarlyClobber()) {
OS << '<';
bool NeedComma = false;
if (isImplicit()) {
OS << "def";
NeedComma = true;
}
- if (isKill() || isDead()) {
+ if (isKill() || isDead() || isUndef()) {
if (NeedComma) OS << ',';
if (isKill()) OS << "kill";
if (isDead()) OS << "dead";
+ if (isUndef()) {
+ if (isKill() || isDead())
+ OS << ',';
+ OS << "undef";
+ }
}
OS << '>';
}
OS << '>';
break;
default:
- assert(0 && "Unrecognized operand type");
+ llvm_unreachable("Unrecognized operand type");
}
if (unsigned TF = getTargetFlags())
unsigned DefPart = 0;
for (unsigned i = 1, e = getNumOperands(); i < e; ) {
const MachineOperand &FMO = getOperand(i);
- assert(FMO.isImm());
+ // After the normal asm operands there may be additional imp-def regs.
+ if (!FMO.isImm())
+ return false;
// Skip over this def.
unsigned NumOps = InlineAsm::getNumOperandRegisters(FMO.getImm());
unsigned PrevDef = i + 1;
const MachineOperand &MO = getOperand(UseOpIdx);
if (!MO.isReg() || !MO.isUse() || MO.getReg() == 0)
return false;
- int FlagIdx = UseOpIdx - 1;
- if (FlagIdx < 1)
- return false;
- while (!getOperand(FlagIdx).isImm()) {
- if (--FlagIdx == 0)
+
+ // Find the flag operand corresponding to UseOpIdx
+ unsigned FlagIdx, NumOps=0;
+ for (FlagIdx = 1; FlagIdx < UseOpIdx; FlagIdx += NumOps+1) {
+ const MachineOperand &UFMO = getOperand(FlagIdx);
+ // After the normal asm operands there may be additional imp-def regs.
+ if (!UFMO.isImm())
return false;
+ NumOps = InlineAsm::getNumOperandRegisters(UFMO.getImm());
+ assert(NumOps < getNumOperands() && "Invalid inline asm flag");
+ if (UseOpIdx < FlagIdx+NumOps+1)
+ break;
}
- const MachineOperand &UFMO = getOperand(FlagIdx);
- if (FlagIdx + InlineAsm::getNumOperandRegisters(UFMO.getImm()) < UseOpIdx)
+ if (FlagIdx >= UseOpIdx)
return false;
+ const MachineOperand &UFMO = getOperand(FlagIdx);
unsigned DefNo;
if (InlineAsm::isUseOperandTiedToDef(UFMO.getImm(), DefNo)) {
if (!DefOpIdx)