X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FTarget%2FTargetLowering.h;h=dc2c74a835bb46eb7cf6cdd41fc529b2f5356bdd;hb=21cfedee056a1e0789bbe6cafa23549d0ff16f24;hp=5141afbfa0dfe591276f4848d1a1faa76a1d9050;hpb=39d8dcb53b806841c8455637c23549b24760ce80;p=oota-llvm.git diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 5141afbfa0d..dc2c74a835b 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -28,9 +28,11 @@ #include "llvm/CodeGen/RuntimeLibcalls.h" #include "llvm/CodeGen/SelectionDAGNodes.h" #include "llvm/IR/Attributes.h" +#include "llvm/IR/CallSite.h" #include "llvm/IR/CallingConv.h" #include "llvm/IR/InlineAsm.h" -#include "llvm/Support/CallSite.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/MC/MCRegisterInfo.h" #include "llvm/Target/TargetCallingConv.h" #include "llvm/Target/TargetMachine.h" #include @@ -48,8 +50,10 @@ namespace llvm { class MachineFunction; class MachineInstr; class MachineJumpTableInfo; + class Mangler; class MCContext; class MCExpr; + class MCSymbol; template class SmallVectorImpl; class DataLayout; class TargetRegisterClass; @@ -178,10 +182,28 @@ public: return HasMultipleConditionRegisters; } + /// Return true if the target has BitExtract instructions. + bool hasExtractBitsInsn() const { return HasExtractBitsInsn; } + /// Return true if a vector of the given type should be split /// (TypeSplitVector) instead of promoted (TypePromoteInteger) during type /// legalization. - virtual bool shouldSplitVectorElementType(EVT /*VT*/) const { return false; } + virtual bool shouldSplitVectorType(EVT /*VT*/) const { return false; } + + // There are two general methods for expanding a BUILD_VECTOR node: + // 1. Use SCALAR_TO_VECTOR on the defined scalar values and then shuffle + // them together. + // 2. Build the vector on the stack and then load it. + // If this function returns true, then method (1) will be used, subject to + // the constraint that all of the necessary shuffles are legal (as determined + // by isShuffleMaskLegal). If this function returns false, then method (2) is + // always used. The vector type, and the number of defined values, are + // provided. + virtual bool + shouldExpandBuildVectorWithShuffles(EVT /* VT */, + unsigned DefinedValues) const { + return DefinedValues < 3; + } /// Return true if integer divide is usually cheaper than a sequence of /// several shifts, adds, and multiplies for this target. @@ -220,6 +242,21 @@ public: return true; } + /// \brief Return if the target supports combining a + /// chain like: + /// \code + /// %andResult = and %val1, #imm-with-one-bit-set; + /// %icmpResult = icmp %andResult, 0 + /// br i1 %icmpResult, label %dest1, label %dest2 + /// \endcode + /// into a single machine instruction of a form like: + /// \code + /// brOnBitSet %register, #bitNumber, dest + /// \endcode + bool isMaskAndBranchFoldingLegal() const { + return MaskAndBranchFoldingIsLegal; + } + /// 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 BRCOND the argument passed is MVT::Other @@ -290,7 +327,7 @@ public: bool isTypeLegal(EVT VT) const { assert(!VT.isSimple() || (unsigned)VT.getSimpleVT().SimpleTy < array_lengthof(RegClassForVT)); - return VT.isSimple() && RegClassForVT[VT.getSimpleVT().SimpleTy] != 0; + return VT.isSimple() && RegClassForVT[VT.getSimpleVT().SimpleTy] != nullptr; } class ValueTypeActionImpl { @@ -300,7 +337,7 @@ public: public: ValueTypeActionImpl() { - std::fill(ValueTypeActions, array_endof(ValueTypeActions), 0); + std::fill(std::begin(ValueTypeActions), std::end(ValueTypeActions), 0); } LegalizeTypeAction getTypeAction(MVT VT) const { @@ -722,7 +759,7 @@ public: /// alignment error (trap) on the target machine. virtual bool allowsUnalignedMemoryAccesses(EVT, unsigned AddrSpace = 0, - bool * /*Fast*/ = 0) const { + bool * /*Fast*/ = nullptr) const { return false; } @@ -863,6 +900,35 @@ public: /// @} + //===--------------------------------------------------------------------===// + /// \name Helpers for load-linked/store-conditional atomic expansion. + /// @{ + + /// Perform a load-linked operation on Addr, returning a "Value *" with the + /// corresponding pointee type. This may entail some non-trivial operations to + /// truncate or reconstruct types that will be illegal in the backend. See + /// ARMISelLowering for an example implementation. + virtual Value *emitLoadLinked(IRBuilder<> &Builder, Value *Addr, + AtomicOrdering Ord) const { + llvm_unreachable("Load linked unimplemented on this target"); + } + + /// Perform a store-conditional operation to Addr. Return the status of the + /// store. This should be 0 if the store succeeded, non-zero otherwise. + virtual Value *emitStoreConditional(IRBuilder<> &Builder, Value *Val, + Value *Addr, AtomicOrdering Ord) const { + llvm_unreachable("Store conditional unimplemented on this target"); + } + + /// Return true if the given (atomic) instruction should be expanded by the + /// IR-level AtomicExpandLoadLinked pass into a loop involving + /// load-linked/store-conditional pairs. Atomic stores will be expanded in the + /// same way as "atomic xchg" operations which ignore their output if needed. + virtual bool shouldExpandAtomicInIR(Instruction *Inst) const { + return false; + } + + //===--------------------------------------------------------------------===// // TargetLowering Configuration Methods - These methods should be invoked by // the derived class constructor to configure this object for the target. @@ -943,6 +1009,14 @@ protected: HasMultipleConditionRegisters = hasManyRegs; } + /// Tells the code generator that the target has BitExtract instructions. + /// The code generator will aggressively sink "shift"s into the blocks of + /// their users if the users will generate "and" instructions which can be + /// combined with "shift" to BitExtract instructions. + void setHasExtractBitsInsn(bool hasExtractInsn = true) { + 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) { @@ -1146,7 +1220,7 @@ public: int64_t BaseOffs; bool HasBaseReg; int64_t Scale; - AddrMode() : BaseGV(0), BaseOffs(0), HasBaseReg(false), Scale(0) {} + AddrMode() : BaseGV(nullptr), BaseOffs(0), HasBaseReg(false), Scale(0) {} }; /// Return true if the addressing mode represented by AM is legal for this @@ -1183,6 +1257,14 @@ public: return true; } + /// Return true if it's significantly cheaper to shift a vector by a uniform + /// scalar than by an amount which will vary across each lane. On x86, for + /// example, there is a "psllw" instruction for the former case, but no simple + /// instruction for a general "a << b" operation on vectors. + virtual bool isVectorShiftByScalarCheap(Type *Ty) const { + return false; + } + /// Return true if it's free to truncate a value of type Ty1 to type /// Ty2. e.g. On x86 it's free to truncate a i32 value in register EAX to i16 /// by referencing its sub-register AX. @@ -1354,6 +1436,12 @@ private: /// the blocks of their users. bool HasMultipleConditionRegisters; + /// Tells the code generator that the target has BitExtract instructions. + /// The code generator will aggressively sink "shift"s into the blocks of + /// their users if the users will generate "and" instructions which can be + /// combined with "shift" to BitExtract instructions. + bool HasExtractBitsInsn; + /// Tells the code generator not to expand integer divides by constants into a /// sequence of muls, adds, and shifts. This is a hack until a real cost /// model is in place. If we ever optimize for size, this will be set to true @@ -1714,6 +1802,10 @@ protected: /// the branch is usually predicted right. bool PredictableSelectIsExpensive; + /// MaskAndBranchFoldingIsLegal - Indicates if the target supports folding + /// a mask of a single bit, a compare, and a branch into a single instruction. + bool MaskAndBranchFoldingIsLegal; + protected: /// Return true if the value types that can be represented by the specified /// register class are all legal. @@ -1851,15 +1943,16 @@ public: /// Determine which of the bits specified in Mask are known to be either zero /// or one and return them in the KnownZero/KnownOne bitsets. - virtual void computeMaskedBitsForTargetNode(const SDValue Op, - APInt &KnownZero, - APInt &KnownOne, - const SelectionDAG &DAG, - unsigned Depth = 0) const; + virtual void computeKnownBitsForTargetNode(const SDValue Op, + APInt &KnownZero, + APInt &KnownOne, + const SelectionDAG &DAG, + unsigned Depth = 0) const; /// This method can be implemented by targets that want to expose additional /// information about sign bits to the DAG Combiner. virtual unsigned ComputeNumSignBitsForTargetNode(SDValue Op, + const SelectionDAG &DAG, unsigned Depth = 0) const; struct DAGCombinerInfo { @@ -1890,6 +1983,14 @@ public: void CommitTargetLoweringOpt(const TargetLoweringOpt &TLO); }; + /// Return if the N is a constant or constant vector equal to the true value + /// from getBooleanContents(). + bool isConstTrueVal(const SDNode *N) const; + + /// Return if the N is a constant or constant vector equal to the false value + /// from getBooleanContents(). + bool isConstFalseVal(const SDNode *N) const; + /// Try to simplify a setcc built with the specified operands and cc. If it is /// unable to simplify it, return a null SDValue. SDValue SimplifySetCC(EVT VT, SDValue N0, SDValue N1, @@ -1916,6 +2017,15 @@ public: /// virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; + /// Return true if it is profitable to move a following shift through this + // node, adjusting any immediate operands as necessary to preserve semantics. + // This transformation may not be desirable if it disrupts a particularly + // auspicious target-specific tree (e.g. bitfield extraction in AArch64). + // By default, it returns true. + virtual bool isDesirableToCommuteWithShift(const SDNode *N /*Op*/) const { + return true; + } + /// Return true if the target has native support for the specified value type /// and it is 'desirable' to use the type for the given node type. e.g. On x86 /// i16 is legal, but undesirable since i16 instruction encodings are longer @@ -2035,7 +2145,7 @@ public: IsVarArg(isVarArg), IsInReg(isInReg), DoesNotReturn(doesNotReturn), IsReturnValueUsed(isReturnValueUsed), IsTailCall(isTailCall), NumFixedArgs(numFixedArgs), CallConv(callConv), Callee(callee), - Args(args), DAG(dag), DL(dl), CS(NULL) {} + Args(args), DAG(dag), DL(dl), CS(nullptr) {} }; /// This function lowers an abstract call to a function into an actual call. @@ -2098,6 +2208,19 @@ public: return false; } + /// Return the builtin name for the __builtin___clear_cache intrinsic + /// Default is to invoke the clear cache library call + virtual const char * getClearCacheBuiltinName() const { + return "__clear_cache"; + } + + /// Return the register ID of the name passed in. Used by named register + /// global variables extension. There is no target-independent behaviour + /// so the default action is to bail. + virtual unsigned getRegisterByName(const char* RegName, EVT VT) const { + report_fatal_error("Named registers not implemented for this target"); + } + /// Return the type that should be used to zero or sign extend a /// zeroext/signext integer argument or return value. FIXME: Most C calling /// convention requires the return type to be promoted, but this is not true @@ -2110,10 +2233,19 @@ public: return VT.bitsLT(MinVT) ? MinVT : VT; } + /// For some targets, an LLVM struct type must be broken down into multiple + /// simple types, but the calling convention specifies that the entire struct + /// must be passed in a block of consecutive registers. + virtual bool + functionArgumentNeedsConsecutiveRegisters(Type *Ty, CallingConv::ID CallConv, + bool isVarArg) const { + return false; + } + /// Returns a 0 terminated array of registers that can be safely used as /// scratch registers. - virtual const uint16_t *getScratchRegisters(CallingConv::ID CC) const { - return NULL; + virtual const MCPhysReg *getScratchRegisters(CallingConv::ID CC) const { + return nullptr; } /// This callback is used to prepare for a volatile or atomic load. @@ -2174,7 +2306,7 @@ public: /// target does not support "fast" ISel. virtual FastISel *createFastISel(FunctionLoweringInfo &, const TargetLibraryInfo *) const { - return 0; + return nullptr; } @@ -2244,20 +2376,11 @@ public: /// operand it matches. unsigned getMatchedOperand() const; - /// Copy constructor for copying from an AsmOperandInfo. - AsmOperandInfo(const AsmOperandInfo &info) - : InlineAsm::ConstraintInfo(info), - ConstraintCode(info.ConstraintCode), - ConstraintType(info.ConstraintType), - CallOperandVal(info.CallOperandVal), - ConstraintVT(info.ConstraintVT) { - } - /// Copy constructor for copying from a ConstraintInfo. AsmOperandInfo(const InlineAsm::ConstraintInfo &info) : InlineAsm::ConstraintInfo(info), ConstraintType(TargetLowering::C_Unknown), - CallOperandVal(0), ConstraintVT(MVT::Other) { + CallOperandVal(nullptr), ConstraintVT(MVT::Other) { } }; @@ -2285,7 +2408,7 @@ public: /// Op, otherwise an empty SDValue can be passed. virtual void ComputeConstraintToUse(AsmOperandInfo &OpInfo, SDValue Op, - SelectionDAG *DAG = 0) const; + 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; @@ -2319,10 +2442,30 @@ public: // SDValue BuildExactSDIV(SDValue Op1, SDValue Op2, SDLoc dl, SelectionDAG &DAG) const; - SDValue BuildSDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization, - std::vector *Created) const; - SDValue BuildUDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization, - std::vector *Created) const; + SDValue BuildSDIV(SDNode *N, const APInt &Divisor, SelectionDAG &DAG, + bool IsAfterLegalization, + std::vector *Created) const; + SDValue BuildUDIV(SDNode *N, const APInt &Divisor, SelectionDAG &DAG, + bool IsAfterLegalization, + std::vector *Created) const; + + //===--------------------------------------------------------------------===// + // Legalization utility functions + // + + /// Expand a MUL into two nodes. One that computes the high bits of + /// the result and one that computes the low bits. + /// \param HiLoVT The value type to use for the Lo and Hi nodes. + /// \param LL Low bits of the LHS of the MUL. You can use this parameter + /// if you want to control how low bits are extracted from the LHS. + /// \param LH High bits of the LHS of the MUL. See LL for meaning. + /// \param RL Low bits of the RHS of the MUL. See LL for meaning + /// \param RH High bits of the RHS of the MUL. See LL for meaning. + /// \returns true if the node has been expanded. false if it has not + bool expandMUL(SDNode *N, SDValue &Lo, SDValue &Hi, EVT HiLoVT, + SelectionDAG &DAG, SDValue LL = SDValue(), + SDValue LH = SDValue(), SDValue RL = SDValue(), + SDValue RH = SDValue()) const; //===--------------------------------------------------------------------===// // Instruction Emitting Hooks