X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FCodeGen%2FMachineInstr.h;h=a0b8d1ad431bd69b4ed033acaf624f29ae499444;hb=ceb408f6a263e319683209ae5c6f8d1e3e4d9b69;hp=421d753d10e2c3fc23ea687d87d30c5d58045e6a;hpb=23e6bba592af68ba991ee6900978e81eb21a08af;p=oota-llvm.git diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index 421d753d10e..a0b8d1ad431 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -1,7 +1,14 @@ -//===-- llvm/CodeGen/MachineInstr.h - MachineInstr class ---------*- C++ -*--=// +//===-- llvm/CodeGen/MachineInstr.h - MachineInstr class --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// // // This file contains the declaration of the MachineInstr class, which is the -// basic representation for all target dependant machine instructions used by +// basic representation for all target dependent machine instructions used by // the back end. // //===----------------------------------------------------------------------===// @@ -9,285 +16,308 @@ #ifndef LLVM_CODEGEN_MACHINEINSTR_H #define LLVM_CODEGEN_MACHINEINSTR_H -#include "llvm/Annotation.h" -#include "Support/iterator" -#include "Support/NonCopyable.h" +#include "llvm/ADT/iterator" +#include "llvm/Support/DataTypes.h" #include +#include + +namespace llvm { + class Value; class Function; class MachineBasicBlock; class TargetMachine; +class GlobalValue; -typedef int MachineOpCode; +template struct ilist_traits; +template struct ilist; -/// MOTy - MachineOperandType - This namespace contains an enum that describes -/// how the machine operand is used by the instruction: is it read, defined, or -/// both? Note that the MachineInstr/Operator class currently uses bool -/// arguments to represent this information instead of an enum. Eventually this -/// should change over to use this _easier to read_ representation instead. -/// -namespace MOTy { - enum UseType { - Use, /// This machine operand is only read by the instruction - Def, /// This machine operand is only written by the instruction - UseAndDef /// This machine operand is read AND written - }; -} +typedef short MachineOpCode; -//--------------------------------------------------------------------------- -// class MachineOperand -// -// Purpose: +//===----------------------------------------------------------------------===// +// class MachineOperand +// // Representation of each machine instruction operand. -// This class is designed so that you can allocate a vector of operands -// first and initialize each one later. // -// E.g, for this VM instruction: -// ptr = alloca type, numElements -// we generate 2 machine instructions on the SPARC: -// -// mul Constant, Numelements -> Reg -// add %sp, Reg -> Ptr -// -// Each instruction has 3 operands, listed above. Of those: -// - Reg, NumElements, and Ptr are of operand type MO_Register. -// - Constant is of operand type MO_SignExtendedImmed on the SPARC. -// -// For the register operands, the virtual register type is as follows: -// -// - Reg will be of virtual register type MO_MInstrVirtualReg. The field -// MachineInstr* minstr will point to the instruction that computes reg. -// -// - %sp will be of virtual register type MO_MachineReg. -// The field regNum identifies the machine register. -// -// - NumElements will be of virtual register type MO_VirtualReg. -// The field Value* value identifies the value. -// -// - Ptr will also be of virtual register type MO_VirtualReg. -// Again, the field Value* value identifies the value. -// -//--------------------------------------------------------------------------- - -class MachineOperand { +struct MachineOperand { +private: + // Bit fields of the flags variable used for different operand properties + enum { + DEFFLAG = 0x01, // this is a def of the operand + USEFLAG = 0x02, // this is a use of the operand + }; + public: + // UseType - This enum describes how the machine operand is used by + // the instruction. Note that the MachineInstr/Operator class + // currently uses bool arguments to represent this information + // instead of an enum. Eventually this should change over to use + // this _easier to read_ representation instead. + // + enum UseType { + Use = USEFLAG, /// only read + Def = DEFFLAG, /// only written + UseAndDef = Use | Def /// read AND written + }; + enum MachineOperandType { - MO_VirtualRegister, // virtual register for *value - MO_MachineRegister, // pre-assigned machine register `regNum' - MO_CCRegister, + MO_VirtualRegister, // virtual register for *value MO_SignExtendedImmed, MO_UnextendedImmed, - MO_PCRelativeDisp, + MO_MachineBasicBlock, // MachineBasicBlock reference + MO_FrameIndex, // Abstract Stack Frame Index + MO_ConstantPoolIndex, // Address of indexed Constant in Constant Pool + MO_JumpTableIndex, // Address of indexed Jump Table for switch + MO_ExternalSymbol, // Name of external global symbol + MO_GlobalAddress // Address of a global value }; - -private: - // Bit fields of the flags variable used for different operand properties - static const char DEFFLAG = 0x1; // this is a def of the operand - static const char DEFUSEFLAG = 0x2; // this is both a def and a use - static const char HIFLAG32 = 0x4; // operand is %hi32(value_or_immedVal) - static const char LOFLAG32 = 0x8; // operand is %lo32(value_or_immedVal) - static const char HIFLAG64 = 0x10; // operand is %hi64(value_or_immedVal) - static const char LOFLAG64 = 0x20; // operand is %lo64(value_or_immedVal) - + private: union { - Value* value; // BasicBlockVal for a label operand. - // ConstantVal for a non-address immediate. - // Virtual register for an SSA operand, - // including hidden operands required for - // the generated machine code. - int64_t immedVal; // constant value for an explicit constant - }; + GlobalValue *GV; // LLVM global for MO_GlobalAddress. + int64_t immedVal; // Constant value for an explicit constant + MachineBasicBlock *MBB; // For MO_MachineBasicBlock type + const char *SymbolName; // For MO_ExternalSymbol type + } contents; - MachineOperandType opType:8; // Pack into 8 bits efficiently after flags. char flags; // see bit field definitions above - int regNum; // register number for an explicit register - // will be set for a value after reg allocation -private: - MachineOperand() - : immedVal(0), - opType(MO_VirtualRegister), - flags(0), - regNum(-1) {} - - MachineOperand(int64_t ImmVal, MachineOperandType OpTy) - : immedVal(ImmVal), - opType(OpTy), - flags(0), - regNum(-1) {} - - MachineOperand(int Reg, MachineOperandType OpTy, MOTy::UseType UseTy) - : immedVal(0), - opType(OpTy), - regNum(Reg) { - switch (UseTy) { - case MOTy::Use: flags = 0; break; - case MOTy::Def: flags = DEFFLAG; break; - case MOTy::UseAndDef: flags = DEFUSEFLAG; break; - default: assert(0 && "Invalid value for UseTy!"); - } - } - - MachineOperand(Value *V, MachineOperandType OpTy, MOTy::UseType UseTy) - : value(V), opType(OpTy), regNum(-1) { - switch (UseTy) { - case MOTy::Use: flags = 0; break; - case MOTy::Def: flags = DEFFLAG; break; - case MOTy::UseAndDef: flags = DEFUSEFLAG; break; - default: assert(0 && "Invalid value for UseTy!"); - } + MachineOperandType opType:8; // Pack into 8 bits efficiently after flags. + union { + int regNum; // register number for an explicit register + int offset; // Offset to address of global or external, only + // valid for MO_GlobalAddress, MO_ExternalSym + // and MO_ConstantPoolIndex + } extra; + + void zeroContents() { + contents.immedVal = 0; + extra.offset = 0; + } + + MachineOperand(int64_t ImmVal, MachineOperandType OpTy, int Offset = 0) + : flags(0), opType(OpTy) { + contents.immedVal = ImmVal; + extra.offset = Offset; + } + + MachineOperand(int Reg, MachineOperandType OpTy, UseType UseTy) + : flags(UseTy), opType(OpTy) { + zeroContents(); + extra.regNum = Reg; + } + + MachineOperand(GlobalValue *V, int Offset = 0) + : flags(MachineOperand::Use), opType(MachineOperand::MO_GlobalAddress) { + contents.GV = V; + extra.offset = Offset; + } + + MachineOperand(MachineBasicBlock *mbb) + : flags(0), opType(MO_MachineBasicBlock) { + zeroContents (); + contents.MBB = mbb; + } + + MachineOperand(const char *SymName, int Offset) + : flags(0), opType(MO_ExternalSymbol) { + zeroContents (); + contents.SymbolName = SymName; + extra.offset = Offset; } public: MachineOperand(const MachineOperand &M) - : immedVal(M.immedVal), - opType(M.opType), - flags(M.flags), - regNum(M.regNum) {} + : flags(M.flags), opType(M.opType) { + zeroContents (); + contents = M.contents; + extra = M.extra; + } ~MachineOperand() {} - - // Accessor methods. Caller is responsible for checking the - // operand type before invoking the corresponding accessor. - // + + const MachineOperand &operator=(const MachineOperand &MO) { + contents = MO.contents; + flags = MO.flags; + opType = MO.opType; + extra = MO.extra; + return *this; + } + + /// getType - Returns the MachineOperandType for this operand. + /// MachineOperandType getType() const { return opType; } - inline Value* getVRegValue () const { - assert(opType == MO_VirtualRegister || opType == MO_CCRegister || - opType == MO_PCRelativeDisp); - return value; + /// getUseType - Returns the MachineOperandUseType of this operand. + /// + UseType getUseType() const { return UseType(flags & (USEFLAG|DEFFLAG)); } + + /// isRegister - Return true if this operand is a register operand. + /// + bool isRegister() const { + return opType == MO_VirtualRegister; + } + + /// Accessors that tell you what kind of MachineOperand you're looking at. + /// + bool isMachineBasicBlock() const { return opType == MO_MachineBasicBlock; } + bool isImmediate() const { + return opType == MO_SignExtendedImmed || opType == MO_UnextendedImmed; + } + bool isFrameIndex() const { return opType == MO_FrameIndex; } + bool isConstantPoolIndex() const { return opType == MO_ConstantPoolIndex; } + bool isJumpTableIndex() const { return opType == MO_JumpTableIndex; } + bool isGlobalAddress() const { return opType == MO_GlobalAddress; } + bool isExternalSymbol() const { return opType == MO_ExternalSymbol; } + + int64_t getImmedValue() const { + assert(isImmediate() && "Wrong MachineOperand accessor"); + return contents.immedVal; + } + MachineBasicBlock *getMachineBasicBlock() const { + assert(isMachineBasicBlock() && "Wrong MachineOperand accessor"); + return contents.MBB; } - inline Value* getVRegValueOrNull() const { - return (opType == MO_VirtualRegister || opType == MO_CCRegister || - opType == MO_PCRelativeDisp)? value : NULL; + void setMachineBasicBlock(MachineBasicBlock *MBB) { + assert(isMachineBasicBlock() && "Wrong MachineOperand accessor"); + contents.MBB = MBB; } - inline int getMachineRegNum() const { - assert(opType == MO_MachineRegister); - return regNum; + int getFrameIndex() const { + assert(isFrameIndex() && "Wrong MachineOperand accessor"); + return (int)contents.immedVal; } - inline int64_t getImmedValue () const { - assert(opType == MO_SignExtendedImmed || opType == MO_UnextendedImmed); - return immedVal; + unsigned getConstantPoolIndex() const { + assert(isConstantPoolIndex() && "Wrong MachineOperand accessor"); + return (unsigned)contents.immedVal; } - bool opIsDef () const { return flags & DEFFLAG; } - bool opIsDefAndUse () const { return flags & DEFUSEFLAG; } - bool opHiBits32 () const { return flags & HIFLAG32; } - bool opLoBits32 () const { return flags & LOFLAG32; } - bool opHiBits64 () const { return flags & HIFLAG64; } - bool opLoBits64 () const { return flags & LOFLAG64; } + unsigned getJumpTableIndex() const { + assert(isJumpTableIndex() && "Wrong MachineOperand accessor"); + return (unsigned)contents.immedVal; + } + GlobalValue *getGlobal() const { + assert(isGlobalAddress() && "Wrong MachineOperand accessor"); + return contents.GV; + } + int getOffset() const { + assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex()) && + "Wrong MachineOperand accessor"); + return extra.offset; + } + const char *getSymbolName() const { + assert(isExternalSymbol() && "Wrong MachineOperand accessor"); + return contents.SymbolName; + } + + /// MachineOperand methods for testing that work on any kind of + /// MachineOperand... + /// + bool isUse () const { return flags & USEFLAG; } + MachineOperand& setUse () { flags |= USEFLAG; return *this; } + bool isDef () const { return flags & DEFFLAG; } + MachineOperand& setDef () { flags |= DEFFLAG; return *this; } - // used to check if a machine register has been allocated to this operand - inline bool hasAllocatedReg() const { - return (regNum >= 0 && - (opType == MO_VirtualRegister || opType == MO_CCRegister || - opType == MO_MachineRegister)); + /// hasAllocatedReg - Returns true iff a machine register has been + /// allocated to this operand. + /// + bool hasAllocatedReg() const { + return extra.regNum >= 0 && opType == MO_VirtualRegister; } - // used to get the reg number if when one is allocated - inline int getAllocatedRegNum() const { - assert(opType == MO_VirtualRegister || opType == MO_CCRegister || - opType == MO_MachineRegister); - return regNum; + /// getReg - Returns the register number. It is a runtime error to call this + /// if a register is not allocated. + /// + unsigned getReg() const { + assert(hasAllocatedReg()); + return extra.regNum; } - - friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop); + /// MachineOperand mutators. + /// + void setReg(unsigned Reg) { + assert(hasAllocatedReg() && "This operand cannot have a register number!"); + extra.regNum = Reg; + } -private: + void setImmedValue(int immVal) { + assert(isImmediate() && "Wrong MachineOperand mutator"); + contents.immedVal = immVal; + } - // Construction methods needed for fine-grain control. - // These must be accessed via coresponding methods in MachineInstr. - void markHi32() { flags |= HIFLAG32; } - void markLo32() { flags |= LOFLAG32; } - void markHi64() { flags |= HIFLAG64; } - void markLo64() { flags |= LOFLAG64; } - - // Replaces the Value with its corresponding physical register after - // register allocation is complete - void setRegForValue(int reg) { - assert(opType == MO_VirtualRegister || opType == MO_CCRegister || - opType == MO_MachineRegister); - regNum = reg; + void setOffset(int Offset) { + assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex() || + isJumpTableIndex()) && + "Wrong MachineOperand accessor"); + extra.offset = Offset; } - + + friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop); + friend class MachineInstr; }; -//--------------------------------------------------------------------------- -// class MachineInstr -// +//===----------------------------------------------------------------------===// +// class MachineInstr +// // Purpose: // Representation of each machine instruction. -// +// // MachineOpCode must be an enum, defined separately for each target. // E.g., It is defined in SparcInstructionSelection.h for the SPARC. -// +// // There are 2 kinds of operands: -// -// (1) Explicit operands of the machine instruction in vector operands[] -// +// +// (1) Explicit operands of the machine instruction in vector operands[] +// // (2) "Implicit operands" are values implicitly used or defined by the // machine instruction, such as arguments to a CALL, return value of // a CALL (if any), and return value of a RETURN. -//--------------------------------------------------------------------------- - -class MachineInstr: public NonCopyable { // Disable copy operations +//===----------------------------------------------------------------------===// - MachineOpCode opCode; // the opcode +class MachineInstr { + short Opcode; // the opcode std::vector operands; // the operands - unsigned numImplicitRefs; // number of implicit operands - - MachineOperand& getImplicitOp(unsigned i) { - assert(i < numImplicitRefs && "implicit ref# out of range!"); - return operands[i + operands.size() - numImplicitRefs]; - } - const MachineOperand& getImplicitOp(unsigned i) const { - assert(i < numImplicitRefs && "implicit ref# out of range!"); - return operands[i + operands.size() - numImplicitRefs]; - } - - // regsUsed - all machine registers used for this instruction, including regs - // used to save values across the instruction. This is a bitset of registers. - std::vector regsUsed; + MachineInstr* prev, *next; // links for our intrusive list + MachineBasicBlock* parent; // pointer to the owning basic block // OperandComplete - Return true if it's illegal to add a new operand bool OperandsComplete() const; -public: - MachineInstr(MachineOpCode Opcode); - MachineInstr(MachineOpCode Opcode, unsigned numOperands); + //Constructor used by clone() method + MachineInstr(const MachineInstr&); + + void operator=(const MachineInstr&); // DO NOT IMPLEMENT + + // Intrusive list support + // + friend struct ilist_traits; +public: /// MachineInstr ctor - This constructor only does a _reserve_ of the /// operands, not a resize for them. It is expected that if you use this that /// you call add* methods below to fill up the operands, instead of the Set /// methods. Eventually, the "resizing" ctors will be phased out. /// - MachineInstr(MachineOpCode Opcode, unsigned numOperands, bool XX, bool YY); + MachineInstr(short Opcode, unsigned numOperands, bool XX, bool YY); /// 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, MachineOpCode Opcode, unsigned numOps); - + MachineInstr(MachineBasicBlock *MBB, short Opcode, unsigned numOps); - /// replace - Support to rewrite a machine instruction in place: for now, - /// simply replace() and then set new operands with Set.*Operand methods - /// below. - /// - void replace(MachineOpCode Opcode, unsigned numOperands); - - // The opcode. - // - const MachineOpCode getOpcode() const { return opCode; } - const MachineOpCode getOpCode() const { return opCode; } + ~MachineInstr(); + + const MachineBasicBlock* getParent() const { return parent; } + MachineBasicBlock* getParent() { return parent; } + + /// getOpcode - Returns the opcode of this MachineInstr. + /// + const int getOpcode() const { return Opcode; } + + /// Access to explicit operands of the instruction. + /// + unsigned getNumOperands() const { return operands.size(); } - // - // Information about explicit operands of the instruction - // - unsigned getNumOperands() const { return operands.size() - numImplicitRefs; } - const MachineOperand& getOperand(unsigned i) const { assert(i < getNumOperands() && "getOperand() out of range!"); return operands[i]; @@ -297,286 +327,157 @@ public: return operands[i]; } - MachineOperand::MachineOperandType getOperandType(unsigned i) const { - return getOperand(i).getType(); - } - - bool operandIsDefined(unsigned i) const { - return getOperand(i).opIsDef(); - } - - bool operandIsDefinedAndUsed(unsigned i) const { - return getOperand(i).opIsDefAndUse(); - } - // - // Information about implicit operands of the instruction - // - unsigned getNumImplicitRefs() const{ return numImplicitRefs; } + /// clone - Create a copy of 'this' instruction that is identical in + /// all ways except the the instruction has no parent, prev, or next. + MachineInstr* clone() const; - const Value* getImplicitRef(unsigned i) const { - return getImplicitOp(i).getVRegValue(); - } - Value* getImplicitRef(unsigned i) { - return getImplicitOp(i).getVRegValue(); - } - - bool implicitRefIsDefined(unsigned i) const { - return getImplicitOp(i).opIsDef(); - } - bool implicitRefIsDefinedAndUsed(unsigned i) const { - return getImplicitOp(i).opIsDefAndUse(); - } - inline void addImplicitRef (Value* V, - bool isDef=false,bool isDefAndUse=false); - inline void setImplicitRef (unsigned i, Value* V, - bool isDef=false, bool isDefAndUse=false); - - // - // Information about registers used in this instruction - // - const std::vector &getRegsUsed() const { return regsUsed; } + /// removeFromParent - This method unlinks 'this' from the containing basic + /// block, and returns it, but does not delete it. + MachineInstr *removeFromParent(); - // insertUsedReg - Add a register to the Used registers set... - void insertUsedReg(unsigned Reg) { - if (Reg >= regsUsed.size()) - regsUsed.resize(Reg+1); - regsUsed[Reg] = true; + /// eraseFromParent - This method unlinks 'this' from the containing basic + /// block and deletes it. + void eraseFromParent() { + delete removeFromParent(); } // // Debugging support // - void print(std::ostream &OS, const TargetMachine &TM); + void print(std::ostream &OS, const TargetMachine *TM) const; void dump() const; friend std::ostream& operator<<(std::ostream& os, const MachineInstr& minstr); - // - // Define iterators to access the Value operands of the Machine Instruction. - // Note that these iterators only enumerate the explicit operands. - // begin() and end() are defined to produce these iterators... - // - template class ValOpIterator; - typedef ValOpIterator const_val_op_iterator; - typedef ValOpIterator< MachineInstr*, Value*> val_op_iterator; - - // Access to set the operands when building the machine instruction - // - void SetMachineOperandVal (unsigned i, - MachineOperand::MachineOperandType operandType, - Value* V, - bool isDef=false, - bool isDefAndUse=false); - - void SetMachineOperandConst (unsigned i, - MachineOperand::MachineOperandType operandType, - int64_t intValue); - - void SetMachineOperandReg (unsigned i, - int regNum, - bool isDef=false); - //===--------------------------------------------------------------------===// // Accessors to add operands when building up machine instructions // - /// addRegOperand - Add a MO_VirtualRegister operand to the end of the - /// operands list... + /// addRegOperand - Add a symbolic virtual register reference... /// - void addRegOperand(Value *V, bool isDef, bool isDefAndUse=false) { + void addRegOperand(int reg, bool isDef) { assert(!OperandsComplete() && "Trying to add an operand to a machine instr that is already done!"); - operands.push_back(MachineOperand(V, MachineOperand::MO_VirtualRegister, - !isDef ? MOTy::Use : (isDefAndUse ? MOTy::UseAndDef : MOTy::Def))); + operands.push_back( + MachineOperand(reg, MachineOperand::MO_VirtualRegister, + isDef ? MachineOperand::Def : MachineOperand::Use)); } - void addRegOperand(Value *V, MOTy::UseType UTy = MOTy::Use) { + /// addRegOperand - Add a symbolic virtual register reference... + /// + void addRegOperand(int reg, + MachineOperand::UseType UTy = MachineOperand::Use) { assert(!OperandsComplete() && "Trying to add an operand to a machine instr that is already done!"); - operands.push_back(MachineOperand(V, MachineOperand::MO_VirtualRegister, - UTy)); + operands.push_back( + MachineOperand(reg, MachineOperand::MO_VirtualRegister, UTy)); } - /// addRegOperand - Add a symbolic virtual register reference... + /// addZeroExtImmOperand - Add a zero extended constant argument to the + /// machine instruction. /// - void addRegOperand(int reg, bool isDef) { + void addZeroExtImmOperand(int intValue) { assert(!OperandsComplete() && "Trying to add an operand to a machine instr that is already done!"); - operands.push_back(MachineOperand(reg, MachineOperand::MO_VirtualRegister, - isDef ? MOTy::Def : MOTy::Use)); + operands.push_back( + MachineOperand(intValue, MachineOperand::MO_UnextendedImmed)); } - /// addRegOperand - Add a symbolic virtual register reference... + /// addZeroExtImm64Operand - Add a zero extended 64-bit constant argument + /// to the machine instruction. /// - void addRegOperand(int reg, MOTy::UseType UTy = MOTy::Use) { + void addZeroExtImm64Operand(uint64_t intValue) { assert(!OperandsComplete() && "Trying to add an operand to a machine instr that is already done!"); - operands.push_back(MachineOperand(reg, MachineOperand::MO_VirtualRegister, - UTy)); + operands.push_back( + MachineOperand(intValue, MachineOperand::MO_UnextendedImmed)); } - /// addPCDispOperand - Add a PC relative displacement operand to the MI + /// addSignExtImmOperand - Add a zero extended constant argument to the + /// machine instruction. /// - void addPCDispOperand(Value *V) { + void addSignExtImmOperand(int intValue) { assert(!OperandsComplete() && "Trying to add an operand to a machine instr that is already done!"); - operands.push_back(MachineOperand(V, MachineOperand::MO_PCRelativeDisp, - MOTy::Use)); + operands.push_back( + MachineOperand(intValue, MachineOperand::MO_SignExtendedImmed)); } - /// addMachineRegOperand - Add a virtual register operand to this MachineInstr - /// - void addMachineRegOperand(int reg, bool isDef) { + void addMachineBasicBlockOperand(MachineBasicBlock *MBB) { assert(!OperandsComplete() && "Trying to add an operand to a machine instr that is already done!"); - operands.push_back(MachineOperand(reg, MachineOperand::MO_MachineRegister, - isDef ? MOTy::Def : MOTy::Use)); - insertUsedReg(reg); + operands.push_back(MachineOperand(MBB)); } - /// addMachineRegOperand - Add a virtual register operand to this MachineInstr + /// addFrameIndexOperand - Add an abstract frame index to the instruction /// - void addMachineRegOperand(int reg, MOTy::UseType UTy = MOTy::Use) { + void addFrameIndexOperand(unsigned Idx) { assert(!OperandsComplete() && "Trying to add an operand to a machine instr that is already done!"); - operands.push_back(MachineOperand(reg, MachineOperand::MO_MachineRegister, - UTy)); - insertUsedReg(reg); + operands.push_back(MachineOperand(Idx, MachineOperand::MO_FrameIndex)); } - /// addZeroExtImmOperand - Add a zero extended constant argument to the - /// machine instruction. + /// addConstantPoolndexOperand - Add a constant pool object index to the + /// instruction. /// - void addZeroExtImmOperand(int64_t intValue) { + void addConstantPoolIndexOperand(unsigned I, int Offset=0) { assert(!OperandsComplete() && "Trying to add an operand to a machine instr that is already done!"); - operands.push_back(MachineOperand(intValue, - MachineOperand::MO_UnextendedImmed)); + operands.push_back(MachineOperand(I, MachineOperand::MO_ConstantPoolIndex)); } - /// addSignExtImmOperand - Add a zero extended constant argument to the - /// machine instruction. + /// addJumpTableIndexOperand - Add a jump table object index to the + /// instruction. /// - void addSignExtImmOperand(int64_t intValue) { + void addJumpTableIndexOperand(unsigned I) { assert(!OperandsComplete() && "Trying to add an operand to a machine instr that is already done!"); - operands.push_back(MachineOperand(intValue, - MachineOperand::MO_SignExtendedImmed)); + operands.push_back(MachineOperand(I, MachineOperand::MO_JumpTableIndex)); } - - - unsigned substituteValue(const Value* oldVal, Value* newVal, - bool defsOnly = true); - - void setOperandHi32(unsigned i) { operands[i].markHi32(); } - void setOperandLo32(unsigned i) { operands[i].markLo32(); } - void setOperandHi64(unsigned i) { operands[i].markHi64(); } - void setOperandLo64(unsigned i) { operands[i].markLo64(); } - - // SetRegForOperand - Replaces the Value for the operand with its allocated - // physical register after register allocation is complete. - // - void SetRegForOperand(unsigned i, int regNum); + void addGlobalAddressOperand(GlobalValue *GV, int Offset) { + assert(!OperandsComplete() && + "Trying to add an operand to a machine instr that is already done!"); + operands.push_back(MachineOperand(GV, Offset)); + } + + /// addExternalSymbolOperand - Add an external symbol operand to this instr + /// + void addExternalSymbolOperand(const char *SymName) { + operands.push_back(MachineOperand(SymName, 0)); + } + //===--------------------------------------------------------------------===// + // Accessors used to modify instructions in place. // - // Iterator to enumerate machine operands. - // - template - class ValOpIterator : public forward_iterator { - unsigned i; - MITy MI; - - void skipToNextVal() { - while (i < MI->getNumOperands() && - !( (MI->getOperandType(i) == MachineOperand::MO_VirtualRegister || - MI->getOperandType(i) == MachineOperand::MO_CCRegister) - && MI->getOperand(i).getVRegValue() != 0)) - ++i; - } - - inline ValOpIterator(MITy mi, unsigned I) : i(I), MI(mi) { - skipToNextVal(); - } - - public: - typedef ValOpIterator _Self; - - inline VTy operator*() const { - return MI->getOperand(i).getVRegValue(); - } - - const MachineOperand &getMachineOperand() const { return MI->getOperand(i);} - MachineOperand &getMachineOperand() { return MI->getOperand(i);} - - inline VTy operator->() const { return operator*(); } - - inline bool isDef() const { return MI->getOperand(i).opIsDef(); } - inline bool isDefAndUse() const { return MI->getOperand(i).opIsDefAndUse();} - - inline _Self& operator++() { i++; skipToNextVal(); return *this; } - inline _Self operator++(int) { _Self tmp = *this; ++*this; return tmp; } - - inline bool operator==(const _Self &y) const { - return i == y.i; - } - inline bool operator!=(const _Self &y) const { - return !operator==(y); - } - - static _Self begin(MITy MI) { - return _Self(MI, 0); - } - static _Self end(MITy MI) { - return _Self(MI, MI->getNumOperands()); - } - }; + // FIXME: Move this stuff to MachineOperand itself! - // define begin() and end() - val_op_iterator begin() { return val_op_iterator::begin(this); } - val_op_iterator end() { return val_op_iterator::end(this); } + /// setOpcode - Replace the opcode of the current instruction with a new one. + /// + void setOpcode(unsigned Op) { Opcode = Op; } - const_val_op_iterator begin() const { - return const_val_op_iterator::begin(this); - } - const_val_op_iterator end() const { - return const_val_op_iterator::end(this); + /// RemoveOperand - Erase an operand from an instruction, leaving it with one + /// fewer operand than it started with. + /// + void RemoveOperand(unsigned i) { + operands.erase(operands.begin()+i); } -}; + // Access to set the operands when building the machine instruction + // + void SetMachineOperandConst(unsigned i, + MachineOperand::MachineOperandType operandType, + int intValue); + + void SetMachineOperandReg(unsigned i, int regNum); +}; -// Define here to enable inlining of the functions used. -// -void MachineInstr::addImplicitRef(Value* V, - bool isDef, - bool isDefAndUse) -{ - ++numImplicitRefs; - addRegOperand(V, isDef, isDefAndUse); -} - -void MachineInstr::setImplicitRef(unsigned i, - Value* V, - bool isDef, - bool isDefAndUse) -{ - assert(i < getNumImplicitRefs() && "setImplicitRef() out of range!"); - SetMachineOperandVal(i + getNumOperands(), - MachineOperand::MO_VirtualRegister, - V, isDef, isDefAndUse); -} - - -//--------------------------------------------------------------------------- +//===----------------------------------------------------------------------===// // Debugging Support -//--------------------------------------------------------------------------- -std::ostream& operator<< (std::ostream& os, - const MachineInstr& minstr); +std::ostream& operator<<(std::ostream &OS, const MachineInstr &MI); +std::ostream& operator<<(std::ostream &OS, const MachineOperand &MO); -std::ostream& operator<< (std::ostream& os, - const MachineOperand& mop); - -void PrintMachineInstructions (const Function *F); +} // End llvm namespace #endif