diff options
author | Stephen Hines <srhines@google.com> | 2014-02-11 20:01:10 -0800 |
---|---|---|
committer | Stephen Hines <srhines@google.com> | 2014-02-11 20:01:10 -0800 |
commit | ce9904c6ea8fd669978a8eefb854b330eb9828ff (patch) | |
tree | 2418ee2e96ea220977c8fb74959192036ab5b133 /include/llvm/Target | |
parent | c27b10b198c1d9e9b51f2303994313ec2778edd7 (diff) | |
parent | dbb832b83351cec97b025b61c26536ef50c3181c (diff) | |
download | external_llvm-ce9904c6ea8fd669978a8eefb854b330eb9828ff.zip external_llvm-ce9904c6ea8fd669978a8eefb854b330eb9828ff.tar.gz external_llvm-ce9904c6ea8fd669978a8eefb854b330eb9828ff.tar.bz2 |
Merge remote-tracking branch 'upstream/release_34' into merge-20140211
Conflicts:
lib/Linker/LinkModules.cpp
lib/Support/Unix/Signals.inc
Change-Id: Ia54f291fa5dc828052d2412736e8495c1282aa64
Diffstat (limited to 'include/llvm/Target')
-rw-r--r-- | include/llvm/Target/CostTable.h | 35 | ||||
-rw-r--r-- | include/llvm/Target/Mangler.h | 9 | ||||
-rw-r--r-- | include/llvm/Target/Target.td | 31 | ||||
-rw-r--r-- | include/llvm/Target/TargetCallingConv.h | 8 | ||||
-rw-r--r-- | include/llvm/Target/TargetCallingConv.td | 6 | ||||
-rw-r--r-- | include/llvm/Target/TargetInstrInfo.h | 41 | ||||
-rw-r--r-- | include/llvm/Target/TargetLibraryInfo.h | 17 | ||||
-rw-r--r-- | include/llvm/Target/TargetLowering.h | 143 | ||||
-rw-r--r-- | include/llvm/Target/TargetLoweringObjectFile.h | 4 | ||||
-rw-r--r-- | include/llvm/Target/TargetMachine.h | 13 | ||||
-rw-r--r-- | include/llvm/Target/TargetOpcodes.h | 19 | ||||
-rw-r--r-- | include/llvm/Target/TargetRegisterInfo.h | 16 | ||||
-rw-r--r-- | include/llvm/Target/TargetSchedule.td | 11 | ||||
-rw-r--r-- | include/llvm/Target/TargetSelectionDAG.td | 3 | ||||
-rw-r--r-- | include/llvm/Target/TargetSelectionDAGInfo.h | 68 | ||||
-rw-r--r-- | include/llvm/Target/TargetSubtargetInfo.h | 18 |
16 files changed, 375 insertions, 67 deletions
diff --git a/include/llvm/Target/CostTable.h b/include/llvm/Target/CostTable.h index a974b56..34f6041 100644 --- a/include/llvm/Target/CostTable.h +++ b/include/llvm/Target/CostTable.h @@ -25,18 +25,25 @@ struct CostTblEntry { unsigned Cost; }; -/// Find in cost table, TypeTy must be comparable by == -template <class TypeTy> -int CostTableLookup(const CostTblEntry<TypeTy> *Tbl, - unsigned len, int ISD, TypeTy Ty) { +/// Find in cost table, TypeTy must be comparable to CompareTy by == +template <class TypeTy, class CompareTy> +int CostTableLookup(const CostTblEntry<TypeTy> *Tbl, unsigned len, int ISD, + CompareTy Ty) { for (unsigned int i = 0; i < len; ++i) - if (Tbl[i].ISD == ISD && Tbl[i].Type == Ty) + if (ISD == Tbl[i].ISD && Ty == Tbl[i].Type) return i; // Could not find an entry. return -1; } +/// Find in cost table, TypeTy must be comparable to CompareTy by == +template <class TypeTy, class CompareTy, unsigned N> +int CostTableLookup(const CostTblEntry<TypeTy>(&Tbl)[N], int ISD, + CompareTy Ty) { + return CostTableLookup(Tbl, N, ISD, Ty); +} + /// Type Conversion Cost Table template <class TypeTy> struct TypeConversionCostTblEntry { @@ -46,18 +53,28 @@ struct TypeConversionCostTblEntry { unsigned Cost; }; -/// Find in type conversion cost table, TypeTy must be comparable by == -template <class TypeTy> +/// Find in type conversion cost table, TypeTy must be comparable to CompareTy +/// by == +template <class TypeTy, class CompareTy> int ConvertCostTableLookup(const TypeConversionCostTblEntry<TypeTy> *Tbl, - unsigned len, int ISD, TypeTy Dst, TypeTy Src) { + unsigned len, int ISD, CompareTy Dst, + CompareTy Src) { for (unsigned int i = 0; i < len; ++i) - if (Tbl[i].ISD == ISD && Tbl[i].Src == Src && Tbl[i].Dst == Dst) + if (ISD == Tbl[i].ISD && Src == Tbl[i].Src && Dst == Tbl[i].Dst) return i; // Could not find an entry. return -1; } +/// Find in type conversion cost table, TypeTy must be comparable to CompareTy +/// by == +template <class TypeTy, class CompareTy, unsigned N> +int ConvertCostTableLookup(const TypeConversionCostTblEntry<TypeTy>(&Tbl)[N], + int ISD, CompareTy Dst, CompareTy Src) { + return ConvertCostTableLookup(Tbl, N, ISD, Dst, Src); +} + } // namespace llvm diff --git a/include/llvm/Target/Mangler.h b/include/llvm/Target/Mangler.h index e925cd5..eee7bf6 100644 --- a/include/llvm/Target/Mangler.h +++ b/include/llvm/Target/Mangler.h @@ -20,7 +20,6 @@ namespace llvm { class GlobalValue; class MCContext; -class MCSymbol; template <typename T> class SmallVectorImpl; class TargetMachine; class Twine; @@ -34,7 +33,6 @@ public: }; private: - MCContext &Context; const TargetMachine *TM; /// AnonGlobalIDs - We need to give global values the same name every time @@ -48,12 +46,7 @@ private: unsigned NextAnonGlobalID; public: - Mangler(MCContext &Context, const TargetMachine *TM) - : Context(Context), TM(TM), NextAnonGlobalID(1) {} - - /// getSymbol - Return the MCSymbol for the specified global value. This - /// symbol is the main label that is the address of the global. - MCSymbol *getSymbol(const GlobalValue *GV); + Mangler(const TargetMachine *TM) : TM(TM), NextAnonGlobalID(1) {} /// getNameWithPrefix - Fill OutName with the name of the appropriate prefix /// and the specified global variable's name. If the global variable doesn't diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 89ca529..3f6eae6 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -632,6 +632,11 @@ def f64imm : Operand<f64>; /// def zero_reg; +/// All operands which the MC layer classifies as predicates should inherit from +/// this class in some manner. This is already handled for the most commonly +/// used PredicateOperand, but may be useful in other circumstances. +class PredicateOp; + /// OperandWithDefaultOps - This Operand class can be used as the parent class /// for an Operand that needs to be initialized with a default value if /// no value is supplied in a pattern. This class can be used to simplify the @@ -647,7 +652,7 @@ class OperandWithDefaultOps<ValueType ty, dag defaultops> /// AlwaysVal specifies the value of this predicate when set to "always /// execute". class PredicateOperand<ValueType ty, dag OpTypes, dag AlwaysVal> - : OperandWithDefaultOps<ty, AlwaysVal> { + : OperandWithDefaultOps<ty, AlwaysVal>, PredicateOp { let MIOperandInfo = OpTypes; } @@ -795,6 +800,19 @@ def LIFETIME_END : Instruction { let AsmString = "LIFETIME_END"; let neverHasSideEffects = 1; } +def STACKMAP : Instruction { + let OutOperandList = (outs); + let InOperandList = (ins i32imm:$id, i32imm:$nbytes, variable_ops); + let isCall = 1; + let mayLoad = 1; +} +def PATCHPOINT : Instruction { + let OutOperandList = (outs unknown:$dst); + let InOperandList = (ins i32imm:$id, i32imm:$nbytes, unknown:$callee, + i32imm:$nargs, i32imm:$cc, variable_ops); + let isCall = 1; + let mayLoad = 1; +} } //===----------------------------------------------------------------------===// @@ -1005,6 +1023,17 @@ class SubtargetFeature<string n, string a, string v, string d, list<SubtargetFeature> Implies = i; } +/// Specifies a Subtarget feature that this instruction is deprecated on. +class Deprecated<SubtargetFeature dep> { + SubtargetFeature DeprecatedFeatureMask = dep; +} + +/// A custom predicate used to determine if an instruction is +/// deprecated or not. +class ComplexDeprecationPredicate<string dep> { + string ComplexDeprecationPredicate = dep; +} + //===----------------------------------------------------------------------===// // Processor chip sets - These values represent each of the chip sets supported // by the scheduler. Each Processor definition requires corresponding diff --git a/include/llvm/Target/TargetCallingConv.h b/include/llvm/Target/TargetCallingConv.h index 1fd0bd9..9cc52a5 100644 --- a/include/llvm/Target/TargetCallingConv.h +++ b/include/llvm/Target/TargetCallingConv.h @@ -113,6 +113,7 @@ namespace ISD { struct InputArg { ArgFlagsTy Flags; MVT VT; + EVT ArgVT; bool Used; /// Index original Function's argument. @@ -124,10 +125,11 @@ namespace ISD { unsigned PartOffset; InputArg() : VT(MVT::Other), Used(false) {} - InputArg(ArgFlagsTy flags, EVT vt, bool used, + InputArg(ArgFlagsTy flags, EVT vt, EVT argvt, bool used, unsigned origIdx, unsigned partOffs) : Flags(flags), Used(used), OrigArgIndex(origIdx), PartOffset(partOffs) { VT = vt.getSimpleVT(); + ArgVT = argvt; } }; @@ -138,6 +140,7 @@ namespace ISD { struct OutputArg { ArgFlagsTy Flags; MVT VT; + EVT ArgVT; /// IsFixed - Is this a "fixed" value, ie not passed through a vararg "...". bool IsFixed; @@ -151,11 +154,12 @@ namespace ISD { unsigned PartOffset; OutputArg() : IsFixed(false) {} - OutputArg(ArgFlagsTy flags, EVT vt, bool isfixed, + OutputArg(ArgFlagsTy flags, EVT vt, EVT argvt, bool isfixed, unsigned origIdx, unsigned partOffs) : Flags(flags), IsFixed(isfixed), OrigArgIndex(origIdx), PartOffset(partOffs) { VT = vt.getSimpleVT(); + ArgVT = argvt; } }; } diff --git a/include/llvm/Target/TargetCallingConv.td b/include/llvm/Target/TargetCallingConv.td index a53ed29..c1bef28 100644 --- a/include/llvm/Target/TargetCallingConv.td +++ b/include/llvm/Target/TargetCallingConv.td @@ -143,4 +143,10 @@ class CallingConv<list<CCAction> actions> { /// returning from getCallPreservedMask(). class CalleeSavedRegs<dag saves> { dag SaveList = saves; + + // Registers that are also preserved across function calls, but should not be + // included in the generated FOO_SaveList array. These registers will be + // included in the FOO_RegMask bit mask. This can be used for registers that + // are saved automatically, like the SPARC register windows. + dag OtherPreserved; } diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index f746daf..d4e14f6 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -181,6 +181,23 @@ public: return false; } + /// Compute the size in bytes and offset within a stack slot of a spilled + /// register or subregister. + /// + /// \param [out] Size in bytes of the spilled value. + /// \param [out] Offset in bytes within the stack slot. + /// \returns true if both Size and Offset are successfully computed. + /// + /// Not all subregisters have computable spill slots. For example, + /// subregisters registers may not be byte-sized, and a pair of discontiguous + /// subregisters has no single offset. + /// + /// Targets with nontrivial bigendian implementations may need to override + /// this, particularly to support spilled vector registers. + virtual bool getStackSlotRange(const TargetRegisterClass *RC, unsigned SubIdx, + unsigned &Size, unsigned &Offset, + const TargetMachine *TM) const; + /// reMaterialize - Re-issue the specified 'original' instruction at the /// specific location targeting a new destination register. /// The register in Orig->getOperand(0).getReg() will be substituted by @@ -615,6 +632,8 @@ public: return false; } + virtual bool enableClusterLoads() const { return false; } + virtual bool shouldClusterLoads(MachineInstr *FirstLdSt, MachineInstr *SecondLdSt, unsigned NumLoads) const { @@ -821,6 +840,8 @@ public: const MachineInstr *MI, unsigned *PredCost = 0) const; + virtual unsigned getPredicationCost(const MachineInstr *MI) const; + virtual int getInstrLatency(const InstrItineraryData *ItinData, SDNode *Node) const; @@ -938,6 +959,26 @@ public: return 0; } + /// \brief Return the minimum clearance before an instruction that reads an + /// unused register. + /// + /// For example, AVX instructions may copy part of an register operand into + /// the unused high bits of the destination register. + /// + /// vcvtsi2sdq %rax, %xmm0<undef>, %xmm14 + /// + /// In the code above, vcvtsi2sdq copies %xmm0[127:64] into %xmm14 creating a + /// false dependence on any previous write to %xmm0. + /// + /// This hook works similarly to getPartialRegUpdateClearance, except that it + /// does not take an operand index. Instead sets \p OpNum to the index of the + /// unused register. + virtual unsigned getUndefRegClearance(const MachineInstr *MI, unsigned &OpNum, + const TargetRegisterInfo *TRI) const { + // The default implementation returns 0 for no undef register dependency. + return 0; + } + /// breakPartialRegDependency - Insert a dependency-breaking instruction /// before MI to eliminate an unwanted dependency on OpNum. /// diff --git a/include/llvm/Target/TargetLibraryInfo.h b/include/llvm/Target/TargetLibraryInfo.h index 8c1f223..46eaef2 100644 --- a/include/llvm/Target/TargetLibraryInfo.h +++ b/include/llvm/Target/TargetLibraryInfo.h @@ -46,6 +46,10 @@ namespace llvm { Znwm, /// void *new(unsigned long, nothrow); ZnwmRKSt9nothrow_t, + /// double __cospi(double x); + cospi, + /// float __cospif(float x); + cospif, /// int __cxa_atexit(void (*f)(void *), void *p, void *d); cxa_atexit, /// void __cxa_guard_abort(guard_t *guard); @@ -61,6 +65,14 @@ namespace llvm { dunder_isoc99_sscanf, /// void *__memcpy_chk(void *s1, const void *s2, size_t n, size_t s1size); memcpy_chk, + /// double __sincospi_stret(double x); + sincospi_stret, + /// float __sincospi_stretf(float x); + sincospi_stretf, + /// double __sinpi(double x); + sinpi, + /// float __sinpif(float x); + sinpif, /// double __sqrt_finite(double x); sqrt_finite, /// float __sqrt_finite(float x); @@ -695,10 +707,13 @@ public: case LibFunc::nearbyint: case LibFunc::nearbyintf: case LibFunc::nearbyintl: case LibFunc::ceil: case LibFunc::ceilf: case LibFunc::ceill: case LibFunc::rint: case LibFunc::rintf: case LibFunc::rintl: + case LibFunc::round: case LibFunc::roundf: case LibFunc::roundl: case LibFunc::trunc: case LibFunc::truncf: case LibFunc::truncl: case LibFunc::log2: case LibFunc::log2f: case LibFunc::log2l: case LibFunc::exp2: case LibFunc::exp2f: case LibFunc::exp2l: - case LibFunc::memcmp: + case LibFunc::memcmp: case LibFunc::strcmp: case LibFunc::strcpy: + case LibFunc::stpcpy: case LibFunc::strlen: case LibFunc::strnlen: + case LibFunc::memchr: return true; } return false; diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index c3fa3cc..5ab04f7 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -148,10 +148,13 @@ public: bool isBigEndian() const { return !IsLittleEndian; } bool isLittleEndian() const { return IsLittleEndian; } - // 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 { return PointerTy; } + + /// 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; virtual MVT getScalarShiftAmountTy(EVT LHSTy) const; EVT getShiftAmountTy(EVT LHSTy) const; @@ -201,6 +204,17 @@ public: return PredictableSelectIsExpensive; } + /// 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 + /// dag combiner. + virtual bool isLoadBitCastBeneficial(EVT /* Load */, EVT /* Bitcast */) const { + return true; + } + /// 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 @@ -518,13 +532,12 @@ public: LegalizeAction getCondCodeAction(ISD::CondCode CC, MVT VT) const { assert((unsigned)CC < array_lengthof(CondCodeActions) && - (unsigned)VT.SimpleTy < sizeof(CondCodeActions[0])*4 && + ((unsigned)VT.SimpleTy >> 4) < array_lengthof(CondCodeActions[0]) && "Table isn't big enough!"); - /// The lower 5 bits of the SimpleTy index into Nth 2bit set from the 64bit - /// value and the upper 27 bits index into the second dimension of the - /// array to select what 64bit value to use. - LegalizeAction Action = (LegalizeAction) - ((CondCodeActions[CC][VT.SimpleTy >> 5] >> (2*(VT.SimpleTy & 0x1F))) & 3); + // See setCondCodeAction for how this is encoded. + uint32_t Shift = 2 * (VT.SimpleTy & 0xF); + uint32_t Value = CondCodeActions[CC][VT.SimpleTy >> 4]; + LegalizeAction Action = (LegalizeAction) ((Value >> Shift) & 0x3); assert(Action != Promote && "Can't promote condition code!"); return Action; } @@ -568,14 +581,18 @@ public: /// otherwise it will assert. EVT getValueType(Type *Ty, bool AllowUnknown = false) const { // Lower scalar pointers to native pointer types. - if (Ty->isPointerTy()) return PointerTy; + if (PointerType *PTy = dyn_cast<PointerType>(Ty)) + return getPointerTy(PTy->getAddressSpace()); if (Ty->isVectorTy()) { VectorType *VTy = cast<VectorType>(Ty); Type *Elm = VTy->getElementType(); // Lower vectors of pointers to native pointer types. - if (Elm->isPointerTy()) - Elm = EVT(PointerTy).getTypeForEVT(Ty->getContext()); + if (PointerType *PT = dyn_cast<PointerType>(Elm)) { + EVT PointerTy(getPointerTy(PT->getAddressSpace())); + Elm = PointerTy.getTypeForEVT(Ty->getContext()); + } + return EVT::getVectorVT(Ty->getContext(), EVT::getEVT(Elm, false), VTy->getNumElements()); } @@ -821,6 +838,11 @@ public: return 0; } + /// Returns true if a cast between SrcAS and DestAS is a noop. + virtual bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const { + return false; + } + //===--------------------------------------------------------------------===// /// \name Helpers for TargetTransformInfo implementations /// @{ @@ -1014,13 +1036,12 @@ protected: assert(VT < MVT::LAST_VALUETYPE && (unsigned)CC < array_lengthof(CondCodeActions) && "Table isn't big enough!"); - /// The lower 5 bits of the SimpleTy index into Nth 2bit set from the 64bit - /// value and the upper 27 bits index into the second dimension of the - /// array to select what 64bit value to use. - CondCodeActions[(unsigned)CC][VT.SimpleTy >> 5] - &= ~(uint64_t(3UL) << (VT.SimpleTy & 0x1F)*2); - CondCodeActions[(unsigned)CC][VT.SimpleTy >> 5] - |= (uint64_t)Action << (VT.SimpleTy & 0x1F)*2; + /// The lower 5 bits of the SimpleTy index into Nth 2bit set from the 32-bit + /// value and the upper 27 bits index into the second dimension of the array + /// to select what 32-bit value to use. + uint32_t Shift = 2 * (VT.SimpleTy & 0xF); + CondCodeActions[CC][VT.SimpleTy >> 4] &= ~((uint32_t)0x3 << Shift); + CondCodeActions[CC][VT.SimpleTy >> 4] |= (uint32_t)Action << Shift; } /// If Opc/OrigVT is specified as being promoted, the promotion code defaults @@ -1181,6 +1202,37 @@ public: return false; } + /// Return true if the target supplies and combines to a paired load + /// two loaded values of type LoadedType next to each other in memory. + /// RequiredAlignment gives the minimal alignment constraints that must be met + /// to be able to select this paired load. + /// + /// This information is *not* used to generate actual paired loads, but it is + /// used to generate a sequence of loads that is easier to combine into a + /// paired load. + /// For instance, something like this: + /// a = load i64* addr + /// b = trunc i64 a to i32 + /// c = lshr i64 a, 32 + /// d = trunc i64 c to i32 + /// will be optimized into: + /// b = load i32* addr1 + /// d = load i32* addr2 + /// Where addr1 = addr2 +/- sizeof(i32). + /// + /// In other words, unless the target performs a post-isel load combining, + /// this information should not be provided because it will generate more + /// loads. + virtual bool hasPairedLoad(Type * /*LoadedType*/, + unsigned & /*RequiredAligment*/) const { + return false; + } + + virtual bool hasPairedLoad(EVT /*LoadedType*/, + unsigned & /*RequiredAligment*/) 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). @@ -1262,10 +1314,6 @@ private: const DataLayout *TD; const TargetLoweringObjectFile &TLOF; - /// The type to use for pointers for the default address space, usually i32 or - /// i64. - MVT PointerTy; - /// True if this is a little endian target. bool IsLittleEndian; @@ -1414,9 +1462,9 @@ private: /// indicates how instruction selection should deal with the condition code. /// /// Because each CC action takes up 2 bits, we need to have the array size be - /// large enough to fit all of the value types. This can be done by dividing - /// the MVT::LAST_VALUETYPE by 32 and adding one. - uint64_t CondCodeActions[ISD::SETCC_INVALID][(MVT::LAST_VALUETYPE / 32) + 1]; + /// large enough to fit all of the value types. This can be done by rounding + /// up the MVT::LAST_VALUETYPE value to the next multiple of 16. + uint32_t CondCodeActions[ISD::SETCC_INVALID][(MVT::LAST_VALUETYPE + 15) / 16]; ValueTypeActionImpl ValueTypeActions; @@ -1471,10 +1519,12 @@ public: if (NumElts == 1) return LegalizeKind(TypeScalarizeVector, EltVT); - // Try to widen vector elements until a legal type is found. + // 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 float> -> <4 x float>. + // widened, for example <3 x i8> -> <4 x i8>. if (!VT.isPow2VectorType()) { NumElts = (unsigned)NextPowerOf2(NumElts); EVT NVT = EVT::getVectorVT(Context, EltVT, NumElts); @@ -1503,7 +1553,8 @@ public: // 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. + // 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. @@ -1664,7 +1715,8 @@ public: /// by reference if this node can be combined with a load / store to form a /// post-indexed load / store. virtual bool getPostIndexedAddressParts(SDNode * /*N*/, SDNode * /*Op*/, - SDValue &/*Base*/, SDValue &/*Offset*/, + SDValue &/*Base*/, + SDValue &/*Offset*/, ISD::MemIndexedMode &/*AM*/, SelectionDAG &/*DAG*/) const { return false; @@ -1702,9 +1754,12 @@ public: SDValue &NewLHS, SDValue &NewRHS, ISD::CondCode &CCCode, SDLoc DL) const; - SDValue makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, - const SDValue *Ops, unsigned NumOps, - bool isSigned, SDLoc dl) const; + /// Returns a pair of (return value, chain). + std::pair<SDValue, SDValue> makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, + EVT RetVT, const SDValue *Ops, + unsigned NumOps, bool isSigned, + SDLoc dl, bool doesNotReturn = false, + bool isReturnValueUsed = true) const; //===--------------------------------------------------------------------===// // TargetLowering Optimization Methods @@ -1882,6 +1937,8 @@ public: ArgListEntry() : isSExt(false), isZExt(false), isInReg(false), isSRet(false), isNest(false), isByVal(false), isReturned(false), Alignment(0) { } + + void setAttributes(ImmutableCallSite *CS, unsigned AttrIdx); }; typedef std::vector<ArgListEntry> ArgListTy; @@ -2015,6 +2072,12 @@ public: return VT.bitsLT(MinVT) ? MinVT : VT; } + /// 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; + } + /// 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. The reason we can not do @@ -2211,12 +2274,12 @@ public: // Instruction Emitting Hooks // - // This method should be implemented by targets that mark instructions with - // the 'usesCustomInserter' flag. These instructions are special in various - // ways, which require special support to insert. The specified MachineInstr - // 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. + /// This method should be implemented by targets that mark instructions with + /// the 'usesCustomInserter' flag. These instructions are special in various + /// ways, which require special support to insert. The specified MachineInstr + /// 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. virtual MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const; diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h index 7f15b74..284b6bb 100644 --- a/include/llvm/Target/TargetLoweringObjectFile.h +++ b/include/llvm/Target/TargetLoweringObjectFile.h @@ -117,6 +117,10 @@ public: MachineModuleInfo *MMI, unsigned Encoding, MCStreamer &Streamer) const; + /// Return the MCSymbol for the specified global value. This symbol is the + /// main label that is the address of the global + MCSymbol *getSymbol(Mangler &M, const GlobalValue *GV) const; + // getCFIPersonalitySymbol - The symbol that gets passed to .cfi_personality. virtual MCSymbol * getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang, diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index fd7228a..11b0f5f 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -29,7 +29,6 @@ class GlobalValue; class MCAsmInfo; class MCCodeGenInfo; class MCContext; -class PassManagerBase; class Target; class DataLayout; class TargetLibraryInfo; @@ -47,6 +46,12 @@ class VectorTargetTransformInfo; class formatted_raw_ostream; class raw_ostream; +// The old pass manager infrastructure is hidden in a legacy namespace now. +namespace legacy { +class PassManagerBase; +} +using legacy::PassManagerBase; + //===----------------------------------------------------------------------===// /// /// TargetMachine - Primary interface to the complete machine description for @@ -70,7 +75,8 @@ protected: // Can only create subclasses. std::string TargetFS; /// CodeGenInfo - Low level target information such as relocation model. - const MCCodeGenInfo *CodeGenInfo; + /// Non-const to allow resetting optimization level per-function. + MCCodeGenInfo *CodeGenInfo; /// AsmInfo - Contains target specific asm information. /// @@ -208,6 +214,9 @@ public: /// Default, or Aggressive. CodeGenOpt::Level getOptLevel() const; + /// \brief Overrides the optimization level. + void setOptLevel(CodeGenOpt::Level Level) const; + void setFastISel(bool Enable) { Options.EnableFastISel = Enable; } bool shouldPrintMachineCode() const { return Options.PrintMachineCode; } diff --git a/include/llvm/Target/TargetOpcodes.h b/include/llvm/Target/TargetOpcodes.h index 516e070..bd74cb9 100644 --- a/include/llvm/Target/TargetOpcodes.h +++ b/include/llvm/Target/TargetOpcodes.h @@ -69,8 +69,9 @@ namespace TargetOpcode { DBG_VALUE = 11, /// REG_SEQUENCE - This variadic instruction is used to form a register that - /// represent a consecutive sequence of sub-registers. It's used as register - /// coalescing / allocation aid and must be eliminated before code emission. + /// represents a consecutive sequence of sub-registers. It's used as a + /// register coalescing / allocation aid and must be eliminated before code + /// emission. // In SDNode form, the first operand encodes the register class created by // the REG_SEQUENCE, while each subsequent pair names a vreg + subreg index // pair. Once it has been lowered to a MachineInstr, the regclass operand @@ -91,7 +92,19 @@ namespace TargetOpcode { /// Lifetime markers. LIFETIME_START = 15, - LIFETIME_END = 16 + LIFETIME_END = 16, + + /// A Stackmap instruction captures the location of live variables at its + /// position in the instruction stream. It is followed by a shadow of bytes + /// that must lie within the function and not contain another stackmap. + STACKMAP = 17, + + /// Patchable call instruction - this instruction represents a call to a + /// constant address, followed by a series of NOPs. It is intended to + /// support optimizations for dynamic languages (such as javascript) that + /// rewrite calls to runtimes with more efficient code sequences. + /// This also implies a stack map. + PATCHPOINT = 18 }; } // end namespace TargetOpcode } // end namespace llvm diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index 82fccde..958bea6 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -901,6 +901,7 @@ static inline raw_ostream &operator<<(raw_ostream &OS, const PrintReg &PR) { /// Usage: OS << PrintRegUnit(Unit, TRI) << '\n'; /// class PrintRegUnit { +protected: const TargetRegisterInfo *TRI; unsigned Unit; public: @@ -914,6 +915,21 @@ static inline raw_ostream &operator<<(raw_ostream &OS, const PrintRegUnit &PR) { return OS; } +/// PrintVRegOrUnit - It is often convenient to track virtual registers and +/// physical register units in the same list. +class PrintVRegOrUnit : protected PrintRegUnit { +public: + PrintVRegOrUnit(unsigned VRegOrUnit, const TargetRegisterInfo *tri) + : PrintRegUnit(VRegOrUnit, tri) {} + void print(raw_ostream&) const; +}; + +static inline raw_ostream &operator<<(raw_ostream &OS, + const PrintVRegOrUnit &PR) { + PR.print(OS); + return OS; +} + } // End llvm namespace #endif diff --git a/include/llvm/Target/TargetSchedule.td b/include/llvm/Target/TargetSchedule.td index 575cb83..9d4858a 100644 --- a/include/llvm/Target/TargetSchedule.td +++ b/include/llvm/Target/TargetSchedule.td @@ -76,7 +76,7 @@ def instregex; // See MCSchedule.h for detailed comments. class SchedMachineModel { int IssueWidth = -1; // Max micro-ops that may be scheduled per cycle. - int MinLatency = -1; // Determines which instrucions are allowed in a group. + int MinLatency = -1; // Determines which instructions are allowed in a group. // (-1) inorder (0) ooo, (1): inorder +var latencies. int MicroOpBufferSize = -1; // Max micro-ops that can be buffered. int LoadLatency = -1; // Cycles for loads to access the cache. @@ -86,6 +86,15 @@ class SchedMachineModel { // Per-cycle resources tables. ProcessorItineraries Itineraries = NoItineraries; + // Subtargets that define a model for only a subset of instructions + // that have a scheduling class (itinerary class or SchedRW list) + // and may actually be generated for that subtarget must clear this + // bit. Otherwise, the scheduler considers an unmodelled opcode to + // be an error. This should only be set during initial bringup, + // or there will be no way to catch simple errors in the model + // resulting from changes to the instruction definitions. + bit CompleteModel = 1; + bit NoModel = 0; // Special tag to indicate missing machine model. } diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td index befab43..d94bdc6 100644 --- a/include/llvm/Target/TargetSelectionDAG.td +++ b/include/llvm/Target/TargetSelectionDAG.td @@ -383,6 +383,7 @@ def ftrunc : SDNode<"ISD::FTRUNC" , SDTFPUnaryOp>; def fceil : SDNode<"ISD::FCEIL" , SDTFPUnaryOp>; def ffloor : SDNode<"ISD::FFLOOR" , SDTFPUnaryOp>; def fnearbyint : SDNode<"ISD::FNEARBYINT" , SDTFPUnaryOp>; +def frnd : SDNode<"ISD::FROUND" , SDTFPUnaryOp>; def fround : SDNode<"ISD::FP_ROUND" , SDTFPRoundOp>; def fextend : SDNode<"ISD::FP_EXTEND" , SDTFPExtendOp>; @@ -464,6 +465,8 @@ def vector_extract : SDNode<"ISD::EXTRACT_VECTOR_ELT", SDTypeProfile<1, 2, [SDTCisPtrTy<2>]>, []>; def vector_insert : SDNode<"ISD::INSERT_VECTOR_ELT", SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisPtrTy<3>]>, []>; +def concat_vectors : SDNode<"ISD::CONCAT_VECTORS", + SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisVec<1>, SDTCisSameAs<1, 2>]>,[]>; // This operator does not do subvector type checking. The ARM // backend, at least, needs it. diff --git a/include/llvm/Target/TargetSelectionDAGInfo.h b/include/llvm/Target/TargetSelectionDAGInfo.h index fe2fba4..3474ee4 100644 --- a/include/llvm/Target/TargetSelectionDAGInfo.h +++ b/include/llvm/Target/TargetSelectionDAGInfo.h @@ -94,6 +94,74 @@ public: MachinePointerInfo DstPtrInfo) const { return SDValue(); } + + /// EmitTargetCodeForMemcmp - Emit target-specific code that performs a + /// memcmp, in cases where that is faster than a libcall. The first + /// returned SDValue is the result of the memcmp and the second is + /// the chain. Both SDValues can be null if a normal libcall should + /// be used. + virtual std::pair<SDValue, SDValue> + EmitTargetCodeForMemcmp(SelectionDAG &DAG, SDLoc dl, + SDValue Chain, + SDValue Op1, SDValue Op2, + SDValue Op3, MachinePointerInfo Op1PtrInfo, + MachinePointerInfo Op2PtrInfo) const { + return std::make_pair(SDValue(), SDValue()); + } + + /// EmitTargetCodeForMemchr - Emit target-specific code that performs a + /// memchr, in cases where that is faster than a libcall. The first + /// returned SDValue is the result of the memchr and the second is + /// the chain. Both SDValues can be null if a normal libcall should + /// be used. + virtual std::pair<SDValue, SDValue> + EmitTargetCodeForMemchr(SelectionDAG &DAG, SDLoc dl, SDValue Chain, + SDValue Src, SDValue Char, SDValue Length, + MachinePointerInfo SrcPtrInfo) const { + return std::make_pair(SDValue(), SDValue()); + } + + /// EmitTargetCodeForStrcpy - Emit target-specific code that performs a + /// strcpy or stpcpy, in cases where that is faster than a libcall. + /// The first returned SDValue is the result of the copy (the start + /// of the destination string for strcpy, a pointer to the null terminator + /// for stpcpy) and the second is the chain. Both SDValues can be null + /// if a normal libcall should be used. + virtual std::pair<SDValue, SDValue> + EmitTargetCodeForStrcpy(SelectionDAG &DAG, SDLoc DL, SDValue Chain, + SDValue Dest, SDValue Src, + MachinePointerInfo DestPtrInfo, + MachinePointerInfo SrcPtrInfo, + bool isStpcpy) const { + return std::make_pair(SDValue(), SDValue()); + } + + /// EmitTargetCodeForStrcmp - Emit target-specific code that performs a + /// strcmp, in cases where that is faster than a libcall. The first + /// returned SDValue is the result of the strcmp and the second is + /// the chain. Both SDValues can be null if a normal libcall should + /// be used. + virtual std::pair<SDValue, SDValue> + EmitTargetCodeForStrcmp(SelectionDAG &DAG, SDLoc dl, + SDValue Chain, + SDValue Op1, SDValue Op2, + MachinePointerInfo Op1PtrInfo, + MachinePointerInfo Op2PtrInfo) const { + return std::make_pair(SDValue(), SDValue()); + } + + virtual std::pair<SDValue, SDValue> + EmitTargetCodeForStrlen(SelectionDAG &DAG, SDLoc DL, SDValue Chain, + SDValue Src, MachinePointerInfo SrcPtrInfo) const { + return std::make_pair(SDValue(), SDValue()); + } + + virtual std::pair<SDValue, SDValue> + EmitTargetCodeForStrnlen(SelectionDAG &DAG, SDLoc DL, SDValue Chain, + SDValue Src, SDValue MaxLength, + MachinePointerInfo SrcPtrInfo) const { + return std::make_pair(SDValue(), SDValue()); + } }; } // end llvm namespace diff --git a/include/llvm/Target/TargetSubtargetInfo.h b/include/llvm/Target/TargetSubtargetInfo.h index b2d405d..1b2e06a 100644 --- a/include/llvm/Target/TargetSubtargetInfo.h +++ b/include/llvm/Target/TargetSubtargetInfo.h @@ -25,6 +25,7 @@ class SDep; class SUnit; class TargetRegisterClass; class TargetSchedModel; +struct MachineSchedPolicy; template <typename T> class SmallVectorImpl; //===----------------------------------------------------------------------===// @@ -55,6 +56,9 @@ public: return 0; } + /// \brief Temporary API to test migration to MI scheduler. + bool useMachineScheduler() const; + /// \brief True if the subtarget should run MachineScheduler after aggressive /// coalescing. /// @@ -62,6 +66,16 @@ public: /// scheduler. It does not yet disable the postRA scheduler. virtual bool enableMachineScheduler() const; + /// \brief Override generic scheduling policy within a region. + /// + /// This is a convenient way for targets that don't provide any custom + /// scheduling heuristics (no custom MachineSchedStrategy) to make + /// changes to the generic scheduling policy. + virtual void overrideSchedPolicy(MachineSchedPolicy &Policy, + MachineInstr *begin, + MachineInstr *end, + unsigned NumRegionInstrs) const {} + // enablePostRAScheduler - If the target can benefit from post-regalloc // scheduling and the specified optimization level meets the requirement // return true to enable post-register-allocation scheduling. In @@ -75,6 +89,10 @@ public: virtual void adjustSchedDependency(SUnit *def, SUnit *use, SDep& dep) const { } + /// \brief Enable use of alias analysis during code generation (during MI + /// scheduling, DAGCombine, etc.). + virtual bool useAA() const; + /// \brief Reset the features for the subtarget. virtual void resetSubtargetFeatures(const MachineFunction *MF) { } }; |