X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FCodeGen%2FMachineInstr.h;h=fc886d97f54830e7919067e89d2ea8bb013069f0;hb=6fbcc26f1460eaee4e0eb8b426fc1ff0c7af11be;hp=499ec2498cf0db44821e1c3071aca51735bda677;hpb=32f3d08cdebd8941f2149a8f32acd45bd224ca8d;p=oota-llvm.git diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index 499ec2498cf..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,17 +16,30 @@ #ifndef LLVM_CODEGEN_MACHINEINSTR_H #define LLVM_CODEGEN_MACHINEINSTR_H -#include "llvm/Annotation.h" +#include "llvm/Target/MRegisterInfo.h" +#include "Support/Annotation.h" #include "Support/iterator" -#include "Support/NonCopyable.h" -#include + 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 @@ -34,7 +54,7 @@ namespace MOTy { }; } -//--------------------------------------------------------------------------- +//===----------------------------------------------------------------------===// // class MachineOperand // // Purpose: @@ -67,10 +87,9 @@ namespace MOTy { // - 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' @@ -78,42 +97,57 @@ 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: // 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) + 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 }; - MachineOperandType opType:8; // Pack into 8 bits efficiently after flags. 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), - opType(MO_VirtualRegister), flags(0), + opType(MO_VirtualRegister), regNum(-1) {} MachineOperand(int64_t ImmVal, MachineOperandType OpTy) : immedVal(ImmVal), - opType(OpTy), flags(0), + opType(OpTy), regNum(-1) {} MachineOperand(int Reg, MachineOperandType OpTy, MOTy::UseType UseTy) @@ -122,54 +156,131 @@ private: regNum(Reg) { switch (UseTy) { case MOTy::Use: flags = 0; break; - case MOTy::Def: flags = DEFFLAG; 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) + 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 = DEFFLAG; 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: - MachineOperand(const MachineOperand &M) - : immedVal(M.immedVal), - opType(M.opType), - flags(M.flags), - regNum(M.regNum) {} + 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() {} + ~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. // MachineOperandType getType() const { return opType; } - inline Value* getVRegValue () const { + /// 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; + } + 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 Value* getVRegValueOrNull() const { + Value* getVRegValueOrNull() const { return (opType == MO_VirtualRegister || opType == MO_CCRegister || - opType == MO_PCRelativeDisp)? value : NULL; + isPCRelativeDisp()) ? value : NULL; } - inline int getMachineRegNum() const { + 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; } - bool opIsDef () const { return flags & DEFFLAG; } + + GlobalValue *getGlobal() const { + assert(isGlobalAddress()); + return (GlobalValue*)value; + } + + const std::string &getSymbolName() const { + assert(isExternalSymbol()); + return *SymbolName; + } + + 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; } @@ -177,28 +288,29 @@ public: bool opLoBits64 () const { return flags & LOFLAG64; } // used to check if a machine register has been allocated to this operand - inline bool hasAllocatedReg() const { + bool hasAllocatedReg() const { return (regNum >= 0 && (opType == MO_VirtualRegister || opType == MO_CCRegister || opType == MO_MachineRegister)); } // 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); + 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: // Construction methods needed for fine-grain control. // These must be accessed via coresponding methods in MachineInstr. - void markDef() { flags |= DEFFLAG; } - void markDefAndUse() { flags |= DEFUSEFLAG; } void markHi32() { flags |= HIFLAG32; } void markLo32() { flags |= LOFLAG32; } void markHi64() { flags |= HIFLAG64; } @@ -216,7 +328,7 @@ private: }; -//--------------------------------------------------------------------------- +//===----------------------------------------------------------------------===// // class MachineInstr // // Purpose: @@ -232,61 +344,47 @@ private: // (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 { + int opCode; // the opcode + unsigned opCodeFlags; // flags modifying instrn behavior 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; - // 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: - MachineInstr(MachineOpCode Opcode); - MachineInstr(MachineOpCode Opcode, unsigned numOperands); + 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(MachineOpCode Opcode, unsigned numOperands, bool XX, bool YY); + 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, MachineOpCode Opcode, unsigned numOps); + MachineInstr(MachineBasicBlock *MBB, int 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; } + 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 getNumOperands() const { return operands.size() - numImplicitRefs; } @@ -299,57 +397,53 @@ 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(); + // + // 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())); } // - // Information about implicit operands of the instruction + // Access to implicit operands of the instruction // unsigned getNumImplicitRefs() const{ return numImplicitRefs; } - const Value* getImplicitRef(unsigned i) const { - return getImplicitOp(i).getVRegValue(); + MachineOperand& getImplicitOp(unsigned i) { + assert(i < numImplicitRefs && "implicit ref# out of range!"); + return operands[i + operands.size() - numImplicitRefs]; } - Value* getImplicitRef(unsigned i) { - return getImplicitOp(i).getVRegValue(); + const MachineOperand& getImplicitOp(unsigned i) const { + assert(i < numImplicitRefs && "implicit ref# out of range!"); + return operands[i + operands.size() - numImplicitRefs]; } - bool implicitRefIsDefined(unsigned i) const { - return getImplicitOp(i).opIsDef(); + Value* getImplicitRef(unsigned i) { + return getImplicitOp(i).getVRegValue(); } - bool implicitRefIsDefinedAndUsed(unsigned i) const { - return getImplicitOp(i).opIsDefAndUse(); + const Value* getImplicitRef(unsigned i) const { + return getImplicitOp(i).getVRegValue(); } - 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; } - - // insertUsedReg - Add a register to the Used registers set... - void insertUsedReg(unsigned Reg) { - if (Reg >= regsUsed.size()) - regsUsed.resize(Reg+1); - regsUsed[Reg] = true; + 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 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); @@ -362,21 +456,6 @@ public: 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 @@ -385,29 +464,47 @@ public: /// addRegOperand - Add a MO_VirtualRegister operand to the end of the /// operands list... /// - void addRegOperand(Value *V, bool isDef=false, bool isDefAndUse=false) { + 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) { + 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)); + 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 = 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(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) { @@ -419,12 +516,20 @@ public: /// addMachineRegOperand - Add a virtual register operand to this MachineInstr /// - void addMachineRegOperand(int reg, bool isDef=false) { + 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)); - insertUsedReg(reg); + } + + /// 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 @@ -447,9 +552,81 @@ public: 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* 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 = true); + bool defsOnly, bool notDefsAndUses, + bool& someArgsWereIgnored); void setOperandHi32(unsigned i) { operands[i].markHi32(); } void setOperandLo32(unsigned i) { operands[i].markLo32(); } @@ -457,10 +634,12 @@ public: void setOperandLo64(unsigned i) { operands[i].markLo64(); } - // SetRegForOperand - Replaces the Value for the operand with its allocated - // physical register after register allocation is complete. + // 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. @@ -472,8 +651,8 @@ public: void skipToNextVal() { while (i < MI->getNumOperands() && - !( (MI->getOperandType(i) == MachineOperand::MO_VirtualRegister || - MI->getOperandType(i) == MachineOperand::MO_CCRegister) + !( (MI->getOperand(i).getType() == MachineOperand::MO_VirtualRegister || + MI->getOperand(i).getType() == MachineOperand::MO_CCRegister) && MI->getOperand(i).getVRegValue() != 0)) ++i; } @@ -494,7 +673,8 @@ public: 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; } @@ -528,38 +708,11 @@ public: }; -// 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 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