X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FTarget%2FTargetInstrInfo.h;h=c6b89878bdc0d8d031ac2ce7eb5dbd391a611acc;hb=98a366d547772010e94609e4584489b3e5ce0043;hp=d8aff40fa1c35e9c8ca95aef9fce917b8d54ed51;hpb=cc8cd0cbf12c12916d4b38ef0de5be5501c8270e;p=oota-llvm.git diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index d8aff40fa1c..c6b89878bdc 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -7,23 +7,18 @@ // //===----------------------------------------------------------------------===// // -// 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 TargetRegisterClass; class LiveVariables; class CalleeSavedInfo; @@ -32,255 +27,62 @@ class SelectionDAG; template class SmallVectorImpl; -//===----------------------------------------------------------------------===// -// 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; - -/// M_SIMPLE_LOAD_FLAG - This flag is set for instructions that are simple loads -/// from memory. This should only be set on instructions that load a value from -/// memory and return it in their only virtual register definition. -const unsigned M_SIMPLE_LOAD_FLAG = 1 << 5; - -/// M_MAY_STORE_FLAG - This flag is set to any instruction that could possibly -/// modify memory. Instructions with this flag set are not necessarily simple -/// store instructions, they may store a modified value based on their operands, -/// or may not actually modify anything, for example. -const unsigned M_MAY_STORE_FLAG = 1 << 6; - -const unsigned M_INDIRECT_FLAG = 1 << 7; -const unsigned M_IMPLICIT_DEF_FLAG = 1 << 8; - -// 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 << 9; - -// 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 << 10; - -// 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 << 11; - -// 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 << 12; - -// 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 << 13; - -// M_PREDICABLE - Set if this instruction has a predicate operand that -// controls execution. It may be set to 'always'. -const unsigned M_PREDICABLE = 1 << 14; - -// 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 << 15; - -// M_NOT_DUPLICABLE - Set if this instruction cannot be safely duplicated. -// (e.g. instructions with unique labels attached). -const unsigned M_NOT_DUPLICABLE = 1 << 16; - -// M_HAS_OPTIONAL_DEF - Set if this instruction has an optional definition, e.g. -// ARM instructions which can set condition code if 's' bit is set. -const unsigned M_HAS_OPTIONAL_DEF = 1 << 17; - -// M_NEVER_HAS_SIDE_EFFECTS - Set if this instruction has no side effects that -// are not captured by any operands of the instruction or other flags, and when -// *all* instances of the instruction of that opcode have no side effects. -// -// Note: This and M_MAY_HAVE_SIDE_EFFECTS are mutually exclusive. You can't set -// both! If neither flag is set, then the instruction *always* has side effects. -const unsigned M_NEVER_HAS_SIDE_EFFECTS = 1 << 18; - -// M_MAY_HAVE_SIDE_EFFECTS - Set if some instances of this instruction can have -// side effects. The virtual method "isReallySideEffectFree" is called to -// determine this. Load instructions are an example of where this is useful. In -// general, loads always have side effects. However, loads from constant pools -// don't. We let the specific back end make this determination. -// -// Note: This and M_NEVER_HAS_SIDE_EFFECTS are mutually exclusive. You can't set -// both! If neither flag is set, then the instruction *always* has side effects. -const unsigned M_MAY_HAVE_SIDE_EFFECTS = 1 << 19; - - -//===----------------------------------------------------------------------===// -// Machine operand flags -//===----------------------------------------------------------------------===// - -namespace TOI { - // Operand constraints: only "tied_to" for now. - enum OperandConstraint { - TIED_TO = 0 // Must be allocated the same register as. - }; - - /// OperandFlags - These are flags set on operands, but should be considered - /// private, all access should go through the TargetOperandInfo accessors. - /// See the accessors for a description of what these are. - enum OperandFlags { - LookupPtrRegClass = 1 << 0, - Predicate = 1 << 1, - OptionalDef = 1 << 2 - }; -} - -/// 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. - - /// isLookupPtrRegClass - Set if this operand is a pointer value and it - /// requires a callback to look up its register class. - bool isLookupPtrRegClass() const { return Flags & TOI::LookupPtrRegClass; } - - /// isPredicate - Set if this is one of the operands that made up of - /// the predicate operand that controls an M_PREDICATED instruction. - bool isPredicate() const { return Flags & TOI::Predicate; } - - /// isOptionalDef - Set if this operand is a optional def. - /// - bool isOptionalDef() const { return Flags & TOI::OptionalDef; } -}; - - -class TargetInstrDescriptor { -public: - unsigned short Opcode; // The opcode. - unsigned short numOperands; // Num of args (may be more if variable_ops). - unsigned short numDefs; // Num of args that are definitions. - const char * Name; // Assembly language mnemonic for the opcode. - unsigned 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; - - bool isCall() const { - return Flags & M_CALL_FLAG; - } - - bool isBranch() const { - return Flags & M_BRANCH_FLAG; - } - - bool isTerminator() const { - return Flags & M_TERMINATOR_FLAG; - } - - bool isIndirectBranch() const { - return Flags & M_INDIRECT_FLAG; - } - - bool isPredicable() const { - return Flags & M_PREDICABLE; - } - - bool isNotDuplicable() const { - return Flags & M_NOT_DUPLICABLE; - } - - - - /// isSimpleLoad - Return true for instructions that are simple loads from - /// memory. This should only be set on instructions that load a value from - /// memory and return it in their only virtual register definition. - /// Instructions that return a value loaded from memory and then modified in - /// some way should not return true for this. - bool isSimpleLoad() const { - return Flags & M_SIMPLE_LOAD_FLAG; - } - - /// mayStore - Return true if this instruction could possibly modify memory. - /// Instructions with this flag set are not necessarily simple store - /// instructions, they may store a modified value based on their operands, or - /// may not actually modify anything, for example. - bool mayStore() const { - return Flags & M_MAY_STORE_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() const { - return Flags & M_BARRIER_FLAG; - } - - /// hasDelaySlot - Returns true if the specified instruction has a delay slot - /// which must be filled by the code generator. - bool hasDelaySlot() const { - return Flags & M_DELAY_SLOT_FLAG; - } - - unsigned getSchedClass() const { - return SchedClass; - } -}; - //--------------------------------------------------------------------------- /// -/// 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, - EXTRACT_SUBREG = 3, - INSERT_SUBREG = 4 + 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; } @@ -288,76 +90,19 @@ public: /// get - Return the machine instruction descriptor that corresponds to the /// specified instruction opcode. /// - const TargetInstrDescriptor& get(unsigned Opcode) const { - assert(Opcode < NumOpcodes); - return desc[Opcode]; - } - - const char *getName(unsigned Opcode) const { - return get(Opcode).Name; - } - - int getNumOperands(unsigned Opcode) const { - return get(Opcode).numOperands; - } - - int getNumDefs(unsigned Opcode) const { - return get(Opcode).numDefs; - } - - const unsigned *getImplicitUses(unsigned Opcode) const { - return get(Opcode).ImplicitUses; - } - - const unsigned *getImplicitDefs(unsigned Opcode) const { - return get(Opcode).ImplicitDefs; - } - - - // - // Query instruction class flags according to the machine-independent - // flags listed above. - // - bool isReturn(unsigned Opcode) const { - return get(Opcode).Flags & M_RET_FLAG; - } - - bool isCommutableInstr(unsigned Opcode) const { - return get(Opcode).Flags & M_COMMUTABLE; - } - - /// usesCustomDAGSchedInsertionHook - Return true if this instruction requires - /// custom insertion support when the DAG scheduler is inserting it into a - /// machine basic block. - bool usesCustomDAGSchedInsertionHook(unsigned Opcode) const { - return get(Opcode).Flags & M_USES_CUSTOM_DAG_SCHED_INSERTION; - } - - bool hasVariableOperands(unsigned Opcode) const { - return get(Opcode).Flags & M_VARIABLE_OPS; - } - - bool hasOptionalDef(unsigned Opcode) const { - return get(Opcode).Flags & M_HAS_OPTIONAL_DEF; + 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->getDesc()->Flags & M_REMATERIALIZIBLE) && + bool isTriviallyReMaterializable(const MachineInstr *MI) const { + return MI->getDesc().isRematerializable() && isReallyTriviallyReMaterializable(MI); } - /// hasUnmodelledSideEffects - Returns true if the instruction has side - /// effects that are not captured by any operands of the instruction or other - /// flags. - bool hasUnmodelledSideEffects(MachineInstr *MI) const { - const TargetInstrDescriptor *TID = MI->getDesc(); - if (TID->Flags & M_NEVER_HAS_SIDE_EFFECTS) return false; - if (!(TID->Flags & M_MAY_HAVE_SIDE_EFFECTS)) return true; - return !isReallySideEffectFree(MI); // May have side effects - } protected: /// isReallyTriviallyReMaterializable - For instructions with opcodes for /// which the M_REMATERIALIZABLE flag is set, this function tests whether the @@ -367,32 +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; } - /// isReallySideEffectFree - If the M_MAY_HAVE_SIDE_EFFECTS flag is set, this - /// method is called to determine if the specific instance of this - /// instruction has side effects. This is useful in cases of instructions, - /// like loads, which generally always have side effects. A load from a - /// constant pool doesn't have side effects, though. So we need to - /// differentiate it from the general case. - virtual bool isReallySideEffectFree(MachineInstr *MI) const { - return false; - } public: - /// getOperandConstraint - Returns the value of the specific constraint if - /// it is set. Returns -1 if it is not set. - int getOperandConstraint(unsigned 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; } @@ -401,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; } @@ -410,10 +140,28 @@ 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 more true @@ -426,7 +174,7 @@ public: /// virtual MachineInstr * convertToThreeAddress(MachineFunction::iterator &MFI, - MachineBasicBlock::iterator &MBBI, LiveVariables &LV) const { + MachineBasicBlock::iterator &MBBI, LiveVariables *LV) const { return 0; } @@ -440,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 = 0; + /// 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 @@ -452,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!"); @@ -485,22 +248,35 @@ 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 - Add a copy between a pair of registers - virtual void copyRegToReg(MachineBasicBlock &MBB, + /// 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, @@ -508,6 +284,11 @@ public: 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, @@ -515,6 +296,10 @@ public: 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, @@ -522,6 +307,9 @@ public: 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, @@ -555,26 +343,46 @@ public: /// operand folded, otherwise NULL is returned. The client is responsible for /// removing the old instruction and adding the new one in the instruction /// stream. - virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, - SmallVectorImpl &Ops, - int FrameIndex) const { - return 0; - } + 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. - virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, - SmallVectorImpl &Ops, - MachineInstr* LoadMI) const { + 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; } - /// canFoldMemoryOperand - Returns true if the specified load / store is +public: + /// canFoldMemoryOperand - Returns true for the specified load / store if /// folding is possible. virtual - bool canFoldMemoryOperand(MachineInstr *MI, - SmallVectorImpl &Ops) const{ + bool canFoldMemoryOperand(const MachineInstr *MI, + const SmallVectorImpl &Ops) const { return false; } @@ -605,14 +413,15 @@ public: /// 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; } @@ -638,13 +447,13 @@ public: /// instruction. It returns true if the operation was successful. virtual bool PredicateInstruction(MachineInstr *MI, - const std::vector &Pred) const = 0; + 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; } @@ -656,13 +465,22 @@ public: 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 + /// 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 @@ -671,13 +489,20 @@ public: /// libcodegen, not in libtarget. class TargetInstrInfoImpl : public TargetInstrInfo { protected: - TargetInstrInfoImpl(const TargetInstrDescriptor *desc, unsigned NumOpcodes) + TargetInstrInfoImpl(const TargetInstrDesc *desc, unsigned NumOpcodes) : TargetInstrInfo(desc, NumOpcodes) {} public: - virtual MachineInstr *commuteInstruction(MachineInstr *MI) const; + virtual MachineInstr *commuteInstruction(MachineInstr *MI, + bool NewMI = false) const; + virtual bool CommuteChangesDestination(MachineInstr *MI, + unsigned &OpIdx) const; virtual bool PredicateInstruction(MachineInstr *MI, - const std::vector &Pred) const; - + 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