#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"
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 << '>';
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)
// load.
if (TID->mayLoad() && !TII->isInvariantLoad(this))
// Otherwise, this is a real load. If there is a store between the load and
- // end of block, or if the laod is volatile, we can't move it.
+ // end of block, or if the load is volatile, we can't move it.
return !SawStore && !hasVolatileMemoryRef();
return true;
if (MO.isKill())
// The register is already marked kill.
return true;
+ if (isPhysReg && isRegTiedToDefOperand(i))
+ // Two-address uses of physregs must not be marked kill.
+ return true;
MO.setIsKill();
Found = true;
}