diff options
Diffstat (limited to 'include/llvm/Target/TargetLowering.h')
-rw-r--r-- | include/llvm/Target/TargetLowering.h | 159 |
1 files changed, 111 insertions, 48 deletions
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 75e5325524..42c330f4f2 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -39,6 +39,7 @@ namespace llvm { class AllocaInst; class APFloat; class CallInst; + class CCState; class Function; class FastISel; class FunctionLoweringInfo; @@ -111,7 +112,7 @@ public: bool isBigEndian() const { return !IsLittleEndian; } bool isLittleEndian() const { return IsLittleEndian; } MVT getPointerTy() const { return PointerTy; } - MVT getShiftAmountTy() const { return ShiftAmountTy; } + virtual MVT getShiftAmountTy(EVT LHSTy) const; /// isSelectExpensive - Return true if the select operation is expensive for /// this target. @@ -125,6 +126,10 @@ public: /// srl/add/sra. bool isPow2DivCheap() const { return Pow2DivIsCheap; } + /// isJumpExpensive() - Return true if Flow Control is an expensive operation + /// that should be avoided. + bool isJumpExpensive() const { return JumpIsExpensive; } + /// getSetCCResultType - Return the ValueType of the result of SETCC /// operations. Also used to obtain the target's preferred type for /// the condition operand of SELECT and BRCOND nodes. In the case of @@ -206,7 +211,7 @@ public: /// ValueTypeActions - For each value type, keep a LegalizeAction enum /// that indicates how instruction selection should deal with the type. uint8_t ValueTypeActions[MVT::LAST_VALUETYPE]; - + LegalizeAction getExtendedTypeAction(EVT VT) const { // Handle non-vector integers. if (!VT.isVector()) { @@ -217,42 +222,56 @@ public: return Promote; return Expand; } - - // If this is a type smaller than a legal vector type, promote to that - // type, e.g. <2 x float> -> <4 x float>. - if (VT.getVectorElementType().isSimple() && - VT.getVectorNumElements() != 1) { - MVT EltType = VT.getVectorElementType().getSimpleVT(); - unsigned NumElts = VT.getVectorNumElements(); - while (1) { - // Round up to the nearest power of 2. - NumElts = (unsigned)NextPowerOf2(NumElts); - - MVT LargerVector = MVT::getVectorVT(EltType, NumElts); - if (LargerVector == MVT()) break; - - // If this the larger type is legal, promote to it. - if (getTypeAction(LargerVector) == Legal) return Promote; - } + + // Vectors with only one element are always scalarized. + if (VT.getVectorNumElements() == 1) + return Expand; + + // Vectors with a number of elements that is not a power of two are always + // widened, for example <3 x float> -> <4 x float>. + if (!VT.isPow2VectorType()) + return Promote; + + // Vectors with a crazy element type are always expanded, for example + // <4 x i2> is expanded into two vectors of type <2 x i2>. + if (!VT.getVectorElementType().isSimple()) + return Expand; + + // If this type is smaller than a legal vector type then widen it, + // otherwise expand it. E.g. <2 x float> -> <4 x float>. + MVT EltType = VT.getVectorElementType().getSimpleVT(); + unsigned NumElts = VT.getVectorNumElements(); + while (1) { + // Round up to the next power of 2. + NumElts = (unsigned)NextPowerOf2(NumElts); + + // If there is no simple vector type with this many elements then there + // cannot be a larger legal vector type. Note that this assumes that + // there are no skipped intermediate vector types in the simple types. + MVT LargerVector = MVT::getVectorVT(EltType, NumElts); + if (LargerVector == MVT()) + return Expand; + + // If this type is legal then widen the vector. + if (getTypeAction(LargerVector) == Legal) + return Promote; } - - return VT.isPow2VectorType() ? Expand : Promote; - } + } public: ValueTypeActionImpl() { std::fill(ValueTypeActions, array_endof(ValueTypeActions), 0); } - + LegalizeAction getTypeAction(EVT VT) const { if (!VT.isExtended()) return getTypeAction(VT.getSimpleVT()); return getExtendedTypeAction(VT); } - + LegalizeAction getTypeAction(MVT VT) const { return (LegalizeAction)ValueTypeActions[VT.SimpleTy]; } - + void setTypeAction(EVT VT, LegalizeAction Action) { unsigned I = VT.getSimpleVT().SimpleTy; ValueTypeActions[I] = Action; @@ -273,7 +292,7 @@ public: LegalizeAction getTypeAction(MVT VT) const { return ValueTypeActions.getTypeAction(VT); } - + /// getTypeToTransformTo - For types supported by the target, this is an /// identity function. For types that must be promoted to larger types, this /// returns the larger type to promote to. For integer types that are larger @@ -306,7 +325,7 @@ public: EVT NVT = VT.getRoundIntegerType(Context); if (NVT == VT) // Size is a power of two - expand to half the size. return EVT::getIntegerVT(Context, VT.getSizeInBits() / 2); - + // Promote to a power of two size, avoiding multi-step promotion. return getTypeAction(NVT) == Promote ? getTypeToTransformTo(Context, NVT) : NVT; @@ -638,21 +657,30 @@ public: /// This function returns the maximum number of store operations permitted /// to replace a call to llvm.memset. The value is set by the target at the - /// performance threshold for such a replacement. + /// performance threshold for such a replacement. If OptSize is true, + /// return the limit for functions that have OptSize attribute. /// @brief Get maximum # of store operations permitted for llvm.memset - unsigned getMaxStoresPerMemset() const { return maxStoresPerMemset; } + unsigned getMaxStoresPerMemset(bool OptSize) const { + return OptSize ? maxStoresPerMemsetOptSize : maxStoresPerMemset; + } /// This function returns the maximum number of store operations permitted /// to replace a call to llvm.memcpy. The value is set by the target at the - /// performance threshold for such a replacement. + /// performance threshold for such a replacement. If OptSize is true, + /// return the limit for functions that have OptSize attribute. /// @brief Get maximum # of store operations permitted for llvm.memcpy - unsigned getMaxStoresPerMemcpy() const { return maxStoresPerMemcpy; } + unsigned getMaxStoresPerMemcpy(bool OptSize) const { + return OptSize ? maxStoresPerMemcpyOptSize : maxStoresPerMemcpy; + } /// This function returns the maximum number of store operations permitted /// to replace a call to llvm.memmove. The value is set by the target at the - /// performance threshold for such a replacement. + /// performance threshold for such a replacement. If OptSize is true, + /// return the limit for functions that have OptSize attribute. /// @brief Get maximum # of store operations permitted for llvm.memmove - unsigned getMaxStoresPerMemmove() const { return maxStoresPerMemmove; } + unsigned getMaxStoresPerMemmove(bool OptSize) const { + return OptSize ? maxStoresPerMemmoveOptSize : maxStoresPerMemmove; + } /// This function returns true if the target allows unaligned memory accesses. /// of the specified type. This is used, for example, in situations where an @@ -950,6 +978,13 @@ public: return isTypeLegal(VT); } + /// isDesirableToPromoteOp - Return true if it is profitable for dag combiner + /// to transform a floating point op of specified opcode to a equivalent op of + /// an integer type. e.g. f32 load -> i32 load can be profitable on ARM. + virtual bool isDesirableToTransformToIntegerOp(unsigned Opc, EVT VT) const { + return false; + } + /// IsDesirableToPromoteOp - This method query the target whether it is /// beneficial for dag combiner to promote the specified node. If true, it /// should return the desired promotion type by reference. @@ -963,10 +998,6 @@ public: // protected: - /// setShiftAmountType - Describe the type that should be used for shift - /// amounts. This type defaults to the pointer type. - void setShiftAmountType(MVT VT) { ShiftAmountTy = VT; } - /// setBooleanContents - Specify how the target extends the result of a /// boolean value from i1 to a wider type. See getBooleanContents. void setBooleanContents(BooleanContent Ty) { BooleanContents = Ty; } @@ -1013,7 +1044,16 @@ protected: /// SelectIsExpensive - Tells the code generator not to expand operations /// into sequences that use the select operations if possible. - void setSelectIsExpensive() { SelectIsExpensive = true; } + void setSelectIsExpensive(bool isExpensive = true) { + SelectIsExpensive = isExpensive; + } + + /// JumpIsExpensive - Tells the code generator not to expand sequence of + /// operations into a seperate sequences that increases the amount of + /// flow control. + void setJumpIsExpensive(bool isExpensive = true) { + JumpIsExpensive = isExpensive; + } /// setIntDivIsCheap - Tells the code generator that integer divide is /// expensive, and if possible, should be replaced by an alternate sequence @@ -1219,6 +1259,9 @@ public: return SDValue(); // this is here to silence compiler errors } + /// HandleByVal - Target-specific cleanup for formal ByVal parameters. + virtual void HandleByVal(CCState *) const {} + /// CanLowerReturn - This hook should be implemented to check whether the /// return values described by the Outs array can fit into the return /// registers. If false is returned, an sret-demotion is performed. @@ -1245,6 +1288,13 @@ public: return SDValue(); // this is here to silence compiler errors } + /// isUsedByReturnOnly - Return true if result of the specified node is used + /// by a return node only. This is used to determine whether it is possible + /// to codegen a libcall as tail call at legalization time. + virtual bool isUsedByReturnOnly(SDNode *N) const { + return false; + } + /// LowerOperationWrapper - This callback is invoked by the type legalizer /// to legalize nodes with an illegal operand type but legal result types. /// It replaces the LowerOperation callback in the type Legalizer. @@ -1319,7 +1369,7 @@ public: CW_Good = 1, // Good weight. CW_Better = 2, // Better weight. CW_Best = 3, // Best weight. - + // Well-known weights. CW_SpecificReg = CW_Okay, // Specific register operands. CW_Register = CW_Good, // Register operands. @@ -1372,21 +1422,21 @@ public: CallOperandVal(0), ConstraintVT(MVT::Other) { } }; - + typedef std::vector<AsmOperandInfo> AsmOperandInfoVector; - + /// ParseConstraints - Split up the constraint string from the inline /// assembly value into the specific constraints and their prefixes, /// and also tie in the associated operand values. /// If this returns an empty vector, and if the constraint string itself /// isn't empty, there was an error parsing. virtual AsmOperandInfoVector ParseConstraints(ImmutableCallSite CS) const; - + /// Examine constraint type and operand type and determine a weight value. /// The operand object must already have been set up with the operand type. virtual ConstraintWeight getMultipleConstraintMatchWeight( AsmOperandInfo &info, int maIndex) const; - + /// Examine constraint string and operand type and determine a weight value. /// The operand object must already have been set up with the operand type. virtual ConstraintWeight getSingleConstraintMatchWeight( @@ -1396,7 +1446,7 @@ public: /// type to use for the specific AsmOperandInfo, setting /// OpInfo.ConstraintCode and OpInfo.ConstraintType. If the actual operand /// being passed in is available, it can be passed in as Op, otherwise an - /// empty SDValue can be passed. + /// empty SDValue can be passed. virtual void ComputeConstraintToUse(AsmOperandInfo &OpInfo, SDValue Op, SelectionDAG *DAG = 0) const; @@ -1597,6 +1647,11 @@ private: /// it. bool Pow2DivIsCheap; + /// JumpIsExpensive - Tells the code generator that it shouldn't generate + /// extra flow control instructions and should attempt to combine flow + /// control instructions via predication. + bool JumpIsExpensive; + /// UseUnderscoreSetJmp - This target prefers to use _setjmp to implement /// llvm.setjmp. Defaults to false. bool UseUnderscoreSetJmp; @@ -1605,10 +1660,6 @@ private: /// llvm.longjmp. Defaults to false. bool UseUnderscoreLongJmp; - /// ShiftAmountTy - The type to use for shift amounts, usually i8 or whatever - /// PointerTy is. - MVT ShiftAmountTy; - /// BooleanContents - Information about the contents of the high-bits in /// boolean values held in a type wider than i1. See getBooleanContents. BooleanContent BooleanContents; @@ -1751,6 +1802,10 @@ protected: /// @brief Specify maximum number of store instructions per memset call. unsigned maxStoresPerMemset; + /// Maximum number of stores operations that may be substituted for the call + /// to memset, used for functions with OptSize attribute. + unsigned maxStoresPerMemsetOptSize; + /// When lowering \@llvm.memcpy this field specifies the maximum number of /// store operations that may be substituted for a call to memcpy. Targets /// must set this value based on the cost threshold for that target. Targets @@ -1763,6 +1818,10 @@ protected: /// @brief Specify maximum bytes of store instructions per memcpy call. unsigned maxStoresPerMemcpy; + /// Maximum number of store operations that may be substituted for a call + /// to memcpy, used for functions with OptSize attribute. + unsigned maxStoresPerMemcpyOptSize; + /// When lowering \@llvm.memmove this field specifies the maximum number of /// store instructions that may be substituted for a call to memmove. Targets /// must set this value based on the cost threshold for that target. Targets @@ -1774,6 +1833,10 @@ protected: /// @brief Specify maximum bytes of store instructions per memmove call. unsigned maxStoresPerMemmove; + /// Maximum number of store instructions that may be substituted for a call + /// to memmove, used for functions with OpSize attribute. + unsigned maxStoresPerMemmoveOptSize; + /// This field specifies whether the target can benefit from code placement /// optimization. bool benefitFromCodePlacementOpt; |