X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FX86%2FX86InstrInfo.h;h=b49fb31c16a678faf835b9935654507ea11d9301;hb=c9f5f3f64f896d0a8c8fa35a1dd98bc57b8960f6;hp=589edac25cc4e5ad6060f5abc91b00b9df158f2b;hpb=6259d51c91d7da9bf16114849236b5bdfa85f35e;p=oota-llvm.git diff --git a/lib/Target/X86/X86InstrInfo.h b/lib/Target/X86/X86InstrInfo.h index 589edac25cc..b49fb31c16a 100644 --- a/lib/Target/X86/X86InstrInfo.h +++ b/lib/Target/X86/X86InstrInfo.h @@ -15,9 +15,10 @@ #define X86INSTRUCTIONINFO_H #include "llvm/Target/TargetInstrInfo.h" +#include "X86.h" #include "X86RegisterInfo.h" #include "llvm/ADT/IndexedMap.h" -#include "llvm/Target/MRegisterInfo.h" +#include "llvm/Target/TargetRegisterInfo.h" namespace llvm { class X86RegisterInfo; @@ -45,7 +46,7 @@ namespace X86 { COND_S = 15, COND_INVALID }; - + // Turn condition code into conditional branch opcode. unsigned GetCondBranchFromCond(CondCode CC); @@ -216,30 +217,40 @@ namespace X86II { // SpecialFP - Special instruction forms. Dispatch by opcode explicitly. SpecialFP = 7 << FPTypeShift, - // Bits 19 -> 23 are unused + // Lock prefix + LOCKShift = 19, + LOCK = 1 << LOCKShift, + + // Bits 20 -> 23 are unused OpcodeShift = 24, OpcodeMask = 0xFF << OpcodeShift }; } -class X86InstrInfo : public TargetInstrInfo { +class X86InstrInfo : public TargetInstrInfoImpl { X86TargetMachine &TM; const X86RegisterInfo RI; - mutable IndexedMap MachineInstrMap; - - /// isDefinedInEntryBlock - Goes through the entry block to see if the given - /// virtual register is indeed defined in the entry block. - /// - bool isDefinedInEntryBlock(const MachineBasicBlock &Entry, - unsigned VReg) const; + + /// RegOp2MemOpTable2Addr, RegOp2MemOpTable0, RegOp2MemOpTable1, + /// RegOp2MemOpTable2 - Load / store folding opcode maps. + /// + DenseMap RegOp2MemOpTable2Addr; + DenseMap RegOp2MemOpTable0; + DenseMap RegOp2MemOpTable1; + DenseMap RegOp2MemOpTable2; + + /// MemOp2RegOpTable - Load / store unfolding opcode map. + /// + DenseMap > MemOp2RegOpTable; + public: - X86InstrInfo(X86TargetMachine &tm); + explicit X86InstrInfo(X86TargetMachine &tm); /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As /// such, whenever a client has an instance of instruction info, it should /// always be able to get register info as well (through this method). /// - virtual const MRegisterInfo &getRegisterInfo() const { return RI; } + virtual const X86RegisterInfo &getRegisterInfo() const { return RI; } // Return true if the instruction is a register to register move and // leave the source and dest operands in the passed parameters. @@ -248,8 +259,12 @@ public: unsigned& destReg) const; unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const; unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const; - bool isReallyTriviallyReMaterializable(MachineInstr *MI) const; - bool isReallySideEffectFree(MachineInstr *MI) const; + + bool isReallyTriviallyReMaterializable(const MachineInstr *MI) const; + void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, + unsigned DestReg, const MachineInstr *Orig) const; + + bool isInvariantLoad(MachineInstr *MI) const; /// convertToThreeAddress - This method must be implemented by targets that /// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target @@ -279,6 +294,79 @@ public: virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, const std::vector &Cond) const; + virtual void copyRegToReg(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + unsigned DestReg, unsigned SrcReg, + const TargetRegisterClass *DestRC, + const TargetRegisterClass *SrcRC) const; + virtual void storeRegToStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + unsigned SrcReg, bool isKill, int FrameIndex, + const TargetRegisterClass *RC) const; + + virtual void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill, + SmallVectorImpl &Addr, + const TargetRegisterClass *RC, + SmallVectorImpl &NewMIs) const; + + virtual void loadRegFromStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + unsigned DestReg, int FrameIndex, + const TargetRegisterClass *RC) const; + + virtual void loadRegFromAddr(MachineFunction &MF, unsigned DestReg, + SmallVectorImpl &Addr, + const TargetRegisterClass *RC, + SmallVectorImpl &NewMIs) const; + + virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + const std::vector &CSI) const; + + virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + const std::vector &CSI) const; + + /// foldMemoryOperand - If this target supports it, fold a load or store of + /// the specified stack slot into the specified machine instruction for the + /// specified operand(s). If this is possible, the target should perform the + /// folding and return true, otherwise it should return false. If it folds + /// the instruction, it is likely that the MachineInstruction the iterator + /// references has been changed. + virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, + MachineInstr* MI, + SmallVectorImpl &Ops, + int FrameIndex) const; + + /// foldMemoryOperand - Same as the previous version except it allows folding + /// of any load and store from / to any address, not just from a specific + /// stack slot. + virtual MachineInstr* foldMemoryOperand(MachineFunction &MF, + MachineInstr* MI, + SmallVectorImpl &Ops, + MachineInstr* LoadMI) const; + + /// canFoldMemoryOperand - Returns true if the specified load / store is + /// folding is possible. + virtual bool canFoldMemoryOperand(MachineInstr*, SmallVectorImpl &) const; + + /// unfoldMemoryOperand - Separate a single instruction which folded a load or + /// a store or a load and a store into two or more instruction. If this is + /// possible, returns true as well as the new instructions by reference. + virtual bool unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI, + unsigned Reg, bool UnfoldLoad, bool UnfoldStore, + SmallVectorImpl &NewMIs) const; + + virtual bool unfoldMemoryOperand(SelectionDAG &DAG, SDNode *N, + SmallVectorImpl &NewNodes) const; + + /// getOpcodeAfterMemoryUnfold - Returns the opcode of the would be new + /// instruction after load / store are unfolded from an instruction of the + /// specified opcode. It returns zero if the specified unfolding is not + /// possible. + virtual unsigned getOpcodeAfterMemoryUnfold(unsigned Opc, + bool UnfoldLoad, bool UnfoldStore) const; + virtual bool BlockHasNoFallThrough(MachineBasicBlock &MBB) const; virtual bool ReverseBranchCondition(std::vector &Cond) const; @@ -287,12 +375,31 @@ public: // getBaseOpcodeFor - This function returns the "base" X86 opcode for the // specified machine instruction. // - unsigned char getBaseOpcodeFor(const TargetInstrDescriptor *TID) const { + unsigned char getBaseOpcodeFor(const TargetInstrDesc *TID) const { return TID->TSFlags >> X86II::OpcodeShift; } - unsigned char getBaseOpcodeFor(MachineOpCode Opcode) const { + unsigned char getBaseOpcodeFor(unsigned Opcode) const { return getBaseOpcodeFor(&get(Opcode)); } + + static bool isX86_64NonExtLowByteReg(unsigned reg) { + return (reg == X86::SPL || reg == X86::BPL || + reg == X86::SIL || reg == X86::DIL); + } + + static unsigned sizeOfImm(const TargetInstrDesc *Desc); + static unsigned getX86RegNum(unsigned RegNo); + static bool isX86_64ExtendedReg(const MachineOperand &MO); + static unsigned determineREX(const MachineInstr &MI); + + /// GetInstSize - Returns the size of the specified MachineInstr. + /// + virtual unsigned GetInstSizeInBytes(const MachineInstr *MI) const; + +private: + MachineInstr* foldMemoryOperand(MachineInstr* MI, + unsigned OpNum, + SmallVector &MOs) const; }; } // End llvm namespace