#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;
}
/// isIdenticalTo - Return true if this operand is identical to the specified
/// operand.
bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const {
- if (getType() != Other.getType()) return false;
+ if (getType() != Other.getType() ||
+ getTargetFlags() != Other.getTargetFlags())
+ 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) {
- OS << ":" << getSubReg();
- }
+ if (getSubReg() != 0)
+ OS << ':' << getSubReg();
- if (isDef() || isKill() || isDead() || isImplicit() || isEarlyClobber()) {
- OS << "<";
+ if (isDef() || isKill() || isDead() || isImplicit() || isUndef() ||
+ isEarlyClobber()) {
+ OS << '<';
bool NeedComma = false;
if (isImplicit()) {
- if (NeedComma) OS << ",";
+ if (NeedComma) OS << ',';
OS << (isDef() ? "imp-def" : "imp-use");
NeedComma = true;
} else if (isDef()) {
- if (NeedComma) OS << ",";
+ if (NeedComma) OS << ',';
if (isEarlyClobber())
OS << "earlyclobber,";
OS << "def";
NeedComma = true;
}
- if (isKill() || isDead()) {
- if (NeedComma) OS << ",";
+ 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;
case MachineOperand::MO_Immediate:
OS << getImm();
break;
case MachineOperand::MO_FPImmediate:
- if (getFPImm()->getType() == Type::FloatTy) {
+ if (getFPImm()->getType() == Type::FloatTy)
OS << getFPImm()->getValueAPF().convertToFloat();
- } else {
+ else
OS << getFPImm()->getValueAPF().convertToDouble();
- }
break;
case MachineOperand::MO_MachineBasicBlock:
OS << "mbb<"
<< ((Value*)getMBB()->getBasicBlock())->getName()
- << "," << (void*)getMBB() << ">";
+ << "," << (void*)getMBB() << '>';
break;
case MachineOperand::MO_FrameIndex:
- OS << "<fi#" << getIndex() << ">";
+ OS << "<fi#" << getIndex() << '>';
break;
case MachineOperand::MO_ConstantPoolIndex:
OS << "<cp#" << getIndex();
if (getOffset()) OS << "+" << getOffset();
- OS << ">";
+ OS << '>';
break;
case MachineOperand::MO_JumpTableIndex:
- OS << "<jt#" << getIndex() << ">";
+ OS << "<jt#" << getIndex() << '>';
break;
case MachineOperand::MO_GlobalAddress:
OS << "<ga:" << ((Value*)getGlobal())->getName();
if (getOffset()) OS << "+" << getOffset();
- OS << ">";
+ OS << '>';
break;
case MachineOperand::MO_ExternalSymbol:
OS << "<es:" << getSymbolName();
if (getOffset()) OS << "+" << getOffset();
- OS << ">";
+ OS << '>';
break;
default:
- assert(0 && "Unrecognized operand type");
+ llvm_unreachable("Unrecognized operand type");
}
+
+ if (unsigned TF = getTargetFlags())
+ OS << "[TF=" << TF << ']';
}
//===----------------------------------------------------------------------===//
const MachineOperand &MO = getOperand(DefOpIdx);
if (!MO.isReg() || !MO.isDef() || MO.getReg() == 0)
return false;
- // Determine the actual operand no corresponding to this index.
+ // Determine the actual operand index that corresponds to this index.
unsigned DefNo = 0;
+ 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.
- i += InlineAsm::getNumOperandRegisters(FMO.getImm()) + 1;
- if (i > DefOpIdx)
+ unsigned NumOps = InlineAsm::getNumOperandRegisters(FMO.getImm());
+ unsigned PrevDef = i + 1;
+ i = PrevDef + NumOps;
+ if (i > DefOpIdx) {
+ DefPart = DefOpIdx - PrevDef;
break;
+ }
++DefNo;
}
- for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
+ for (unsigned i = 1, e = getNumOperands(); i != e; ++i) {
const MachineOperand &FMO = getOperand(i);
if (!FMO.isImm())
continue;
if (i+1 >= e || !getOperand(i+1).isReg() || !getOperand(i+1).isUse())
continue;
unsigned Idx;
- if (InlineAsm::isUseOperandTiedToDef(FMO.getImm(), Idx) &&
+ if (InlineAsm::isUseOperandTiedToDef(FMO.getImm(), Idx) &&
Idx == DefNo) {
if (UseOpIdx)
- *UseOpIdx = (unsigned)i + 1;
+ *UseOpIdx = (unsigned)i + 1 + DefPart;
return true;
}
}
+ return false;
}
assert(getOperand(DefOpIdx).isDef() && "DefOpIdx is not a def!");
const MachineOperand &MO = getOperand(UseOpIdx);
if (!MO.isReg() || !MO.isUse() || MO.getReg() == 0)
return false;
- assert(UseOpIdx > 0);
- const MachineOperand &UFMO = getOperand(UseOpIdx-1);
- if (!UFMO.isImm())
- return false; // Must be physreg uses.
+
+ // 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;
+ }
+ if (FlagIdx >= UseOpIdx)
+ return false;
+ const MachineOperand &UFMO = getOperand(FlagIdx);
unsigned DefNo;
if (InlineAsm::isUseOperandTiedToDef(UFMO.getImm(), DefNo)) {
if (!DefOpIdx)
DefIdx += InlineAsm::getNumOperandRegisters(FMO.getImm()) + 1;
--DefNo;
}
- *DefOpIdx = DefIdx+1;
+ *DefOpIdx = DefIdx + UseOpIdx - FlagIdx;
return true;
}
return false;
// If not found, this means an alias of one of the operands is dead. Add a
// new implicit operand if required.
- if (!Found && AddIfNotFound) {
- addOperand(MachineOperand::CreateReg(IncomingReg,
- true /*IsDef*/,
- true /*IsImp*/,
- false /*IsKill*/,
- true /*IsDead*/));
- return true;
- }
- return Found;
+ if (Found || !AddIfNotFound)
+ return Found;
+
+ addOperand(MachineOperand::CreateReg(IncomingReg,
+ true /*IsDef*/,
+ true /*IsImp*/,
+ false /*IsKill*/,
+ true /*IsDead*/));
+ return true;
}