#include "llvm/ADT/iterator"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Streams.h"
#include <vector>
#include <cassert>
#include <iosfwd>
class Value;
class Function;
class MachineBasicBlock;
-class TargetInstrInfo;
class TargetInstrDescriptor;
class TargetMachine;
class GlobalValue;
// immediately after the write. i.e. A register
// that is defined but never used.
- /// offset - Offset to address of global or external, only valid for
- /// MO_GlobalAddress, MO_ExternalSym and MO_ConstantPoolIndex
- int offset;
-
+ /// auxInfo - auxiliary information used by the MachineOperand
+ union {
+ /// offset - Offset to address of global or external, only valid for
+ /// MO_GlobalAddress, MO_ExternalSym and MO_ConstantPoolIndex
+ int offset;
+ } auxInfo;
+
MachineOperand() {}
+
+ void print(std::ostream &os) const;
+ void print(std::ostream *os) const { if (os) print(*os); }
+
public:
MachineOperand(const MachineOperand &M) {
*this = M;
Op.IsImp = false;
Op.IsKill = false;
Op.IsDead = false;
- Op.offset = 0;
+ Op.auxInfo.offset = 0;
return Op;
}
+ static MachineOperand CreateFrameIndex(unsigned Idx) {
+ MachineOperand Op;
+ Op.opType = MachineOperand::MO_FrameIndex;
+ Op.contents.immedVal = Idx;
+ Op.IsDef = false;
+ Op.IsImp = false;
+ Op.IsKill = false;
+ Op.IsDead = false;
+ Op.auxInfo.offset = 0;
+ return Op;
+ }
+
const MachineOperand &operator=(const MachineOperand &MO) {
contents = MO.contents;
IsDef = MO.IsDef;
IsKill = MO.IsKill;
IsDead = MO.IsDead;
opType = MO.opType;
- offset = MO.offset;
+ auxInfo = MO.auxInfo;
return *this;
}
/// Accessors that tell you what kind of MachineOperand you're looking at.
///
- bool isReg() const { return opType == MO_Register; }
- bool isImm() const { return opType == MO_Immediate; }
- bool isMBB() const { return opType == MO_MachineBasicBlock; }
-
bool isRegister() const { return opType == MO_Register; }
bool isImmediate() const { return opType == MO_Immediate; }
bool isMachineBasicBlock() const { return opType == MO_MachineBasicBlock; }
bool isExternalSymbol() const { return opType == MO_ExternalSymbol; }
int64_t getImm() const {
- assert(isImm() && "Wrong MachineOperand accessor");
+ assert(isImmediate() && "Wrong MachineOperand accessor");
return contents.immedVal;
}
int64_t getImmedValue() const {
- assert(isImm() && "Wrong MachineOperand accessor");
+ assert(isImmediate() && "Wrong MachineOperand accessor");
return contents.immedVal;
}
MachineBasicBlock *getMBB() const {
int getOffset() const {
assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex()) &&
"Wrong MachineOperand accessor");
- return offset;
+ return auxInfo.offset;
}
const char *getSymbolName() const {
assert(isExternalSymbol() && "Wrong MachineOperand accessor");
}
void setImmedValue(int64_t immVal) {
- assert(isImm() && "Wrong MachineOperand mutator");
+ assert(isImmediate() && "Wrong MachineOperand mutator");
contents.immedVal = immVal;
}
void setImm(int64_t immVal) {
- assert(isImm() && "Wrong MachineOperand mutator");
+ assert(isImmediate() && "Wrong MachineOperand mutator");
contents.immedVal = immVal;
}
assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex() ||
isJumpTableIndex()) &&
"Wrong MachineOperand accessor");
- offset = Offset;
+ auxInfo.offset = Offset;
}
void setConstantPoolIndex(unsigned Idx) {
assert(isConstantPoolIndex() && "Wrong MachineOperand accessor");
/// ChangeToRegister - Replace this operand with a new register operand of
/// the specified value. If an operand is known to be an register already,
/// the setReg method should be used.
- void ChangeToRegister(unsigned Reg, bool isDef) {
+ void ChangeToRegister(unsigned Reg, bool isDef, bool isImp = false,
+ bool isKill = false, bool isDead = false) {
opType = MO_Register;
contents.RegNo = Reg;
IsDef = isDef;
- IsImp = false;
- IsKill = false;
- IsDead = false;
+ IsImp = isImp;
+ IsKill = isKill;
+ IsDead = isDead;
}
- friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop);
+ friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop) {
+ mop.print(os);
+ return os;
+ }
friend class MachineInstr;
};
/// MachineInstr - Representation of each machine instruction.
///
class MachineInstr {
- short Opcode; // the opcode
- short NumImplicitOps; // Number of implicit operands (which
+ const TargetInstrDescriptor *TID; // Instruction descriptor.
+ unsigned short NumImplicitOps; // Number of implicit operands (which
// are determined at construction time).
std::vector<MachineOperand> Operands; // the operands
friend struct ilist_traits<MachineInstr>;
public:
- /// MachineInstr ctor - This constructor reserves space for numOperand
- /// operands.
- MachineInstr(short Opcode, unsigned numOperands);
+ /// MachineInstr ctor - This constructor creates a dummy MachineInstr with
+ /// TID NULL and no operands.
+ MachineInstr();
/// MachineInstr ctor - This constructor create a MachineInstr and add the
- /// implicit operands. It reserves space for numOperand operands.
- MachineInstr(const TargetInstrInfo &TII, short Opcode, unsigned numOperands);
+ /// implicit operands. It reserves space for number of operands specified by
+ /// TargetInstrDescriptor.
+ explicit MachineInstr(const TargetInstrDescriptor &TID);
/// MachineInstr ctor - Work exactly the same as the ctor above, except that
/// the MachineInstr is created and added to the end of the specified basic
/// block.
///
- MachineInstr(MachineBasicBlock *MBB, short Opcode, unsigned numOps);
+ MachineInstr(MachineBasicBlock *MBB, const TargetInstrDescriptor &TID);
~MachineInstr();
const MachineBasicBlock* getParent() const { return parent; }
MachineBasicBlock* getParent() { return parent; }
+
+ /// getInstrDescriptor - Returns the target instruction descriptor of this
+ /// MachineInstr.
+ const TargetInstrDescriptor *getInstrDescriptor() const { return TID; }
/// getOpcode - Returns the opcode of this MachineInstr.
///
- const int getOpcode() const { return Opcode; }
+ int getOpcode() const;
/// Access to explicit operands of the instruction.
///
return Operands[i];
}
+ /// getNumExplicitOperands - Returns the number of non-implicit operands.
+ ///
+ unsigned getNumExplicitOperands() const;
/// isIdenticalTo - Return true if this instruction is identical to (same
/// opcode and same operands as) the specified instruction.
delete removeFromParent();
}
+ /// findRegisterUseOperandIdx() - Returns the operand index that is a use of
+ /// the specific register or -1 if it is not found. It further tightening
+ /// the search criteria to a use that kills the register if isKill is true.
+ int findRegisterUseOperandIdx(unsigned Reg, bool isKill = false) const;
+
+ /// findRegisterDefOperand() - Returns the MachineOperand that is a def of
+ /// the specific register or NULL if it is not found.
+ MachineOperand *findRegisterDefOperand(unsigned Reg);
+
+ /// findFirstPredOperandIdx() - Find the index of the first operand in the
+ /// operand list that is used to represent the predicate. It returns -1 if
+ /// none is found.
+ int findFirstPredOperandIdx() const;
+
+ /// isRegReDefinedByTwoAddr - Returns true if the Reg re-definition is due
+ /// to two addr elimination.
+ bool isRegReDefinedByTwoAddr(unsigned Reg) const;
+
/// copyKillDeadInfo - Copies kill / dead operand properties from MI.
///
- void copyKillDeadInfo(const MachineInstr *MI) {
- for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
- const MachineOperand &MO = MI->getOperand(i);
- if (MO.isReg() && (MO.isKill() || MO.isDead())) {
- for (unsigned j = 0, ee = getNumOperands(); j != ee; ++j) {
- MachineOperand &MOp = getOperand(j);
- if (MOp.isIdenticalTo(MO)) {
- if (MO.isKill())
- MOp.setIsKill();
- else
- MOp.setIsDead();
- break;
- }
- }
- }
- }
- }
+ void copyKillDeadInfo(const MachineInstr *MI);
+
+ /// copyPredicates - Copies predicate operand(s) from MI.
+ void copyPredicates(const MachineInstr *MI);
//
// Debugging support
//
+ void print(std::ostream *OS, const TargetMachine *TM) const {
+ if (OS) print(*OS, TM);
+ }
void print(std::ostream &OS, const TargetMachine *TM) const;
+ void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
void dump() const;
- friend std::ostream& operator<<(std::ostream& os, const MachineInstr& minstr);
+ friend std::ostream& operator<<(std::ostream& os, const MachineInstr& minstr){
+ minstr.print(os);
+ return os;
+ }
//===--------------------------------------------------------------------===//
// Accessors to add operands when building up machine instructions.
Op.IsKill = IsKill;
Op.IsDead = IsDead;
Op.contents.RegNo = Reg;
- Op.offset = 0;
}
/// addImmOperand - Add a zero extended constant argument to the
MachineOperand &Op = AddNewOperand();
Op.opType = MachineOperand::MO_Immediate;
Op.contents.immedVal = Val;
- Op.offset = 0;
+ Op.auxInfo.offset = 0;
}
void addMachineBasicBlockOperand(MachineBasicBlock *MBB) {
MachineOperand &Op = AddNewOperand();
Op.opType = MachineOperand::MO_MachineBasicBlock;
Op.contents.MBB = MBB;
- Op.offset = 0;
+ Op.auxInfo.offset = 0;
}
/// addFrameIndexOperand - Add an abstract frame index to the instruction
MachineOperand &Op = AddNewOperand();
Op.opType = MachineOperand::MO_FrameIndex;
Op.contents.immedVal = Idx;
- Op.offset = 0;
+ Op.auxInfo.offset = 0;
}
/// addConstantPoolndexOperand - Add a constant pool object index to the
MachineOperand &Op = AddNewOperand();
Op.opType = MachineOperand::MO_ConstantPoolIndex;
Op.contents.immedVal = Idx;
- Op.offset = Offset;
+ Op.auxInfo.offset = Offset;
}
/// addJumpTableIndexOperand - Add a jump table object index to the
MachineOperand &Op = AddNewOperand();
Op.opType = MachineOperand::MO_JumpTableIndex;
Op.contents.immedVal = Idx;
- Op.offset = 0;
+ Op.auxInfo.offset = 0;
}
void addGlobalAddressOperand(GlobalValue *GV, int Offset) {
MachineOperand &Op = AddNewOperand();
Op.opType = MachineOperand::MO_GlobalAddress;
Op.contents.GV = GV;
- Op.offset = Offset;
+ Op.auxInfo.offset = Offset;
}
/// addExternalSymbolOperand - Add an external symbol operand to this instr
MachineOperand &Op = AddNewOperand();
Op.opType = MachineOperand::MO_ExternalSymbol;
Op.contents.SymbolName = SymName;
- Op.offset = 0;
+ Op.auxInfo.offset = 0;
}
//===--------------------------------------------------------------------===//
// Accessors used to modify instructions in place.
//
- /// setOpcode - Replace the opcode of the current instruction with a new one.
+ /// setInstrDescriptor - Replace the instruction descriptor (thus opcode) of
+ /// the current instruction with a new one.
///
- void setOpcode(unsigned Op);
+ void setInstrDescriptor(const TargetInstrDescriptor &tid) { TID = &tid; }
/// RemoveOperand - Erase an operand from an instruction, leaving it with one
/// fewer operand than it started with.
MachineOperand &AddNewOperand(bool IsImp = false) {
assert((IsImp || !OperandsComplete()) &&
"Trying to add an operand to a machine instr that is already done!");
- if (NumImplicitOps == 0) { // This is true most of the time.
+ if (IsImp || NumImplicitOps == 0) { // This is true most of the time.
Operands.push_back(MachineOperand());
return Operands.back();
- } else {
- return *Operands.insert(Operands.begin()+Operands.size()-NumImplicitOps,
- MachineOperand());
}
+ return *Operands.insert(Operands.begin()+Operands.size()-NumImplicitOps,
+ MachineOperand());
}
/// addImplicitDefUseOperands - Add all implicit def and use operands to
/// this instruction.
- void addImplicitDefUseOperands(const TargetInstrDescriptor &TID);
+ void addImplicitDefUseOperands();
};
//===----------------------------------------------------------------------===//