X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FCodeGen%2FMachineInstr.h;h=44d716e7344f27d7647314402dd1e08b64cbf6ab;hb=3c7b3fecacee40df7b9a99d290638398b5a62173;hp=0a9ad1139986377e113ef32cc614daf40c60260d;hpb=a054ae02fda1886f36b4b51cba8ac8000ed8be8a;p=oota-llvm.git diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index 0a9ad113998..44d716e7344 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -16,17 +16,19 @@ #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/Target/TargetInstrDesc.h" #include "llvm/Target/TargetOpcodes.h" +#include "llvm/ADT/ilist.h" +#include "llvm/ADT/ilist_node.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/DenseMapInfo.h" #include "llvm/Support/DebugLoc.h" #include namespace llvm { +template class SmallVectorImpl; class AliasAnalysis; class TargetInstrDesc; class TargetInstrInfo; @@ -90,15 +92,14 @@ private: // 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. The version with a DebugLoc should be preferred. + /// MachineInstr ctor - This constructor creates a MachineInstr and adds the + /// implicit operands. It reserves space for the number of operands specified + /// by the 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. The version with a DebugLoc should be preferred. - /// MachineInstr(MachineBasicBlock *MBB, const TargetInstrDesc &TID); /// MachineInstr ctor - This constructor create a MachineInstr and add the @@ -110,7 +111,6 @@ private: /// 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); @@ -224,14 +224,33 @@ public: bool isSubregToReg() const { return getOpcode() == TargetOpcode::SUBREG_TO_REG; } + bool isRegSequence() const { + return getOpcode() == TargetOpcode::REG_SEQUENCE; + } /// readsRegister - Return true if the MachineInstr reads the specified /// register. If TargetRegisterInfo is passed, then it also checks if there /// is a read of a super-register. + /// This does not count partial redefines of virtual registers as reads: + /// %reg1024:6 = OP. bool readsRegister(unsigned Reg, const TargetRegisterInfo *TRI = NULL) const { return findRegisterUseOperandIdx(Reg, false, TRI) != -1; } + /// readsVirtualRegister - Return true if the MachineInstr reads the specified + /// virtual register. Take into account that a partial define is a + /// read-modify-write operation. + bool readsVirtualRegister(unsigned Reg) const { + return readsWritesVirtualRegister(Reg).first; + } + + /// readsWritesVirtualRegister - Return a pair of bools (reads, writes) + /// indicating if this instruction reads or writes Reg. This also considers + /// partial defines. + /// If Ops is not null, all operand indices for Reg are added. + std::pair readsWritesVirtualRegister(unsigned Reg, + SmallVectorImpl *Ops = 0) const; + /// killsRegister - Return true if the MachineInstr kills the specified /// register. If TargetRegisterInfo is passed, then it also checks if there is /// a kill of a super-register. @@ -239,12 +258,19 @@ public: return findRegisterUseOperandIdx(Reg, true, TRI) != -1; } - /// modifiesRegister - Return true if the MachineInstr modifies the + /// definesRegister - Return true if the MachineInstr fully defines the /// specified register. If TargetRegisterInfo is passed, then it also checks /// if there is a def of a super-register. - bool modifiesRegister(unsigned Reg, - const TargetRegisterInfo *TRI = NULL) const { - return findRegisterDefOperandIdx(Reg, false, TRI) != -1; + /// NOTE: It's ignoring subreg indices on virtual registers. + bool definesRegister(unsigned Reg, const TargetRegisterInfo *TRI=NULL) const { + return findRegisterDefOperandIdx(Reg, false, false, TRI) != -1; + } + + /// modifiesRegister - Return true if the MachineInstr modifies (fully define + /// or partially define) the specified register. + /// NOTE: It's ignoring subreg indices on virtual registers. + bool modifiesRegister(unsigned Reg, const TargetRegisterInfo *TRI) const { + return findRegisterDefOperandIdx(Reg, false, true, TRI) != -1; } /// registerDefIsDead - Returns true if the register is dead in this machine @@ -252,7 +278,7 @@ public: /// if there is a dead def of a super-register. bool registerDefIsDead(unsigned Reg, const TargetRegisterInfo *TRI = NULL) const { - return findRegisterDefOperandIdx(Reg, true, TRI) != -1; + return findRegisterDefOperandIdx(Reg, true, false, TRI) != -1; } /// findRegisterUseOperandIdx() - Returns the operand index that is a use of @@ -271,16 +297,18 @@ public: /// findRegisterDefOperandIdx() - Returns the operand index that is a def of /// 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, + /// that are not dead are skipped. If Overlap is true, then it also looks for + /// defs that merely overlap the specified register. 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, bool Overlap = 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, const TargetRegisterInfo *TRI = NULL) { - int Idx = findRegisterDefOperandIdx(Reg, isDead, TRI); + int Idx = findRegisterDefOperandIdx(Reg, isDead, false, TRI); return (Idx == -1) ? NULL : &getOperand(Idx); } @@ -300,6 +328,10 @@ public: /// reference if DefOpIdx is not null. bool isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx = 0) const; + /// clearKillInfo - Clears kill flags on all operands. + /// + void clearKillInfo(); + /// copyKillDeadInfo - Copies kill / dead operand properties from MI. /// void copyKillDeadInfo(const MachineInstr *MI); @@ -307,6 +339,11 @@ public: /// copyPredicates - Copies predicate operand(s) from MI. void copyPredicates(const MachineInstr *MI); + /// substituteRegister - Replace all occurrences of FromReg with ToReg:SubIdx, + /// properly composing subreg indices where necessary. + void substituteRegister(unsigned FromReg, unsigned ToReg, unsigned SubIdx, + const TargetRegisterInfo &RegInfo); + /// addRegisterKilled - We have determined MI kills a register. Look for the /// operand that uses it and mark it as IsKill. If AddIfNotFound is true, /// add a implicit operand if it's not found. Returns true if the operand @@ -325,7 +362,12 @@ public: /// addRegisterDefined - We have determined MI defines a register. Make sure /// there is an operand defining Reg. void addRegisterDefined(unsigned IncomingReg, - const TargetRegisterInfo *RegInfo); + const TargetRegisterInfo *RegInfo = 0); + + /// setPhysRegsDeadExcept - Mark every physreg used by this instruction as dead + /// except those in the UsedRegs list. + void setPhysRegsDeadExcept(const SmallVectorImpl &UsedRegs, + const TargetRegisterInfo &TRI); /// 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 @@ -356,6 +398,10 @@ public: /// return 0. unsigned isConstantValuePHI() const; + /// allDefsAreDead - Return true if all the defs of this instruction are dead. + /// + bool allDefsAreDead() const; + // // Debugging support // @@ -419,8 +465,11 @@ private: void AddRegOperandsToUseLists(MachineRegisterInfo &RegInfo); }; -/// DenseMapInfo for MachineInstr*. -template<> struct DenseMapInfo { +/// MachineInstrExpressionTrait - Special DenseMapInfo traits to compare +/// MachineInstr* by *value* of the instruction rather than by pointer value. +/// The hashing and equality testing functions ignore definitions so this is +/// useful for CSE, etc. +struct MachineInstrExpressionTrait : DenseMapInfo { static inline MachineInstr *getEmptyKey() { return 0; } @@ -429,48 +478,7 @@ template<> struct DenseMapInfo { return reinterpret_cast(-1); } - static unsigned getHashValue(const MachineInstr* const &MI) { - unsigned Hash = MI->getOpcode() * 37; - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - const MachineOperand &MO = MI->getOperand(i); - uint64_t Key = (uint64_t)MO.getType() << 32; - switch (MO.getType()) { - default: break; - case MachineOperand::MO_Register: - if (MO.isDef()) - continue; // Skip defs. - Key |= MO.getReg(); - break; - case MachineOperand::MO_Immediate: - Key |= MO.getImm(); - break; - case MachineOperand::MO_FrameIndex: - case MachineOperand::MO_ConstantPoolIndex: - case MachineOperand::MO_JumpTableIndex: - Key |= MO.getIndex(); - break; - case MachineOperand::MO_MachineBasicBlock: - Key |= DenseMapInfo::getHashValue(MO.getMBB()); - break; - case MachineOperand::MO_GlobalAddress: - Key |= DenseMapInfo::getHashValue(MO.getGlobal()); - break; - case MachineOperand::MO_BlockAddress: - Key |= DenseMapInfo::getHashValue(MO.getBlockAddress()); - break; - } - Key += ~(Key << 32); - Key ^= (Key >> 22); - Key += ~(Key << 13); - Key ^= (Key >> 8); - Key += (Key << 3); - Key ^= (Key >> 15); - Key += ~(Key << 27); - Key ^= (Key >> 31); - Hash = (unsigned)Key + Hash * 37; - } - return Hash; - } + static unsigned getHashValue(const MachineInstr* const &MI); static bool isEqual(const MachineInstr* const &LHS, const MachineInstr* const &RHS) {