#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetInstrDesc.h"
#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/Analysis/DebugInfo.h"
#include "llvm/Support/LeakDetector.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Streams.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/FoldingSet.h"
-#include <ostream>
using namespace llvm;
//===----------------------------------------------------------------------===//
*Head = this;
}
+/// RemoveRegOperandFromRegInfo - Remove this register operand from the
+/// MachineRegisterInfo it is linked with.
+void MachineOperand::RemoveRegOperandFromRegInfo() {
+ assert(isOnRegUseList() && "Reg operand is not on a use list");
+ // Unlink this from the doubly linked list of operands.
+ MachineOperand *NextOp = Contents.Reg.Next;
+ *Contents.Reg.Prev = NextOp;
+ if (NextOp) {
+ assert(NextOp->getReg() == getReg() && "Corrupt reg use/def chain!");
+ NextOp->Contents.Reg.Prev = Contents.Reg.Prev;
+ }
+ Contents.Reg.Prev = 0;
+ Contents.Reg.Next = 0;
+}
+
void MachineOperand::setReg(unsigned Reg) {
if (getReg() == Reg) return; // No change.
/// 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");
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");
}
+
+ if (unsigned TF = getTargetFlags())
+ OS << "[TF=" << TF << ']';
}
//===----------------------------------------------------------------------===//
if (!TID->isVariadic())
return NumOperands;
- for (unsigned e = getNumOperands(); NumOperands != e; ++NumOperands) {
- const MachineOperand &MO = getOperand(NumOperands);
+ for (unsigned i = NumOperands, e = getNumOperands(); i != e; ++i) {
+ const MachineOperand &MO = getOperand(i);
if (!MO.isReg() || !MO.isImplicit())
NumOperands++;
}
/// check if the register def is tied to a source operand, due to either
/// two-address elimination or inline assembly constraints. Returns the
/// first tied use operand index by reference is UseOpIdx is not null.
-bool MachineInstr::isRegTiedToUseOperand(unsigned DefOpIdx, unsigned *UseOpIdx){
+bool MachineInstr::
+isRegTiedToUseOperand(unsigned DefOpIdx, unsigned *UseOpIdx) const {
if (getOpcode() == TargetInstrInfo::INLINEASM) {
assert(DefOpIdx >= 2);
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());
// 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!");
/// isRegTiedToDefOperand - Return true if the operand of the specified index
/// is a register use and it is tied to an def operand. It also returns the def
/// operand index by reference.
-bool MachineInstr::isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx){
+bool MachineInstr::
+isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx) const {
if (getOpcode() == TargetInstrInfo::INLINEASM) {
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.
+ int FlagIdx = UseOpIdx - 1;
+ if (FlagIdx < 1)
+ return false;
+ while (!getOperand(FlagIdx).isImm()) {
+ if (--FlagIdx == 0)
+ return false;
+ }
+ const MachineOperand &UFMO = getOperand(FlagIdx);
+ if (FlagIdx + InlineAsm::getNumOperandRegisters(UFMO.getImm()) < UseOpIdx)
+ return false;
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 (!debugLoc.isUnknown()) {
const MachineFunction *MF = getParent()->getParent();
DebugLocTuple DLT = MF->getDebugLocTuple(debugLoc);
+ DICompileUnit CU(DLT.CompileUnit);
+ std::string Dir, Fn;
OS << " [dbg: "
- << DLT.Src << ","
+ << CU.getDirectory(Dir) << '/' << CU.getFilename(Fn) << ","
<< DLT.Line << ","
<< DLT.Col << "]";
}
// 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;
}