X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FTarget%2FTargetLowering.h;h=29ecedcc6432841e08b0adaf473f8d17e416022b;hb=320efb05a1e7516268e711901ca9454bb4d94172;hp=a2d1c4caf203d550d95f7b40021493de233f6c43;hpb=b3f0a42d003cd6fc93dd4786ca580eaa48bb5fad;p=oota-llvm.git diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index a2d1c4caf20..29ecedcc643 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -77,8 +77,8 @@ namespace llvm { /// This base class for TargetLowering contains the SelectionDAG-independent /// parts that can be used from the rest of CodeGen. class TargetLoweringBase { - TargetLoweringBase(const TargetLoweringBase&) LLVM_DELETED_FUNCTION; - void operator=(const TargetLoweringBase&) LLVM_DELETED_FUNCTION; + TargetLoweringBase(const TargetLoweringBase&) = delete; + void operator=(const TargetLoweringBase&) = delete; public: /// This enum indicates whether operations are valid for a target, and if not, @@ -123,6 +123,18 @@ public: // mask (ex: x86 blends). }; + /// Enum that specifies what a AtomicRMWInst is expanded to, if at all. Exists + /// because different targets have different levels of support for these + /// atomic RMW instructions, and also have different options w.r.t. what they should + /// expand to. + enum class AtomicRMWExpansionKind { + None, // Don't expand the instruction. + LLSC, // Expand the instruction into loadlinked/storeconditional; used + // by ARM/AArch64. Implies `hasLoadLinkedStoreConditional` + // returns true. + CmpXChg, // Expand the instruction into cmpxchg; used by at least X86. + }; + static ISD::NodeType getExtendForContent(BooleanContent Content) { switch (Content) { case UndefinedBooleanContent: @@ -148,7 +160,7 @@ protected: public: const TargetMachine &getTargetMachine() const { return TM; } - const DataLayout *getDataLayout() const { return DL; } + const DataLayout *getDataLayout() const { return TM.getDataLayout(); } bool isBigEndian() const { return !IsLittleEndian; } bool isLittleEndian() const { return IsLittleEndian; } @@ -574,6 +586,14 @@ public: getLoadExtAction(ExtType, ValVT, MemVT) == Legal; } + /// Return true if the specified load with extension is legal or custom + /// on this target. + bool isLoadExtLegalOrCustom(unsigned ExtType, EVT ValVT, EVT MemVT) const { + return ValVT.isSimple() && MemVT.isSimple() && + (getLoadExtAction(ExtType, ValVT, MemVT) == Legal || + getLoadExtAction(ExtType, ValVT, MemVT) == Custom); + } + /// Return how this store with truncation should be treated: either it is /// legal, needs to be promoted to a larger size, needs to be expanded to some /// other code sequence, or the target has a custom expander for it. @@ -951,17 +971,20 @@ public: return false; } - /// Returns the maximal possible offset which can be used for loads / stores - /// from the global. - virtual unsigned getMaximalGlobalOffset() const { - return 0; - } - /// Returns true if a cast between SrcAS and DestAS is a noop. virtual bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const { return false; } + /// Return true if the pointer arguments to CI should be aligned by aligning + /// the object whose address is being passed. If so then MinSize is set to the + /// minimum size the object must be to be aligned and PrefAlign is set to the + /// preferred alignment. + virtual bool shouldAlignPointerArgs(CallInst * /*CI*/, unsigned & /*MinSize*/, + unsigned & /*PrefAlign*/) const { + return false; + } + //===--------------------------------------------------------------------===// /// \name Helpers for TargetTransformInfo implementations /// @{ @@ -1057,15 +1080,21 @@ public: return false; } + /// Returns true if arguments should be sign-extended in lib calls. + virtual bool shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const { + return IsSigned; + } + /// Returns true if the given (atomic) load should be expanded by the /// IR-level AtomicExpand pass into a load-linked instruction /// (through emitLoadLinked()). virtual bool shouldExpandAtomicLoadInIR(LoadInst *LI) const { return false; } - /// Returns true if the given AtomicRMW should be expanded by the - /// IR-level AtomicExpand pass into a loop using LoadLinked/StoreConditional. - virtual bool shouldExpandAtomicRMWInIR(AtomicRMWInst *RMWI) const { - return false; + /// Returns how the IR-level AtomicExpand pass should expand the given + /// AtomicRMW, if at all. Default is to never expand. + virtual AtomicRMWExpansionKind + shouldExpandAtomicRMWInIR(AtomicRMWInst *) const { + return AtomicRMWExpansionKind::None; } /// On some platforms, an AtomicRMW that never actually modifies the value @@ -1082,6 +1111,25 @@ public: virtual LoadInst *lowerIdempotentRMWIntoFencedLoad(AtomicRMWInst *RMWI) const { return nullptr; } + + /// Returns true if we should normalize + /// select(N0&N1, X, Y) => select(N0, select(N1, X, Y), Y) and + /// select(N0|N1, X, Y) => select(N0, select(N1, X, Y, Y)) if it is likely + /// that it saves us from materializing N0 and N1 in an integer register. + /// Targets that are able to perform and/or on flags should return false here. + virtual bool shouldNormalizeToSelectSequence(LLVMContext &Context, + EVT VT) const { + // If a target has multiple condition registers, then it likely has logical + // operations on those registers. + if (hasMultipleConditionRegisters()) + return false; + // Only do the transform if the value won't be split into multiple + // registers. + LegalizeTypeAction Action = getTypeAction(Context, VT); + return Action != TypeExpandInteger && Action != TypeExpandFloat && + Action != TypeSplitVector; + } + //===--------------------------------------------------------------------===// // TargetLowering Configuration Methods - These methods should be invoked by // the derived class constructor to configure this object for the target. @@ -1223,12 +1271,12 @@ protected: /// Return the largest legal super-reg register class of the register class /// for the specified type and its associated "cost". - virtual std::pair - findRepresentativeClass(MVT VT) const; + virtual std::pair + findRepresentativeClass(const TargetRegisterInfo *TRI, MVT VT) const; /// Once all of the register classes are added, this allows us to compute /// derived properties we expose. - void computeRegisterProperties(); + void computeRegisterProperties(const TargetRegisterInfo *TRI); /// Indicate that the specified operation does not work with the specified /// type and indicate what to do about it. @@ -1448,6 +1496,35 @@ public: return false; } + virtual bool isProfitableToHoist(Instruction *I) const { return true; } + + /// Return true if the extension represented by \p I is free. + /// Unlikely the is[Z|FP]ExtFree family which is based on types, + /// this method can use the context provided by \p I to decide + /// whether or not \p I is free. + /// This method extends the behavior of the is[Z|FP]ExtFree family. + /// In other words, if is[Z|FP]Free returns true, then this method + /// returns true as well. The converse is not true. + /// The target can perform the adequate checks by overriding isExtFreeImpl. + /// \pre \p I must be a sign, zero, or fp extension. + bool isExtFree(const Instruction *I) const { + switch (I->getOpcode()) { + case Instruction::FPExt: + if (isFPExtFree(EVT::getEVT(I->getType()))) + return true; + break; + case Instruction::ZExt: + if (isZExtFree(I->getOperand(0)->getType(), I->getType())) + return true; + break; + case Instruction::SExt: + break; + default: + llvm_unreachable("Instruction is not an extension"); + } + return isExtFreeImpl(I); + } + /// Return true if any actual instruction that defines a value of type Ty1 /// implicitly zero-extends the value to Ty2 in the result register. /// @@ -1510,6 +1587,10 @@ public: return false; } + /// Return true if folding a vector load into ExtVal (a sign, zero, or any + /// extend node) is profitable. + virtual bool isVectorLoadExtDesirable(SDValue ExtVal) const { return false; } + /// Return true if an fneg operation is free to the point where it is never /// worthwhile to replace it with a bitwise operation. virtual bool isFNegFree(EVT VT) const { @@ -1599,7 +1680,6 @@ public: private: const TargetMachine &TM; - const DataLayout *DL; /// True if this is a little endian target. bool IsLittleEndian; @@ -1776,136 +1856,8 @@ private: ValueTypeActionImpl ValueTypeActions; -public: - LegalizeKind - getTypeConversion(LLVMContext &Context, EVT VT) const { - // If this is a simple type, use the ComputeRegisterProp mechanism. - if (VT.isSimple()) { - MVT SVT = VT.getSimpleVT(); - assert((unsigned)SVT.SimpleTy < array_lengthof(TransformToType)); - MVT NVT = TransformToType[SVT.SimpleTy]; - LegalizeTypeAction LA = ValueTypeActions.getTypeAction(SVT); - - assert( - (LA == TypeLegal || LA == TypeSoftenFloat || - ValueTypeActions.getTypeAction(NVT) != TypePromoteInteger) - && "Promote may not follow Expand or Promote"); - - if (LA == TypeSplitVector) - return LegalizeKind(LA, EVT::getVectorVT(Context, - SVT.getVectorElementType(), - SVT.getVectorNumElements()/2)); - if (LA == TypeScalarizeVector) - return LegalizeKind(LA, SVT.getVectorElementType()); - return LegalizeKind(LA, NVT); - } - - // Handle Extended Scalar Types. - if (!VT.isVector()) { - assert(VT.isInteger() && "Float types must be simple"); - unsigned BitSize = VT.getSizeInBits(); - // First promote to a power-of-two size, then expand if necessary. - if (BitSize < 8 || !isPowerOf2_32(BitSize)) { - EVT NVT = VT.getRoundIntegerType(Context); - assert(NVT != VT && "Unable to round integer VT"); - LegalizeKind NextStep = getTypeConversion(Context, NVT); - // Avoid multi-step promotion. - if (NextStep.first == TypePromoteInteger) return NextStep; - // Return rounded integer type. - return LegalizeKind(TypePromoteInteger, NVT); - } - - return LegalizeKind(TypeExpandInteger, - EVT::getIntegerVT(Context, VT.getSizeInBits()/2)); - } - - // Handle vector types. - unsigned NumElts = VT.getVectorNumElements(); - EVT EltVT = VT.getVectorElementType(); - - // Vectors with only one element are always scalarized. - if (NumElts == 1) - return LegalizeKind(TypeScalarizeVector, EltVT); - - // Try to widen vector elements until the element type is a power of two and - // promote it to a legal type later on, for example: - // <3 x i8> -> <4 x i8> -> <4 x i32> - if (EltVT.isInteger()) { - // Vectors with a number of elements that is not a power of two are always - // widened, for example <3 x i8> -> <4 x i8>. - if (!VT.isPow2VectorType()) { - NumElts = (unsigned)NextPowerOf2(NumElts); - EVT NVT = EVT::getVectorVT(Context, EltVT, NumElts); - return LegalizeKind(TypeWidenVector, NVT); - } - - // Examine the element type. - LegalizeKind LK = getTypeConversion(Context, EltVT); - - // If type is to be expanded, split the vector. - // <4 x i140> -> <2 x i140> - if (LK.first == TypeExpandInteger) - return LegalizeKind(TypeSplitVector, - EVT::getVectorVT(Context, EltVT, NumElts / 2)); - - // Promote the integer element types until a legal vector type is found - // or until the element integer type is too big. If a legal type was not - // found, fallback to the usual mechanism of widening/splitting the - // vector. - EVT OldEltVT = EltVT; - while (1) { - // Increase the bitwidth of the element to the next pow-of-two - // (which is greater than 8 bits). - EltVT = EVT::getIntegerVT(Context, 1 + EltVT.getSizeInBits() - ).getRoundIntegerType(Context); - - // Stop trying when getting a non-simple element type. - // Note that vector elements may be greater than legal vector element - // types. Example: X86 XMM registers hold 64bit element on 32bit - // systems. - if (!EltVT.isSimple()) break; - - // Build a new vector type and check if it is legal. - MVT NVT = MVT::getVectorVT(EltVT.getSimpleVT(), NumElts); - // Found a legal promoted vector type. - if (NVT != MVT() && ValueTypeActions.getTypeAction(NVT) == TypeLegal) - return LegalizeKind(TypePromoteInteger, - EVT::getVectorVT(Context, EltVT, NumElts)); - } - - // Reset the type to the unexpanded type if we did not find a legal vector - // type with a promoted vector element type. - EltVT = OldEltVT; - } - - // Try to widen the vector until a legal type is found. - // If there is no wider legal type, split the vector. - 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. - if (!EltVT.isSimple()) break; - MVT LargerVector = MVT::getVectorVT(EltVT.getSimpleVT(), NumElts); - if (LargerVector == MVT()) break; - - // If this type is legal then widen the vector. - if (ValueTypeActions.getTypeAction(LargerVector) == TypeLegal) - return LegalizeKind(TypeWidenVector, LargerVector); - } - - // Widen odd vectors to next power of two. - if (!VT.isPow2VectorType()) { - EVT NVT = VT.getPow2VectorType(Context); - return LegalizeKind(TypeWidenVector, NVT); - } - - // Vectors with illegal element types are expanded. - EVT NVT = EVT::getVectorVT(Context, EltVT, VT.getVectorNumElements() / 2); - return LegalizeKind(TypeSplitVector, NVT); - } +private: + LegalizeKind getTypeConversion(LLVMContext &Context, EVT VT) const; private: std::vector > AvailableRegClasses; @@ -1936,6 +1888,11 @@ private: CallingConv::ID LibcallCallingConvs[RTLIB::UNKNOWN_LIBCALL]; protected: + /// Return true if the extension represented by \p I is free. + /// \pre \p I is a sign, zero, or fp extension and + /// is[Z|FP]ExtFree of the related types is not true. + virtual bool isExtFreeImpl(const Instruction *I) const { return false; } + /// \brief Specify maximum number of store instructions per memset call. /// /// When lowering \@llvm.memset this field specifies the maximum number of @@ -2012,8 +1969,8 @@ protected: /// This class also defines callbacks that targets must implement to lower /// target-specific constructs to SelectionDAG operators. class TargetLowering : public TargetLoweringBase { - TargetLowering(const TargetLowering&) LLVM_DELETED_FUNCTION; - void operator=(const TargetLowering&) LLVM_DELETED_FUNCTION; + TargetLowering(const TargetLowering&) = delete; + void operator=(const TargetLowering&) = delete; public: /// NOTE: The TargetMachine owns TLOF. @@ -2073,6 +2030,7 @@ public: ISD::CondCode &CCCode, SDLoc DL) const; /// Returns a pair of (return value, chain). + /// It is an error to pass RTLIB::UNKNOWN_LIBCALL as \p LC. std::pair makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, const SDValue *Ops, unsigned NumOps, bool isSigned, @@ -2164,8 +2122,7 @@ public: void AddToWorklist(SDNode *N); void RemoveFromWorklist(SDNode *N); - SDValue CombineTo(SDNode *N, const std::vector &To, - bool AddTo = true); + SDValue CombineTo(SDNode *N, ArrayRef To, bool AddTo = true); SDValue CombineTo(SDNode *N, SDValue Res, bool AddTo = true); SDValue CombineTo(SDNode *N, SDValue Res0, SDValue Res1, bool AddTo = true); @@ -2646,7 +2603,8 @@ public: /// 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; + virtual AsmOperandInfoVector ParseConstraints(const TargetRegisterInfo *TRI, + 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. @@ -2678,9 +2636,18 @@ public: /// /// This should only be used for C_Register constraints. On error, this /// returns a register number of 0 and a null register class pointer. - virtual std::pair - getRegForInlineAsmConstraint(const std::string &Constraint, - MVT VT) const; + virtual std::pair + getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, + const std::string &Constraint, MVT VT) const; + + virtual unsigned + getInlineAsmMemConstraint(const std::string &ConstraintCode) const { + if (ConstraintCode == "i") + return InlineAsm::Constraint_i; + else if (ConstraintCode == "m") + return InlineAsm::Constraint_m; + return InlineAsm::Constraint_Unknown; + } /// Try to replace an X constraint, which matches anything, with another that /// has more specific requirements based on the type of the corresponding @@ -2784,6 +2751,8 @@ public: /// is created but not inserted into any basic blocks, and this method is /// called to expand it into a sequence of instructions, potentially also /// creating new basic blocks and control flow. + /// As long as the returned basic block is different (i.e., we created a new + /// one), the custom inserter is free to modify the rest of \p MBB. virtual MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const;