X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FTarget%2FTargetInstrInfo.h;h=110976a0a825b674c2e2d7819a233e0ffbc0435d;hb=320efb05a1e7516268e711901ca9454bb4d94172;hp=b8c6c28a90121b8e7fee26524e7f5b2d65512f9b;hpb=12d4f9f4e40a61602b74777aa56cb21728286ad5;p=oota-llvm.git diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index b8c6c28a901..110976a0a82 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -14,11 +14,10 @@ #ifndef LLVM_TARGET_TARGETINSTRINFO_H #define LLVM_TARGET_TARGETINSTRINFO_H -#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/CodeGen/DFAPacketizer.h" -#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/CodeGen/MachineCombinerPattern.h" +#include "llvm/CodeGen/MachineFunction.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/Target/TargetRegisterInfo.h" @@ -31,7 +30,7 @@ class MachineMemOperand; class MachineRegisterInfo; class MDNode; class MCInst; -class MCSchedModel; +struct MCSchedModel; class MCSymbolRefExpr; class SDNode; class ScheduleHazardRecognizer; @@ -41,6 +40,7 @@ class TargetRegisterClass; class TargetRegisterInfo; class BranchProbability; class TargetSubtargetInfo; +class DFAPacketizer; template class SmallVectorImpl; @@ -50,8 +50,8 @@ template class SmallVectorImpl; /// TargetInstrInfo - Interface to description of machine instruction set /// class TargetInstrInfo : public MCInstrInfo { - TargetInstrInfo(const TargetInstrInfo &) LLVM_DELETED_FUNCTION; - void operator=(const TargetInstrInfo &) LLVM_DELETED_FUNCTION; + TargetInstrInfo(const TargetInstrInfo &) = delete; + void operator=(const TargetInstrInfo &) = delete; public: TargetInstrInfo(int CFSetupOpcode = -1, int CFDestroyOpcode = -1) : CallFrameSetupOpcode(CFSetupOpcode), @@ -109,6 +109,12 @@ public: int getCallFrameSetupOpcode() const { return CallFrameSetupOpcode; } int getCallFrameDestroyOpcode() const { return CallFrameDestroyOpcode; } + /// Returns the actual stack pointer adjustment made by an instruction + /// as part of a call sequence. By default, only call frame setup/destroy + /// instructions adjust the stack, but targets may want to override this + /// to enable more fine-grained adjustment, or adjust by a different value. + virtual int getSPAdjust(const MachineInstr *MI) const; + /// isCoalescableExtInstr - Return true if the instruction is a "coalescable" /// extension instruction. That is, it's like a copy where it's legal for the /// source to overlap the destination. e.g. X86::MOVSX64rr32. If this returns @@ -201,7 +207,7 @@ public: /// this, particularly to support spilled vector registers. virtual bool getStackSlotRange(const TargetRegisterClass *RC, unsigned SubIdx, unsigned &Size, unsigned &Offset, - const TargetMachine *TM) const; + const MachineFunction &MF) const; /// isAsCheapAsAMove - Return true if the instruction is as cheap as a move /// instruction. @@ -264,6 +270,85 @@ public: virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const; + /// A pair composed of a register and a sub-register index. + /// Used to give some type checking when modeling Reg:SubReg. + struct RegSubRegPair { + unsigned Reg; + unsigned SubReg; + RegSubRegPair(unsigned Reg = 0, unsigned SubReg = 0) + : Reg(Reg), SubReg(SubReg) {} + }; + /// A pair composed of a pair of a register and a sub-register index, + /// and another sub-register index. + /// Used to give some type checking when modeling Reg:SubReg1, SubReg2. + struct RegSubRegPairAndIdx : RegSubRegPair { + unsigned SubIdx; + RegSubRegPairAndIdx(unsigned Reg = 0, unsigned SubReg = 0, + unsigned SubIdx = 0) + : RegSubRegPair(Reg, SubReg), SubIdx(SubIdx) {} + }; + + /// Build the equivalent inputs of a REG_SEQUENCE for the given \p MI + /// and \p DefIdx. + /// \p [out] InputRegs of the equivalent REG_SEQUENCE. Each element of + /// the list is modeled as . + /// E.g., REG_SEQUENCE vreg1:sub1, sub0, vreg2, sub1 would produce + /// two elements: + /// - vreg1:sub1, sub0 + /// - vreg2<:0>, sub1 + /// + /// \returns true if it is possible to build such an input sequence + /// with the pair \p MI, \p DefIdx. False otherwise. + /// + /// \pre MI.isRegSequence() or MI.isRegSequenceLike(). + /// + /// \note The generic implementation does not provide any support for + /// MI.isRegSequenceLike(). In other words, one has to override + /// getRegSequenceLikeInputs for target specific instructions. + bool + getRegSequenceInputs(const MachineInstr &MI, unsigned DefIdx, + SmallVectorImpl &InputRegs) const; + + /// Build the equivalent inputs of a EXTRACT_SUBREG for the given \p MI + /// and \p DefIdx. + /// \p [out] InputReg of the equivalent EXTRACT_SUBREG. + /// E.g., EXTRACT_SUBREG vreg1:sub1, sub0, sub1 would produce: + /// - vreg1:sub1, sub0 + /// + /// \returns true if it is possible to build such an input sequence + /// with the pair \p MI, \p DefIdx. False otherwise. + /// + /// \pre MI.isExtractSubreg() or MI.isExtractSubregLike(). + /// + /// \note The generic implementation does not provide any support for + /// MI.isExtractSubregLike(). In other words, one has to override + /// getExtractSubregLikeInputs for target specific instructions. + bool + getExtractSubregInputs(const MachineInstr &MI, unsigned DefIdx, + RegSubRegPairAndIdx &InputReg) const; + + /// Build the equivalent inputs of a INSERT_SUBREG for the given \p MI + /// and \p DefIdx. + /// \p [out] BaseReg and \p [out] InsertedReg contain + /// the equivalent inputs of INSERT_SUBREG. + /// E.g., INSERT_SUBREG vreg0:sub0, vreg1:sub1, sub3 would produce: + /// - BaseReg: vreg0:sub0 + /// - InsertedReg: vreg1:sub1, sub3 + /// + /// \returns true if it is possible to build such an input sequence + /// with the pair \p MI, \p DefIdx. False otherwise. + /// + /// \pre MI.isInsertSubreg() or MI.isInsertSubregLike(). + /// + /// \note The generic implementation does not provide any support for + /// MI.isInsertSubregLike(). In other words, one has to override + /// getInsertSubregLikeInputs for target specific instructions. + bool + getInsertSubregInputs(const MachineInstr &MI, unsigned DefIdx, + RegSubRegPair &BaseReg, + RegSubRegPairAndIdx &InsertedReg) const; + + /// produceSameValue - Return true if two machine instructions would produce /// identical values. By default, this is only true when the two instructions /// are deemed identical except for defs. If this function is called when the @@ -349,6 +434,26 @@ public: llvm_unreachable("Target didn't implement TargetInstrInfo::getTrap!"); } + /// getJumpInstrTableEntryBound - Get a number of bytes that suffices to hold + /// either the instruction returned by getUnconditionalBranch or the + /// instruction returned by getTrap. This only makes sense because + /// getUnconditionalBranch returns a single, specific instruction. This + /// information is needed by the jumptable construction code, since it must + /// decide how many bytes to use for a jumptable entry so it can generate the + /// right mask. + /// + /// Note that if the jumptable instruction requires alignment, then that + /// alignment should be factored into this required bound so that the + /// resulting bound gives the right alignment for the instruction. + virtual unsigned getJumpInstrTableEntryBound() const { + // This method gets called by LLVMTargetMachine always, so it can't fail + // just because there happens to be no implementation for this target. + // Any code that tries to use a jumptable annotation without defining + // getUnconditionalBranch on the appropriate Target will fail anyway, and + // the value returned here won't matter in that case. + return 0; + } + /// isLegalToSplitMBBAt - Return true if it's legal to split the given basic /// block at the specified instruction (i.e. instruction would be the start /// of a new basic block). @@ -498,9 +603,12 @@ public: /// a side. /// /// @param MI Optimizable select instruction. + /// @param NewMIs Set that record all MIs in the basic block up to \p + /// MI. Has to be updated with any newly created MI or deleted ones. /// @param PreferFalse Try to optimize FalseOp instead of TrueOp. /// @returns Optimized instruction or NULL. virtual MachineInstr *optimizeSelect(MachineInstr *MI, + SmallPtrSetImpl &NewMIs, bool PreferFalse = false) const { // This function must be implemented if Optimizable is ever set. llvm_unreachable("Target must implement TargetInstrInfo::optimizeSelect!"); @@ -564,16 +672,15 @@ public: /// operand folded, otherwise NULL is returned. /// The new instruction is inserted before MI, and the client is responsible /// for removing the old instruction. - MachineInstr* foldMemoryOperand(MachineBasicBlock::iterator MI, - const SmallVectorImpl &Ops, - int FrameIndex) const; + MachineInstr *foldMemoryOperand(MachineBasicBlock::iterator MI, + ArrayRef 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. - MachineInstr* foldMemoryOperand(MachineBasicBlock::iterator MI, - const SmallVectorImpl &Ops, - MachineInstr* LoadMI) const; + MachineInstr *foldMemoryOperand(MachineBasicBlock::iterator MI, + ArrayRef Ops, + MachineInstr *LoadMI) const; /// hasPattern - return true when there is potentially a faster code sequence /// for an instruction chain ending in \p Root. All potential pattern are @@ -609,35 +716,77 @@ public: } /// useMachineCombiner - return true when a target supports MachineCombiner - virtual bool useMachineCombiner(void) const { return false; } + virtual bool useMachineCombiner() const { return false; } protected: /// foldMemoryOperandImpl - Target-dependent implementation for /// foldMemoryOperand. Target-independent code in foldMemoryOperand will /// take care of adding a MachineMemOperand to the newly created instruction. - virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, - MachineInstr* MI, - const SmallVectorImpl &Ops, - int FrameIndex) const { + virtual MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, + MachineInstr *MI, + ArrayRef Ops, + int FrameIndex) const { return nullptr; } /// foldMemoryOperandImpl - Target-dependent implementation for /// foldMemoryOperand. Target-independent code in foldMemoryOperand will /// take care of adding a MachineMemOperand to the newly created instruction. - virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, - MachineInstr* MI, - const SmallVectorImpl &Ops, - MachineInstr* LoadMI) const { + virtual MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, + MachineInstr *MI, + ArrayRef Ops, + MachineInstr *LoadMI) const { return nullptr; } + /// \brief Target-dependent implementation of getRegSequenceInputs. + /// + /// \returns true if it is possible to build the equivalent + /// REG_SEQUENCE inputs with the pair \p MI, \p DefIdx. False otherwise. + /// + /// \pre MI.isRegSequenceLike(). + /// + /// \see TargetInstrInfo::getRegSequenceInputs. + virtual bool getRegSequenceLikeInputs( + const MachineInstr &MI, unsigned DefIdx, + SmallVectorImpl &InputRegs) const { + return false; + } + + /// \brief Target-dependent implementation of getExtractSubregInputs. + /// + /// \returns true if it is possible to build the equivalent + /// EXTRACT_SUBREG inputs with the pair \p MI, \p DefIdx. False otherwise. + /// + /// \pre MI.isExtractSubregLike(). + /// + /// \see TargetInstrInfo::getExtractSubregInputs. + virtual bool getExtractSubregLikeInputs( + const MachineInstr &MI, unsigned DefIdx, + RegSubRegPairAndIdx &InputReg) const { + return false; + } + + /// \brief Target-dependent implementation of getInsertSubregInputs. + /// + /// \returns true if it is possible to build the equivalent + /// INSERT_SUBREG inputs with the pair \p MI, \p DefIdx. False otherwise. + /// + /// \pre MI.isInsertSubregLike(). + /// + /// \see TargetInstrInfo::getInsertSubregInputs. + virtual bool + getInsertSubregLikeInputs(const MachineInstr &MI, unsigned DefIdx, + RegSubRegPair &BaseReg, + RegSubRegPairAndIdx &InsertedReg) const { + return false; + } + public: /// canFoldMemoryOperand - Returns true for the specified load / store if /// folding is possible. - virtual - bool canFoldMemoryOperand(const MachineInstr *MI, - const SmallVectorImpl &Ops) const; + virtual bool canFoldMemoryOperand(const MachineInstr *MI, + ArrayRef Ops) 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 @@ -725,10 +874,8 @@ public: MachineBasicBlock::iterator MI) const; - /// getNoopForMachoTarget - Return the noop instruction to use for a noop. - virtual void getNoopForMachoTarget(MCInst &NopInst) const { - // Default to just using 'nop' string. - } + /// Return the noop instruction to use for a noop. + virtual void getNoopForMachoTarget(MCInst &NopInst) const; /// isPredicated - Returns true if the instruction is already predicated. @@ -832,6 +979,7 @@ public: const MachineRegisterInfo *MRI) const { return false; } + virtual bool optimizeCondBranch(MachineInstr *MI) const { return false; } /// optimizeLoadInstr - Try to remove the load by folding it to a register /// operand at the use. We fold the load instructions if and only if the @@ -910,7 +1058,7 @@ public: SDNode *Node) const; /// Return the default expected latency for a def based on it's opcode. - unsigned defaultDefLatency(const MCSchedModel *SchedModel, + unsigned defaultDefLatency(const MCSchedModel &SchedModel, const MachineInstr *DefMI) const; int computeDefOperandLatency(const InstrItineraryData *ItinData, @@ -1065,11 +1213,25 @@ public: const TargetRegisterInfo *TRI) const {} /// Create machine specific model for scheduling. - virtual DFAPacketizer* - CreateTargetScheduleState(const TargetMachine*, const ScheduleDAG*) const { + virtual DFAPacketizer * + CreateTargetScheduleState(const TargetSubtargetInfo &) const { return nullptr; } + // areMemAccessesTriviallyDisjoint - Sometimes, it is possible for the target + // to tell, even without aliasing information, that two MIs access different + // memory addresses. This function returns true if two MIs access different + // memory addresses, and false otherwise. + virtual bool + areMemAccessesTriviallyDisjoint(MachineInstr *MIa, MachineInstr *MIb, + AliasAnalysis *AA = nullptr) const { + assert(MIa && (MIa->mayLoad() || MIa->mayStore()) && + "MIa must load from or modify a memory location"); + assert(MIb && (MIb->mayLoad() || MIb->mayStore()) && + "MIb must load from or modify a memory location"); + return false; + } + private: int CallFrameSetupOpcode, CallFrameDestroyOpcode; };