X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FTarget%2FTargetInstrInfo.h;h=2ca75134aa4e620546d940dddf5fcbc01d1e3561;hb=8245aab33021f31888c7436af9fb1fe2360be791;hp=596afd69c3bc2b4abc3c1e5f5010753a5a2f56a9;hpb=33247d537ddce29e65bc324bf8d40a15d2d88c01;p=oota-llvm.git diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index 596afd69c3b..2ca75134aa4 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -15,6 +15,7 @@ #define LLVM_TARGET_TARGETINSTRINFO_H #include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineFunction.h" #include "llvm/Support/DataTypes.h" #include #include @@ -23,13 +24,9 @@ namespace llvm { class MachineInstr; class TargetMachine; -class Value; -class Type; -class Instruction; -class Constant; -class Function; class MachineCodeForInstruction; class TargetRegisterClass; +class LiveVariables; //--------------------------------------------------------------------------- // Data types used to define information about a single machine instruction @@ -51,46 +48,68 @@ 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; +const unsigned M_INDIRECT_FLAG = 1 << 7; // 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; +const unsigned M_CONVERTIBLE_TO_3_ADDR = 1 << 8; // 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; +const unsigned M_COMMUTABLE = 1 << 9; // 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; +const unsigned M_TERMINATOR_FLAG = 1 << 10; // 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; +const unsigned M_USES_CUSTOM_DAG_SCHED_INSERTION = 1 << 11; // 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; +const unsigned M_VARIABLE_OPS = 1 << 12; -// M_PREDICATED - Set if this instruction has a predicate that controls its -// execution. -const unsigned M_PREDICATED = 1 << 12; +// M_PREDICABLE - Set if this instruction has a predicate operand that +// controls execution. It may be set to 'always'. +const unsigned M_PREDICABLE = 1 << 13; +// 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 << 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; + +// 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 << 16; // 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 the first operand of a predicate -/// operand that controls an M_PREDICATED instruction. +/// 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; +/// M_OPTIONAL_DEF_OPERAND - Set if this operand is a optional def. +/// +const unsigned M_OPTIONAL_DEF_OPERAND = 1 << 2; + +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. @@ -112,6 +131,7 @@ class TargetInstrDescriptor { public: MachineOpCode 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. InstrSchedClass schedClass; // enum identifying instr sched class unsigned Flags; // flags identifying machine instr class @@ -119,6 +139,24 @@ public: 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; }; @@ -140,7 +178,10 @@ public: // Invariant opcodes: All instruction sets have these as their low opcodes. enum { PHI = 0, - INLINEASM = 1 + INLINEASM = 1, + LABEL = 2, + EXTRACT_SUBREG = 3, + INSERT_SUBREG = 4 }; unsigned getNumOpcodes() const { return NumOpcodes; } @@ -161,6 +202,10 @@ public: return get(Opcode).numOperands; } + int getNumDefs(MachineOpCode Opcode) const { + return get(Opcode).numDefs; + } + InstrSchedClass getSchedClass(MachineOpCode Opcode) const { return get(Opcode).schedClass; } @@ -182,13 +227,10 @@ public: return get(Opcode).Flags & M_RET_FLAG; } - bool isPredicated(MachineOpCode Opcode) const { - return get(Opcode).Flags & M_PREDICATED; - } bool isCommutableInstr(MachineOpCode Opcode) const { return get(Opcode).Flags & M_COMMUTABLE; } - bool isTerminatorInstr(unsigned Opcode) const { + bool isTerminatorInstr(MachineOpCode Opcode) const { return get(Opcode).Flags & M_TERMINATOR_FLAG; } @@ -196,6 +238,10 @@ public: return get(Opcode).Flags & M_BRANCH_FLAG; } + bool isIndirectBranch(MachineOpCode Opcode) const { + return get(Opcode).Flags & M_INDIRECT_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. @@ -215,14 +261,14 @@ public: /// hasDelaySlot - Returns true if the specified instruction has a delay slot /// which must be filled by the code generator. - bool hasDelaySlot(unsigned Opcode) const { + 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(unsigned Opcode) const { + bool usesCustomDAGSchedInsertionHook(MachineOpCode Opcode) const { return get(Opcode).Flags & M_USES_CUSTOM_DAG_SCHED_INSERTION; } @@ -230,35 +276,47 @@ public: return get(Opcode).Flags & M_VARIABLE_OPS; } - // Operand constraints: only "tied_to" for now. - enum OperandConstraint { - TIED_TO = 0 // Must be allocated the same register as. - }; + bool isPredicable(MachineOpCode Opcode) const { + return get(Opcode).Flags & M_PREDICABLE; + } + + bool isNotDuplicable(MachineOpCode Opcode) const { + return get(Opcode).Flags & M_NOT_DUPLICABLE; + } + bool hasOptionalDef(MachineOpCode Opcode) const { + return get(Opcode).Flags & M_HAS_OPTIONAL_DEF; + } + + /// 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) && + isReallyTriviallyReMaterializable(MI); + } + +protected: + /// isReallyTriviallyReMaterializable - For instructions with opcodes for + /// which the M_REMATERIALIZABLE flag is set, this function tests whether the + /// instruction itself is actually trivially rematerializable, considering + /// its operands. This is used for targets that have instructions that are + /// only trivially rematerializable for specific uses. This predicate must + /// 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 { + 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, - OperandConstraint Constraint) const { - assert(OpNum < get(Opcode).numOperands && - "Invalid operand # of TargetInstrInfo"); - if (get(Opcode).OpInfo[OpNum].Constraints & (1 << Constraint)) { - unsigned Pos = 16 + Constraint * 4; - return (int)(get(Opcode).OpInfo[OpNum].Constraints >> Pos) & 0xf; - } - return -1; + TOI::OperandConstraint Constraint) const { + return get(Opcode).getOperandConstraint(OpNum, Constraint); } - /// findTiedToSrcOperand - Returns the operand that is tied to the specified - /// dest operand. Returns -1 if there isn't one. - int findTiedToSrcOperand(MachineOpCode Opcode, unsigned OpNum) const; - - /// getDWARF_LABELOpcode - Return the opcode of the target's DWARF_LABEL - /// instruction if it has one. This is used by codegen passes that update - /// DWARF line number info as they modify the code. - virtual unsigned getDWARF_LABELOpcode() const { - return 0; - } - /// Return true if the instruction is a register to register move /// and leave the source and dest operands in the passed parameters. virtual bool isMoveInstr(const MachineInstr& MI, @@ -287,15 +345,17 @@ public: /// 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 a true - /// three-address instruction on demand. This allows the X86 target (for + /// 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. /// /// This method returns a null pointer if the transformation cannot be - /// performed, otherwise it returns the new instruction. + /// performed, otherwise it returns the last new instruction. /// - virtual MachineInstr *convertToThreeAddress(MachineInstr *TA) const { + virtual MachineInstr * + convertToThreeAddress(MachineFunction::iterator &MFI, + MachineBasicBlock::iterator &MBBI, LiveVariables &LV) const { return 0; } @@ -320,10 +380,16 @@ public: /// just return false, leaving TBB/FBB null. /// 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, 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. + /// 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 + /// 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. /// /// Note that RemoveBranch and InsertBranch must be implemented to support /// cases where this method returns success. @@ -335,20 +401,24 @@ public: } /// RemoveBranch - Remove the branching code at the end of the specific MBB. - /// this is only invoked in cases where AnalyzeBranch returns success. - virtual void RemoveBranch(MachineBasicBlock &MBB) const { + /// 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!"); + return 0; } /// InsertBranch - Insert a branch into the end of the specified /// MachineBasicBlock. This operands to this method are the same as those /// returned by AnalyzeBranch. This is invoked in cases where AnalyzeBranch /// returns success and when an unconditional branch (TBB is non-null, FBB is - /// null, Cond is empty) needs to be inserted. - virtual void InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, + /// null, Cond is empty) needs to be inserted. It returns the number of + /// instructions inserted. + virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, const std::vector &Cond) const { assert(0 && "Target didn't implement TargetInstrInfo::InsertBranch!"); + return 0; } /// BlockHasNoFallThrough - Return true if the specified block does not @@ -374,11 +444,44 @@ public: abort(); } + /// isPredicated - Returns true if the instruction is already predicated. + /// + virtual bool isPredicated(const MachineInstr *MI) const { + return false; + } + + /// isUnpredicatedTerminator - Returns true if the instruction is a + /// terminator instruction that has not been predicated. + virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const; + + /// PredicateInstruction - Convert the instruction into a predicated + /// instruction. It returns true if the operation was successful. + virtual + bool PredicateInstruction(MachineInstr *MI, + const std::vector &Pred) const; + + /// 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 { + return false; + } + + /// 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; + } + /// 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 } };