X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FCodeGen%2FMachineInstr.h;h=fc886d97f54830e7919067e89d2ea8bb013069f0;hb=6fbcc26f1460eaee4e0eb8b426fc1ff0c7af11be;hp=5ae9e4b0b9105e3aa3642dc81812af22109d702b;hpb=8eb04905e84470a0baff867fa99b0de097f49a3b;p=oota-llvm.git diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index 5ae9e4b0b91..fc886d97f54 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,12 +16,45 @@ #ifndef LLVM_CODEGEN_MACHINEINSTR_H #define LLVM_CODEGEN_MACHINEINSTR_H -#include "llvm/Target/MachineInstrInfo.h" -#include "llvm/Annotation.h" -#include -class Instruction; +#include "llvm/Target/MRegisterInfo.h" +#include "Support/Annotation.h" +#include "Support/iterator" + +class Value; +class Function; +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 +}; -//--------------------------------------------------------------------------- +//===----------------------------------------------------------------------===// +/// 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: @@ -47,11 +87,9 @@ class Instruction; // - Ptr will also be of virtual register type MO_VirtualReg. // Again, the field Value* value identifies the value. // -//--------------------------------------------------------------------------- - +//===----------------------------------------------------------------------===// -class MachineOperand { -public: +struct MachineOperand { enum MachineOperandType { MO_VirtualRegister, // virtual register for *value MO_MachineRegister, // pre-assigned machine register `regNum' @@ -59,156 +97,238 @@ public: 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_ExternalSymbol, // Name of external global symbol + MO_GlobalAddress, // Address of a global value }; private: - MachineOperandType opType; + // Bit fields of the flags variable used for different operand properties + enum { + DEFONLYFLAG = 0x01, // this is a def but not a use of the operand + DEFUSEFLAG = 0x02, // this is both a def and a use + 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 + USEDEFMASK = 0x03, + }; + +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 + // 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 - bool isDef; // is this a defition for the value - +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 = 0; break; + case MOTy::Def: flags = DEFONLYFLAG; break; + case MOTy::UseAndDef: flags = DEFUSEFLAG; 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 = 0; break; + case MOTy::Def: flags = DEFONLYFLAG; break; + case MOTy::UseAndDef: flags = DEFUSEFLAG; 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) {} + public: - /*ctor*/ MachineOperand (); - /*ctor*/ MachineOperand (MachineOperandType operandType, - Value* _val); - /*copy ctor*/ MachineOperand (const MachineOperand&); - /*dtor*/ ~MachineOperand () {} + 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() { + if (isExternalSymbol()) + delete SymbolName; + } + 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; + opType = MO.opType; + regNum = MO.regNum; + if (isExternalSymbol()) + SymbolName = new std::string(MO.getSymbolName()); + return *this; + } + // Accessor methods. Caller is responsible for checking the // operand type before invoking the corresponding accessor. // - inline MachineOperandType getOperandType() const { - return opType; + 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 + /// + 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; } - inline Value* getVRegValue () const { + bool isPhysicalRegister() const { + return (opType == MO_VirtualRegister || opType == MO_MachineRegister) + && (unsigned)regNum < MRegisterInfo::FirstVirtualRegister; + } + bool isRegister() const { return isVirtualRegister() || isPhysicalRegister();} + bool isMachineRegister() const { return !isVirtualRegister(); } + 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 isGlobalAddress() const { return opType == MO_GlobalAddress; } + bool isExternalSymbol() const { return opType == MO_ExternalSymbol; } + + Value* getVRegValue() const { assert(opType == MO_VirtualRegister || opType == MO_CCRegister || - opType == MO_PCRelativeDisp); + isPCRelativeDisp()); return value; } - inline int getMachineRegNum() const { + Value* getVRegValueOrNull() const { + return (opType == MO_VirtualRegister || opType == MO_CCRegister || + isPCRelativeDisp()) ? value : NULL; + } + int getMachineRegNum() const { assert(opType == MO_MachineRegister); return regNum; } - inline int64_t getImmedValue () const { - assert(opType == MO_SignExtendedImmed || opType == MO_UnextendedImmed); + int64_t getImmedValue() const { assert(isImmediate()); return immedVal; } + MachineBasicBlock *getMachineBasicBlock() const { + assert(isMachineBasicBlock() && "Can't get MBB in non-MBB operand!"); + return MBB; + } + int getFrameIndex() const { assert(isFrameIndex()); return immedVal; } + unsigned getConstantPoolIndex() const { + assert(isConstantPoolIndex()); return immedVal; } - inline bool opIsDef () const { - return isDef; + + GlobalValue *getGlobal() const { + assert(isGlobalAddress()); + return (GlobalValue*)value; } - -public: - friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop); - -private: - // These functions are provided so that a vector of operands can be - // statically allocated and individual ones can be initialized later. - // Give class MachineInstr gets access to these functions. - // - void Initialize (MachineOperandType operandType, - Value* _val); - void InitializeConst (MachineOperandType operandType, - int64_t intValue); - void InitializeReg (int regNum, - bool isCCReg); + const std::string &getSymbolName() const { + assert(isExternalSymbol()); + return *SymbolName; + } - friend class MachineInstr; + bool opIsUse () const { return (flags & USEDEFMASK) == 0; } + bool opIsDefOnly () const { return flags & DEFONLYFLAG; } + 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; } + + // 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)); + } -public: + // used to get the reg number if when one is allocated + int getAllocatedRegNum() const { + assert(hasAllocatedReg()); + return regNum; + } + + // ********** TODO: get rid of this duplicate code! *********** + unsigned getReg() const { + return getAllocatedRegNum(); + } + + friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop); + +private: - // replaces the Value with its corresponding physical register after + // 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; } - - // used to get the reg number if when one is allocted (must be - // called only after reg alloc) - inline int getAllocatedRegNum() const { - assert(opType == MO_VirtualRegister || opType == MO_CCRegister || - opType == MO_MachineRegister); - return regNum; - } - - + + friend class MachineInstr; }; -inline -MachineOperand::MachineOperand() - : opType(MO_VirtualRegister), - immedVal(0), - regNum(-1), - isDef(false) -{} - -inline -MachineOperand::MachineOperand(MachineOperandType operandType, - Value* _val) - : opType(operandType), - immedVal(0), - regNum(-1), - isDef(false) -{} - -inline -MachineOperand::MachineOperand(const MachineOperand& mo) - : opType(mo.opType), - isDef(false) -{ - switch(opType) { - case MO_VirtualRegister: - case MO_CCRegister: value = mo.value; break; - case MO_MachineRegister: regNum = mo.regNum; break; - case MO_SignExtendedImmed: - case MO_UnextendedImmed: - case MO_PCRelativeDisp: immedVal = mo.immedVal; break; - default: assert(0); - } -} - -inline void -MachineOperand::Initialize(MachineOperandType operandType, - Value* _val) -{ - opType = operandType; - value = _val; - regNum = -1; -} - -inline void -MachineOperand::InitializeConst(MachineOperandType operandType, - int64_t intValue) -{ - opType = operandType; - value = NULL; - immedVal = intValue; - regNum = -1; -} - -inline void -MachineOperand::InitializeReg(int _regNum, bool isCCReg) -{ - opType = isCCReg? MO_CCRegister : MO_MachineRegister; - value = NULL; - regNum = (int) _regNum; -} - - -//--------------------------------------------------------------------------- +//===----------------------------------------------------------------------===// // class MachineInstr // // Purpose: @@ -217,13 +337,6 @@ MachineOperand::InitializeReg(int _regNum, bool isCCReg) // MachineOpCode must be an enum, defined separately for each target. // E.g., It is defined in SparcInstructionSelection.h for the SPARC. // -// opCodeMask is used to record variants of an instruction. -// E.g., each branch instruction on SPARC has 2 flags (i.e., 4 variants): -// ANNUL: if 1: Annul delay slot instruction. -// PREDICT-NOT-TAKEN: if 1: predict branch not taken. -// Instead of creating 4 different opcodes for BNZ, we create a single -// opcode and set bits in opCodeMask for each of these flags. -// // There are 2 kinds of operands: // // (1) Explicit operands of the machine instruction in vector operands[] @@ -231,54 +344,112 @@ MachineOperand::InitializeReg(int _regNum, bool isCCReg) // (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 Annotable, // Values are annotable - public NonCopyableV { // Disable copy operations - MachineOpCode opCode; - OpCodeMask opCodeMask; // extra bits for variants of an opcode - std::vector operands; - std::vector implicitRefs; // values implicitly referenced by this - std::vector implicitIsDef; // machine instruction (eg, call args) - +//===----------------------------------------------------------------------===// + +class MachineInstr { + int opCode; // the opcode + unsigned opCodeFlags; // flags modifying instrn behavior + std::vector operands; // the operands + unsigned numImplicitRefs; // number of implicit operands + + // OperandComplete - Return true if it's illegal to add a new operand + bool OperandsComplete() const; + + MachineInstr(const MachineInstr &); // DO NOT IMPLEMENT + void operator=(const MachineInstr&); // DO NOT IMPLEMENT public: - /*ctor*/ MachineInstr (MachineOpCode _opCode, - OpCodeMask _opCodeMask = 0x0); - /*ctor*/ MachineInstr (MachineOpCode _opCode, - unsigned numOperands, - OpCodeMask _opCodeMask = 0x0); - inline ~MachineInstr () {} - const MachineOpCode getOpCode () const { return opCode; } + 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); + + /// 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); + + + // The opcode. + // + const int getOpcode() const { return opCode; } + const int getOpCode() const { return opCode; } + + // Opcode flags. + // + unsigned getOpCodeFlags() const { return opCodeFlags; } // - // Information about explicit operands of the instruction + // Access to explicit operands of the instruction // - unsigned int getNumOperands () const { return operands.size(); } - - bool operandIsDefined(unsigned i) const; - - const MachineOperand& getOperand (unsigned i) const; - MachineOperand& getOperand (unsigned i); + unsigned getNumOperands() const { return operands.size() - numImplicitRefs; } + const MachineOperand& getOperand(unsigned i) const { + assert(i < getNumOperands() && "getOperand() out of range!"); + return operands[i]; + } + MachineOperand& getOperand(unsigned i) { + assert(i < getNumOperands() && "getOperand() out of range!"); + return operands[i]; + } + // - // Information about implicit operands of the instruction + // 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. // - unsigned getNumImplicitRefs() const{return implicitRefs.size();} - - bool implicitRefIsDefined(unsigned i) const; - - const Value* getImplicitRef (unsigned i) const; - Value* getImplicitRef (unsigned i); + const MachineOperand& getExplOrImplOperand(unsigned i) const { + assert(i < operands.size() && "getExplOrImplOperand() out of range!"); + return (i < getNumOperands()? getOperand(i) + : getImplicitOp(i - getNumOperands())); + } + + // + // 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); + } + // // Debugging support - // - void dump (unsigned int indent = 0) 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; @@ -286,35 +457,203 @@ public: typedef ValOpIterator< MachineInstr*, Value*> val_op_iterator; + //===--------------------------------------------------------------------===// + // 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 + /// + 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)); + } + + /// addZeroExtImmOperand - 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 addMachineBasicBlockOperand(MachineBasicBlock *MBB) { + assert(!OperandsComplete() && + "Trying to add an operand to a machine instr that is already done!"); + operands.push_back(MachineOperand(MBB)); + } + + /// 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)); + } + + /// 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 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)); + } + + /// addExternalSymbolOperand - Add an external symbol operand to this instr + /// + void addExternalSymbolOperand(const std::string &SymName, bool isPCRelative) { + operands.push_back(MachineOperand(SymName, isPCRelative)); + } + + //===--------------------------------------------------------------------===// + // 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; } + + /// 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 SetMachineOperandVal(unsigned i, - MachineOperand::MachineOperandType operandType, - Value* _val, bool isDef=false); - void SetMachineOperandConst(unsigned i, - MachineOperand::MachineOperandType operandType, - int64_t intValue); - void SetMachineOperandReg(unsigned i, - int regNum, - bool isDef=false, - bool isCCReg=false); - - void addImplicitRef (Value* val, - bool isDef=false); + // + 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(); } + - void setImplicitRef (unsigned i, - Value* val, - bool isDef=false); + // 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 std::forward_iterator { + class ValOpIterator : public forward_iterator { unsigned i; MITy MI; - inline void skipToNextVal() { + void skipToNextVal() { while (i < MI->getNumOperands() && - !((MI->getOperand(i).getOperandType() == MachineOperand::MO_VirtualRegister || - MI->getOperand(i).getOperandType() == MachineOperand::MO_CCRegister) - && MI->getOperand(i).getVRegValue() != 0)) + !( (MI->getOperand(i).getType() == MachineOperand::MO_VirtualRegister || + MI->getOperand(i).getType() == MachineOperand::MO_CCRegister) + && MI->getOperand(i).getVRegValue() != 0)) ++i; } @@ -325,16 +664,19 @@ public: public: typedef ValOpIterator _Self; - inline VTy operator*() const { return MI->getOperand(i).getVRegValue(); } - - const MachineOperand &getMachineOperand() const { - return MI->getOperand(i); + 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 isUseOnly() const { return MI->getOperand(i).opIsUse(); } + inline bool isDefOnly() const { return MI->getOperand(i).opIsDefOnly(); } + 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; } @@ -366,138 +708,11 @@ public: }; -inline MachineOperand& -MachineInstr::getOperand(unsigned int i) -{ - assert(i < operands.size() && "getOperand() out of range!"); - return operands[i]; -} - -inline const MachineOperand& -MachineInstr::getOperand(unsigned int i) const -{ - assert(i < operands.size() && "getOperand() out of range!"); - return operands[i]; -} - -inline bool -MachineInstr::operandIsDefined(unsigned int i) const -{ - return getOperand(i).opIsDef(); -} - -inline bool -MachineInstr::implicitRefIsDefined(unsigned int i) const -{ - assert(i < implicitIsDef.size() && "operand out of range!"); - return implicitIsDef[i]; -} - -inline const Value* -MachineInstr::getImplicitRef(unsigned int i) const -{ - assert(i < implicitRefs.size() && "getImplicitRef() out of range!"); - return implicitRefs[i]; -} - -inline Value* -MachineInstr::getImplicitRef(unsigned int i) -{ - assert(i < implicitRefs.size() && "getImplicitRef() out of range!"); - return implicitRefs[i]; -} - -inline void -MachineInstr::addImplicitRef(Value* val, - bool isDef) -{ - implicitRefs.push_back(val); - implicitIsDef.push_back(isDef); -} - -inline void -MachineInstr::setImplicitRef(unsigned int i, - Value* val, - bool isDef) -{ - assert(i < implicitRefs.size() && "setImplicitRef() out of range!"); - implicitRefs[i] = val; - implicitIsDef[i] = isDef; -} - - - -//--------------------------------------------------------------------------- -// class MachineCodeForBasicBlock -// -// Purpose: -// Representation of the sequence of machine instructions created -// for a basic block. -//--------------------------------------------------------------------------- - - -class MachineCodeForBasicBlock { - std::vector Insts; -public: - ~MachineCodeForBasicBlock() { -#if 0 - for (unsigned i = 0, e = Insts.size(); i != e; ++i) - delete Insts[i]; -#endif - } - - typedef std::vector::iterator iterator; - typedef std::vector::const_iterator const_iterator; - typedef std::reverse_iterator const_reverse_iterator; - typedef std::reverse_iterator reverse_iterator; - - unsigned size() const { return Insts.size(); } - bool empty() const { return Insts.empty(); } - - MachineInstr * operator[](unsigned i) const { return Insts[i]; } - MachineInstr *&operator[](unsigned i) { return Insts[i]; } - - MachineInstr *front() const { return Insts.front(); } - MachineInstr *back() const { return Insts.back(); } - - iterator begin() { return Insts.begin(); } - const_iterator begin() const { return Insts.begin(); } - iterator end() { return Insts.end(); } - const_iterator end() const { return Insts.end(); } - reverse_iterator rbegin() { return Insts.rbegin(); } - const_reverse_iterator rbegin() const { return Insts.rbegin(); } - reverse_iterator rend () { return Insts.rend(); } - const_reverse_iterator rend () const { return Insts.rend(); } - - void push_back(MachineInstr *MI) { Insts.push_back(MI); } - template - void insert(iterator I, IT S, IT E) { Insts.insert(I, S, E); } - iterator insert(iterator I, MachineInstr *M) { return Insts.insert(I, M); } - - // erase - Remove the specified range from the instruction list. This does - // not delete in instructions removed. - // - iterator erase(iterator I, iterator E) { return Insts.erase(I, E); } - - MachineInstr *pop_back() { - MachineInstr *R = back(); - Insts.pop_back(); - return R; - } -}; - - -//--------------------------------------------------------------------------- +//===----------------------------------------------------------------------===// // Debugging Support -//--------------------------------------------------------------------------- - - -std::ostream& operator<< (std::ostream& os, const MachineInstr& minstr); - - -std::ostream& operator<< (std::ostream& os, const MachineOperand& mop); - -void PrintMachineInstructions(const Function *F); +std::ostream& operator<<(std::ostream &OS, const MachineInstr &MI); +std::ostream& operator<<(std::ostream &OS, const MachineOperand &MO); +void PrintMachineInstructions(const Function *F); #endif