X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FCodeGen%2FMachineInstr.h;h=b0705182e9f4e462bc0fcd0a13749f48e8f48923;hb=a62e52ab181c10738066e65a6dcc6c3cdfa5d806;hp=3950630aed1e4beaff79b954aeba918830712fcd;hpb=c54839573cd9ffa6af33dc5190cc40d498534585;p=oota-llvm.git diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index 3950630aed1..b0705182e9f 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,7 +16,8 @@ #ifndef LLVM_CODEGEN_MACHINEINSTR_H #define LLVM_CODEGEN_MACHINEINSTR_H -#include "Support/iterator" +#include "llvm/ADT/iterator" +#include "llvm/Support/DataTypes.h" #include #include @@ -28,44 +29,44 @@ class MachineBasicBlock; class TargetMachine; class GlobalValue; -template class ilist_traits; -template class ilist; +template struct ilist_traits; +template struct ilist; typedef short MachineOpCode; //===----------------------------------------------------------------------===// -// class MachineOperand -// +// class MachineOperand +// // Purpose: // 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 +// ptr = alloca type, numElements // we generate 2 machine instructions on the SPARC: -// -// mul Constant, Numelements -> Reg -// add %sp, Reg -> Ptr -// +// +// 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. -// +// - 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. -// +// +// - 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 { @@ -95,8 +96,8 @@ public: }; enum MachineOperandType { - MO_VirtualRegister, // virtual register for *value - MO_MachineRegister, // pre-assigned machine register `regNum' + MO_VirtualRegister, // virtual register for *value + MO_MachineRegister, // pre-assigned machine register `regNum' MO_CCRegister, MO_SignExtendedImmed, MO_UnextendedImmed, @@ -107,88 +108,104 @@ public: MO_ExternalSymbol, // Name of external global symbol 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. + // the generated machine code. // LLVM global for MO_GlobalAddress. - int immedVal; // Constant value for an explicit constant + int64_t immedVal; // Constant value for an explicit constant MachineBasicBlock *MBB; // For MO_MachineBasicBlock type - std::string *SymbolName; // For MO_ExternalSymbol type + const char *SymbolName; // For MO_ExternalSymbol type } contents; 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 + union { + int regNum; // register number for an explicit register // will be set for a value after reg allocation -private: - void zeroContents () { + + int offset; // Offset to address of global or external, only + // valid for MO_GlobalAddress and MO_ExternalSym + } extra; + + void zeroContents () { memset (&contents, 0, sizeof (contents)); + memset (&extra, 0, sizeof (extra)); } - MachineOperand(int ImmVal = 0, MachineOperandType OpTy = MO_VirtualRegister) - : flags(0), opType(OpTy), regNum(-1) { + MachineOperand(int64_t ImmVal = 0, + MachineOperandType OpTy = MO_VirtualRegister) + : flags(0), opType(OpTy) { zeroContents (); + contents.immedVal = ImmVal; + extra.regNum = -1; } MachineOperand(int Reg, MachineOperandType OpTy, UseType UseTy) - : flags(UseTy), opType(OpTy), regNum(Reg) { + : flags(UseTy), opType(OpTy) { zeroContents (); + extra.regNum = Reg; } MachineOperand(Value *V, MachineOperandType OpTy, UseType UseTy, - bool isPCRelative = false) - : flags(UseTy | (isPCRelative?PCRELATIVE:0)), opType(OpTy), regNum(-1) { - zeroContents (); + bool isPCRelative = false) + : flags(UseTy | (isPCRelative?PCRELATIVE:0)), opType(OpTy) { + assert(OpTy != MachineOperand::MO_GlobalAddress); + zeroContents(); contents.value = V; + extra.regNum = -1; + } + + MachineOperand(GlobalValue *V, MachineOperandType OpTy, UseType UseTy, + bool isPCRelative = false, int Offset = 0) + : flags(UseTy | (isPCRelative?PCRELATIVE:0)), opType(OpTy) { + assert(OpTy == MachineOperand::MO_GlobalAddress); + zeroContents (); + contents.value = (Value*)V; + extra.offset = Offset; } MachineOperand(MachineBasicBlock *mbb) - : flags(0), opType(MO_MachineBasicBlock), regNum(-1) { + : flags(0), opType(MO_MachineBasicBlock) { zeroContents (); contents.MBB = mbb; + extra.regNum = -1; } - MachineOperand(const std::string &SymName, bool isPCRelative) - : flags(isPCRelative?PCRELATIVE:0), opType(MO_ExternalSymbol), regNum(-1) { + MachineOperand(const char *SymName, bool isPCRelative, int Offset) + : flags(isPCRelative?PCRELATIVE:0), opType(MO_ExternalSymbol) { zeroContents (); - contents.SymbolName = new std::string (SymName); + contents.SymbolName = SymName; + extra.offset = Offset; } public: MachineOperand(const MachineOperand &M) - : flags(M.flags), opType(M.opType), regNum(M.regNum) { + : flags(M.flags), opType(M.opType) { zeroContents (); contents = M.contents; - if (isExternalSymbol()) - contents.SymbolName = new std::string(M.getSymbolName()); + extra = M.extra; } - ~MachineOperand() { - if (isExternalSymbol()) - delete contents.SymbolName; - } - + + ~MachineOperand() {} + const MachineOperand &operator=(const MachineOperand &MO) { - if (isExternalSymbol()) // if old operand had a symbol name, - delete contents.SymbolName; // release old memory contents = MO.contents; flags = MO.flags; opType = MO.opType; - regNum = MO.regNum; - if (isExternalSymbol()) - contents.SymbolName = new std::string(MO.getSymbolName()); + extra = MO.extra; return *this; } /// getType - Returns the MachineOperandType for this operand. - /// + /// MachineOperandType getType() const { return opType; } /// getUseType - Returns the MachineOperandUseType of this operand. @@ -228,7 +245,7 @@ public: /// has one. This is deprecated and only used by the SPARC v9 backend. /// Value* getVRegValueOrNull() const { - return (opType == MO_VirtualRegister || opType == MO_CCRegister || + return (opType == MO_VirtualRegister || opType == MO_CCRegister || isPCRelativeDisp()) ? contents.value : NULL; } @@ -242,9 +259,9 @@ public: } int getMachineRegNum() const { assert(opType == MO_MachineRegister && "Wrong MachineOperand accessor"); - return regNum; + return extra.regNum; } - int getImmedValue() const { + int64_t getImmedValue() const { assert(isImmediate() && "Wrong MachineOperand accessor"); return contents.immedVal; } @@ -252,21 +269,30 @@ public: 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 contents.immedVal; + return (int)contents.immedVal; } unsigned getConstantPoolIndex() const { assert(isConstantPoolIndex() && "Wrong MachineOperand accessor"); - return contents.immedVal; + return (unsigned)contents.immedVal; } GlobalValue *getGlobal() const { assert(isGlobalAddress() && "Wrong MachineOperand accessor"); return (GlobalValue*)contents.value; } - const std::string &getSymbolName() const { + int getOffset() const { + assert((isGlobalAddress() || isExternalSymbol()) && + "Wrong MachineOperand accessor"); + return extra.offset; + } + const char *getSymbolName() const { assert(isExternalSymbol() && "Wrong MachineOperand accessor"); - return *contents.SymbolName; + return contents.SymbolName; } /// MachineOperand methods for testing that work on any kind of @@ -285,8 +311,8 @@ public: /// allocated to this operand. /// bool hasAllocatedReg() const { - return (regNum >= 0 && - (opType == MO_VirtualRegister || opType == MO_CCRegister || + return (extra.regNum >= 0 && + (opType == MO_VirtualRegister || opType == MO_CCRegister || opType == MO_MachineRegister)); } @@ -295,7 +321,7 @@ public: /// unsigned getReg() const { assert(hasAllocatedReg()); - return regNum; + return extra.regNum; } /// MachineOperand mutators... @@ -304,52 +330,63 @@ public: // This method's comment used to say: 'TODO: get rid of this duplicate // code.' It's not clear where the duplication is. assert(hasAllocatedReg() && "This operand cannot have a register number!"); - regNum = Reg; - } + extra.regNum = Reg; + } + + void setValueReg(Value *val) { + assert(getVRegValueOrNull() != 0 && "Original operand must of type Value*"); + contents.value = val; + } + void setImmedValue(int immVal) { assert(isImmediate() && "Wrong MachineOperand mutator"); contents.immedVal = immVal; } + void setOffset(int Offset) { + assert((isGlobalAddress() || isExternalSymbol()) && + "Wrong MachineOperand accessor"); + extra.offset = Offset; + } + friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop); -private: - /// markHi32, markLo32, etc. - These methods must be accessed via - /// corresponding methods in MachineInstr. These methods are deprecated - /// and only used by the SPARC v9 back-end. + /// markHi32, markLo32, etc. - These methods are deprecated and only used by + /// the SPARC v9 back-end. /// void markHi32() { flags |= HIFLAG32; } void markLo32() { flags |= LOFLAG32; } void markHi64() { flags |= HIFLAG64; } void markLo64() { flags |= LOFLAG64; } - + +private: /// setRegForValue - Replaces the Value with its corresponding physical /// register after register allocation is complete. This is deprecated /// and only used by the SPARC v9 back-end. /// void setRegForValue(int reg) { - assert(opType == MO_VirtualRegister || opType == MO_CCRegister || - opType == MO_MachineRegister); - regNum = reg; + assert(opType == MO_VirtualRegister || opType == MO_CCRegister || + opType == MO_MachineRegister); + extra.regNum = reg; } - + friend class MachineInstr; }; //===----------------------------------------------------------------------===// -// class MachineInstr -// +// class MachineInstr +// // Purpose: // Representation of each machine instruction. -// +// // MachineOpCode must be an enum, defined separately for each target. // E.g., It is defined in SparcInstructionSelection.h for the SPARC. -// +// // There are 2 kinds of operands: -// -// (1) Explicit operands of the machine instruction in vector operands[] -// +// +// (1) Explicit operands of the machine instruction in vector operands[] +// // (2) "Implicit operands" are values implicitly used or defined by the // machine instruction, such as arguments to a CALL, return value of // a CALL (if any), and return value of a RETURN. @@ -365,12 +402,14 @@ class MachineInstr { // OperandComplete - Return true if it's illegal to add a new operand bool OperandsComplete() const; - MachineInstr(const MachineInstr &); // DO NOT IMPLEMENT + //Constructor used by clone() method + MachineInstr(const MachineInstr&); + void operator=(const MachineInstr&); // DO NOT IMPLEMENT // Intrusive list support // - friend class ilist_traits; + friend struct ilist_traits; public: MachineInstr(short Opcode, unsigned numOperands); @@ -387,7 +426,7 @@ public: /// block. /// MachineInstr(MachineBasicBlock *MBB, short Opcode, unsigned numOps); - + ~MachineInstr(); const MachineBasicBlock* getParent() const { return parent; } @@ -400,7 +439,7 @@ public: /// 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]; @@ -415,7 +454,7 @@ public: // 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) @@ -424,9 +463,9 @@ public: // // 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]; @@ -453,10 +492,14 @@ public: MachineOperand::MO_VirtualRegister, V); } + /// 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; + // // 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); @@ -564,6 +607,16 @@ public: MachineOperand(intValue, MachineOperand::MO_UnextendedImmed)); } + /// addZeroExtImm64Operand - Add a zero extended 64-bit constant argument + /// to the machine instruction. + /// + void addZeroExtImm64Operand(uint64_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. /// @@ -597,18 +650,18 @@ public: operands.push_back(MachineOperand(I, MachineOperand::MO_ConstantPoolIndex)); } - void addGlobalAddressOperand(GlobalValue *GV, bool isPCRelative) { + void addGlobalAddressOperand(GlobalValue *GV, bool isPCRelative, int Offset) { assert(!OperandsComplete() && "Trying to add an operand to a machine instr that is already done!"); operands.push_back( - MachineOperand((Value*)GV, MachineOperand::MO_GlobalAddress, - MachineOperand::Use, isPCRelative)); + MachineOperand(GV, MachineOperand::MO_GlobalAddress, + MachineOperand::Use, isPCRelative, 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, bool isPCRelative) { + operands.push_back(MachineOperand(SymName, isPCRelative, 0)); } //===--------------------------------------------------------------------===// @@ -619,7 +672,7 @@ public: /// 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(short Opcode, unsigned numOperands); /// setOpcode - Replace the opcode of the current instruction with a new one. @@ -634,7 +687,7 @@ public: } // Access to set the operands when building the machine instruction - // + // void SetMachineOperandVal(unsigned i, MachineOperand::MachineOperandType operandType, Value* V); @@ -650,27 +703,21 @@ public: 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 || @@ -678,14 +725,14 @@ public: && 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(); } @@ -695,16 +742,16 @@ public: 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 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 { + inline bool operator==(const _Self &y) const { return i == y.i; } - inline bool operator!=(const _Self &y) const { + inline bool operator!=(const _Self &y) const { return !operator==(y); }