X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FTarget%2FTargetInstrInfo.h;h=c6b89878bdc0d8d031ac2ce7eb5dbd391a611acc;hb=98a366d547772010e94609e4584489b3e5ce0043;hp=8fa73a78d9b3c2ea0be4f2d590229262612223dd;hpb=d45eddd214061bf12ad1e6b86497a41725e61d75;p=oota-llvm.git diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index 8fa73a78d9b..c6b89878bdc 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -2,178 +2,87 @@ // // 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 is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // -// This file describes the target machine instructions to the code generator. +// This file describes the target machine instruction set to the code generator. // //===----------------------------------------------------------------------===// #ifndef LLVM_TARGET_TARGETINSTRINFO_H #define LLVM_TARGET_TARGETINSTRINFO_H -#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/Target/TargetInstrDesc.h" #include "llvm/CodeGen/MachineFunction.h" -#include "llvm/Support/DataTypes.h" -#include -#include namespace llvm { -class MachineInstr; -class TargetMachine; -class MachineCodeForInstruction; class TargetRegisterClass; class LiveVariables; +class CalleeSavedInfo; +class SDNode; +class SelectionDAG; -//--------------------------------------------------------------------------- -// Data types used to define information about a single machine instruction -//--------------------------------------------------------------------------- - -typedef short MachineOpCode; -typedef unsigned InstrSchedClass; - -//--------------------------------------------------------------------------- -// struct TargetInstrDescriptor: -// Predefined information about each machine instruction. -// Designed to initialized statically. -// - -const unsigned M_BRANCH_FLAG = 1 << 0; -const unsigned M_CALL_FLAG = 1 << 1; -const unsigned M_RET_FLAG = 1 << 2; -const unsigned M_BARRIER_FLAG = 1 << 3; -const unsigned M_DELAY_SLOT_FLAG = 1 << 4; -const unsigned M_LOAD_FLAG = 1 << 5; -const unsigned M_STORE_FLAG = 1 << 6; - -// M_CONVERTIBLE_TO_3_ADDR - This is a 2-address instruction which can be -// changed into a 3-address instruction if the first two operands cannot be -// assigned to the same register. The target must implement the -// TargetInstrInfo::convertToThreeAddress method for this instruction. -const unsigned M_CONVERTIBLE_TO_3_ADDR = 1 << 7; - -// This M_COMMUTABLE - is a 2- or 3-address instruction (of the form X = op Y, -// Z), which produces the same result if Y and Z are exchanged. -const unsigned M_COMMUTABLE = 1 << 8; - -// M_TERMINATOR_FLAG - Is this instruction part of the terminator for a basic -// block? Typically this is things like return and branch instructions. -// Various passes use this to insert code into the bottom of a basic block, but -// before control flow occurs. -const unsigned M_TERMINATOR_FLAG = 1 << 9; - -// M_USES_CUSTOM_DAG_SCHED_INSERTION - Set if this instruction requires custom -// insertion support when the DAG scheduler is inserting it into a machine basic -// block. -const unsigned M_USES_CUSTOM_DAG_SCHED_INSERTION = 1 << 10; - -// M_VARIABLE_OPS - Set if this instruction can have a variable number of extra -// operands in addition to the minimum number operands specified. -const unsigned M_VARIABLE_OPS = 1 << 11; - -// M_PREDICABLE - Set if this instruction has a predicate operand that -// controls execution. It may be set to 'always'. -const unsigned M_PREDICABLE = 1 << 12; - -// M_REMATERIALIZIBLE - Set if this instruction can be trivally re-materialized -// at any time, e.g. constant generation, load from constant pool. -const unsigned M_REMATERIALIZIBLE = 1 << 13; - -// M_CLOBBERS_PRED - Set if this instruction may clobbers the condition code -// register and / or registers that are used to predicate instructions. -const unsigned M_CLOBBERS_PRED = 1 << 14; - -// M_NOT_DUPLICABLE - Set if this instruction cannot be safely duplicated. -// (e.g. instructions with unique labels attached). -const unsigned M_NOT_DUPLICABLE = 1 << 15; - -// Machine operand flags -// M_LOOK_UP_PTR_REG_CLASS - Set if this operand is a pointer value and it -// requires a callback to look up its register class. -const unsigned M_LOOK_UP_PTR_REG_CLASS = 1 << 0; - -/// M_PREDICATE_OPERAND - Set if this is one of the operands that made up of the -/// predicate operand that controls an M_PREDICATED instruction. -const unsigned M_PREDICATE_OPERAND = 1 << 1; - -namespace TOI { - // Operand constraints: only "tied_to" for now. - enum OperandConstraint { - TIED_TO = 0 // Must be allocated the same register as. - }; -} - -/// TargetOperandInfo - This holds information about one operand of a machine -/// instruction, indicating the register class for register operands, etc. -/// -class TargetOperandInfo { -public: - /// RegClass - This specifies the register class enumeration of the operand - /// if the operand is a register. If not, this contains 0. - unsigned short RegClass; - unsigned short Flags; - /// Lower 16 bits are used to specify which constraints are set. The higher 16 - /// bits are used to specify the value of constraints (4 bits each). - unsigned int Constraints; - /// Currently no other information. -}; - - -class TargetInstrDescriptor { -public: - MachineOpCode Opcode; // The opcode. - unsigned short numOperands; // Num of args (may be more if variable_ops). - const char * Name; // Assembly language mnemonic for the opcode. - InstrSchedClass schedClass; // enum identifying instr sched class - unsigned Flags; // flags identifying machine instr class - unsigned TSFlags; // Target Specific Flag values - const unsigned *ImplicitUses; // Registers implicitly read by this instr - const unsigned *ImplicitDefs; // Registers implicitly defined by this instr - const TargetOperandInfo *OpInfo; // 'numOperands' entries about operands. - - /// getOperandConstraint - Returns the value of the specific constraint if - /// it is set. Returns -1 if it is not set. - int getOperandConstraint(unsigned OpNum, - TOI::OperandConstraint Constraint) const { - assert((OpNum < numOperands || (Flags & M_VARIABLE_OPS)) && - "Invalid operand # of TargetInstrInfo"); - if (OpNum < numOperands && - (OpInfo[OpNum].Constraints & (1 << Constraint))) { - unsigned Pos = 16 + Constraint * 4; - return (int)(OpInfo[OpNum].Constraints >> Pos) & 0xf; - } - return -1; - } - - /// findTiedToSrcOperand - Returns the operand that is tied to the specified - /// dest operand. Returns -1 if there isn't one. - int findTiedToSrcOperand(unsigned OpNum) const; -}; +template class SmallVectorImpl; //--------------------------------------------------------------------------- /// -/// TargetInstrInfo - Interface to description of machine instructions +/// TargetInstrInfo - Interface to description of machine instruction set /// class TargetInstrInfo { - const TargetInstrDescriptor* desc; // raw array to allow static init'n - unsigned NumOpcodes; // number of entries in the desc array - unsigned numRealOpCodes; // number of non-dummy op codes + const TargetInstrDesc *Descriptors; // Raw array to allow static init'n + unsigned NumOpcodes; // Number of entries in the desc array TargetInstrInfo(const TargetInstrInfo &); // DO NOT IMPLEMENT void operator=(const TargetInstrInfo &); // DO NOT IMPLEMENT public: - TargetInstrInfo(const TargetInstrDescriptor *desc, unsigned NumOpcodes); + TargetInstrInfo(const TargetInstrDesc *desc, unsigned NumOpcodes); virtual ~TargetInstrInfo(); // Invariant opcodes: All instruction sets have these as their low opcodes. enum { PHI = 0, INLINEASM = 1, - LABEL = 2 + DBG_LABEL = 2, + EH_LABEL = 3, + GC_LABEL = 4, + DECLARE = 5, + + /// EXTRACT_SUBREG - This instruction takes two operands: a register + /// that has subregisters, and a subregister index. It returns the + /// extracted subregister value. This is commonly used to implement + /// truncation operations on target architectures which support it. + EXTRACT_SUBREG = 6, + + /// INSERT_SUBREG - This instruction takes three operands: a register + /// that has subregisters, a register providing an insert value, and a + /// subregister index. It returns the value of the first register with + /// the value of the second register inserted. The first register is + /// often defined by an IMPLICIT_DEF, as is commonly used to implement + /// anyext operations on target architectures which support it. + INSERT_SUBREG = 7, + + /// IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef. + IMPLICIT_DEF = 8, + + /// SUBREG_TO_REG - This instruction is similar to INSERT_SUBREG except + /// that the first operand is an immediate integer constant. This constant + /// is often zero, as is commonly used to implement zext operations on + /// target architectures which support it, such as with x86-64 (with + /// zext from i32 to i64 via implicit zero-extension). + SUBREG_TO_REG = 9, + + /// COPY_TO_REGCLASS - This instruction is a placeholder for a plain + /// register-to-register copy into a specific register class. This is only + /// used between instruction selection and MachineInstr creation, before + /// virtual registers have been created for all the instructions, and it's + /// only needed in cases where the register classes implied by the + /// instructions are insufficient. The actual MachineInstrs to perform + /// the copy are emitted with the TargetInstrInfo::copyRegToReg hook. + COPY_TO_REGCLASS = 10 }; unsigned getNumOpcodes() const { return NumOpcodes; } @@ -181,102 +90,16 @@ public: /// get - Return the machine instruction descriptor that corresponds to the /// specified instruction opcode. /// - const TargetInstrDescriptor& get(MachineOpCode Opcode) const { - assert((unsigned)Opcode < NumOpcodes); - return desc[Opcode]; - } - - const char *getName(MachineOpCode Opcode) const { - return get(Opcode).Name; - } - - int getNumOperands(MachineOpCode Opcode) const { - return get(Opcode).numOperands; - } - - InstrSchedClass getSchedClass(MachineOpCode Opcode) const { - return get(Opcode).schedClass; - } - - const unsigned *getImplicitUses(MachineOpCode Opcode) const { - return get(Opcode).ImplicitUses; - } - - const unsigned *getImplicitDefs(MachineOpCode Opcode) const { - return get(Opcode).ImplicitDefs; - } - - - // - // Query instruction class flags according to the machine-independent - // flags listed above. - // - bool isReturn(MachineOpCode Opcode) const { - return get(Opcode).Flags & M_RET_FLAG; - } - - bool isCommutableInstr(MachineOpCode Opcode) const { - return get(Opcode).Flags & M_COMMUTABLE; - } - bool isTerminatorInstr(MachineOpCode Opcode) const { - return get(Opcode).Flags & M_TERMINATOR_FLAG; - } - - bool isBranch(MachineOpCode Opcode) const { - return get(Opcode).Flags & M_BRANCH_FLAG; - } - - /// isBarrier - Returns true if the specified instruction stops control flow - /// from executing the instruction immediately following it. Examples include - /// unconditional branches and return instructions. - bool isBarrier(MachineOpCode Opcode) const { - return get(Opcode).Flags & M_BARRIER_FLAG; - } - - bool isCall(MachineOpCode Opcode) const { - return get(Opcode).Flags & M_CALL_FLAG; - } - bool isLoad(MachineOpCode Opcode) const { - return get(Opcode).Flags & M_LOAD_FLAG; - } - bool isStore(MachineOpCode Opcode) const { - return get(Opcode).Flags & M_STORE_FLAG; - } - - /// hasDelaySlot - Returns true if the specified instruction has a delay slot - /// which must be filled by the code generator. - bool hasDelaySlot(MachineOpCode Opcode) const { - return get(Opcode).Flags & M_DELAY_SLOT_FLAG; - } - - /// usesCustomDAGSchedInsertionHook - Return true if this instruction requires - /// custom insertion support when the DAG scheduler is inserting it into a - /// machine basic block. - bool usesCustomDAGSchedInsertionHook(MachineOpCode Opcode) const { - return get(Opcode).Flags & M_USES_CUSTOM_DAG_SCHED_INSERTION; - } - - bool hasVariableOperands(MachineOpCode Opcode) const { - return get(Opcode).Flags & M_VARIABLE_OPS; - } - - bool isPredicable(MachineOpCode Opcode) const { - return get(Opcode).Flags & M_PREDICABLE; - } - - bool clobbersPredicate(MachineOpCode Opcode) const { - return get(Opcode).Flags & M_CLOBBERS_PRED; - } - - bool isNotDuplicable(MachineOpCode Opcode) const { - return get(Opcode).Flags & M_NOT_DUPLICABLE; + const TargetInstrDesc &get(unsigned Opcode) const { + assert(Opcode < NumOpcodes && "Invalid opcode!"); + return Descriptors[Opcode]; } /// isTriviallyReMaterializable - Return true if the instruction is trivially /// rematerializable, meaning it has no side effects and requires no operands /// that aren't always available. - bool isTriviallyReMaterializable(MachineInstr *MI) const { - return (MI->getInstrDescriptor()->Flags & M_REMATERIALIZIBLE) && + bool isTriviallyReMaterializable(const MachineInstr *MI) const { + return MI->getDesc().isRematerializable() && isReallyTriviallyReMaterializable(MI); } @@ -289,23 +112,16 @@ protected: /// return false if the instruction has any side effects other than /// producing a value, or if it requres any address registers that are not /// always available. - virtual bool isReallyTriviallyReMaterializable(MachineInstr *MI) const { + virtual bool isReallyTriviallyReMaterializable(const MachineInstr *MI) const { return true; } public: - /// getOperandConstraint - Returns the value of the specific constraint if - /// it is set. Returns -1 if it is not set. - int getOperandConstraint(MachineOpCode Opcode, unsigned OpNum, - TOI::OperandConstraint Constraint) const { - return get(Opcode).getOperandConstraint(OpNum, Constraint); - } - - /// Return true if the instruction is a register to register move - /// and leave the source and dest operands in the passed parameters. + /// Return true if the instruction is a register to register move and return + /// the source and dest operands and their sub-register indices by reference. virtual bool isMoveInstr(const MachineInstr& MI, - unsigned& sourceReg, - unsigned& destReg) const { + unsigned& SrcReg, unsigned& DstReg, + unsigned& SrcSubIdx, unsigned& DstSubIdx) const { return false; } @@ -314,7 +130,8 @@ public: /// the destination along with the FrameIndex of the loaded stack slot. If /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than loading from the stack slot. - virtual unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const{ + virtual unsigned isLoadFromStackSlot(const MachineInstr *MI, + int &FrameIndex) const { return 0; } @@ -323,13 +140,31 @@ public: /// the source reg along with the FrameIndex of the loaded stack slot. If /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than storing to the stack slot. - virtual unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const { + virtual unsigned isStoreToStackSlot(const MachineInstr *MI, + int &FrameIndex) const { return 0; } + /// reMaterialize - Re-issue the specified 'original' instruction at the + /// specific location targeting a new destination register. + virtual void reMaterialize(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + unsigned DestReg, + const MachineInstr *Orig) const = 0; + + /// isInvariantLoad - Return true if the specified instruction (which is + /// marked mayLoad) is loading from a location whose value is invariant across + /// the function. For example, loading a value from the constant pool or from + /// from the argument area of a function if it does not change. This should + /// only return true of *all* loads the instruction does are invariant (if it + /// does multiple loads). + virtual bool isInvariantLoad(const MachineInstr *MI) const { + return false; + } + /// convertToThreeAddress - This method must be implemented by targets that /// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target - /// may be able to convert a two-address instruction into one or moretrue + /// may be able to convert a two-address instruction into one or more true /// three-address instructions on demand. This allows the X86 target (for /// example) to convert ADD and SHL instructions into LEA instructions if they /// would require register copies due to two-addressness. @@ -339,7 +174,7 @@ public: /// virtual MachineInstr * convertToThreeAddress(MachineFunction::iterator &MFI, - MachineBasicBlock::iterator &MBBI, LiveVariables &LV) const { + MachineBasicBlock::iterator &MBBI, LiveVariables *LV) const { return 0; } @@ -353,7 +188,18 @@ public: /// return a new machine instruction. If an instruction cannot commute, it /// can also return null. /// - virtual MachineInstr *commuteInstruction(MachineInstr *MI) const; + /// If NewMI is true, then a new machine instruction must be created. + /// + virtual MachineInstr *commuteInstruction(MachineInstr *MI, + bool NewMI = false) const = 0; + + /// CommuteChangesDestination - Return true if commuting the specified + /// instruction will also changes the destination operand. Also return the + /// current operand index of the would be new destination register by + /// reference. This can happen when the commutable instruction is also a + /// two-address instruction. + virtual bool CommuteChangesDestination(MachineInstr *MI, + unsigned &OpIdx) const = 0; /// AnalyzeBranch - Analyze the branching code at the end of MBB, returning /// true if it cannot be understood (e.g. it's a switch dispatch or isn't @@ -365,27 +211,31 @@ public: /// 2. If this block ends with only an unconditional branch, it sets TBB to be /// the destination block. /// 3. If this block ends with an conditional branch and it falls through to - /// an successor block, it sets TBB to be the branch destination block and a - /// list of operands that evaluate the condition. These + /// an successor block, it sets TBB to be the branch destination block and + /// a list of operands that evaluate the condition. These /// operands can be passed to other TargetInstrInfo methods to create new /// branches. /// 4. If this block ends with an conditional branch and an unconditional - /// block, it returns the 'true' destination in TBB, the 'false' destination - /// in FBB, and a list of operands that evaluate the condition. These - /// operands can be passed to other TargetInstrInfo methods to create new - /// branches. + /// block, it returns the 'true' destination in TBB, the 'false' + /// destination in FBB, and a list of operands that evaluate the condition. + /// These operands can be passed to other TargetInstrInfo methods to create + /// new branches. /// /// Note that RemoveBranch and InsertBranch must be implemented to support /// cases where this method returns success. /// + /// If AllowModify is true, then this routine is allowed to modify the basic + /// block (e.g. delete instructions after the unconditional branch). + /// virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, - std::vector &Cond) const { + SmallVectorImpl &Cond, + bool AllowModify = false) const { return true; } /// RemoveBranch - Remove the branching code at the end of the specific MBB. - /// this is only invoked in cases where AnalyzeBranch returns success. It + /// This is only invoked in cases where AnalyzeBranch returns success. It /// returns the number of instructions that were removed. virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const { assert(0 && "Target didn't implement TargetInstrInfo::RemoveBranch!"); @@ -398,25 +248,180 @@ public: /// returns success and when an unconditional branch (TBB is non-null, FBB is /// null, Cond is empty) needs to be inserted. It returns the number of /// instructions inserted. + /// + /// It is also invoked by tail merging to add unconditional branches in + /// cases where AnalyzeBranch doesn't apply because there was no original + /// branch to analyze. At least this much must be implemented, else tail + /// merging needs to be disabled. virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, - const std::vector &Cond) const { + const SmallVectorImpl &Cond) const { assert(0 && "Target didn't implement TargetInstrInfo::InsertBranch!"); return 0; } + /// copyRegToReg - Emit instructions to copy between a pair of registers. It + /// returns false if the target does not how to copy between the specified + /// registers. + virtual bool copyRegToReg(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + unsigned DestReg, unsigned SrcReg, + const TargetRegisterClass *DestRC, + const TargetRegisterClass *SrcRC) const { + assert(0 && "Target didn't implement TargetInstrInfo::copyRegToReg!"); + return false; + } + + /// storeRegToStackSlot - Store the specified register of the given register + /// class to the specified stack frame index. The store instruction is to be + /// added to the given machine basic block before the specified machine + /// instruction. If isKill is true, the register operand is the last use and + /// must be marked kill. + virtual void storeRegToStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + unsigned SrcReg, bool isKill, int FrameIndex, + const TargetRegisterClass *RC) const { + assert(0 && "Target didn't implement TargetInstrInfo::storeRegToStackSlot!"); + } + + /// storeRegToAddr - Store the specified register of the given register class + /// to the specified address. The store instruction is to be added to the + /// given machine basic block before the specified machine instruction. If + /// isKill is true, the register operand is the last use and must be marked + /// kill. + virtual void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill, + SmallVectorImpl &Addr, + const TargetRegisterClass *RC, + SmallVectorImpl &NewMIs) const { + assert(0 && "Target didn't implement TargetInstrInfo::storeRegToAddr!"); + } + + /// loadRegFromStackSlot - Load the specified register of the given register + /// class from the specified stack frame index. The load instruction is to be + /// added to the given machine basic block before the specified machine + /// instruction. + virtual void loadRegFromStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + unsigned DestReg, int FrameIndex, + const TargetRegisterClass *RC) const { + assert(0 && "Target didn't implement TargetInstrInfo::loadRegFromStackSlot!"); + } + + /// loadRegFromAddr - Load the specified register of the given register class + /// class from the specified address. The load instruction is to be added to + /// the given machine basic block before the specified machine instruction. + virtual void loadRegFromAddr(MachineFunction &MF, unsigned DestReg, + SmallVectorImpl &Addr, + const TargetRegisterClass *RC, + SmallVectorImpl &NewMIs) const { + assert(0 && "Target didn't implement TargetInstrInfo::loadRegFromAddr!"); + } + + /// spillCalleeSavedRegisters - Issues instruction(s) to spill all callee + /// saved registers and returns true if it isn't possible / profitable to do + /// so by issuing a series of store instructions via + /// storeRegToStackSlot(). Returns false otherwise. + virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + const std::vector &CSI) const { + return false; + } + + /// restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee + /// saved registers and returns true if it isn't possible / profitable to do + /// so by issuing a series of load instructions via loadRegToStackSlot(). + /// Returns false otherwise. + virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + const std::vector &CSI) const { + return false; + } + + /// foldMemoryOperand - Attempt to fold a load or store of the specified stack + /// slot into the specified machine instruction for the specified operand(s). + /// If this is possible, a new instruction is returned with the specified + /// operand folded, otherwise NULL is returned. The client is responsible for + /// removing the old instruction and adding the new one in the instruction + /// stream. + MachineInstr* foldMemoryOperand(MachineFunction &MF, + MachineInstr* MI, + const 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. + MachineInstr* foldMemoryOperand(MachineFunction &MF, + MachineInstr* MI, + const SmallVectorImpl &Ops, + MachineInstr* LoadMI) const; + +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 { + return 0; + } + + /// 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 { + return 0; + } + +public: + /// canFoldMemoryOperand - Returns true for the specified load / store if + /// folding is possible. + virtual + bool canFoldMemoryOperand(const MachineInstr *MI, + const SmallVectorImpl &Ops) const { + return false; + } + + /// 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{ + return false; + } + + virtual bool unfoldMemoryOperand(SelectionDAG &DAG, SDNode *N, + SmallVectorImpl &NewNodes) const { + return false; + } + + /// 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 { + return 0; + } + /// BlockHasNoFallThrough - Return true if the specified block does not /// fall-through into its successor block. This is primarily used when a /// branch is unanalyzable. It is useful for things like unconditional /// indirect branches (jump tables). - virtual bool BlockHasNoFallThrough(MachineBasicBlock &MBB) const { + virtual bool BlockHasNoFallThrough(const MachineBasicBlock &MBB) const { return false; } /// ReverseBranchCondition - Reverses the branch condition of the specified /// condition list, returning false on success and true if it cannot be /// reversed. - virtual bool ReverseBranchCondition(std::vector &Cond) const { + virtual + bool ReverseBranchCondition(SmallVectorImpl &Cond) const { return true; } @@ -442,23 +447,62 @@ public: /// instruction. It returns true if the operation was successful. virtual bool PredicateInstruction(MachineInstr *MI, - const std::vector &Pred) const; + const SmallVectorImpl &Pred) const = 0; /// SubsumesPredicate - Returns true if the first specified predicate /// subsumes the second, e.g. GE subsumes GT. virtual - bool SubsumesPredicate(const std::vector &Pred1, - const std::vector &Pred2) const { + bool SubsumesPredicate(const SmallVectorImpl &Pred1, + const SmallVectorImpl &Pred2) const { return false; } - /// getPointerRegClass - Returns a TargetRegisterClass used for pointer - /// values. - virtual const TargetRegisterClass *getPointerRegClass() const { - assert(0 && "Target didn't implement getPointerRegClass!"); - abort(); - return 0; // Must return a value in order to compile with VS 2005 + /// DefinesPredicate - If the specified instruction defines any predicate + /// or condition code register(s) used for predication, returns true as well + /// as the definition predicate(s) by reference. + virtual bool DefinesPredicate(MachineInstr *MI, + std::vector &Pred) const { + return false; } + + /// isSafeToMoveRegClassDefs - Return true if it's safe to move a machine + /// instruction that defines the specified register class. + virtual bool isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const { + return true; + } + + /// GetInstSize - Returns the size of the specified Instruction. + /// + virtual unsigned GetInstSizeInBytes(const MachineInstr *MI) const { + assert(0 && "Target didn't implement TargetInstrInfo::GetInstSize!"); + return 0; + } + + /// GetFunctionSizeInBytes - Returns the size of the specified MachineFunction. + /// + virtual unsigned GetFunctionSizeInBytes(const MachineFunction &MF) const = 0; +}; + +/// TargetInstrInfoImpl - This is the default implementation of +/// TargetInstrInfo, which just provides a couple of default implementations +/// for various methods. This separated out because it is implemented in +/// libcodegen, not in libtarget. +class TargetInstrInfoImpl : public TargetInstrInfo { +protected: + TargetInstrInfoImpl(const TargetInstrDesc *desc, unsigned NumOpcodes) + : TargetInstrInfo(desc, NumOpcodes) {} +public: + virtual MachineInstr *commuteInstruction(MachineInstr *MI, + bool NewMI = false) const; + virtual bool CommuteChangesDestination(MachineInstr *MI, + unsigned &OpIdx) const; + virtual bool PredicateInstruction(MachineInstr *MI, + const SmallVectorImpl &Pred) const; + virtual void reMaterialize(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + unsigned DestReg, + const MachineInstr *Orig) const; + virtual unsigned GetFunctionSizeInBytes(const MachineFunction &MF) const; }; } // End llvm namespace