X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FCodeGen%2FMachineInstr.h;h=25a7b3fedb6ca6b2f3d91a082dd890443e6ef104;hb=846c1b49365be588b5aaddd02916e46c2422ae6f;hp=5f0f1b91bcf8f3737110b16a16cf5889862708f3;hpb=9f42dd5472097c8657eaea829ebd384256d0f669;p=oota-llvm.git diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index 5f0f1b91bcf..25a7b3fedb6 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -1,10 +1,10 @@ //===-- 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 @@ -16,9 +16,10 @@ #ifndef LLVM_CODEGEN_MACHINEINSTR_H #define LLVM_CODEGEN_MACHINEINSTR_H -#include "llvm/Target/MRegisterInfo.h" -#include "Support/Annotation.h" -#include "Support/iterator" +#include "llvm/ADT/iterator" +#include "llvm/Support/DataTypes.h" +#include +#include namespace llvm { @@ -28,696 +29,401 @@ class MachineBasicBlock; class TargetMachine; class GlobalValue; -typedef int MachineOpCode; - -//===----------------------------------------------------------------------===// -/// Special flags on instructions that modify the opcode. -/// These flags are unused for now, but having them enforces that some -/// changes will be needed if they are used. -/// -enum MachineOpCodeFlags { - AnnulFlag, /// 1 if annul bit is set on a branch - PredTakenFlag, /// 1 if branch should be predicted taken - PredNotTakenFlag /// 1 if branch should be predicted not taken -}; +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 - }; -} - -//===----------------------------------------------------------------------===// -// 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. -// -//===----------------------------------------------------------------------===// - struct MachineOperand { enum MachineOperandType { - MO_VirtualRegister, // virtual register for *value - MO_MachineRegister, // pre-assigned machine register `regNum' - MO_CCRegister, - MO_SignExtendedImmed, - MO_UnextendedImmed, - MO_PCRelativeDisp, + MO_Register, // Register operand. + MO_Immediate, // Immediate Operand 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 - enum { - DEFFLAG = 0x01, // this is a def of the operand - USEFLAG = 0x02, // this is a use of the operand - HIFLAG32 = 0x04, // operand is %hi32(value_or_immedVal) - LOFLAG32 = 0x08, // operand is %lo32(value_or_immedVal) - HIFLAG64 = 0x10, // operand is %hi64(value_or_immedVal) - LOFLAG64 = 0x20, // operand is %lo64(value_or_immedVal) - PCRELATIVE = 0x40, // Operand is relative to PC, not a global address + MO_GlobalAddress // Address of a global value }; 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. - // LLVM global for MO_GlobalAddress. - - int64_t immedVal; // Constant value for an explicit constant - - MachineBasicBlock *MBB; // For MO_MachineBasicBlock type - std::string *SymbolName; // For MO_ExternalSymbol type - }; - - char flags; // see bit field definitions above - MachineOperandType opType:8; // Pack into 8 bits efficiently after flags. - int regNum; // register number for an explicit register - // will be set for a value after reg allocation -private: - MachineOperand() - : immedVal(0), - flags(0), - opType(MO_VirtualRegister), - regNum(-1) {} - - MachineOperand(int64_t ImmVal, MachineOperandType OpTy) - : immedVal(ImmVal), - flags(0), - opType(OpTy), - regNum(-1) {} - - MachineOperand(int Reg, MachineOperandType OpTy, MOTy::UseType UseTy) - : immedVal(0), - opType(OpTy), - regNum(Reg) { - switch (UseTy) { - case MOTy::Use: flags = USEFLAG; break; - case MOTy::Def: flags = DEFFLAG; break; - case MOTy::UseAndDef: flags = DEFFLAG | USEFLAG; break; - default: assert(0 && "Invalid value for UseTy!"); - } - } - - MachineOperand(Value *V, MachineOperandType OpTy, MOTy::UseType UseTy, - bool isPCRelative = false) - : value(V), opType(OpTy), regNum(-1) { - switch (UseTy) { - case MOTy::Use: flags = USEFLAG; break; - case MOTy::Def: flags = DEFFLAG; break; - case MOTy::UseAndDef: flags = DEFFLAG | USEFLAG; break; - default: assert(0 && "Invalid value for UseTy!"); - } - if (isPCRelative) flags |= PCRELATIVE; - } - - MachineOperand(MachineBasicBlock *mbb) - : MBB(mbb), flags(0), opType(MO_MachineBasicBlock), regNum(-1) {} - - MachineOperand(const std::string &SymName, bool isPCRelative) - : SymbolName(new std::string(SymName)), flags(isPCRelative ? PCRELATIVE :0), - opType(MO_ExternalSymbol), regNum(-1) {} + GlobalValue *GV; // For MO_GlobalAddress. + MachineBasicBlock *MBB; // For MO_MachineBasicBlock. + const char *SymbolName; // For MO_ExternalSymbol. + unsigned RegNo; // For MO_Register. + int64_t immedVal; // For MO_Immediate and MO_*Index. + } contents; + + MachineOperandType opType:8; // Discriminate the union. + bool IsDef : 1; // True if this is a def, false if this is a use. + + /// offset - Offset to address of global or external, only valid for + /// MO_GlobalAddress, MO_ExternalSym and MO_ConstantPoolIndex + int offset; + MachineOperand() {} public: - MachineOperand(const MachineOperand &M) : immedVal(M.immedVal), - flags(M.flags), - opType(M.opType), - regNum(M.regNum) { - if (isExternalSymbol()) - SymbolName = new std::string(M.getSymbolName()); + MachineOperand(const MachineOperand &M) { + *this = M; } - - ~MachineOperand() { - if (isExternalSymbol()) - delete SymbolName; + + ~MachineOperand() {} + + static MachineOperand CreateImm(int64_t Val) { + MachineOperand Op; + Op.opType = MachineOperand::MO_Immediate; + Op.contents.immedVal = Val; + Op.IsDef = false; + Op.offset = 0; + return Op; } const MachineOperand &operator=(const MachineOperand &MO) { - if (isExternalSymbol()) // if old operand had a symbol name, - delete SymbolName; // release old memory - immedVal = MO.immedVal; - flags = MO.flags; + contents = MO.contents; + IsDef = MO.IsDef; opType = MO.opType; - regNum = MO.regNum; - if (isExternalSymbol()) - SymbolName = new std::string(MO.getSymbolName()); + offset = MO.offset; return *this; } - // Accessor methods. Caller is responsible for checking the - // operand type before invoking the corresponding accessor. - // + /// getType - Returns the MachineOperandType for this operand. + /// MachineOperandType getType() const { return opType; } - /// isPCRelative - This returns the value of the PCRELATIVE flag, which - /// indicates whether this operand should be emitted as a PC relative value - /// instead of a global address. This is used for operands of the forms: - /// MachineBasicBlock, GlobalAddress, ExternalSymbol + /// Accessors that tell you what kind of MachineOperand you're looking at. /// - bool isPCRelative() const { return (flags & PCRELATIVE) != 0; } - - - // This is to finally stop caring whether we have a virtual or machine - // register -- an easier interface is to simply call both virtual and machine - // registers essentially the same, yet be able to distinguish when - // necessary. Thus the instruction selector can just add registers without - // abandon, and the register allocator won't be confused. - bool isVirtualRegister() const { - return (opType == MO_VirtualRegister || opType == MO_MachineRegister) - && regNum >= MRegisterInfo::FirstVirtualRegister; - } - bool isRegister() const { - return opType == MO_VirtualRegister || opType == MO_MachineRegister; - } - bool isMachineRegister() const { return !isVirtualRegister(); } + 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 isPCRelativeDisp() const { return opType == MO_PCRelativeDisp; } - 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; } - Value* getVRegValue() const { - assert(opType == MO_VirtualRegister || opType == MO_CCRegister || - isPCRelativeDisp()); - return value; + int64_t getImm() const { + assert(isImm() && "Wrong MachineOperand accessor"); + return contents.immedVal; } - Value* getVRegValueOrNull() const { - return (opType == MO_VirtualRegister || opType == MO_CCRegister || - isPCRelativeDisp()) ? value : NULL; + + int64_t getImmedValue() const { + assert(isImm() && "Wrong MachineOperand accessor"); + return contents.immedVal; } - int getMachineRegNum() const { - assert(opType == MO_MachineRegister); - return regNum; + MachineBasicBlock *getMBB() const { + assert(isMachineBasicBlock() && "Wrong MachineOperand accessor"); + return contents.MBB; } - int64_t getImmedValue() const { assert(isImmediate()); return immedVal; } - void setImmedValue(int64_t ImmVal) { assert(isImmediate()); immedVal=ImmVal; } - MachineBasicBlock *getMachineBasicBlock() const { - assert(isMachineBasicBlock() && "Can't get MBB in non-MBB operand!"); - return MBB; + assert(isMachineBasicBlock() && "Wrong MachineOperand accessor"); + return contents.MBB; + } + void setMachineBasicBlock(MachineBasicBlock *MBB) { + assert(isMachineBasicBlock() && "Wrong MachineOperand accessor"); + contents.MBB = MBB; + } + int getFrameIndex() const { + assert(isFrameIndex() && "Wrong MachineOperand accessor"); + return (int)contents.immedVal; } - int getFrameIndex() const { assert(isFrameIndex()); return immedVal; } unsigned getConstantPoolIndex() const { - assert(isConstantPoolIndex()); - return immedVal; + assert(isConstantPoolIndex() && "Wrong MachineOperand accessor"); + return (unsigned)contents.immedVal; + } + unsigned getJumpTableIndex() const { + assert(isJumpTableIndex() && "Wrong MachineOperand accessor"); + return (unsigned)contents.immedVal; } - GlobalValue *getGlobal() const { - assert(isGlobalAddress()); - return (GlobalValue*)value; + assert(isGlobalAddress() && "Wrong MachineOperand accessor"); + return contents.GV; } - - const std::string &getSymbolName() const { - assert(isExternalSymbol()); - return *SymbolName; + int getOffset() const { + assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex()) && + "Wrong MachineOperand accessor"); + return offset; } - - bool isUse () const { return flags & USEFLAG; } - MachineOperand& setUse () { flags |= USEFLAG; return *this; } - bool isDef () const { return flags & DEFFLAG; } - MachineOperand& setDef () { flags |= DEFFLAG; return *this; } - bool isHiBits32 () const { return flags & HIFLAG32; } - bool isLoBits32 () const { return flags & LOFLAG32; } - bool isHiBits64 () const { return flags & HIFLAG64; } - bool isLoBits64 () const { return flags & LOFLAG64; } - - // used to check if a machine register has been allocated to this operand - bool hasAllocatedReg() const { - return (regNum >= 0 && - (opType == MO_VirtualRegister || opType == MO_CCRegister || - opType == MO_MachineRegister)); + const char *getSymbolName() const { + assert(isExternalSymbol() && "Wrong MachineOperand accessor"); + return contents.SymbolName; } - // used to get the reg number if when one is allocated - int getAllocatedRegNum() const { - assert(hasAllocatedReg()); - return regNum; + bool isUse() const { + assert(isRegister() && "Wrong MachineOperand accessor"); + return !IsDef; + } + bool isDef() const { + assert(isRegister() && "Wrong MachineOperand accessor"); + return IsDef; + } + void setIsUse() { + assert(isRegister() && "Wrong MachineOperand accessor"); + IsDef = false; + } + void setIsDef() { + assert(isRegister() && "Wrong MachineOperand accessor"); + IsDef = true; } - // ********** TODO: get rid of this duplicate code! *********** + /// getReg - Returns the register number. + /// unsigned getReg() const { - return getAllocatedRegNum(); - } - void setReg(unsigned Reg) { - assert(hasAllocatedReg() && "This operand cannot have a register number!"); - regNum = Reg; - } + assert(isRegister() && "This is not a register operand!"); + return contents.RegNo; + } - friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop); + /// MachineOperand mutators. + /// + void setReg(unsigned Reg) { + assert(isRegister() && "This is not a register operand!"); + contents.RegNo = Reg; + } -private: + void setImmedValue(int64_t immVal) { + assert(isImm() && "Wrong MachineOperand mutator"); + contents.immedVal = immVal; + } + void setImm(int64_t immVal) { + assert(isImm() && "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"); + offset = Offset; + } + void setConstantPoolIndex(unsigned Idx) { + assert(isConstantPoolIndex() && "Wrong MachineOperand accessor"); + contents.immedVal = Idx; } + /// isIdenticalTo - Return true if this operand is identical to the specified + /// operand. + bool isIdenticalTo(const MachineOperand &Other) const; + + /// ChangeToImmediate - Replace this operand with a new immediate operand of + /// the specified value. If an operand is known to be an immediate already, + /// the setImmedValue method should be used. + void ChangeToImmediate(int64_t ImmVal) { + opType = MO_Immediate; + contents.immedVal = ImmVal; + } + + /// 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) { + opType = MO_Register; + contents.RegNo = Reg; + IsDef = isDef; + } + + friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop); + friend 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[] -// -// (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. -//===----------------------------------------------------------------------===// - +/// MachineInstr - Representation of each machine instruction. +/// class MachineInstr { - int opCode; // the opcode - unsigned opCodeFlags; // flags modifying instrn behavior - std::vector operands; // the operands - unsigned numImplicitRefs; // number of implicit operands + short Opcode; // the opcode + std::vector Operands; // the operands + 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; - MachineInstr(const MachineInstr &); // DO NOT IMPLEMENT + MachineInstr(const MachineInstr&); void operator=(const MachineInstr&); // DO NOT IMPLEMENT -public: - MachineInstr(int Opcode, unsigned numOperands); - /// 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(int Opcode, unsigned numOperands, bool XX, bool YY); + // Intrusive list support + // + friend struct ilist_traits; + +public: + /// MachineInstr ctor - This constructor reserve's space for numOperand + /// operands. + MachineInstr(short Opcode, unsigned numOperands); /// 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, int Opcode, unsigned numOps); - + MachineInstr(MachineBasicBlock *MBB, short Opcode, unsigned numOps); - // The opcode. - // - const int getOpcode() const { return opCode; } - const int getOpCode() const { return opCode; } + ~MachineInstr(); - // Opcode flags. - // - unsigned getOpCodeFlags() const { return opCodeFlags; } + 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(); } - // - // Access to 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]; + return Operands[i]; } MachineOperand& getOperand(unsigned i) { assert(i < getNumOperands() && "getOperand() out of range!"); - return operands[i]; - } - - // - // Access to explicit or implicit operands of the instruction - // This returns the i'th entry in the operand vector. - // That represents the i'th explicit operand or the (i-N)'th implicit operand, - // depending on whether i < N or i >= N. - // - const MachineOperand& getExplOrImplOperand(unsigned i) const { - assert(i < operands.size() && "getExplOrImplOperand() out of range!"); - return (i < getNumOperands()? getOperand(i) - : getImplicitOp(i - getNumOperands())); + return Operands[i]; } - // - // Access to implicit operands of the instruction - // - unsigned getNumImplicitRefs() const{ return numImplicitRefs; } - 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]; - } - - Value* getImplicitRef(unsigned i) { - return getImplicitOp(i).getVRegValue(); - } - const Value* getImplicitRef(unsigned i) const { - return getImplicitOp(i).getVRegValue(); - } - - void addImplicitRef(Value* V, bool isDef = false, bool isDefAndUse = false) { - ++numImplicitRefs; - addRegOperand(V, isDef, isDefAndUse); - } - void setImplicitRef(unsigned i, Value* V) { - assert(i < getNumImplicitRefs() && "setImplicitRef() out of range!"); - SetMachineOperandVal(i + getNumOperands(), - MachineOperand::MO_VirtualRegister, V); + /// isIdenticalTo - Return true if this instruction is identical to (same + /// opcode and same operands as) the specified instruction. + bool isIdenticalTo(const MachineInstr *Other) const { + if (Other->getOpcode() != getOpcode() || + Other->getNumOperands() != getNumOperands()) + return false; + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) + if (!getOperand(i).isIdenticalTo(Other->getOperand(i))) + return false; + return true; + } + + /// 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 { return new MachineInstr(*this); } + + /// removeFromParent - This method unlinks 'this' from the containing basic + /// block, and returns it, but does not delete it. + MachineInstr *removeFromParent(); + + /// 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) const; + 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; - - //===--------------------------------------------------------------------===// - // Accessors to add operands when building up machine instructions + // Accessors to add operands when building up machine instructions. // - /// addRegOperand - Add a MO_VirtualRegister operand to the end of the - /// operands list... - /// - void addRegOperand(Value *V, bool isDef, bool isDefAndUse=false) { - 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))); - } - - void addRegOperand(Value *V, MOTy::UseType UTy = MOTy::Use, - bool isPCRelative = false) { - assert(!OperandsComplete() && - "Trying to add an operand to a machine instr that is already done!"); - operands.push_back(MachineOperand(V, MachineOperand::MO_VirtualRegister, - UTy, isPCRelative)); - } - - void addCCRegOperand(Value *V, MOTy::UseType UTy = MOTy::Use) { - assert(!OperandsComplete() && - "Trying to add an operand to a machine instr that is already done!"); - operands.push_back(MachineOperand(V, MachineOperand::MO_CCRegister, UTy, - false)); - } - - - /// addRegOperand - Add a symbolic virtual register reference... - /// - 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(reg, MachineOperand::MO_VirtualRegister, - isDef ? MOTy::Def : MOTy::Use)); - } - - /// addRegOperand - Add a symbolic virtual register reference... - /// - void addRegOperand(int reg, MOTy::UseType UTy = MOTy::Use) { - assert(!OperandsComplete() && - "Trying to add an operand to a machine instr that is already done!"); - operands.push_back(MachineOperand(reg, MachineOperand::MO_VirtualRegister, - UTy)); - } - - /// addPCDispOperand - Add a PC relative displacement operand to the MI - /// - void addPCDispOperand(Value *V) { - 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)); - } - - /// addMachineRegOperand - Add a virtual register operand to this MachineInstr - /// - void addMachineRegOperand(int reg, bool isDef) { - 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)); - } - - /// addMachineRegOperand - Add a virtual register operand to this MachineInstr + /// addRegOperand - Add a register operand. /// - void addMachineRegOperand(int reg, MOTy::UseType UTy = MOTy::Use) { - assert(!OperandsComplete() && - "Trying to add an operand to a machine instr that is already done!"); - operands.push_back(MachineOperand(reg, MachineOperand::MO_MachineRegister, - UTy)); + void addRegOperand(unsigned Reg, bool IsDef) { + MachineOperand &Op = AddNewOperand(); + Op.opType = MachineOperand::MO_Register; + Op.IsDef = IsDef; + Op.contents.RegNo = Reg; + Op.offset = 0; } - /// addZeroExtImmOperand - Add a zero extended constant argument to the + /// addImmOperand - Add a zero extended constant argument to the /// machine instruction. /// - void addZeroExtImmOperand(int64_t intValue) { - assert(!OperandsComplete() && - "Trying to add an operand to a machine instr that is already done!"); - operands.push_back(MachineOperand(intValue, - MachineOperand::MO_UnextendedImmed)); - } - - /// addSignExtImmOperand - Add a zero extended constant argument to the - /// machine instruction. - /// - void addSignExtImmOperand(int64_t intValue) { - assert(!OperandsComplete() && - "Trying to add an operand to a machine instr that is already done!"); - operands.push_back(MachineOperand(intValue, - MachineOperand::MO_SignExtendedImmed)); + void addImmOperand(int64_t Val) { + MachineOperand &Op = AddNewOperand(); + Op.opType = MachineOperand::MO_Immediate; + Op.contents.immedVal = Val; + Op.offset = 0; } void addMachineBasicBlockOperand(MachineBasicBlock *MBB) { - assert(!OperandsComplete() && - "Trying to add an operand to a machine instr that is already done!"); - operands.push_back(MachineOperand(MBB)); + MachineOperand &Op = AddNewOperand(); + Op.opType = MachineOperand::MO_MachineBasicBlock; + Op.contents.MBB = MBB; + Op.offset = 0; } /// addFrameIndexOperand - Add an abstract frame index to the instruction /// void addFrameIndexOperand(unsigned Idx) { - assert(!OperandsComplete() && - "Trying to add an operand to a machine instr that is already done!"); - operands.push_back(MachineOperand(Idx, MachineOperand::MO_FrameIndex)); + MachineOperand &Op = AddNewOperand(); + Op.opType = MachineOperand::MO_FrameIndex; + Op.contents.immedVal = Idx; + Op.offset = 0; } /// addConstantPoolndexOperand - Add a constant pool object index to the /// instruction. /// - void addConstantPoolIndexOperand(unsigned I) { - assert(!OperandsComplete() && - "Trying to add an operand to a machine instr that is already done!"); - operands.push_back(MachineOperand(I, MachineOperand::MO_ConstantPoolIndex)); + void addConstantPoolIndexOperand(unsigned Idx, int Offset) { + MachineOperand &Op = AddNewOperand(); + Op.opType = MachineOperand::MO_ConstantPoolIndex; + Op.contents.immedVal = Idx; + Op.offset = Offset; } - void addGlobalAddressOperand(GlobalValue *GV, bool isPCRelative) { - assert(!OperandsComplete() && - "Trying to add an operand to a machine instr that is already done!"); - operands.push_back(MachineOperand((Value*)GV, - MachineOperand::MO_GlobalAddress, - MOTy::Use, isPCRelative)); + /// addJumpTableIndexOperand - Add a jump table object index to the + /// instruction. + /// + void addJumpTableIndexOperand(unsigned Idx) { + MachineOperand &Op = AddNewOperand(); + Op.opType = MachineOperand::MO_JumpTableIndex; + Op.contents.immedVal = Idx; + Op.offset = 0; + } + + void addGlobalAddressOperand(GlobalValue *GV, int Offset) { + MachineOperand &Op = AddNewOperand(); + Op.opType = MachineOperand::MO_GlobalAddress; + Op.contents.GV = GV; + Op.offset = Offset; } /// addExternalSymbolOperand - Add an external symbol operand to this instr /// - void addExternalSymbolOperand(const std::string &SymName, bool isPCRelative) { - operands.push_back(MachineOperand(SymName, isPCRelative)); + void addExternalSymbolOperand(const char *SymName) { + MachineOperand &Op = AddNewOperand(); + Op.opType = MachineOperand::MO_ExternalSymbol; + Op.contents.SymbolName = SymName; + Op.offset = 0; } //===--------------------------------------------------------------------===// // Accessors used to modify instructions in place. // - // FIXME: Move this stuff to MachineOperand itself! - - /// 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(int Opcode, unsigned numOperands); /// setOpcode - Replace the opcode of the current instruction with a new one. /// - void setOpcode(unsigned Op) { opCode = Op; } + void setOpcode(unsigned Op) { Opcode = Op; } /// 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); + Operands.erase(Operands.begin()+i); } - - // Access to set the operands when building the machine instruction - // - void SetMachineOperandVal (unsigned i, - MachineOperand::MachineOperandType operandType, - Value* V); - - void SetMachineOperandConst (unsigned i, - MachineOperand::MachineOperandType operandType, - int64_t intValue); - - void SetMachineOperandReg(unsigned i, int regNum); - - - unsigned substituteValue(const Value* oldVal, Value* newVal, - bool defsOnly, bool notDefsAndUses, - bool& someArgsWereIgnored); - - 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 - - // SetRegForImplicitRef - - // Mark an explicit or implicit operand with its allocated physical register. - // - void SetRegForOperand(unsigned i, int regNum); - void SetRegForImplicitRef(unsigned i, int regNum); - - // - // Iterator to enumerate machine operands. - // - template - class ValOpIterator : public forward_iterator { - unsigned i; - MITy MI; - - void skipToNextVal() { - while (i < MI->getNumOperands() && - !( (MI->getOperand(i).getType() == MachineOperand::MO_VirtualRegister || - MI->getOperand(i).getType() == 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 isUse() const { return MI->getOperand(i).isUse(); } - inline bool isDef() const { return MI->getOperand(i).isDef(); } - - 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()); - } - }; - - // define begin() and end() - val_op_iterator begin() { return val_op_iterator::begin(this); } - val_op_iterator end() { return val_op_iterator::end(this); } - - 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); +private: + MachineOperand &AddNewOperand() { + assert(!OperandsComplete() && + "Trying to add an operand to a machine instr that is already done!"); + Operands.push_back(MachineOperand()); + return Operands.back(); } }; - //===----------------------------------------------------------------------===// // Debugging Support std::ostream& operator<<(std::ostream &OS, const MachineInstr &MI); std::ostream& operator<<(std::ostream &OS, const MachineOperand &MO); -void PrintMachineInstructions(const Function *F); } // End llvm namespace