X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FCodeGen%2FMachineInstr.h;h=2b2f24a88371ea293bafa1a52d2f40defa52115a;hb=87d33f69194f5fb39080b048b41f51df595c72c9;hp=ff64e7e2e693aceb1d996cad5236511823d6a10a;hpb=34cd4a484e532cc463fd5a4bf59b88d13c5467c1;p=oota-llvm.git diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index ff64e7e2e69..2b2f24a8837 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -16,61 +16,95 @@ #ifndef LLVM_CODEGEN_MACHINEINSTR_H #define LLVM_CODEGEN_MACHINEINSTR_H +#include "llvm/ADT/ilist.h" +#include "llvm/ADT/ilist_node.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/MachineMemOperand.h" +#include "llvm/Target/TargetInstrDesc.h" +#include "llvm/Support/DebugLoc.h" +#include +#include namespace llvm { class TargetInstrDesc; class TargetInstrInfo; class TargetRegisterInfo; - -template struct ilist_traits; -template struct ilist; +class MachineFunction; //===----------------------------------------------------------------------===// /// MachineInstr - Representation of each machine instruction. /// -class MachineInstr { +class MachineInstr : public ilist_node { const TargetInstrDesc *TID; // Instruction descriptor. unsigned short NumImplicitOps; // Number of implicit operands (which // are determined at construction time). std::vector Operands; // the operands - std::vector MemOperands;// information on memory references - MachineInstr *Prev, *Next; // Links for MBB's intrusive list. + std::list MemOperands; // information on memory references MachineBasicBlock *Parent; // Pointer to the owning basic block. + DebugLoc debugLoc; // Source line information. // OperandComplete - Return true if it's illegal to add a new operand bool OperandsComplete() const; - MachineInstr(const MachineInstr&); + MachineInstr(const MachineInstr&); // DO NOT IMPLEMENT void operator=(const MachineInstr&); // DO NOT IMPLEMENT // Intrusive list support friend struct ilist_traits; friend struct ilist_traits; void setParent(MachineBasicBlock *P) { Parent = P; } -public: + + /// MachineInstr ctor - This constructor creates a copy of the given + /// MachineInstr in the given MachineFunction. + MachineInstr(MachineFunction &, const MachineInstr &); + /// MachineInstr ctor - This constructor creates a dummy MachineInstr with /// TID NULL and no operands. MachineInstr(); + // The next two constructors have DebugLoc and non-DebugLoc versions; + // over time, the non-DebugLoc versions should be phased out and eventually + // removed. + /// MachineInstr ctor - This constructor create a MachineInstr and add the /// implicit operands. It reserves space for number of operands specified by - /// TargetInstrDesc. + /// TargetInstrDesc. The version with a DebugLoc should be preferred. explicit MachineInstr(const TargetInstrDesc &TID, bool NoImp = false); /// 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. + /// block. The version with a DebugLoc should be preferred. /// MachineInstr(MachineBasicBlock *MBB, const TargetInstrDesc &TID); + /// MachineInstr ctor - This constructor create a MachineInstr and add the + /// implicit operands. It reserves space for number of operands specified by + /// TargetInstrDesc. An explicit DebugLoc is supplied. + explicit MachineInstr(const TargetInstrDesc &TID, const DebugLoc dl, + bool NoImp = false); + + /// 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, const DebugLoc dl, + const TargetInstrDesc &TID); + ~MachineInstr(); + // MachineInstrs are pool-allocated and owned by MachineFunction. + friend class MachineFunction; + +public: const MachineBasicBlock* getParent() const { return Parent; } MachineBasicBlock* getParent() { return Parent; } + + /// getDebugLoc - Returns the debug location id of this MachineInstr. + /// + DebugLoc getDebugLoc() const { return debugLoc; } /// getDesc - Returns the target instruction descriptor of this /// MachineInstr. @@ -78,7 +112,7 @@ public: /// getOpcode - Returns the opcode of this MachineInstr. /// - int getOpcode() const; + int getOpcode() const { return TID->Opcode; } /// Access to explicit operands of the instruction. /// @@ -98,15 +132,21 @@ public: unsigned getNumExplicitOperands() const; /// Access to memory operands of the instruction - unsigned getNumMemOperands() const { return (unsigned)MemOperands.size(); } - - const MachineMemOperand& getMemOperand(unsigned i) const { - assert(i < getNumMemOperands() && "getMemOperand() out of range!"); - return MemOperands[i]; - } - MachineMemOperand& getMemOperand(unsigned i) { - assert(i < getNumMemOperands() && "getMemOperand() out of range!"); - return MemOperands[i]; + std::list::iterator memoperands_begin() + { return MemOperands.begin(); } + std::list::iterator memoperands_end() + { return MemOperands.end(); } + std::list::const_iterator memoperands_begin() const + { return MemOperands.begin(); } + std::list::const_iterator memoperands_end() const + { return MemOperands.end(); } + bool memoperands_empty() const { return MemOperands.empty(); } + + /// hasOneMemOperand - Return true if this instruction has exactly one + /// MachineMemOperand. + bool hasOneMemOperand() const { + return !memoperands_empty() && + next(memoperands_begin()) == memoperands_end(); } /// isIdenticalTo - Return true if this instruction is identical to (same @@ -121,19 +161,17 @@ public: 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(); - } + void eraseFromParent(); + + /// isLabel - Returns true if the MachineInstr represents a label. + /// + bool isLabel() const; /// isDebugLabel - Returns true if the MachineInstr represents a debug label. /// @@ -184,16 +222,15 @@ public: } /// findRegisterDefOperandIdx() - Returns the operand index that is a def of - /// the specific register or -1 if it is not found. It further tightening - /// the search criteria to a def that is dead the register if isDead is true. - /// If TargetRegisterInfo is passed, then it also checks if there is a def of - /// a super-register. + /// the specified register or -1 if it is not found. If isDead is true, defs + /// that are not dead are skipped. If TargetRegisterInfo is non-null, then it + /// also checks if there is a def of a super-register. int findRegisterDefOperandIdx(unsigned Reg, bool isDead = false, const TargetRegisterInfo *TRI = NULL) const; /// findRegisterDefOperand - Wrapper for findRegisterDefOperandIdx, it returns /// a pointer to the MachineOperand rather than an index. - MachineOperand *findRegisterDefOperand(unsigned Reg,bool isDead = false, + MachineOperand *findRegisterDefOperand(unsigned Reg, bool isDead = false, const TargetRegisterInfo *TRI = NULL) { int Idx = findRegisterDefOperandIdx(Reg, isDead, TRI); return (Idx == -1) ? NULL : &getOperand(Idx); @@ -204,9 +241,16 @@ public: /// none is found. int findFirstPredOperandIdx() const; - /// isRegReDefinedByTwoAddr - Returns true if the Reg re-definition is due - /// to two addr elimination. - bool isRegReDefinedByTwoAddr(unsigned Reg) const; + /// isRegTiedToUseOperand - Given the index of a register def operand, + /// check if the register def is tied to a source operand, due to either + /// two-address elimination or inline assembly constraints. Returns the + /// first tied use operand index by reference is UseOpIdx is not null. + bool isRegTiedToUseOperand(unsigned DefOpIdx, unsigned *UseOpIdx = 0) const; + + /// isRegTiedToDefOperand - Return true if the use operand of the specified + /// index is tied to an def operand. It also returns the def operand index by + /// reference if DefOpIdx is not null. + bool isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx = 0) const; /// copyKillDeadInfo - Copies kill / dead operand properties from MI. /// @@ -230,14 +274,20 @@ public: bool addRegisterDead(unsigned IncomingReg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound = false); - /// copyKillDeadInfo - Copies killed/dead information from one instr to another - void copyKillDeadInfo(MachineInstr *OldMI, - const TargetRegisterInfo *RegInfo); + /// isSafeToMove - Return true if it is safe to move this instruction. If + /// SawStore is set to true, it means that there is a store (or call) between + /// the instruction's location and its intended destination. + bool isSafeToMove(const TargetInstrInfo *TII, bool &SawStore) const; - /// isSafeToMove - Return true if it is safe to this instruction. If SawStore - /// true, it means there is a store (or call) between the instruction the - /// localtion and its intended destination. - bool isSafeToMove(const TargetInstrInfo *TII, bool &SawStore); + /// isSafeToReMat - Return true if it's safe to rematerialize the specified + /// instruction which defined the specified register instead of copying it. + bool isSafeToReMat(const TargetInstrInfo *TII, unsigned DstReg) const; + + /// hasVolatileMemoryRef - Return true if this instruction may have a + /// volatile memory reference, or if the information describing the + /// memory reference is not available. Return false if it is known to + /// have no volatile memory references. + bool hasVolatileMemoryRef() const; // // Debugging support @@ -247,6 +297,11 @@ public: } void print(std::ostream &OS, const TargetMachine *TM = 0) const; void print(std::ostream *OS) const { if (OS) print(*OS); } + void print(raw_ostream *OS, const TargetMachine *TM) const { + if (OS) print(*OS, TM); + } + void print(raw_ostream &OS, const TargetMachine *TM = 0) const; + void print(raw_ostream *OS) const { if (OS) print(*OS); } void dump() const; //===--------------------------------------------------------------------===// @@ -263,6 +318,11 @@ public: /// void setDesc(const TargetInstrDesc &tid) { TID = &tid; } + /// setDebugLoc - Replace current source information with new such. + /// Avoid using this, the constructor argument is preferable. + /// + void setDebugLoc(const DebugLoc dl) { debugLoc = dl; } + /// RemoveOperand - Erase an operand from an instruction, leaving it with one /// fewer operand than it started with. /// @@ -270,9 +330,11 @@ public: /// addMemOperand - Add a MachineMemOperand to the machine instruction, /// referencing arbitrary storage. - void addMemOperand(const MachineMemOperand &MO) { - MemOperands.push_back(MO); - } + void addMemOperand(MachineFunction &MF, + const MachineMemOperand &MO); + + /// clearMemOperands - Erase all of this MachineInstr's MachineMemOperands. + void clearMemOperands(MachineFunction &MF); private: /// getRegInfo - If this instruction is embedded into a MachineFunction, @@ -303,6 +365,11 @@ inline std::ostream& operator<<(std::ostream &OS, const MachineInstr &MI) { return OS; } +inline raw_ostream& operator<<(raw_ostream &OS, const MachineInstr &MI) { + MI.print(OS); + return OS; +} + } // End llvm namespace #endif