X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FTarget%2FTargetLowering.h;h=eaf2a843e2324ff1c930b6308d2a6d1a1f7e305e;hb=f29cc18dcb043a173f211f8f3e5caabc6f2e7b08;hp=4e08cc961be6a17adeb1479db32763a1910ee8e7;hpb=547ba56bd0dd4dddf79f7db95263fd25d4c3827a;p=oota-llvm.git diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 4e08cc961be..eaf2a843e23 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -100,7 +100,8 @@ public: TypeExpandFloat, // Split this float into two of half the size. TypeScalarizeVector, // Replace this one-element vector with its element. TypeSplitVector, // Split this vector into two of half the size. - TypeWidenVector // This vector should be widened into a larger vector. + TypeWidenVector, // This vector should be widened into a larger vector. + TypePromoteFloat // Replace this float with a larger one. }; /// LegalizeKind holds the legalization kind that needs to happen to EVT @@ -125,8 +126,8 @@ public: /// 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. + /// 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 @@ -162,15 +163,14 @@ public: const TargetMachine &getTargetMachine() const { return TM; } const DataLayout *getDataLayout() const { return TM.getDataLayout(); } - bool isBigEndian() const { return !IsLittleEndian; } - bool isLittleEndian() const { return IsLittleEndian; } + virtual bool useSoftFloat() const { return false; } /// Return the pointer type for the given address space, defaults to /// the pointer type from the data layout. /// FIXME: The default needs to be removed once all the code is updated. - virtual MVT getPointerTy(uint32_t /*AS*/ = 0) const; - unsigned getPointerSizeInBits(uint32_t AS = 0) const; - unsigned getPointerTypeSizeInBits(Type *Ty) const; + MVT getPointerTy(const DataLayout &DL, uint32_t AS = 0) const { + return MVT::getIntegerVT(DL.getPointerSizeInBits(AS)); + } virtual MVT getScalarShiftAmountTy(EVT LHSTy) const; EVT getShiftAmountTy(EVT LHSTy) const; @@ -178,8 +178,8 @@ public: /// Returns the type to be used for the index operand of: /// ISD::INSERT_VECTOR_ELT, ISD::EXTRACT_VECTOR_ELT, /// ISD::INSERT_SUBVECTOR, and ISD::EXTRACT_SUBVECTOR - virtual MVT getVectorIdxTy() const { - return getPointerTy(); + virtual MVT getVectorIdxTy(const DataLayout &DL) const { + return getPointerTy(DL); } /// Return true if the select operation is expensive for this target. @@ -256,19 +256,29 @@ public: /// isLoadBitCastBeneficial() - Return true if the following transform /// is beneficial. /// fold (conv (load x)) -> (load (conv*)x) - /// On architectures that don't natively support some vector loads efficiently, - /// casting the load to a smaller vector of larger types and loading - /// is more efficient, however, this can be undone by optimizations in + /// On architectures that don't natively support some vector loads + /// efficiently, casting the load to a smaller vector of larger types and + /// loading is more efficient, however, this can be undone by optimizations in /// dag combiner. - virtual bool isLoadBitCastBeneficial(EVT /* Load */, EVT /* Bitcast */) const { + virtual bool isLoadBitCastBeneficial(EVT /* Load */, + EVT /* Bitcast */) const { return true; } + /// Return true if it is expected to be cheaper to do a store of a non-zero + /// vector constant with the given size and type for the address space than to + /// store the individual scalar element constants. + virtual bool storeOfVectorConstantIsCheap(EVT MemVT, + unsigned NumElem, + unsigned AddrSpace) const { + return false; + } + /// \brief Return true if it is cheap to speculate a call to intrinsic cttz. virtual bool isCheapToSpeculateCttz() const { return false; } - + /// \brief Return true if it is cheap to speculate a call to intrinsic ctlz. virtual bool isCheapToSpeculateCtlz() const { return false; @@ -315,7 +325,8 @@ public: } /// Return the ValueType of the result of SETCC operations. - virtual EVT getSetCCResultType(LLVMContext &Context, EVT VT) const; + virtual EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, + EVT VT) const; /// Return the ValueType for comparison libcalls. Comparions libcalls include /// floating point comparion calls, and Ordered/Unordered check calls on @@ -571,7 +582,8 @@ public: /// Return how this load with extension 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. - LegalizeAction getLoadExtAction(unsigned ExtType, EVT ValVT, EVT MemVT) const { + LegalizeAction getLoadExtAction(unsigned ExtType, EVT ValVT, + EVT MemVT) const { if (ValVT.isExtended() || MemVT.isExtended()) return Expand; unsigned ValI = (unsigned) ValVT.getSimpleVT().SimpleTy; unsigned MemI = (unsigned) MemVT.getSimpleVT().SimpleTy; @@ -702,17 +714,18 @@ public: /// operations except for the pointer size. If AllowUnknown is true, this /// will return MVT::Other for types with no EVT counterpart (e.g. structs), /// otherwise it will assert. - EVT getValueType(Type *Ty, bool AllowUnknown = false) const { + EVT getValueType(const DataLayout &DL, Type *Ty, + bool AllowUnknown = false) const { // Lower scalar pointers to native pointer types. if (PointerType *PTy = dyn_cast(Ty)) - return getPointerTy(PTy->getAddressSpace()); + return getPointerTy(DL, PTy->getAddressSpace()); if (Ty->isVectorTy()) { VectorType *VTy = cast(Ty); Type *Elm = VTy->getElementType(); // Lower vectors of pointers to native pointer types. if (PointerType *PT = dyn_cast(Elm)) { - EVT PointerTy(getPointerTy(PT->getAddressSpace())); + EVT PointerTy(getPointerTy(DL, PT->getAddressSpace())); Elm = PointerTy.getTypeForEVT(Ty->getContext()); } @@ -723,8 +736,9 @@ public: } /// Return the MVT corresponding to this LLVM type. See getValueType. - MVT getSimpleValueType(Type *Ty, bool AllowUnknown = false) const { - return getValueType(Ty, AllowUnknown).getSimpleVT(); + MVT getSimpleValueType(const DataLayout &DL, Type *Ty, + bool AllowUnknown = false) const { + return getValueType(DL, Ty, AllowUnknown).getSimpleVT(); } /// Return the desired alignment for ByVal or InAlloca aggregate function @@ -805,8 +819,8 @@ public: /// When splitting a value of the specified type into parts, does the Lo /// or Hi part come first? This usually follows the endianness, except /// for ppcf128, where the Hi part always comes first. - bool hasBigEndianPartOrdering(EVT VT) const { - return isBigEndian() || VT == MVT::ppcf128; + bool hasBigEndianPartOrdering(EVT VT, const DataLayout &DL) const { + return DL.isBigEndian() || VT == MVT::ppcf128; } /// If true, the target has custom DAG combine transformations that it can @@ -976,6 +990,15 @@ public: 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 /// @{ @@ -984,7 +1007,8 @@ public: int InstructionOpcodeToISD(unsigned Opcode) const; /// Estimate the cost of type-legalization and the legalized type. - std::pair getTypeLegalizationCost(Type *Ty) const; + std::pair getTypeLegalizationCost(const DataLayout &DL, + Type *Ty) const; /// @} @@ -1042,8 +1066,9 @@ public: /// seq_cst. But if they are lowered to monotonic accesses, no amount of /// IR-level fences can prevent it. /// @{ - virtual Instruction* emitLeadingFence(IRBuilder<> &Builder, AtomicOrdering Ord, - bool IsStore, bool IsLoad) const { + virtual Instruction *emitLeadingFence(IRBuilder<> &Builder, + AtomicOrdering Ord, bool IsStore, + bool IsLoad) const { if (!getInsertFencesForAtomic()) return nullptr; @@ -1053,8 +1078,9 @@ public: return nullptr; } - virtual Instruction* emitTrailingFence(IRBuilder<> &Builder, AtomicOrdering Ord, - bool IsStore, bool IsLoad) const { + virtual Instruction *emitTrailingFence(IRBuilder<> &Builder, + AtomicOrdering Ord, bool IsStore, + bool IsLoad) const { if (!getInsertFencesForAtomic()) return nullptr; @@ -1071,6 +1097,11 @@ 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()). @@ -1094,7 +1125,8 @@ public: /// it succeeds, and nullptr otherwise. /// If shouldExpandAtomicLoadInIR returns true on that load, it will undergo /// another round of expansion. - virtual LoadInst *lowerIdempotentRMWIntoFencedLoad(AtomicRMWInst *RMWI) const { + virtual LoadInst * + lowerIdempotentRMWIntoFencedLoad(AtomicRMWInst *RMWI) const { return nullptr; } @@ -1205,11 +1237,10 @@ protected: HasExtractBitsInsn = hasExtractInsn; } - /// Tells the code generator not to expand sequence of operations into a - /// separate sequences that increases the amount of flow control. - void setJumpIsExpensive(bool isExpensive = true) { - JumpIsExpensive = isExpensive; - } + /// Tells the code generator not to expand logic operations on comparison + /// predicates into separate sequences that increase the amount of flow + /// control. + void setJumpIsExpensive(bool isExpensive = true); /// Tells the code generator that integer divide is expensive, and if /// possible, should be replaced by an alternate sequence of instructions not @@ -1401,7 +1432,8 @@ public: /// load/store. virtual bool GetAddrModeArguments(IntrinsicInst * /*I*/, SmallVectorImpl &/*Ops*/, - Type *&/*AccessTy*/) const { + Type *&/*AccessTy*/, + unsigned AddrSpace = 0) const { return false; } @@ -1426,7 +1458,12 @@ public: /// The type may be VoidTy, in which case only return true if the addressing /// mode is legal for a load/store of any legal type. TODO: Handle /// pre/postinc as well. - virtual bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) const; + /// + /// If the address space cannot be determined, it will be -1. + /// + /// TODO: Remove default argument + virtual bool isLegalAddressingMode(const AddrMode &AM, Type *Ty, + unsigned AddrSpace) const; /// \brief Return the cost of the scaling factor used in the addressing mode /// represented by AM for this target, for a load/store of the specified type. @@ -1434,9 +1471,12 @@ public: /// If the AM is supported, the return value must be >= 0. /// If the AM is not supported, it returns a negative value. /// TODO: Handle pre/postinc as well. - virtual int getScalingFactorCost(const AddrMode &AM, Type *Ty) const { + /// TODO: Remove default argument + virtual int getScalingFactorCost(const AddrMode &AM, Type *Ty, + unsigned AS = 0) const { // Default: assume that any scaling factor used in a legal AM is free. - if (isLegalAddressingMode(AM, Ty)) return 0; + if (isLegalAddressingMode(AM, Ty, AS)) + return 0; return -1; } @@ -1558,6 +1598,35 @@ public: return false; } + /// \brief Get the maximum supported factor for interleaved memory accesses. + /// Default to be the minimum interleave factor: 2. + virtual unsigned getMaxSupportedInterleaveFactor() const { return 2; } + + /// \brief Lower an interleaved load to target specific intrinsics. Return + /// true on success. + /// + /// \p LI is the vector load instruction. + /// \p Shuffles is the shufflevector list to DE-interleave the loaded vector. + /// \p Indices is the corresponding indices for each shufflevector. + /// \p Factor is the interleave factor. + virtual bool lowerInterleavedLoad(LoadInst *LI, + ArrayRef Shuffles, + ArrayRef Indices, + unsigned Factor) const { + return false; + } + + /// \brief Lower an interleaved store to target specific intrinsics. Return + /// true on success. + /// + /// \p SI is the vector store instruction. + /// \p SVI is the shufflevector to RE-interleave the stored vector. + /// \p Factor is the interleave factor. + virtual bool lowerInterleavedStore(StoreInst *SI, ShuffleVectorInst *SVI, + unsigned Factor) const { + return false; + } + /// Return true if zero-extending the specific node Val to type VT2 is free /// (either because it's implicitly zero-extended such as ARM ldrb / ldrh or /// because it's folded such as X86 zero-extending loads). @@ -1667,9 +1736,6 @@ public: private: const TargetMachine &TM; - /// True if this is a little endian target. - bool IsLittleEndian; - /// Tells the code generator not to expand operations into sequences that use /// the select operations if possible. bool SelectIsExpensive; @@ -1946,7 +2012,8 @@ protected: /// Replace/modify any TargetFrameIndex operands with a targte-dependent /// sequence of memory operands that is recognized by PrologEpilogInserter. - MachineBasicBlock *emitPatchPoint(MachineInstr *MI, MachineBasicBlock *MBB) const; + MachineBasicBlock *emitPatchPoint(MachineInstr *MI, + MachineBasicBlock *MBB) const; }; /// This class defines information used to lower LLVM code to legal SelectionDAG @@ -2016,6 +2083,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, @@ -2345,6 +2413,7 @@ public: ArgListTy &getArgs() { return Args; } + }; /// This function lowers an abstract call to a function into an actual call. @@ -2353,7 +2422,7 @@ public: /// outgoing token chain. It calls LowerCall to do the actual lowering. std::pair LowerCallTo(CallLoweringInfo &CLI) const; - /// This hook must be implemented to lower calls into the the specified + /// This hook must be implemented to lower calls into the specified /// DAG. The outgoing arguments to the call are described by the Outs array, /// and the values to be returned by the call are described by the Ins /// array. The implementation should fill in the InVals array with legal-type @@ -2588,7 +2657,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(const TargetRegisterInfo *TRI, + virtual AsmOperandInfoVector ParseConstraints(const DataLayout &DL, + const TargetRegisterInfo *TRI, ImmutableCallSite CS) const; /// Examine constraint type and operand type and determine a weight value. @@ -2610,7 +2680,7 @@ public: SelectionDAG *DAG = nullptr) const; /// Given a constraint, return the type of constraint it is for this target. - virtual ConstraintType getConstraintType(const std::string &Constraint) const; + virtual ConstraintType getConstraintType(StringRef Constraint) const; /// Given a physical register constraint (e.g. {edx}), return the register /// number and the register class for the register. @@ -2623,13 +2693,14 @@ public: /// returns a register number of 0 and a null register class pointer. virtual std::pair getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, - const std::string &Constraint, MVT VT) const; + StringRef Constraint, MVT VT) const; - virtual unsigned - getInlineAsmMemConstraint(const std::string &ConstraintCode) const { - // FIXME: This currently maps all constraints to the the same code. - // This will be corrected once all targets are updated. - return InlineAsm::Constraint_m; + virtual unsigned getInlineAsmMemConstraint(StringRef 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 @@ -2646,8 +2717,6 @@ public: //===--------------------------------------------------------------------===// // Div utility functions // - SDValue BuildExactSDIV(SDValue Op1, SDValue Op2, SDLoc dl, - SelectionDAG &DAG) const; SDValue BuildSDIV(SDNode *N, const APInt &Divisor, SelectionDAG &DAG, bool IsAfterLegalization, std::vector *Created) const; @@ -2668,7 +2737,7 @@ public: /// Hooks for building estimates in place of slower divisions and square /// roots. - + /// Return a reciprocal square root estimate value for the input operand. /// The RefinementSteps output is the number of Newton-Raphson refinement /// iterations required to generate a sufficient (though not necessarily @@ -2679,10 +2748,9 @@ public: /// If that's true, then return '0' as the number of RefinementSteps to avoid /// any further refinement of the estimate. /// An empty SDValue return means no estimate sequence can be created. - virtual SDValue getRsqrtEstimate(SDValue Operand, - DAGCombinerInfo &DCI, - unsigned &RefinementSteps, - bool &UseOneConstNR) const { + virtual SDValue getRsqrtEstimate(SDValue Operand, DAGCombinerInfo &DCI, + unsigned &RefinementSteps, + bool &UseOneConstNR) const { return SDValue(); } @@ -2694,8 +2762,7 @@ public: /// If that's true, then return '0' as the number of RefinementSteps to avoid /// any further refinement of the estimate. /// An empty SDValue return means no estimate sequence can be created. - virtual SDValue getRecipEstimate(SDValue Operand, - DAGCombinerInfo &DCI, + virtual SDValue getRecipEstimate(SDValue Operand, DAGCombinerInfo &DCI, unsigned &RefinementSteps) const { return SDValue(); } @@ -2756,9 +2823,9 @@ public: /// Given an LLVM IR type and return type attributes, compute the return value /// EVTs and flags, and optionally also the offsets, if the return value is /// being lowered to memory. -void GetReturnInfo(Type* ReturnType, AttributeSet attr, +void GetReturnInfo(Type *ReturnType, AttributeSet attr, SmallVectorImpl &Outs, - const TargetLowering &TLI); + const TargetLowering &TLI, const DataLayout &DL); } // end llvm namespace