#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/Value.h"
-#include "llvm/Target/MachineInstrInfo.h" // FIXME: shouldn't need this!
#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/MRegisterInfo.h"
-using std::cerr;
// Global variable holding an array of descriptors for machine instructions.
// The actual object needs to be created separately for each target machine.
-// This variable is initialized and reset by class MachineInstrInfo.
+// This variable is initialized and reset by class TargetInstrInfo.
//
// FIXME: This should be a property of the target so that more than one target
// at a time can be active...
//
-extern const MachineInstrDescriptor *TargetInstrDescriptors;
-
-// Constructor for instructions with fixed #operands (nearly all)
-MachineInstr::MachineInstr(MachineOpCode _opCode)
- : opCode(_opCode),
- operands(TargetInstrDescriptors[_opCode].numOperands, MachineOperand()),
- numImplicitRefs(0)
-{
- assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
-}
+extern const TargetInstrDescriptor *TargetInstrDescriptors;
// Constructor for instructions with variable #operands
MachineInstr::MachineInstr(MachineOpCode OpCode, unsigned numOperands)
: opCode(OpCode),
+ opCodeFlags(0),
operands(numOperands, MachineOperand()),
numImplicitRefs(0)
{
MachineInstr::MachineInstr(MachineOpCode Opcode, unsigned numOperands,
bool XX, bool YY)
: opCode(Opcode),
+ opCodeFlags(0),
numImplicitRefs(0)
{
operands.reserve(numOperands);
MachineInstr::MachineInstr(MachineBasicBlock *MBB, MachineOpCode Opcode,
unsigned numOperands)
: opCode(Opcode),
+ opCodeFlags(0),
numImplicitRefs(0)
{
assert(MBB && "Cannot use inserting ctor with null basic block!");
{
int NumOperands = TargetInstrDescriptors[opCode].numOperands;
if (NumOperands >= 0 && getNumOperands() >= (unsigned)NumOperands)
- return true; // Broken!
+ return true; // Broken: we have all the operands of this instruction!
return false;
}
operands.resize(numOperands, MachineOperand());
}
-void
-MachineInstr::SetMachineOperandVal(unsigned i,
- MachineOperand::MachineOperandType opType,
- Value* V,
- bool isdef,
- bool isDefAndUse)
-{
+void MachineInstr::SetMachineOperandVal(unsigned i,
+ MachineOperand::MachineOperandType opTy,
+ Value* V) {
assert(i < operands.size()); // may be explicit or implicit op
- operands[i].opType = opType;
+ operands[i].opType = opTy;
operands[i].value = V;
operands[i].regNum = -1;
- operands[i].flags = 0;
-
- if (isdef || TargetInstrDescriptors[opCode].resultPos == (int) i)
- operands[i].markDef();
- if (isDefAndUse)
- operands[i].markDefAndUse();
}
void
operands[i].flags = 0;
}
-void
-MachineInstr::SetMachineOperandReg(unsigned i,
- int regNum,
- bool isdef) {
+void MachineInstr::SetMachineOperandReg(unsigned i, int regNum) {
assert(i < getNumOperands()); // must be explicit op
operands[i].opType = MachineOperand::MO_MachineRegister;
operands[i].value = NULL;
operands[i].regNum = regNum;
- operands[i].flags = 0;
-
- if (isdef || TargetInstrDescriptors[opCode].resultPos == (int) i)
- operands[i].markDef();
- insertUsedReg(regNum);
}
void
{
assert(i < getNumOperands()); // must be explicit op
operands[i].setRegForValue(regNum);
- insertUsedReg(regNum);
+}
+
+void
+MachineInstr::SetRegForImplicitRef(unsigned i, int regNum)
+{
+ getImplicitOp(i).setRegForValue(regNum);
}
-// Subsitute all occurrences of Value* oldVal with newVal in all operands
-// and all implicit refs. If defsOnly == true, substitute defs only.
+// Substitute all occurrences of Value* oldVal with newVal in all operands
+// and all implicit refs.
+// If defsOnly == true, substitute defs only.
unsigned
-MachineInstr::substituteValue(const Value* oldVal, Value* newVal, bool defsOnly)
+MachineInstr::substituteValue(const Value* oldVal, Value* newVal,
+ bool defsOnly, bool notDefsAndUses,
+ bool& someArgsWereIgnored)
{
+ assert((!defsOnly || !notDefsAndUses) &&
+ "notDefsAndUses is irrelevant if defsOnly == true.");
+
unsigned numSubst = 0;
- // Subsitute operands
+ // Substitute operands
for (MachineInstr::val_op_iterator O = begin(), E = end(); O != E; ++O)
if (*O == oldVal)
- if (!defsOnly || O.isDef())
+ if (!defsOnly ||
+ notDefsAndUses && O.isDefOnly() ||
+ !notDefsAndUses && !O.isUseOnly())
{
O.getMachineOperand().value = newVal;
++numSubst;
}
+ else
+ someArgsWereIgnored = true;
- // Subsitute implicit refs
+ // Substitute implicit refs
for (unsigned i=0, N=getNumImplicitRefs(); i < N; ++i)
if (getImplicitRef(i) == oldVal)
- if (!defsOnly || implicitRefIsDefined(i))
+ if (!defsOnly ||
+ notDefsAndUses && getImplicitOp(i).opIsDefOnly() ||
+ !notDefsAndUses && !getImplicitOp(i).opIsUse())
{
getImplicitOp(i).value = newVal;
++numSubst;
}
+ else
+ someArgsWereIgnored = true;
return numSubst;
}
void
MachineInstr::dump() const
{
- cerr << " " << *this;
+ std::cerr << " " << *this;
}
static inline std::ostream&
OutputValue(std::ostream &os, const Value* val)
{
os << "(val ";
+ os << (void*) val; // print address always
if (val && val->hasName())
- return os << val->getName() << ")";
- else
- return os << (void*) val << ")"; // print address only
+ os << " " << val->getName() << ")"; // print name also, if available
+ return os;
}
static inline void OutputReg(std::ostream &os, unsigned RegNo,
OS << ")";
break;
}
+ case MachineOperand::MO_MachineBasicBlock:
+ OS << "bb<"
+ << ((Value*)MO.getMachineBasicBlock()->getBasicBlock())->getName()
+ << "," << (void*)MO.getMachineBasicBlock()->getBasicBlock() << ">";
+ break;
+ case MachineOperand::MO_FrameIndex:
+ OS << "<fi#" << MO.getFrameIndex() << ">";
+ break;
+ case MachineOperand::MO_ConstantPoolIndex:
+ OS << "<cp#" << MO.getConstantPoolIndex() << ">";
+ break;
+ case MachineOperand::MO_GlobalAddress:
+ OS << "<ga:" << ((Value*)MO.getGlobal())->getName() << ">";
+ break;
+ case MachineOperand::MO_ExternalSymbol:
+ OS << "<es:" << MO.getSymbolName() << ">";
+ break;
default:
assert(0 && "Unrecognized operand type");
}
OS << ")";
}
-void MachineInstr::print(std::ostream &OS, const TargetMachine &TM) {
- OS << TM.getInstrInfo().getName(getOpcode());
- for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
- OS << "\t";
- ::print(getOperand(i), OS, TM);
+void MachineInstr::print(std::ostream &OS, const TargetMachine &TM) const {
+ unsigned StartOp = 0;
- if (operandIsDefinedAndUsed(i))
+ // Specialize printing if op#0 is definition
+ if (getNumOperands() &&
+ (getOperand(0).opIsDefOnly() || getOperand(0).opIsDefAndUse())) {
+ ::print(getOperand(0), OS, TM);
+ OS << " = ";
+ ++StartOp; // Don't print this operand again!
+ }
+ OS << TM.getInstrInfo().getName(getOpcode());
+
+ for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) {
+ const MachineOperand& mop = getOperand(i);
+ if (i != StartOp)
+ OS << ",";
+ OS << " ";
+ ::print(mop, OS, TM);
+
+ if (mop.opIsDefAndUse())
OS << "<def&use>";
- else if (operandIsDefined(i))
+ else if (mop.opIsDefOnly())
OS << "<def>";
}
-
- // code for printing implict references
+
+ // code for printing implicit references
if (getNumImplicitRefs()) {
OS << "\tImplicitRefs: ";
for(unsigned i = 0, e = getNumImplicitRefs(); i != e; ++i) {
OS << "\t";
- OutputValue(OS, getImplicitRef(i));
- if (implicitRefIsDefinedAndUsed(i))
+ OutputValue(OS, getImplicitRef(i));
+ if (getImplicitOp(i).opIsDefAndUse())
OS << "<def&use>";
- else if (implicitRefIsDefined(i))
+ else if (getImplicitOp(i).opIsDefOnly())
OS << "<def>";
}
}
}
-std::ostream &operator<<(std::ostream& os, const MachineInstr& minstr)
+std::ostream &operator<<(std::ostream& os, const MachineInstr& MI)
{
- os << TargetInstrDescriptors[minstr.opCode].Name;
+ os << TargetInstrDescriptors[MI.opCode].Name;
- for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++) {
- os << "\t" << minstr.getOperand(i);
- if( minstr.operandIsDefined(i) )
- os << "*";
- if( minstr.operandIsDefinedAndUsed(i) )
- os << "*";
+ for (unsigned i=0, N=MI.getNumOperands(); i < N; i++) {
+ os << "\t" << MI.getOperand(i);
+ if (MI.getOperand(i).opIsDefOnly())
+ os << "<d>";
+ if (MI.getOperand(i).opIsDefAndUse())
+ os << "<d&u>";
}
- // code for printing implict references
- unsigned NumOfImpRefs = minstr.getNumImplicitRefs();
- if( NumOfImpRefs > 0 ) {
+ // code for printing implicit references
+ unsigned NumOfImpRefs = MI.getNumImplicitRefs();
+ if (NumOfImpRefs > 0) {
os << "\tImplicit: ";
- for(unsigned z=0; z < NumOfImpRefs; z++) {
- OutputValue(os, minstr.getImplicitRef(z));
- if( minstr.implicitRefIsDefined(z)) os << "*";
- if( minstr.implicitRefIsDefinedAndUsed(z)) os << "*";
+ for (unsigned z=0; z < NumOfImpRefs; z++) {
+ OutputValue(os, MI.getImplicitRef(z));
+ if (MI.getImplicitOp(z).opIsDefOnly()) os << "<d>";
+ if (MI.getImplicitOp(z).opIsDefAndUse()) os << "<d&u>";
os << "\t";
}
}
return os << "\n";
}
-std::ostream &operator<<(std::ostream &os, const MachineOperand &mop)
+std::ostream &operator<<(std::ostream &OS, const MachineOperand &MO)
{
- if (mop.opHiBits32())
- os << "%lm(";
- else if (mop.opLoBits32())
- os << "%lo(";
- else if (mop.opHiBits64())
- os << "%hh(";
- else if (mop.opLoBits64())
- os << "%hm(";
+ if (MO.opHiBits32())
+ OS << "%lm(";
+ else if (MO.opLoBits32())
+ OS << "%lo(";
+ else if (MO.opHiBits64())
+ OS << "%hh(";
+ else if (MO.opLoBits64())
+ OS << "%hm(";
- switch (mop.getType())
+ switch (MO.getType())
{
case MachineOperand::MO_VirtualRegister:
- os << "%reg";
- OutputValue(os, mop.getVRegValue());
- if (mop.hasAllocatedReg()) {
- os << "==";
- OutputReg(os, mop.getAllocatedRegNum());
+ if (MO.hasAllocatedReg())
+ OutputReg(OS, MO.getAllocatedRegNum());
+
+ if (MO.getVRegValue()) {
+ if (MO.hasAllocatedReg()) OS << "==";
+ OS << "%vreg";
+ OutputValue(OS, MO.getVRegValue());
}
break;
case MachineOperand::MO_CCRegister:
- os << "%ccreg";
- OutputValue(os, mop.getVRegValue());
- if (mop.hasAllocatedReg()) {
- os << "==";
- OutputReg(os, mop.getAllocatedRegNum());
+ OS << "%ccreg";
+ OutputValue(OS, MO.getVRegValue());
+ if (MO.hasAllocatedReg()) {
+ OS << "==";
+ OutputReg(OS, MO.getAllocatedRegNum());
}
break;
case MachineOperand::MO_MachineRegister:
- OutputReg(os, mop.getMachineRegNum());
+ OutputReg(OS, MO.getMachineRegNum());
break;
case MachineOperand::MO_SignExtendedImmed:
- os << (long)mop.getImmedValue();
+ OS << (long)MO.getImmedValue();
break;
case MachineOperand::MO_UnextendedImmed:
- os << (long)mop.getImmedValue();
+ OS << (long)MO.getImmedValue();
break;
case MachineOperand::MO_PCRelativeDisp:
{
- const Value* opVal = mop.getVRegValue();
+ const Value* opVal = MO.getVRegValue();
bool isLabel = isa<Function>(opVal) || isa<BasicBlock>(opVal);
- os << "%disp(" << (isLabel? "label " : "addr-of-val ");
+ OS << "%disp(" << (isLabel? "label " : "addr-of-val ");
if (opVal->hasName())
- os << opVal->getName();
+ OS << opVal->getName();
else
- os << (const void*) opVal;
- os << ")";
+ OS << (const void*) opVal;
+ OS << ")";
break;
}
+ case MachineOperand::MO_MachineBasicBlock:
+ OS << "bb<"
+ << ((Value*)MO.getMachineBasicBlock()->getBasicBlock())->getName()
+ << "," << (void*)MO.getMachineBasicBlock()->getBasicBlock() << ">";
+ break;
+ case MachineOperand::MO_FrameIndex:
+ OS << "<fi#" << MO.getFrameIndex() << ">";
+ break;
+ case MachineOperand::MO_ConstantPoolIndex:
+ OS << "<cp#" << MO.getConstantPoolIndex() << ">";
+ break;
+ case MachineOperand::MO_GlobalAddress:
+ OS << "<ga:" << ((Value*)MO.getGlobal())->getName() << ">";
+ break;
+ case MachineOperand::MO_ExternalSymbol:
+ OS << "<es:" << MO.getSymbolName() << ">";
+ break;
default:
assert(0 && "Unrecognized operand type");
break;
}
- if (mop.flags &
+ if (MO.flags &
(MachineOperand::HIFLAG32 | MachineOperand::LOFLAG32 |
MachineOperand::HIFLAG64 | MachineOperand::LOFLAG64))
- os << ")";
+ OS << ")";
- return os;
+ return OS;
}