diff options
Diffstat (limited to 'include')
101 files changed, 1862 insertions, 573 deletions
diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index c3822e35906a..94fbd1a29bf9 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -157,6 +157,11 @@ private: return isSingleWord() ? U.VAL : U.pVal[whichWord(bitPosition)]; } + /// Utility method to change the bit width of this APInt to new bit width, + /// allocating and/or deallocating as necessary. There is no guarantee on the + /// value of any bits upon return. Caller should populate the bits after. + void reallocate(unsigned NewBitWidth); + /// \brief Convert a char array into an APInt /// /// \param radix 2, 8, 10, 16, or 36 @@ -1437,6 +1442,12 @@ public: /// as "bitPosition". void flipBit(unsigned bitPosition); + /// Negate this APInt in place. + void negate() { + flipAllBits(); + ++(*this); + } + /// Insert the bits from a smaller APInt starting at bitPosition. void insertBits(const APInt &SubBits, unsigned bitPosition); @@ -1646,12 +1657,7 @@ public: /// re-interprets the bits as a double. Note that it is valid to do this on /// any bit width. Exactly 64 bits will be translated. double bitsToDouble() const { - union { - uint64_t I; - double D; - } T; - T.I = (isSingleWord() ? U.VAL : U.pVal[0]); - return T.D; + return BitsToDouble(getWord(0)); } /// \brief Converts APInt bits to a double @@ -1660,12 +1666,7 @@ public: /// re-interprets the bits as a float. Note that it is valid to do this on /// any bit width. Exactly 32 bits will be translated. float bitsToFloat() const { - union { - unsigned I; - float F; - } T; - T.I = unsigned((isSingleWord() ? U.VAL : U.pVal[0])); - return T.F; + return BitsToFloat(getWord(0)); } /// \brief Converts a double to APInt bits. @@ -1673,12 +1674,7 @@ public: /// The conversion does not do a translation from double to integer, it just /// re-interprets the bits of the double. static APInt doubleToBits(double V) { - union { - uint64_t I; - double D; - } T; - T.D = V; - return APInt(sizeof T * CHAR_BIT, T.I); + return APInt(sizeof(double) * CHAR_BIT, DoubleToBits(V)); } /// \brief Converts a float to APInt bits. @@ -1686,12 +1682,7 @@ public: /// The conversion does not do a translation from float to integer, it just /// re-interprets the bits of the float. static APInt floatToBits(float V) { - union { - unsigned I; - float F; - } T; - T.F = V; - return APInt(sizeof T * CHAR_BIT, T.I); + return APInt(sizeof(float) * CHAR_BIT, FloatToBits(V)); } /// @} @@ -1852,10 +1843,9 @@ public: unsigned); /// DST = LHS * RHS, where DST has width the sum of the widths of the - /// operands. No overflow occurs. DST must be disjoint from both - /// operands. Returns the number of parts required to hold the result. - static unsigned tcFullMultiply(WordType *, const WordType *, - const WordType *, unsigned, unsigned); + /// operands. No overflow occurs. DST must be disjoint from both operands. + static void tcFullMultiply(WordType *, const WordType *, + const WordType *, unsigned, unsigned); /// If RHS is zero LHS and REMAINDER are left unchanged, return one. /// Otherwise set LHS to LHS / RHS with the fractional part discarded, set @@ -1997,8 +1987,7 @@ inline raw_ostream &operator<<(raw_ostream &OS, const APInt &I) { } inline APInt operator-(APInt v) { - v.flipAllBits(); - ++v; + v.negate(); return v; } diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h index e835f1516225..4a2af7cd68a6 100644 --- a/include/llvm/ADT/BitVector.h +++ b/include/llvm/ADT/BitVector.h @@ -255,7 +255,7 @@ public: /// find_prev - Returns the index of the first set bit that precedes the /// the bit at \p PriorTo. Returns -1 if all previous bits are unset. - int find_prev(unsigned PriorTo) { + int find_prev(unsigned PriorTo) const { if (PriorTo == 0) return -1; diff --git a/include/llvm/ADT/STLExtras.h b/include/llvm/ADT/STLExtras.h index 15945adbe589..8c28412bb607 100644 --- a/include/llvm/ADT/STLExtras.h +++ b/include/llvm/ADT/STLExtras.h @@ -706,6 +706,18 @@ struct is_one_of<T, U, Ts...> { std::is_same<T, U>::value || is_one_of<T, Ts...>::value; }; +/// \brief traits class for checking whether type T is a base class for all +/// the given types in the variadic list. +template <typename T, typename... Ts> struct are_base_of { + static const bool value = true; +}; + +template <typename T, typename U, typename... Ts> +struct are_base_of<T, U, Ts...> { + static const bool value = + std::is_base_of<T, U>::value && are_base_of<T, Ts...>::value; +}; + //===----------------------------------------------------------------------===// // Extra additions for arrays //===----------------------------------------------------------------------===// @@ -1079,7 +1091,7 @@ private: /// /// std::vector<char> Items = {'A', 'B', 'C', 'D'}; /// for (auto X : enumerate(Items)) { -/// printf("Item %d - %c\n", X.Index, X.Value); +/// printf("Item %d - %c\n", X.index(), X.value()); /// } /// /// Output: diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h index 26f11924b771..1c109be3bab3 100644 --- a/include/llvm/ADT/StringExtras.h +++ b/include/llvm/ADT/StringExtras.h @@ -106,6 +106,13 @@ static inline std::string fromHex(StringRef Input) { return Output; } +/// \brief Convert the string \p S to an integer of the specified type using +/// the radix \p Base. If \p Base is 0, auto-detects the radix. +/// Returns true if the number was successfully converted, false otherwise. +template <typename N> bool to_integer(StringRef S, N &Num, unsigned Base = 0) { + return !S.getAsInteger(Base, Num); +} + static inline std::string utostr(uint64_t X, bool isNeg = false) { char Buffer[21]; char *BufPtr = std::end(Buffer); diff --git a/include/llvm/Analysis/CallGraph.h b/include/llvm/Analysis/CallGraph.h index cc4788d3edae..01469a25c96c 100644 --- a/include/llvm/Analysis/CallGraph.h +++ b/include/llvm/Analysis/CallGraph.h @@ -41,12 +41,6 @@ /// of all of the caller-callee relationships, which is useful for /// transformations. /// -/// The CallGraph class also attempts to figure out what the root of the -/// CallGraph is, which it currently does by looking for a function named -/// 'main'. If no function named 'main' is found, the external node is used as -/// the entry node, reflecting the fact that any function without internal -/// linkage could be called into (which is common for libraries). -/// //===----------------------------------------------------------------------===// #ifndef LLVM_ANALYSIS_CALLGRAPH_H @@ -82,10 +76,6 @@ class CallGraph { /// \brief A map from \c Function* to \c CallGraphNode*. FunctionMapTy FunctionMap; - /// \brief Root is root of the call graph, or the external node if a 'main' - /// function couldn't be found. - CallGraphNode *Root; - /// \brief This node has edges to all external functions and those internal /// functions that have their address taken. CallGraphNode *ExternalCallingNode; diff --git a/include/llvm/Analysis/ProfileSummaryInfo.h b/include/llvm/Analysis/ProfileSummaryInfo.h index 75c4cbd03706..c5f97083af4d 100644 --- a/include/llvm/Analysis/ProfileSummaryInfo.h +++ b/include/llvm/Analysis/ProfileSummaryInfo.h @@ -67,8 +67,8 @@ public: } /// Returns the profile count for \p CallInst. - static Optional<uint64_t> getProfileCount(const Instruction *CallInst, - BlockFrequencyInfo *BFI); + Optional<uint64_t> getProfileCount(const Instruction *CallInst, + BlockFrequencyInfo *BFI); /// \brief Returns true if \p F has hot function entry. bool isFunctionEntryHot(const Function *F); /// Returns true if \p F has hot function entry or hot call edge. diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index 85350fa159d6..ceca6cb389a1 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -568,27 +568,16 @@ private: Predicates.insert(P); } - /*implicit*/ ExitLimit(const SCEV *E) - : ExactNotTaken(E), MaxNotTaken(E), MaxOrZero(false) {} + /*implicit*/ ExitLimit(const SCEV *E); ExitLimit( const SCEV *E, const SCEV *M, bool MaxOrZero, - ArrayRef<const SmallPtrSetImpl<const SCEVPredicate *> *> PredSetList) - : ExactNotTaken(E), MaxNotTaken(M), MaxOrZero(MaxOrZero) { - assert((isa<SCEVCouldNotCompute>(ExactNotTaken) || - !isa<SCEVCouldNotCompute>(MaxNotTaken)) && - "Exact is not allowed to be less precise than Max"); - for (auto *PredSet : PredSetList) - for (auto *P : *PredSet) - addPredicate(P); - } + ArrayRef<const SmallPtrSetImpl<const SCEVPredicate *> *> PredSetList); ExitLimit(const SCEV *E, const SCEV *M, bool MaxOrZero, - const SmallPtrSetImpl<const SCEVPredicate *> &PredSet) - : ExitLimit(E, M, MaxOrZero, {&PredSet}) {} + const SmallPtrSetImpl<const SCEVPredicate *> &PredSet); - ExitLimit(const SCEV *E, const SCEV *M, bool MaxOrZero) - : ExitLimit(E, M, MaxOrZero, None) {} + ExitLimit(const SCEV *E, const SCEV *M, bool MaxOrZero); /// Test whether this ExitLimit contains any computed information, or /// whether it's all SCEVCouldNotCompute values. @@ -782,7 +771,7 @@ private: /// Set the memoized range for the given SCEV. const ConstantRange &setRange(const SCEV *S, RangeSignHint Hint, - ConstantRange &&CR) { + ConstantRange CR) { DenseMap<const SCEV *, ConstantRange> &Cache = Hint == HINT_RANGE_UNSIGNED ? UnsignedRanges : SignedRanges; diff --git a/include/llvm/Analysis/TargetLibraryInfo.def b/include/llvm/Analysis/TargetLibraryInfo.def index 099a3c7cf2ac..9cbe917c146d 100644 --- a/include/llvm/Analysis/TargetLibraryInfo.def +++ b/include/llvm/Analysis/TargetLibraryInfo.def @@ -161,6 +161,60 @@ TLI_DEFINE_STRING_INTERNAL("_Znwm") /// void *new(unsigned long, nothrow); TLI_DEFINE_ENUM_INTERNAL(ZnwmRKSt9nothrow_t) TLI_DEFINE_STRING_INTERNAL("_ZnwmRKSt9nothrow_t") +/// double __acos_finite(double x); +TLI_DEFINE_ENUM_INTERNAL(acos_finite) +TLI_DEFINE_STRING_INTERNAL("__acos_finite") +/// float __acosf_finite(float x); +TLI_DEFINE_ENUM_INTERNAL(acosf_finite) +TLI_DEFINE_STRING_INTERNAL("__acosf_finite") +/// double __acosh_finite(double x); +TLI_DEFINE_ENUM_INTERNAL(acosh_finite) +TLI_DEFINE_STRING_INTERNAL("__acosh_finite") +/// float __acoshf_finite(float x); +TLI_DEFINE_ENUM_INTERNAL(acoshf_finite) +TLI_DEFINE_STRING_INTERNAL("__acoshf_finite") +/// long double __acoshl_finite(long double x); +TLI_DEFINE_ENUM_INTERNAL(acoshl_finite) +TLI_DEFINE_STRING_INTERNAL("__acoshl_finite") +/// long double __acosl_finite(long double x); +TLI_DEFINE_ENUM_INTERNAL(acosl_finite) +TLI_DEFINE_STRING_INTERNAL("__acosl_finite") +/// double __asin_finite(double x); +TLI_DEFINE_ENUM_INTERNAL(asin_finite) +TLI_DEFINE_STRING_INTERNAL("__asin_finite") +/// float __asinf_finite(float x); +TLI_DEFINE_ENUM_INTERNAL(asinf_finite) +TLI_DEFINE_STRING_INTERNAL("__asinf_finite") +/// long double __asinl_finite(long double x); +TLI_DEFINE_ENUM_INTERNAL(asinl_finite) +TLI_DEFINE_STRING_INTERNAL("__asinl_finite") +/// double atan2_finite(double y, double x); +TLI_DEFINE_ENUM_INTERNAL(atan2_finite) +TLI_DEFINE_STRING_INTERNAL("__atan2_finite") +/// float atan2f_finite(float y, float x); +TLI_DEFINE_ENUM_INTERNAL(atan2f_finite) +TLI_DEFINE_STRING_INTERNAL("__atan2f_finite") +/// long double atan2l_finite(long double y, long double x); +TLI_DEFINE_ENUM_INTERNAL(atan2l_finite) +TLI_DEFINE_STRING_INTERNAL("__atan2l_finite") +/// double __atanh_finite(double x); +TLI_DEFINE_ENUM_INTERNAL(atanh_finite) +TLI_DEFINE_STRING_INTERNAL("__atanh_finite") +/// float __atanhf_finite(float x); +TLI_DEFINE_ENUM_INTERNAL(atanhf_finite) +TLI_DEFINE_STRING_INTERNAL("__atanhf_finite") +/// long double __atanhl_finite(long double x); +TLI_DEFINE_ENUM_INTERNAL(atanhl_finite) +TLI_DEFINE_STRING_INTERNAL("__atanhl_finite") +/// double __cosh_finite(double x); +TLI_DEFINE_ENUM_INTERNAL(cosh_finite) +TLI_DEFINE_STRING_INTERNAL("__cosh_finite") +/// float __coshf_finite(float x); +TLI_DEFINE_ENUM_INTERNAL(coshf_finite) +TLI_DEFINE_STRING_INTERNAL("__coshf_finite") +/// long double __coshl_finite(long double x); +TLI_DEFINE_ENUM_INTERNAL(coshl_finite) +TLI_DEFINE_STRING_INTERNAL("__coshl_finite") /// double __cospi(double x); TLI_DEFINE_ENUM_INTERNAL(cospi) TLI_DEFINE_STRING_INTERNAL("__cospi") @@ -180,12 +234,66 @@ TLI_DEFINE_STRING_INTERNAL("__cxa_guard_acquire") /// void __cxa_guard_release(guard_t *guard); TLI_DEFINE_ENUM_INTERNAL(cxa_guard_release) TLI_DEFINE_STRING_INTERNAL("__cxa_guard_release") +/// double __exp10_finite(double x); +TLI_DEFINE_ENUM_INTERNAL(exp10_finite) +TLI_DEFINE_STRING_INTERNAL("__exp10_finite") +/// float __exp10f_finite(float x); +TLI_DEFINE_ENUM_INTERNAL(exp10f_finite) +TLI_DEFINE_STRING_INTERNAL("__exp10f_finite") +/// long double __exp10l_finite(long double x); +TLI_DEFINE_ENUM_INTERNAL(exp10l_finite) +TLI_DEFINE_STRING_INTERNAL("__exp10l_finite") +/// double __exp2_finite(double x); +TLI_DEFINE_ENUM_INTERNAL(exp2_finite) +TLI_DEFINE_STRING_INTERNAL("__exp2_finite") +/// float __exp2f_finite(float x); +TLI_DEFINE_ENUM_INTERNAL(exp2f_finite) +TLI_DEFINE_STRING_INTERNAL("__exp2f_finite") +/// long double __exp2l_finite(long double x); +TLI_DEFINE_ENUM_INTERNAL(exp2l_finite) +TLI_DEFINE_STRING_INTERNAL("__exp2l_finite") +/// double __exp_finite(double x); +TLI_DEFINE_ENUM_INTERNAL(exp_finite) +TLI_DEFINE_STRING_INTERNAL("__exp_finite") +/// float __expf_finite(float x); +TLI_DEFINE_ENUM_INTERNAL(expf_finite) +TLI_DEFINE_STRING_INTERNAL("__expf_finite") +/// long double __expl_finite(long double x); +TLI_DEFINE_ENUM_INTERNAL(expl_finite) +TLI_DEFINE_STRING_INTERNAL("__expl_finite") /// int __isoc99_scanf (const char *format, ...) TLI_DEFINE_ENUM_INTERNAL(dunder_isoc99_scanf) TLI_DEFINE_STRING_INTERNAL("__isoc99_scanf") /// int __isoc99_sscanf(const char *s, const char *format, ...) TLI_DEFINE_ENUM_INTERNAL(dunder_isoc99_sscanf) TLI_DEFINE_STRING_INTERNAL("__isoc99_sscanf") +/// double __log10_finite(double x); +TLI_DEFINE_ENUM_INTERNAL(log10_finite) +TLI_DEFINE_STRING_INTERNAL("__log10_finite") +/// float __log10f_finite(float x); +TLI_DEFINE_ENUM_INTERNAL(log10f_finite) +TLI_DEFINE_STRING_INTERNAL("__log10f_finite") +/// long double __log10l_finite(long double x); +TLI_DEFINE_ENUM_INTERNAL(log10l_finite) +TLI_DEFINE_STRING_INTERNAL("__log10l_finite") +/// double __log2_finite(double x); +TLI_DEFINE_ENUM_INTERNAL(log2_finite) +TLI_DEFINE_STRING_INTERNAL("__log2_finite") +/// float __log2f_finite(float x); +TLI_DEFINE_ENUM_INTERNAL(log2f_finite) +TLI_DEFINE_STRING_INTERNAL("__log2f_finite") +/// long double __log2l_finite(long double x); +TLI_DEFINE_ENUM_INTERNAL(log2l_finite) +TLI_DEFINE_STRING_INTERNAL("__log2l_finite") +/// double __log_finite(double x); +TLI_DEFINE_ENUM_INTERNAL(log_finite) +TLI_DEFINE_STRING_INTERNAL("__log_finite") +/// float __logf_finite(float x); +TLI_DEFINE_ENUM_INTERNAL(logf_finite) +TLI_DEFINE_STRING_INTERNAL("__logf_finite") +/// long double __logl_finite(long double x); +TLI_DEFINE_ENUM_INTERNAL(logl_finite) +TLI_DEFINE_STRING_INTERNAL("__logl_finite") /// void *__memcpy_chk(void *s1, const void *s2, size_t n, size_t s1size); TLI_DEFINE_ENUM_INTERNAL(memcpy_chk) TLI_DEFINE_STRING_INTERNAL("__memcpy_chk") @@ -199,13 +307,30 @@ TLI_DEFINE_STRING_INTERNAL("__memset_chk") // int __nvvm_reflect(const char *) TLI_DEFINE_ENUM_INTERNAL(nvvm_reflect) TLI_DEFINE_STRING_INTERNAL("__nvvm_reflect") - +/// double __pow_finite(double x, double y); +TLI_DEFINE_ENUM_INTERNAL(pow_finite) +TLI_DEFINE_STRING_INTERNAL("__pow_finite") +/// float _powf_finite(float x, float y); +TLI_DEFINE_ENUM_INTERNAL(powf_finite) +TLI_DEFINE_STRING_INTERNAL("__powf_finite") +/// long double __powl_finite(long double x, long double y); +TLI_DEFINE_ENUM_INTERNAL(powl_finite) +TLI_DEFINE_STRING_INTERNAL("__powl_finite") /// double __sincospi_stret(double x); TLI_DEFINE_ENUM_INTERNAL(sincospi_stret) TLI_DEFINE_STRING_INTERNAL("__sincospi_stret") /// float __sincospif_stret(float x); TLI_DEFINE_ENUM_INTERNAL(sincospif_stret) TLI_DEFINE_STRING_INTERNAL("__sincospif_stret") +/// double __sinh_finite(double x); +TLI_DEFINE_ENUM_INTERNAL(sinh_finite) +TLI_DEFINE_STRING_INTERNAL("__sinh_finite") +/// float _sinhf_finite(float x); +TLI_DEFINE_ENUM_INTERNAL(sinhf_finite) +TLI_DEFINE_STRING_INTERNAL("__sinhf_finite") +/// long double __sinhl_finite(long double x); +TLI_DEFINE_ENUM_INTERNAL(sinhl_finite) +TLI_DEFINE_STRING_INTERNAL("__sinhl_finite") /// double __sinpi(double x); TLI_DEFINE_ENUM_INTERNAL(sinpi) TLI_DEFINE_STRING_INTERNAL("__sinpi") diff --git a/include/llvm/Analysis/TargetTransformInfo.h b/include/llvm/Analysis/TargetTransformInfo.h index b9639dba1881..0a0af384c3e6 100644 --- a/include/llvm/Analysis/TargetTransformInfo.h +++ b/include/llvm/Analysis/TargetTransformInfo.h @@ -537,6 +537,9 @@ public: /// \return The width of the largest scalar or vector register type. unsigned getRegisterBitWidth(bool Vector) const; + /// \return The width of the smallest vector register type. + unsigned getMinVectorRegisterBitWidth() const; + /// \return True if it should be considered for address type promotion. /// \p AllowPromotionWithoutCommonHeader Set true if promoting \p I is /// profitable without finding other extensions fed by the same input. @@ -740,6 +743,22 @@ public: unsigned ChainSizeInBytes, VectorType *VecTy) const; + /// Flags describing the kind of vector reduction. + struct ReductionFlags { + ReductionFlags() : IsMaxOp(false), IsSigned(false), NoNaN(false) {} + bool IsMaxOp; ///< If the op a min/max kind, true if it's a max operation. + bool IsSigned; ///< Whether the operation is a signed int reduction. + bool NoNaN; ///< If op is an fp min/max, whether NaNs may be present. + }; + + /// \returns True if the target wants to handle the given reduction idiom in + /// the intrinsics form instead of the shuffle form. + bool useReductionIntrinsic(unsigned Opcode, Type *Ty, + ReductionFlags Flags) const; + + /// \returns True if the target wants to expand the given reduction intrinsic + /// into a shuffle sequence. + bool shouldExpandReduction(const IntrinsicInst *II) const; /// @} private: @@ -824,6 +843,7 @@ public: Type *Ty) = 0; virtual unsigned getNumberOfRegisters(bool Vector) = 0; virtual unsigned getRegisterBitWidth(bool Vector) = 0; + virtual unsigned getMinVectorRegisterBitWidth() = 0; virtual bool shouldConsiderAddressTypePromotion( const Instruction &I, bool &AllowPromotionWithoutCommonHeader) = 0; virtual unsigned getCacheLineSize() = 0; @@ -895,6 +915,9 @@ public: virtual unsigned getStoreVectorFactor(unsigned VF, unsigned StoreSize, unsigned ChainSizeInBytes, VectorType *VecTy) const = 0; + virtual bool useReductionIntrinsic(unsigned Opcode, Type *Ty, + ReductionFlags) const = 0; + virtual bool shouldExpandReduction(const IntrinsicInst *II) const = 0; }; template <typename T> @@ -1057,6 +1080,9 @@ public: unsigned getRegisterBitWidth(bool Vector) override { return Impl.getRegisterBitWidth(Vector); } + unsigned getMinVectorRegisterBitWidth() override { + return Impl.getMinVectorRegisterBitWidth(); + } bool shouldConsiderAddressTypePromotion( const Instruction &I, bool &AllowPromotionWithoutCommonHeader) override { return Impl.shouldConsiderAddressTypePromotion( @@ -1200,6 +1226,13 @@ public: VectorType *VecTy) const override { return Impl.getStoreVectorFactor(VF, StoreSize, ChainSizeInBytes, VecTy); } + bool useReductionIntrinsic(unsigned Opcode, Type *Ty, + ReductionFlags Flags) const override { + return Impl.useReductionIntrinsic(Opcode, Ty, Flags); + } + bool shouldExpandReduction(const IntrinsicInst *II) const override { + return Impl.shouldExpandReduction(II); + } }; template <typename T> diff --git a/include/llvm/Analysis/TargetTransformInfoImpl.h b/include/llvm/Analysis/TargetTransformInfoImpl.h index d7fda9e14b05..550e84ad90c4 100644 --- a/include/llvm/Analysis/TargetTransformInfoImpl.h +++ b/include/llvm/Analysis/TargetTransformInfoImpl.h @@ -311,6 +311,8 @@ public: unsigned getRegisterBitWidth(bool Vector) { return 32; } + unsigned getMinVectorRegisterBitWidth() { return 128; } + bool shouldConsiderAddressTypePromotion(const Instruction &I, bool &AllowPromotionWithoutCommonHeader) { @@ -456,6 +458,16 @@ public: VectorType *VecTy) const { return VF; } + + bool useReductionIntrinsic(unsigned Opcode, Type *Ty, + TTI::ReductionFlags Flags) const { + return false; + } + + bool shouldExpandReduction(const IntrinsicInst *II) const { + return true; + } + protected: // Obtain the minimum required size to hold the value (without the sign) // In case of a vector it returns the min required size for one element. diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h index a54c39e3ea3a..f5f323c6b797 100644 --- a/include/llvm/Analysis/ValueTracking.h +++ b/include/llvm/Analysis/ValueTracking.h @@ -56,6 +56,11 @@ template <typename T> class ArrayRef; const Instruction *CxtI = nullptr, const DominatorTree *DT = nullptr, OptimizationRemarkEmitter *ORE = nullptr); + /// Returns the known bits rather than passing by reference. + KnownBits computeKnownBits(const Value *V, const DataLayout &DL, + unsigned Depth = 0, AssumptionCache *AC = nullptr, + const Instruction *CxtI = nullptr, + const DominatorTree *DT = nullptr); /// Compute known bits from the range metadata. /// \p KnownZero the set of bits that are known to be zero /// \p KnownOne the set of bits that are known to be one @@ -68,14 +73,6 @@ template <typename T> class ArrayRef; const Instruction *CxtI = nullptr, const DominatorTree *DT = nullptr); - /// Determine whether the sign bit is known to be zero or one. Convenience - /// wrapper around computeKnownBits. - void ComputeSignBit(const Value *V, bool &KnownZero, bool &KnownOne, - const DataLayout &DL, unsigned Depth = 0, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr, - const DominatorTree *DT = nullptr); - /// Return true if the given value is known to have exactly one bit set when /// defined. For vectors return true if every element is known to be a power /// of two when defined. Supports values with integer or pointer type and diff --git a/include/llvm/Bitcode/BitcodeReader.h b/include/llvm/Bitcode/BitcodeReader.h index 54f990d00233..31ffb7645f3a 100644 --- a/include/llvm/Bitcode/BitcodeReader.h +++ b/include/llvm/Bitcode/BitcodeReader.h @@ -152,10 +152,11 @@ namespace llvm { /// Parse the module summary index out of an IR file and return the module /// summary index object if found, or an empty summary if not. If Path refers - /// to an empty file and the -ignore-empty-index-file cl::opt flag is passed + /// to an empty file and IgnoreEmptyThinLTOIndexFile is true, then /// this function will return nullptr. Expected<std::unique_ptr<ModuleSummaryIndex>> - getModuleSummaryIndexForFile(StringRef Path); + getModuleSummaryIndexForFile(StringRef Path, + bool IgnoreEmptyThinLTOIndexFile = false); /// isBitcodeWrapper - Return true if the given bytes are the magic bytes /// for an LLVM IR bitcode wrapper. diff --git a/include/llvm/CodeGen/ExpandReductions.h b/include/llvm/CodeGen/ExpandReductions.h new file mode 100644 index 000000000000..c6aaaad967b3 --- /dev/null +++ b/include/llvm/CodeGen/ExpandReductions.h @@ -0,0 +1,24 @@ +//===----- ExpandReductions.h - Expand experimental reduction intrinsics --===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_EXPANDREDUCTIONS_H +#define LLVM_CODEGEN_EXPANDREDUCTIONS_H + +#include "llvm/IR/PassManager.h" + +namespace llvm { + +class ExpandReductionsPass + : public PassInfoMixin<ExpandReductionsPass> { +public: + PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); +}; +} // end namespace llvm + +#endif // LLVM_CODEGEN_EXPANDREDUCTIONS_H diff --git a/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h b/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h index 30d67eb49923..21354ae20ed1 100644 --- a/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h +++ b/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h @@ -145,7 +145,7 @@ public: /// Iterate the given function (typically something like doubling the width) /// on Ty until we find a legal type for this operation. - LLT findLegalType(const InstrAspect &Aspect, + Optional<LLT> findLegalType(const InstrAspect &Aspect, function_ref<LLT(LLT)> NextType) const { LegalizeAction Action; const TypeMap &Map = Actions[Aspect.Opcode - FirstOp][Aspect.Idx]; @@ -153,8 +153,12 @@ public: do { Ty = NextType(Ty); auto ActionIt = Map.find(Ty); - if (ActionIt == Map.end()) - Action = DefaultActions.find(Aspect.Opcode)->second; + if (ActionIt == Map.end()) { + auto DefaultIt = DefaultActions.find(Aspect.Opcode); + if (DefaultIt == DefaultActions.end()) + return None; + Action = DefaultIt->second; + } else Action = ActionIt->second; } while(Action != Legal); @@ -163,11 +167,14 @@ public: /// Find what type it's actually OK to perform the given operation on, given /// the general approach we've decided to take. - LLT findLegalType(const InstrAspect &Aspect, LegalizeAction Action) const; + Optional<LLT> findLegalType(const InstrAspect &Aspect, LegalizeAction Action) const; std::pair<LegalizeAction, LLT> findLegalAction(const InstrAspect &Aspect, LegalizeAction Action) const { - return std::make_pair(Action, findLegalType(Aspect, Action)); + auto LegalType = findLegalType(Aspect, Action); + if (!LegalType) + return std::make_pair(LegalizeAction::Unsupported, LLT()); + return std::make_pair(Action, *LegalType); } /// Find the specified \p Aspect in the primary (explicitly set) Actions diff --git a/include/llvm/CodeGen/GlobalISel/Utils.h b/include/llvm/CodeGen/GlobalISel/Utils.h index 92bc9736141a..69d507069808 100644 --- a/include/llvm/CodeGen/GlobalISel/Utils.h +++ b/include/llvm/CodeGen/GlobalISel/Utils.h @@ -30,6 +30,7 @@ class TargetInstrInfo; class TargetPassConfig; class TargetRegisterInfo; class Twine; +class ConstantFP; /// Try to constrain Reg so that it is usable by argument OpIdx of the /// provided MCInstrDesc \p II. If this fails, create a new virtual @@ -62,6 +63,8 @@ void reportGISelFailure(MachineFunction &MF, const TargetPassConfig &TPC, Optional<int64_t> getConstantVRegVal(unsigned VReg, const MachineRegisterInfo &MRI); +const ConstantFP* getConstantFPVRegVal(unsigned VReg, + const MachineRegisterInfo &MRI); } // End namespace llvm. #endif diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h index ca0f3fbad892..f2a9a9f73ca6 100644 --- a/include/llvm/CodeGen/ISDOpcodes.h +++ b/include/llvm/CodeGen/ISDOpcodes.h @@ -644,6 +644,13 @@ namespace ISD { /// of a call sequence, and carry arbitrary information that target might /// want to know. The first operand is a chain, the rest are specified by /// the target and not touched by the DAG optimizers. + /// Targets that may use stack to pass call arguments define additional + /// operands: + /// - size of the call frame part that must be set up within the + /// CALLSEQ_START..CALLSEQ_END pair, + /// - part of the call frame prepared prior to CALLSEQ_START. + /// Both these parameters must be constants, their sum is the total call + /// frame size. /// CALLSEQ_START..CALLSEQ_END pairs may not be nested. CALLSEQ_START, // Beginning of a call sequence CALLSEQ_END, // End of a call sequence @@ -783,6 +790,20 @@ namespace ISD { /// known nonzero constant. The only operand here is the chain. GET_DYNAMIC_AREA_OFFSET, + /// Generic reduction nodes. These nodes represent horizontal vector + /// reduction operations, producing a scalar result. + /// The STRICT variants perform reductions in sequential order. The first + /// operand is an initial scalar accumulator value, and the second operand + /// is the vector to reduce. + VECREDUCE_STRICT_FADD, VECREDUCE_STRICT_FMUL, + /// These reductions are non-strict, and have a single vector operand. + VECREDUCE_FADD, VECREDUCE_FMUL, + VECREDUCE_ADD, VECREDUCE_MUL, + VECREDUCE_AND, VECREDUCE_OR, VECREDUCE_XOR, + VECREDUCE_SMAX, VECREDUCE_SMIN, VECREDUCE_UMAX, VECREDUCE_UMIN, + /// FMIN/FMAX nodes can have flags, for NaN/NoNaN variants. + VECREDUCE_FMAX, VECREDUCE_FMIN, + /// BUILTIN_OP_END - This must be the last enum value in this list. /// The target-specific pre-isel opcode values start here. BUILTIN_OP_END diff --git a/include/llvm/CodeGen/MachineCombinerPattern.h b/include/llvm/CodeGen/MachineCombinerPattern.h index 11238016d447..8c54ae925470 100644 --- a/include/llvm/CodeGen/MachineCombinerPattern.h +++ b/include/llvm/CodeGen/MachineCombinerPattern.h @@ -48,6 +48,8 @@ enum class MachineCombinerPattern { FMULADDD_OP2, FMULSUBD_OP1, FMULSUBD_OP2, + FNMULSUBS_OP1, + FNMULSUBD_OP1, FMLAv1i32_indexed_OP1, FMLAv1i32_indexed_OP2, FMLAv1i64_indexed_OP1, diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index 42299b529410..8a5a1997386f 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -68,6 +68,10 @@ namespace llvm { /// matching during instruction selection. FunctionPass *createCodeGenPreparePass(const TargetMachine *TM = nullptr); + /// createScalarizeMaskedMemIntrinPass - Replace masked load, store, gather + /// and scatter intrinsics with scalar code when target doesn't support them. + FunctionPass *createScalarizeMaskedMemIntrinPass(); + /// AtomicExpandID -- Lowers atomic operations in terms of either cmpxchg /// load-linked/store-conditional loops. extern char &AtomicExpandID; @@ -129,6 +133,10 @@ namespace llvm { // instruction and update the MachineFunctionInfo with that information. extern char &ShrinkWrapID; + /// LiveRangeShrink pass. Move instruction close to its definition to shrink + /// the definition's live range. + extern char &LiveRangeShrinkID; + /// Greedy register allocator. extern char &RAGreedyID; @@ -405,6 +413,10 @@ namespace llvm { /// printing assembly. ModulePass *createMachineOutlinerPass(); + /// This pass expands the experimental reduction intrinsics into sequences of + /// shuffles. + FunctionPass *createExpandReductionsPass(); + } // End llvm namespace /// Target machine pass initializer for passes with dependencies. Use with diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index 9e1d148c7ce5..d761661f763e 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -406,7 +406,7 @@ public: /// certain types of nodes together, or eliminating superfluous nodes. The /// Level argument controls whether Combine is allowed to produce nodes and /// types that are illegal on the target. - void Combine(CombineLevel Level, AliasAnalysis &AA, + void Combine(CombineLevel Level, AliasAnalysis *AA, CodeGenOpt::Level OptLevel); /// This transforms the SelectionDAG into a SelectionDAG that @@ -737,11 +737,15 @@ public: /// \brief Create a logical NOT operation as (XOR Val, BooleanOne). SDValue getLogicalNOT(const SDLoc &DL, SDValue Val, EVT VT); - /// Return a new CALLSEQ_START node, which always must have a glue result - /// (to ensure it's not CSE'd). CALLSEQ_START does not have a useful SDLoc. - SDValue getCALLSEQ_START(SDValue Chain, SDValue Op, const SDLoc &DL) { + /// Return a new CALLSEQ_START node, that starts new call frame, in which + /// InSize bytes are set up inside CALLSEQ_START..CALLSEQ_END sequence and + /// OutSize specifies part of the frame set up prior to the sequence. + SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, + const SDLoc &DL) { SDVTList VTs = getVTList(MVT::Other, MVT::Glue); - SDValue Ops[] = { Chain, Op }; + SDValue Ops[] = { Chain, + getIntPtrConstant(InSize, DL, true), + getIntPtrConstant(OutSize, DL, true) }; return getNode(ISD::CALLSEQ_START, DL, VTs, Ops); } diff --git a/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h b/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h index e9012db7602d..f3122f0bf7f0 100644 --- a/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h +++ b/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h @@ -26,6 +26,7 @@ public: void addTypeServerHandler(TypeServerHandler &Handler); + Error visitTypeRecord(CVType &Record, TypeIndex Index); Error visitTypeRecord(CVType &Record); Error visitMemberRecord(CVMemberRecord &Record); @@ -37,6 +38,9 @@ public: Error visitFieldListMemberStream(BinaryStreamReader Reader); private: + Expected<bool> handleTypeServer(CVType &Record); + Error finishVisitation(CVType &Record); + /// The interface to the class that gets notified of each visitation. TypeVisitorCallbacks &Callbacks; diff --git a/include/llvm/DebugInfo/CodeView/RandomAccessTypeVisitor.h b/include/llvm/DebugInfo/CodeView/RandomAccessTypeVisitor.h new file mode 100644 index 000000000000..35a8010f1163 --- /dev/null +++ b/include/llvm/DebugInfo/CodeView/RandomAccessTypeVisitor.h @@ -0,0 +1,103 @@ +//===- RandomAccessTypeVisitor.h ------------------------------ *- C++ --*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_RANDOMACCESSTYPEVISITOR_H +#define LLVM_DEBUGINFO_CODEVIEW_RANDOMACCESSTYPEVISITOR_H + +#include "llvm/ADT/TinyPtrVector.h" +#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" +#include "llvm/DebugInfo/CodeView/TypeDatabase.h" +#include "llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h" +#include "llvm/DebugInfo/CodeView/TypeDeserializer.h" +#include "llvm/DebugInfo/CodeView/TypeIndex.h" +#include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h" +#include "llvm/Support/Error.h" + +namespace llvm { +namespace codeview { + +class TypeDatabase; +class TypeServerHandler; +class TypeVisitorCallbacks; + +/// \brief Provides amortized O(1) random access to a CodeView type stream. +/// Normally to access a type from a type stream, you must know its byte +/// offset into the type stream, because type records are variable-lengthed. +/// However, this is not the way we prefer to access them. For example, given +/// a symbol record one of the fields may be the TypeIndex of the symbol's +/// type record. Or given a type record such as an array type, there might +/// be a TypeIndex for the element type. Sequential access is perfect when +/// we're just dumping every entry, but it's very poor for real world usage. +/// +/// Type streams in PDBs contain an additional field which is a list of pairs +/// containing indices and their corresponding offsets, roughly every ~8KB of +/// record data. This general idea need not be confined to PDBs though. By +/// supplying such an array, the producer of a type stream can allow the +/// consumer much better access time, because the consumer can find the nearest +/// index in this array, and do a linear scan forward only from there. +/// +/// RandomAccessTypeVisitor implements this algorithm, but additionally goes one +/// step further by caching offsets of every record that has been visited at +/// least once. This way, even repeated visits of the same record will never +/// require more than one linear scan. For a type stream of N elements divided +/// into M chunks of roughly equal size, this yields a worst case lookup time +/// of O(N/M) and an amortized time of O(1). +class RandomAccessTypeVisitor { + typedef FixedStreamArray<TypeIndexOffset> PartialOffsetArray; + +public: + RandomAccessTypeVisitor(const CVTypeArray &Types, uint32_t NumRecords, + PartialOffsetArray PartialOffsets); + + Error visitTypeIndex(TypeIndex Index, TypeVisitorCallbacks &Callbacks); + + const TypeDatabase &database() const { return Database; } + +private: + Error visitRangeForType(TypeIndex TI); + Error visitRange(TypeIndex Begin, uint32_t BeginOffset, TypeIndex End); + + /// Visited records get automatically added to the type database. + TypeDatabase Database; + + /// The type array to allow random access visitation of. + const CVTypeArray &Types; + + /// The database visitor which adds new records to the database. + TypeDatabaseVisitor DatabaseVisitor; + + /// The deserializer which deserializes new records. + TypeDeserializer Deserializer; + + /// The visitation callback pipeline to use. By default this contains a + /// deserializer and a type database visitor. But the callback specified + /// in the constructor is also added. + TypeVisitorCallbackPipeline Pipeline; + + /// The visitor used to visit the internal pipeline for deserialization and + /// database maintenance. + CVTypeVisitor InternalVisitor; + + /// A vector mapping type indices to type offset. For every record that has + /// been visited, contains the absolute offset of that record in the record + /// array. + std::vector<uint32_t> KnownOffsets; + + /// An array of index offsets for the given type stream, allowing log(N) + /// lookups of a type record by index. Similar to KnownOffsets but only + /// contains offsets for some type indices, some of which may not have + /// ever been visited. + PartialOffsetArray PartialOffsets; +}; + +} // end namespace codeview +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_CODEVIEW_RANDOMACCESSTYPEVISITOR_H diff --git a/include/llvm/DebugInfo/CodeView/TypeDatabase.h b/include/llvm/DebugInfo/CodeView/TypeDatabase.h index be7b19e7df0c..92c15ebd8b2b 100644 --- a/include/llvm/DebugInfo/CodeView/TypeDatabase.h +++ b/include/llvm/DebugInfo/CodeView/TypeDatabase.h @@ -10,6 +10,7 @@ #ifndef LLVM_DEBUGINFO_CODEVIEW_TYPEDATABASE_H #define LLVM_DEBUGINFO_CODEVIEW_TYPEDATABASE_H +#include "llvm/ADT/BitVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" @@ -20,14 +21,16 @@ namespace llvm { namespace codeview { class TypeDatabase { + friend class RandomAccessTypeVisitor; + public: - explicit TypeDatabase(uint32_t ExpectedSize); + explicit TypeDatabase(uint32_t Capacity); - /// Gets the type index for the next type record. - TypeIndex getNextTypeIndex() const; + /// Records the name of a type, and reserves its type index. + TypeIndex appendType(StringRef Name, const CVType &Data); /// Records the name of a type, and reserves its type index. - void recordType(StringRef Name, const CVType &Data); + void recordType(StringRef Name, TypeIndex Index, const CVType &Data); /// Saves the name in a StringSet and creates a stable StringRef. StringRef saveTypeName(StringRef TypeName); @@ -37,13 +40,21 @@ public: const CVType &getTypeRecord(TypeIndex Index) const; CVType &getTypeRecord(TypeIndex Index); - bool containsTypeIndex(TypeIndex Index) const; + bool contains(TypeIndex Index) const; uint32_t size() const; + uint32_t capacity() const; + bool empty() const; + + TypeIndex getAppendIndex() const; private: + void grow(); + BumpPtrAllocator Allocator; + uint32_t Count = 0; + /// All user defined type records in .debug$T live in here. Type indices /// greater than 0x1000 are user defined. Subtract 0x1000 from the index to /// index into this vector. @@ -51,6 +62,8 @@ private: SmallVector<CVType, 10> TypeRecords; StringSaver TypeNameStorage; + + BitVector ValidRecords; }; } } diff --git a/include/llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h b/include/llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h index 39d234cf9814..c064e19a7e90 100644 --- a/include/llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h +++ b/include/llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h @@ -10,6 +10,8 @@ #ifndef LLVM_DEBUGINFO_CODEVIEW_TYPEDATABASEVISITOR_H #define LLVM_DEBUGINFO_CODEVIEW_TYPEDATABASEVISITOR_H +#include "llvm/ADT/PointerUnion.h" + #include "llvm/DebugInfo/CodeView/TypeDatabase.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" @@ -21,11 +23,12 @@ namespace codeview { /// Dumper for CodeView type streams found in COFF object files and PDB files. class TypeDatabaseVisitor : public TypeVisitorCallbacks { public: - explicit TypeDatabaseVisitor(TypeDatabase &TypeDB) : TypeDB(TypeDB) {} + explicit TypeDatabaseVisitor(TypeDatabase &TypeDB) : TypeDB(&TypeDB) {} /// Paired begin/end actions for all types. Receives all record data, /// including the fixed-length record prefix. Error visitTypeBegin(CVType &Record) override; + Error visitTypeBegin(CVType &Record, TypeIndex Index) override; Error visitTypeEnd(CVType &Record) override; Error visitMemberBegin(CVMemberRecord &Record) override; Error visitMemberEnd(CVMemberRecord &Record) override; @@ -39,12 +42,18 @@ public: #include "TypeRecords.def" private: + StringRef getTypeName(TypeIndex Index) const; + StringRef saveTypeName(StringRef Name); + bool IsInFieldList = false; /// Name of the current type. Only valid before visitTypeEnd. StringRef Name; + /// Current type index. Only valid before visitTypeEnd, and if we are + /// visiting a random access type database. + Optional<TypeIndex> CurrentTypeIndex; - TypeDatabase &TypeDB; + TypeDatabase *TypeDB; }; } // end namespace codeview diff --git a/include/llvm/DebugInfo/CodeView/TypeDeserializer.h b/include/llvm/DebugInfo/CodeView/TypeDeserializer.h index 0e3443789170..2142d4a2dec7 100644 --- a/include/llvm/DebugInfo/CodeView/TypeDeserializer.h +++ b/include/llvm/DebugInfo/CodeView/TypeDeserializer.h @@ -46,6 +46,10 @@ public: return Mapping->Mapping.visitTypeBegin(Record); } + Error visitTypeBegin(CVType &Record, TypeIndex Index) override { + return visitTypeBegin(Record); + } + Error visitTypeEnd(CVType &Record) override { assert(Mapping && "Not in a type mapping!"); auto EC = Mapping->Mapping.visitTypeEnd(Record); diff --git a/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h b/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h index 00bb09137e48..6f10afb30d60 100644 --- a/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h +++ b/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h @@ -45,6 +45,7 @@ public: /// Paired begin/end actions for all types. Receives all record data, /// including the fixed-length record prefix. Error visitTypeBegin(CVType &Record) override; + Error visitTypeBegin(CVType &Record, TypeIndex Index) override; Error visitTypeEnd(CVType &Record) override; Error visitMemberBegin(CVMemberRecord &Record) override; Error visitMemberEnd(CVMemberRecord &Record) override; diff --git a/include/llvm/DebugInfo/CodeView/TypeIndex.h b/include/llvm/DebugInfo/CodeView/TypeIndex.h index 3c11d248fa72..b5d695fc49d5 100644 --- a/include/llvm/DebugInfo/CodeView/TypeIndex.h +++ b/include/llvm/DebugInfo/CodeView/TypeIndex.h @@ -106,6 +106,15 @@ public: bool isNoneType() const { return *this == None(); } + uint32_t toArrayIndex() const { + assert(!isSimple()); + return getIndex() - FirstNonSimpleIndex; + } + + static TypeIndex fromArrayIndex(uint32_t Index) { + return TypeIndex(Index + FirstNonSimpleIndex); + } + SimpleTypeKind getSimpleKind() const { assert(isSimple()); return static_cast<SimpleTypeKind>(Index & SimpleKindMask); @@ -159,6 +168,39 @@ public: static TypeIndex Float32() { return TypeIndex(SimpleTypeKind::Float32); } static TypeIndex Float64() { return TypeIndex(SimpleTypeKind::Float64); } + TypeIndex &operator+=(unsigned N) { + Index += N; + return *this; + } + + TypeIndex &operator++() { + Index += 1; + return *this; + } + + TypeIndex operator++(int) { + TypeIndex Copy = *this; + operator++(); + return Copy; + } + + TypeIndex &operator-=(unsigned N) { + assert(Index >= N); + Index -= N; + return *this; + } + + TypeIndex &operator--() { + Index -= 1; + return *this; + } + + TypeIndex operator--(int) { + TypeIndex Copy = *this; + operator--(); + return Copy; + } + friend inline bool operator==(const TypeIndex &A, const TypeIndex &B) { return A.getIndex() == B.getIndex(); } @@ -183,10 +225,30 @@ public: return A.getIndex() >= B.getIndex(); } + friend inline TypeIndex operator+(const TypeIndex &A, uint32_t N) { + TypeIndex Result(A); + Result += N; + return Result; + } + + friend inline TypeIndex operator-(const TypeIndex &A, uint32_t N) { + assert(A.getIndex() >= N); + TypeIndex Result(A); + Result -= N; + return Result; + } + private: support::ulittle32_t Index; }; +// Used for pseudo-indexing an array of type records. An array of such records +// sorted by TypeIndex can allow log(N) lookups even though such a type record +// stream does not provide random access. +struct TypeIndexOffset { + TypeIndex Type; + support::ulittle32_t Offset; +}; } } diff --git a/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h b/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h index f25129691041..ed48df33249f 100644 --- a/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h +++ b/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h @@ -47,6 +47,14 @@ public: return Error::success(); } + Error visitTypeBegin(CVType &Record, TypeIndex Index) override { + for (auto Visitor : Pipeline) { + if (auto EC = Visitor->visitTypeBegin(Record, Index)) + return EC; + } + return Error::success(); + } + Error visitTypeEnd(CVType &Record) override { for (auto Visitor : Pipeline) { if (auto EC = Visitor->visitTypeEnd(Record)) diff --git a/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h b/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h index 5e27df346b00..2950c7d27cb6 100644 --- a/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h +++ b/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h @@ -26,8 +26,15 @@ public: virtual Error visitUnknownType(CVType &Record) { return Error::success(); } /// Paired begin/end actions for all types. Receives all record data, /// including the fixed-length record prefix. visitTypeBegin() should return - /// the type of the Record, or an error if it cannot be determined. + /// the type of the Record, or an error if it cannot be determined. Exactly + /// one of the two visitTypeBegin methods will be called, depending on whether + /// records are being visited sequentially or randomly. An implementation + /// should be prepared to handle both (or assert if it can't handle random + /// access visitation). virtual Error visitTypeBegin(CVType &Record) { return Error::success(); } + virtual Error visitTypeBegin(CVType &Record, TypeIndex Index) { + return Error::success(); + } virtual Error visitTypeEnd(CVType &Record) { return Error::success(); } virtual Error visitUnknownMember(CVMemberRecord &Record) { diff --git a/include/llvm/DebugInfo/DWARF/DWARFContext.h b/include/llvm/DebugInfo/DWARF/DWARFContext.h index 3fae8b441439..ca82a68ead31 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFContext.h +++ b/include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -43,13 +43,6 @@ namespace llvm { class MemoryBuffer; class raw_ostream; -// In place of applying the relocations to the data we've read from disk we use -// a separate mapping table to the side and checking that at locations in the -// dwarf where we expect relocated values. This adds a bit of complexity to the -// dwarf parsing/extraction at the benefit of not allocating memory for the -// entire size of the debug info sections. -typedef DenseMap<uint64_t, std::pair<uint8_t, int64_t>> RelocAddrMap; - /// Reads a value from data extractor and applies a relocation to the result if /// one exists for the given offset. uint64_t getRelocatedValue(const DataExtractor &Data, uint32_t Size, diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h index e21245b97b73..39a7ef71de97 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h @@ -30,7 +30,7 @@ public: struct FileNameEntry { FileNameEntry() = default; - StringRef Name = StringRef(); + StringRef Name; uint64_t DirIdx = 0; uint64_t ModTime = 0; uint64_t Length = 0; diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h b/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h index 9172df5bfac6..23a573b7a9fa 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h @@ -22,8 +22,13 @@ namespace llvm { class raw_ostream; +struct DWARFAddressRange { + uint64_t LowPC; + uint64_t HighPC; +}; + /// DWARFAddressRangesVector - represents a set of absolute address ranges. -typedef std::vector<std::pair<uint64_t, uint64_t>> DWARFAddressRangesVector; +typedef std::vector<DWARFAddressRange> DWARFAddressRangesVector; class DWARFDebugRangeList { public: diff --git a/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h b/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h index af01bddeed15..f1e03bb4c2e1 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h +++ b/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h @@ -16,7 +16,17 @@ namespace llvm { -typedef DenseMap<uint64_t, std::pair<uint8_t, int64_t>> RelocAddrMap; +struct RelocAddrEntry { + uint8_t Width; + int64_t Value; +}; + +// In place of applying the relocations to the data we've read from disk we use +// a separate mapping table to the side and checking that at locations in the +// dwarf where we expect relocated values. This adds a bit of complexity to the +// dwarf parsing/extraction at the benefit of not allocating memory for the +// entire size of the debug info sections. +typedef DenseMap<uint64_t, RelocAddrEntry> RelocAddrMap; } // end namespace llvm diff --git a/include/llvm/DebugInfo/DWARF/DWARFVerifier.h b/include/llvm/DebugInfo/DWARF/DWARFVerifier.h index 8e12bcd2c8e2..b9f14be85926 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFVerifier.h +++ b/include/llvm/DebugInfo/DWARF/DWARFVerifier.h @@ -40,7 +40,7 @@ class DWARFVerifier { /// /// @param Die The DWARF DIE that owns the attribute value /// @param AttrValue The DWARF attribute value to check - void verifyDebugInfoAttribute(DWARFDie &Die, DWARFAttribute &AttrValue); + void verifyDebugInfoAttribute(const DWARFDie &Die, DWARFAttribute &AttrValue); /// Verifies the attribute's DWARF form. /// @@ -51,7 +51,7 @@ class DWARFVerifier { /// /// @param Die The DWARF DIE that owns the attribute value /// @param AttrValue The DWARF attribute value to check - void verifyDebugInfoForm(DWARFDie &Die, DWARFAttribute &AttrValue); + void verifyDebugInfoForm(const DWARFDie &Die, DWARFAttribute &AttrValue); /// Verifies the all valid references that were found when iterating through /// all of the DIE attributes. @@ -60,7 +60,7 @@ class DWARFVerifier { /// offset matches. This helps to ensure if a DWARF link phase moved things /// around, that it doesn't create invalid references by failing to relocate /// CU relative and absolute references. - void veifyDebugInfoReferences(); + void verifyDebugInfoReferences(); /// Verify the the DW_AT_stmt_list encoding and value and ensure that no /// compile units that have the same DW_AT_stmt_list value. diff --git a/include/llvm/DebugInfo/PDB/Native/RawTypes.h b/include/llvm/DebugInfo/PDB/Native/RawTypes.h index 979b8454dd5e..771272d6a47d 100644 --- a/include/llvm/DebugInfo/PDB/Native/RawTypes.h +++ b/include/llvm/DebugInfo/PDB/Native/RawTypes.h @@ -73,13 +73,6 @@ struct SecMapEntry { support::ulittle32_t SecByteLength; // Byte count of the segment or group. }; -// Used for serialized hash table in TPI stream. -// In the reference, it is an array of TI and cbOff pair. -struct TypeIndexOffset { - codeview::TypeIndex Type; - support::ulittle32_t Offset; -}; - /// Some of the values are stored in bitfields. Since this needs to be portable /// across compilers and architectures (big / little endian in particular) we /// can't use the actual structures below, but must instead do the shifting diff --git a/include/llvm/DebugInfo/PDB/Native/TpiStream.h b/include/llvm/DebugInfo/PDB/Native/TpiStream.h index 9fef9bee5e1a..4579cbf4227b 100644 --- a/include/llvm/DebugInfo/PDB/Native/TpiStream.h +++ b/include/llvm/DebugInfo/PDB/Native/TpiStream.h @@ -47,7 +47,7 @@ public: uint32_t getHashKeySize() const; uint32_t getNumHashBuckets() const; FixedStreamArray<support::ulittle32_t> getHashValues() const; - FixedStreamArray<TypeIndexOffset> getTypeIndexOffsets() const; + FixedStreamArray<codeview::TypeIndexOffset> getTypeIndexOffsets() const; HashTable &getHashAdjusters(); codeview::CVTypeRange types(bool *HadError) const; @@ -62,7 +62,7 @@ private: std::unique_ptr<BinaryStream> HashStream; FixedStreamArray<support::ulittle32_t> HashValues; - FixedStreamArray<TypeIndexOffset> TypeIndexOffsets; + FixedStreamArray<codeview::TypeIndexOffset> TypeIndexOffsets; HashTable HashAdjusters; const TpiStreamHeader *Header; diff --git a/include/llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h b/include/llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h index a29ed0b610d3..6c609c34665c 100644 --- a/include/llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h +++ b/include/llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h @@ -75,7 +75,7 @@ private: Optional<PdbRaw_TpiVer> VerHeader; std::vector<ArrayRef<uint8_t>> TypeRecords; std::vector<uint32_t> TypeHashes; - std::vector<TypeIndexOffset> TypeIndexOffsets; + std::vector<codeview::TypeIndexOffset> TypeIndexOffsets; uint32_t HashStreamIndex = kInvalidStreamIndex; std::unique_ptr<BinaryByteStream> HashValueStream; diff --git a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h index 7e7f7358938a..1bb911d09cfb 100644 --- a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h +++ b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h @@ -172,6 +172,11 @@ private: return nullptr; } + void removeModulesFromBaseLayer(BaseLayerT &BaseLayer) { + for (auto &BLH : BaseLayerHandles) + BaseLayer.removeModuleSet(BLH); + } + std::unique_ptr<JITSymbolResolver> ExternalSymbolResolver; std::unique_ptr<ResourceOwner<RuntimeDyld::MemoryManager>> MemMgr; std::unique_ptr<IndirectStubsMgrT> StubsMgr; @@ -204,6 +209,11 @@ public: CreateIndirectStubsManager(std::move(CreateIndirectStubsManager)), CloneStubsIntoPartitions(CloneStubsIntoPartitions) {} + ~CompileOnDemandLayer() { + while (!LogicalDylibs.empty()) + removeModuleSet(LogicalDylibs.begin()); + } + /// @brief Add a module to the compile-on-demand layer. template <typename ModuleSetT, typename MemoryManagerPtrT, typename SymbolResolverPtrT> @@ -239,6 +249,7 @@ public: /// This will remove all modules in the layers below that were derived from /// the module represented by H. void removeModuleSet(ModuleSetHandleT H) { + H->removeModulesFromBaseLayer(BaseLayer); LogicalDylibs.erase(H); } @@ -478,6 +489,8 @@ private: return 0; } + LD.BaseLayerHandles.push_back(PartH); + return CalledAddr; } diff --git a/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h b/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h index 02f59d6a831a..a19c30631c57 100644 --- a/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h +++ b/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h @@ -144,16 +144,16 @@ public: void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override { - UnfinalizedEHFrames.push_back( - std::make_pair(LoadAddr, static_cast<uint32_t>(Size))); + UnfinalizedEHFrames.push_back({LoadAddr, Size}); } - void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, - size_t Size) override { - auto Err = Client.deregisterEHFrames(LoadAddr, Size); - // FIXME: Add error poll. - assert(!Err && "Failed to register remote EH frames."); - (void)Err; + void deregisterEHFrames() override { + for (auto &Frame : RegisteredEHFrames) { + auto Err = Client.deregisterEHFrames(Frame.Addr, Frame.Size); + // FIXME: Add error poll. + assert(!Err && "Failed to register remote EH frames."); + (void)Err; + } } void notifyObjectLoaded(RuntimeDyld &Dyld, @@ -320,7 +320,7 @@ public: Unfinalized.clear(); for (auto &EHFrame : UnfinalizedEHFrames) { - if (auto Err = Client.registerEHFrames(EHFrame.first, EHFrame.second)) { + if (auto Err = Client.registerEHFrames(EHFrame.Addr, EHFrame.Size)) { // FIXME: Replace this once finalizeMemory can return an Error. handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) { if (ErrMsg) { @@ -331,7 +331,8 @@ public: return false; } } - UnfinalizedEHFrames.clear(); + RegisteredEHFrames = std::move(UnfinalizedEHFrames); + UnfinalizedEHFrames = {}; return false; } @@ -387,7 +388,13 @@ public: ResourceIdMgr::ResourceId Id; std::vector<ObjectAllocs> Unmapped; std::vector<ObjectAllocs> Unfinalized; - std::vector<std::pair<uint64_t, uint32_t>> UnfinalizedEHFrames; + + struct EHFrame { + JITTargetAddress Addr; + uint64_t Size; + }; + std::vector<EHFrame> UnfinalizedEHFrames; + std::vector<EHFrame> RegisteredEHFrames; }; /// Remote indirect stubs manager. diff --git a/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h b/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h index babcc7f26aab..5b3426afe584 100644 --- a/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h +++ b/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h @@ -120,6 +120,10 @@ private: buildInitialSymbolTable(PFC->Objects); } + ~ConcreteLinkedObjectSet() override { + MemMgr->deregisterEHFrames(); + } + void setHandle(ObjSetHandleT H) { PFC->Handle = H; } diff --git a/include/llvm/ExecutionEngine/RTDyldMemoryManager.h b/include/llvm/ExecutionEngine/RTDyldMemoryManager.h index 5638717790bb..74535fe948ff 100644 --- a/include/llvm/ExecutionEngine/RTDyldMemoryManager.h +++ b/include/llvm/ExecutionEngine/RTDyldMemoryManager.h @@ -69,13 +69,8 @@ public: /// Deregister EH frames in the current proces. static void deregisterEHFramesInProcess(uint8_t *Addr, size_t Size); - void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override { - registerEHFramesInProcess(Addr, Size); - } - - void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override { - deregisterEHFramesInProcess(Addr, Size); - } + void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override; + void deregisterEHFrames() override; /// This method returns the address of the specified function or variable in /// the current process. @@ -139,6 +134,13 @@ public: /// MCJIT or RuntimeDyld. Use getSymbolAddress instead. virtual void *getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure = true); + +private: + struct EHFrame { + uint8_t *Addr; + size_t Size; + }; + std::vector<EHFrame> EHFrames; }; // Create wrappers for C Binding types (see CBindingWrapping.h). diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h index 13a5f9922c51..9470866dc0d6 100644 --- a/include/llvm/ExecutionEngine/RuntimeDyld.h +++ b/include/llvm/ExecutionEngine/RuntimeDyld.h @@ -150,8 +150,7 @@ public: /// be the case for local execution) these two values will be the same. virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) = 0; - virtual void deregisterEHFrames(uint8_t *addr, uint64_t LoadAddr, - size_t Size) = 0; + virtual void deregisterEHFrames() = 0; /// This method is called when object loading is complete and section page /// permissions can be applied. It is up to the memory manager implementation diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h index cbe681684a5c..d4a896c01867 100644 --- a/include/llvm/IR/Attributes.h +++ b/include/llvm/IR/Attributes.h @@ -35,6 +35,7 @@ namespace llvm { class AttrBuilder; class AttributeImpl; class AttributeListImpl; +class AttributeList; class AttributeSetNode; template<typename T> struct DenseMapInfo; class Function; @@ -227,14 +228,51 @@ public: bool operator==(const AttributeSet &O) { return SetNode == O.SetNode; } bool operator!=(const AttributeSet &O) { return !(*this == O); } + /// Add an argument attribute. Because + /// attribute sets are immutable, this returns a new set. + AttributeSet addAttribute(LLVMContext &C, + Attribute::AttrKind Kind) const; + + /// Add a target-dependent attribute. Because + /// attribute sets are immutable, this returns a new set. + AttributeSet addAttribute(LLVMContext &C, StringRef Kind, + StringRef Value = StringRef()) const; + + /// Add attributes to the attribute set. Because + /// attribute sets are immutable, this returns a new set. + AttributeSet addAttributes(LLVMContext &C, AttributeSet AS) const; + + /// Remove the specified attribute from this set. Because + /// attribute sets are immutable, this returns a new set. + AttributeSet removeAttribute(LLVMContext &C, + Attribute::AttrKind Kind) const; + + /// Remove the specified attribute from this set. Because + /// attribute sets are immutable, this returns a new set. + AttributeSet removeAttribute(LLVMContext &C, + StringRef Kind) const; + + /// Remove the specified attributes from this set. Because + /// attribute sets are immutable, this returns a new set. + AttributeSet removeAttributes(LLVMContext &C, + const AttrBuilder &AttrsToRemove) const; + + /// Return the number of attributes in this set. unsigned getNumAttributes() const; + /// Return true if attributes exists in this set. bool hasAttributes() const { return SetNode != nullptr; } + /// Return true if the attribute exists in this set. bool hasAttribute(Attribute::AttrKind Kind) const; + + /// Return true if the attribute exists in this set. bool hasAttribute(StringRef Kind) const; + /// Return the attribute object. Attribute getAttribute(Attribute::AttrKind Kind) const; + + /// Return the target-dependent attribute object. Attribute getAttribute(StringRef Kind) const; unsigned getAlignment() const; @@ -248,6 +286,9 @@ public: iterator begin() const; iterator end() const; +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) + void dump() const; +#endif }; //===----------------------------------------------------------------------===// diff --git a/include/llvm/IR/CallingConv.h b/include/llvm/IR/CallingConv.h index 39fb3f1c791b..801e88aba4d1 100644 --- a/include/llvm/IR/CallingConv.h +++ b/include/llvm/IR/CallingConv.h @@ -201,6 +201,10 @@ namespace CallingConv { /// shaders) AMDGPU_HS = 93, + /// Calling convention used for special MSP430 rtlib functions + /// which have an "optimized" convention using additional registers. + MSP430_BUILTIN = 94, + /// The highest possible calling convention ID. Must be some 2^k - 1. MaxID = 1023 }; diff --git a/include/llvm/IR/Constants.h b/include/llvm/IR/Constants.h index ad83b21c7bf3..5db9b3bb5048 100644 --- a/include/llvm/IR/Constants.h +++ b/include/llvm/IR/Constants.h @@ -26,6 +26,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/IR/Constant.h" #include "llvm/IR/DerivedTypes.h" @@ -452,7 +453,14 @@ class ConstantStruct final : public ConstantAggregate { public: // ConstantStruct accessors static Constant *get(StructType *T, ArrayRef<Constant*> V); - static Constant *get(StructType *T, ...) LLVM_END_WITH_NULL; + + template <typename... Csts> + static typename std::enable_if<are_base_of<Constant, Csts...>::value, + Constant *>::type + get(StructType *T, Csts *... Vs) { + SmallVector<Constant *, 8> Values({Vs...}); + return get(T, Values); + } /// Return an anonymous struct that has the specified elements. /// If the struct is possibly empty, then you must specify a context. diff --git a/include/llvm/IR/DebugInfoMetadata.h b/include/llvm/IR/DebugInfoMetadata.h index 0331d5229e7f..358106aac43b 100644 --- a/include/llvm/IR/DebugInfoMetadata.h +++ b/include/llvm/IR/DebugInfoMetadata.h @@ -16,8 +16,11 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/BitmaskEnum.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/None.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/IR/Metadata.h" #include "llvm/Support/Casting.h" @@ -56,10 +59,6 @@ namespace llvm { -class DIBuilder; - -template <typename T> class Optional; - /// Holds a subclass of DINode. /// /// FIXME: This class doesn't currently make much sense. Previously it was a @@ -94,9 +93,9 @@ public: bool operator!=(const TypedDINodeRef<T> &X) const { return MD != X.MD; } }; -typedef TypedDINodeRef<DINode> DINodeRef; -typedef TypedDINodeRef<DIScope> DIScopeRef; -typedef TypedDINodeRef<DIType> DITypeRef; +using DINodeRef = TypedDINodeRef<DINode>; +using DIScopeRef = TypedDINodeRef<DIScope>; +using DITypeRef = TypedDINodeRef<DIType>; class DITypeRefArray { const MDTuple *N = nullptr; @@ -240,7 +239,8 @@ public: }; template <class T> struct simplify_type<const TypedDINodeRef<T>> { - typedef Metadata *SimpleType; + using SimpleType = Metadata *; + static SimpleType getSimplifiedValue(const TypedDINodeRef<T> &MD) { return MD; } @@ -799,15 +799,18 @@ public: assert(getTag() == dwarf::DW_TAG_ptr_to_member_type); return DITypeRef(getExtraData()); } + DIObjCProperty *getObjCProperty() const { return dyn_cast_or_null<DIObjCProperty>(getExtraData()); } + Constant *getStorageOffsetInBits() const { assert(getTag() == dwarf::DW_TAG_member && isBitField()); if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData())) return C->getValue(); return nullptr; } + Constant *getConstant() const { assert(getTag() == dwarf::DW_TAG_member && isStaticMember()); if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData())) @@ -970,9 +973,11 @@ public: #endif replaceOperandWith(4, Elements.get()); } + void replaceVTableHolder(DITypeRef VTableHolder) { replaceOperandWith(5, VTableHolder); } + void replaceTemplateParams(DITemplateParameterArray TemplateParams) { replaceOperandWith(6, TemplateParams.get()); } @@ -1031,6 +1036,7 @@ public: DITypeRefArray getTypeArray() const { return cast_or_null<MDTuple>(getRawTypeArray()); } + Metadata *getRawTypeArray() const { return getOperand(3); } static bool classof(const Metadata *MD) { @@ -1319,6 +1325,7 @@ public: unsigned getLine() const { return SubclassData32; } unsigned getColumn() const { return SubclassData16; } DILocalScope *getScope() const { return cast<DILocalScope>(getRawScope()); } + DILocation *getInlinedAt() const { return cast_or_null<DILocation>(getRawInlinedAt()); } @@ -1452,7 +1459,6 @@ public: static bool classof(const Metadata *MD) { return MD->getMetadataID() == DILocationKind; } - }; /// Subprogram description. @@ -2087,6 +2093,7 @@ public: return F->getFilename(); return ""; } + StringRef getDirectory() const { if (auto *F = getFile()) return F->getDirectory(); @@ -2143,6 +2150,7 @@ public: ArrayRef<uint64_t> getElements() const { return Elements; } unsigned getNumElements() const { return Elements.size(); } + uint64_t getElement(unsigned I) const { assert(I < Elements.size() && "Index out of range"); return Elements[I]; @@ -2151,7 +2159,8 @@ public: /// Determine whether this represents a standalone constant value. bool isConstant() const; - typedef ArrayRef<uint64_t>::iterator element_iterator; + using element_iterator = ArrayRef<uint64_t>::iterator; + element_iterator elements_begin() const { return getElements().begin(); } element_iterator elements_end() const { return getElements().end(); } @@ -2276,6 +2285,10 @@ public: /// Append \p Ops with operations to apply the \p Offset. static void appendOffset(SmallVectorImpl<uint64_t> &Ops, int64_t Offset); + /// If this is a constant offset, extract it. If there is no expression, + /// return true with an offset of zero. + bool extractIfOffset(int64_t &Offset) const; + /// Constants for DIExpression::prepend. enum { NoDeref = false, WithDeref = true, WithStackValue = true }; @@ -2509,6 +2522,7 @@ public: return F->getFilename(); return ""; } + StringRef getDirectory() const { if (auto *F = getFile()) return F->getDirectory(); @@ -2609,10 +2623,13 @@ public: TempDIGlobalVariableExpression clone() const { return cloneImpl(); } Metadata *getRawVariable() const { return getOperand(0); } + DIGlobalVariable *getVariable() const { return cast_or_null<DIGlobalVariable>(getRawVariable()); } + Metadata *getRawExpression() const { return getOperand(1); } + DIExpression *getExpression() const { return cast_or_null<DIExpression>(getRawExpression()); } diff --git a/include/llvm/IR/DebugLoc.h b/include/llvm/IR/DebugLoc.h index 202be3da14da..aa74f361cda2 100644 --- a/include/llvm/IR/DebugLoc.h +++ b/include/llvm/IR/DebugLoc.h @@ -80,6 +80,22 @@ namespace llvm { static DebugLoc get(unsigned Line, unsigned Col, const MDNode *Scope, const MDNode *InlinedAt = nullptr); + enum { ReplaceLastInlinedAt = true }; + /// Rebuild the entire inlined-at chain for this instruction so that the top of + /// the chain now is inlined-at the new call site. + /// \param InlinedAt The new outermost inlined-at in the chain. + /// \param ReplaceLast Replace the last location in the inlined-at chain. + static DebugLoc appendInlinedAt(DebugLoc DL, DILocation *InlinedAt, + LLVMContext &Ctx, + DenseMap<const MDNode *, MDNode *> &Cache, + bool ReplaceLast = false); + + /// Reparent all debug locations referenced by \c I that belong to \c OrigSP + /// to become (possibly indirect) children of \c NewSP. + static void reparentDebugInfo(Instruction &I, DISubprogram *OrigSP, + DISubprogram *NewSP, + DenseMap<const MDNode *, MDNode *> &Cache); + unsigned getLine() const; unsigned getCol() const; MDNode *getScope() const; diff --git a/include/llvm/IR/DerivedTypes.h b/include/llvm/IR/DerivedTypes.h index 05e99157b8dc..a92321a44511 100644 --- a/include/llvm/IR/DerivedTypes.h +++ b/include/llvm/IR/DerivedTypes.h @@ -1,4 +1,4 @@ -//===-- llvm/DerivedTypes.h - Classes for handling data types ---*- C++ -*-===// +//===- llvm/DerivedTypes.h - Classes for handling data types ----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -19,6 +19,7 @@ #define LLVM_IR_DERIVEDTYPES_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/IR/Type.h" #include "llvm/Support/Casting.h" @@ -122,7 +123,8 @@ public: bool isVarArg() const { return getSubclassData()!=0; } Type *getReturnType() const { return ContainedTys[0]; } - typedef Type::subtype_iterator param_iterator; + using param_iterator = Type::subtype_iterator; + param_iterator param_begin() const { return ContainedTys + 1; } param_iterator param_end() const { return &ContainedTys[NumContainedTys]; } ArrayRef<Type *> params() const { @@ -197,8 +199,7 @@ public: /// generator for a target expects). /// class StructType : public CompositeType { - StructType(LLVMContext &C) - : CompositeType(C, StructTyID), SymbolTableEntry(nullptr) {} + StructType(LLVMContext &C) : CompositeType(C, StructTyID) {} enum { /// This is the contents of the SubClassData field. @@ -212,7 +213,7 @@ class StructType : public CompositeType { /// symbol table entry (maintained by LLVMContext) for the struct. /// This is null if the type is an literal struct or if it is a identified /// type that has an empty name. - void *SymbolTableEntry; + void *SymbolTableEntry = nullptr; public: StructType(const StructType &) = delete; @@ -228,7 +229,14 @@ public: static StructType *create(LLVMContext &Context, ArrayRef<Type *> Elements, StringRef Name, bool isPacked = false); static StructType *create(LLVMContext &Context, ArrayRef<Type *> Elements); - static StructType *create(StringRef Name, Type *elt1, ...) LLVM_END_WITH_NULL; + template <class... Tys> + static typename std::enable_if<are_base_of<Type, Tys...>::value, + StructType *>::type + create(StringRef Name, Type *elt1, Tys *... elts) { + assert(elt1 && "Cannot create a struct type with no elements with this"); + SmallVector<llvm::Type *, 8> StructFields({elt1, elts...}); + return create(StructFields, Name); + } /// This static method is the primary way to create a literal StructType. static StructType *get(LLVMContext &Context, ArrayRef<Type*> Elements, @@ -240,7 +248,15 @@ public: /// This static method is a convenience method for creating structure types by /// specifying the elements as arguments. Note that this method always returns /// a non-packed struct, and requires at least one element type. - static StructType *get(Type *elt1, ...) LLVM_END_WITH_NULL; + template <class... Tys> + static typename std::enable_if<are_base_of<Type, Tys...>::value, + StructType *>::type + get(Type *elt1, Tys *... elts) { + assert(elt1 && "Cannot create a struct type with no elements with this"); + LLVMContext &Ctx = elt1->getContext(); + SmallVector<llvm::Type *, 8> StructFields({elt1, elts...}); + return llvm::StructType::get(Ctx, StructFields); + } bool isPacked() const { return (getSubclassData() & SCDB_Packed) != 0; } @@ -269,13 +285,21 @@ public: /// Specify a body for an opaque identified type. void setBody(ArrayRef<Type*> Elements, bool isPacked = false); - void setBody(Type *elt1, ...) LLVM_END_WITH_NULL; + + template <typename... Tys> + typename std::enable_if<are_base_of<Type, Tys...>::value, void>::type + setBody(Type *elt1, Tys *... elts) { + assert(elt1 && "Cannot create a struct type with no elements with this"); + SmallVector<llvm::Type *, 8> StructFields({elt1, elts...}); + setBody(StructFields); + } /// Return true if the specified type is valid as a element type. static bool isValidElementType(Type *ElemTy); // Iterator access to the elements. - typedef Type::subtype_iterator element_iterator; + using element_iterator = Type::subtype_iterator; + element_iterator element_begin() const { return ContainedTys; } element_iterator element_end() const { return &ContainedTys[NumContainedTys];} ArrayRef<Type *> const elements() const { diff --git a/include/llvm/IR/DiagnosticInfo.h b/include/llvm/IR/DiagnosticInfo.h index 458c3cf29b0d..5497652135bd 100644 --- a/include/llvm/IR/DiagnosticInfo.h +++ b/include/llvm/IR/DiagnosticInfo.h @@ -15,7 +15,6 @@ #ifndef LLVM_IR_DIAGNOSTICINFO_H #define LLVM_IR_DIAGNOSTICINFO_H -#include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" @@ -120,18 +119,18 @@ public: virtual void print(DiagnosticPrinter &DP) const = 0; }; -typedef std::function<void(const DiagnosticInfo &)> DiagnosticHandlerFunction; +using DiagnosticHandlerFunction = std::function<void(const DiagnosticInfo &)>; /// Diagnostic information for inline asm reporting. /// This is basically a message and an optional location. class DiagnosticInfoInlineAsm : public DiagnosticInfo { private: /// Optional line information. 0 if not set. - unsigned LocCookie; + unsigned LocCookie = 0; /// Message to be reported. const Twine &MsgStr; /// Optional origin of the problem. - const Instruction *Instr; + const Instruction *Instr = nullptr; public: /// \p MsgStr is the message to be reported to the frontend. @@ -139,8 +138,7 @@ public: /// for the whole life time of the Diagnostic. DiagnosticInfoInlineAsm(const Twine &MsgStr, DiagnosticSeverity Severity = DS_Error) - : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(0), MsgStr(MsgStr), - Instr(nullptr) {} + : DiagnosticInfo(DK_InlineAsm, Severity), MsgStr(MsgStr) {} /// \p LocCookie if non-zero gives the line number for this report. /// \p MsgStr gives the message. @@ -149,7 +147,7 @@ public: DiagnosticInfoInlineAsm(unsigned LocCookie, const Twine &MsgStr, DiagnosticSeverity Severity = DS_Error) : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(LocCookie), - MsgStr(MsgStr), Instr(nullptr) {} + MsgStr(MsgStr) {} /// \p Instr gives the original instruction that triggered the diagnostic. /// \p MsgStr gives the message. @@ -294,10 +292,10 @@ public: DiagnosticInfoSampleProfile(StringRef FileName, const Twine &Msg, DiagnosticSeverity Severity = DS_Error) : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName), - LineNum(0), Msg(Msg) {} + Msg(Msg) {} DiagnosticInfoSampleProfile(const Twine &Msg, DiagnosticSeverity Severity = DS_Error) - : DiagnosticInfo(DK_SampleProfile, Severity), LineNum(0), Msg(Msg) {} + : DiagnosticInfo(DK_SampleProfile, Severity), Msg(Msg) {} /// \see DiagnosticInfo::print. void print(DiagnosticPrinter &DP) const override; @@ -316,7 +314,7 @@ private: /// Line number where the diagnostic occurred. If 0, no line number will /// be emitted in the message. - unsigned LineNum; + unsigned LineNum = 0; /// Message to report. const Twine &Msg; @@ -351,8 +349,9 @@ class DiagnosticLocation { StringRef Filename; unsigned Line = 0; unsigned Column = 0; + public: - DiagnosticLocation() {} + DiagnosticLocation() = default; DiagnosticLocation(const DebugLoc &DL); DiagnosticLocation(const DISubprogram *SP); @@ -796,6 +795,7 @@ private: const Twine &Msg) : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute, PassName, Fn, Loc, Msg) {} + friend void emitOptimizationRemarkAnalysisFPCommute( LLVMContext &Ctx, const char *PassName, const Function &Fn, const DiagnosticLocation &Loc, const Twine &Msg); @@ -1012,6 +1012,7 @@ public: void print(DiagnosticPrinter &DP) const override; }; + } // end namespace llvm #endif // LLVM_IR_DIAGNOSTICINFO_H diff --git a/include/llvm/IR/Function.h b/include/llvm/IR/Function.h index c12a125b6352..8a2a6ed87eb2 100644 --- a/include/llvm/IR/Function.h +++ b/include/llvm/IR/Function.h @@ -1,4 +1,4 @@ -//===-- llvm/Function.h - Class to represent a single function --*- C++ -*-===// +//===- llvm/Function.h - Class to represent a single function ---*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -22,15 +22,19 @@ #include "llvm/ADT/ilist_node.h" #include "llvm/ADT/iterator_range.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Twine.h" #include "llvm/IR/Argument.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/CallingConv.h" +#include "llvm/IR/DerivedTypes.h" #include "llvm/IR/GlobalObject.h" +#include "llvm/IR/GlobalValue.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/OperandTraits.h" #include "llvm/IR/SymbolTableListTraits.h" #include "llvm/IR/Value.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include <cassert> #include <cstddef> @@ -40,27 +44,31 @@ namespace llvm { -template <typename T> class Optional; class AssemblyAnnotationWriter; -class FunctionType; -class LLVMContext; +class Constant; class DISubprogram; +class LLVMContext; +class Module; +template <typename T> class Optional; +class raw_ostream; +class Type; +class User; class Function : public GlobalObject, public ilist_node<Function> { public: - typedef SymbolTableList<BasicBlock> BasicBlockListType; + using BasicBlockListType = SymbolTableList<BasicBlock>; // BasicBlock iterators... - typedef BasicBlockListType::iterator iterator; - typedef BasicBlockListType::const_iterator const_iterator; + using iterator = BasicBlockListType::iterator; + using const_iterator = BasicBlockListType::const_iterator; - typedef Argument *arg_iterator; - typedef const Argument *const_arg_iterator; + using arg_iterator = Argument *; + using const_arg_iterator = const Argument *; private: // Important things that make up a function! - BasicBlockListType BasicBlocks; ///< The basic blocks - mutable Argument *Arguments; ///< The formal arguments + BasicBlockListType BasicBlocks; ///< The basic blocks + mutable Argument *Arguments = nullptr; ///< The formal arguments size_t NumArgs; std::unique_ptr<ValueSymbolTable> SymTab; ///< Symbol table of args/instructions @@ -124,10 +132,12 @@ public: // Provide fast operand accessors. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + /// Returns the FunctionType for me. FunctionType *getFunctionType() const { return cast<FunctionType>(getValueType()); } + /// Returns the type of the ret val. Type *getReturnType() const { return getFunctionType()->getReturnType(); } @@ -484,7 +494,7 @@ public: /// copyAttributesFrom - copy all additional attributes (those not needed to /// create a Function) from the Function Src to this one. - void copyAttributesFrom(const GlobalValue *Src) override; + void copyAttributesFrom(const Function *Src); /// deleteBody - This method deletes the body of the function, and converts /// the linkage to external. @@ -497,12 +507,12 @@ public: /// removeFromParent - This method unlinks 'this' from the containing module, /// but does not delete it. /// - void removeFromParent() override; + void removeFromParent(); /// eraseFromParent - This method unlinks 'this' from the containing module /// and deletes it. /// - void eraseFromParent() override; + void eraseFromParent(); /// Steal arguments from another function. /// diff --git a/include/llvm/IR/GetElementPtrTypeIterator.h b/include/llvm/IR/GetElementPtrTypeIterator.h index 490bff29cf38..f017a449d33f 100644 --- a/include/llvm/IR/GetElementPtrTypeIterator.h +++ b/include/llvm/IR/GetElementPtrTypeIterator.h @@ -21,7 +21,9 @@ #include "llvm/IR/Operator.h" #include "llvm/IR/User.h" #include "llvm/Support/Casting.h" +#include <cassert> #include <cstddef> +#include <cstdint> #include <iterator> namespace llvm { @@ -29,13 +31,13 @@ namespace llvm { template<typename ItTy = User::const_op_iterator> class generic_gep_type_iterator : public std::iterator<std::forward_iterator_tag, Type *, ptrdiff_t> { - typedef std::iterator<std::forward_iterator_tag, - Type *, ptrdiff_t> super; + using super = std::iterator<std::forward_iterator_tag, Type *, ptrdiff_t>; ItTy OpIt; PointerUnion<StructType *, Type *> CurTy; enum : uint64_t { Unbounded = -1ull }; uint64_t NumElements = Unbounded; + generic_gep_type_iterator() = default; public: @@ -121,7 +123,7 @@ namespace llvm { } }; - typedef generic_gep_type_iterator<> gep_type_iterator; + using gep_type_iterator = generic_gep_type_iterator<>; inline gep_type_iterator gep_type_begin(const User *GEP) { auto *GEPOp = cast<GEPOperator>(GEP); diff --git a/include/llvm/IR/GlobalAlias.h b/include/llvm/IR/GlobalAlias.h index 37a291dfeb7a..d4bf0d7e1ed4 100644 --- a/include/llvm/IR/GlobalAlias.h +++ b/include/llvm/IR/GlobalAlias.h @@ -59,15 +59,19 @@ public: // Linkage, Type, Parent and AddressSpace taken from the Aliasee. static GlobalAlias *create(const Twine &Name, GlobalValue *Aliasee); + void copyAttributesFrom(const GlobalValue *Src) { + GlobalValue::copyAttributesFrom(Src); + } + /// removeFromParent - This method unlinks 'this' from the containing module, /// but does not delete it. /// - void removeFromParent() override; + void removeFromParent(); /// eraseFromParent - This method unlinks 'this' from the containing module /// and deletes it. /// - void eraseFromParent() override; + void eraseFromParent(); /// These methods retrieve and set alias target. void setAliasee(Constant *Aliasee); diff --git a/include/llvm/IR/GlobalIFunc.h b/include/llvm/IR/GlobalIFunc.h index bfaa9960cb13..d90c7c78ed26 100644 --- a/include/llvm/IR/GlobalIFunc.h +++ b/include/llvm/IR/GlobalIFunc.h @@ -47,12 +47,16 @@ public: LinkageTypes Linkage, const Twine &Name, Constant *Resolver, Module *Parent); + void copyAttributesFrom(const GlobalIFunc *Src) { + GlobalValue::copyAttributesFrom(Src); + } + /// This method unlinks 'this' from the containing module, but does not /// delete it. - void removeFromParent() final; + void removeFromParent(); /// This method unlinks 'this' from the containing module and deletes it. - void eraseFromParent() final; + void eraseFromParent(); /// These methods retrieve and set ifunc resolver function. void setResolver(Constant *Resolver) { diff --git a/include/llvm/IR/GlobalObject.h b/include/llvm/IR/GlobalObject.h index f3789bafefe3..fc38f698027b 100644 --- a/include/llvm/IR/GlobalObject.h +++ b/include/llvm/IR/GlobalObject.h @@ -150,8 +150,10 @@ public: void addTypeMetadata(unsigned Offset, Metadata *TypeID); - void copyAttributesFrom(const GlobalValue *Src) override; +protected: + void copyAttributesFrom(const GlobalObject *Src); +public: // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Value *V) { return V->getValueID() == Value::FunctionVal || diff --git a/include/llvm/IR/GlobalValue.h b/include/llvm/IR/GlobalValue.h index bb30fa8be867..0793a1c0ee2e 100644 --- a/include/llvm/IR/GlobalValue.h +++ b/include/llvm/IR/GlobalValue.h @@ -435,14 +435,20 @@ public: bool isWeakForLinker() const { return isWeakForLinker(getLinkage()); } +protected: /// Copy all additional attributes (those not needed to create a GlobalValue) /// from the GlobalValue Src to this one. - virtual void copyAttributesFrom(const GlobalValue *Src); + void copyAttributesFrom(const GlobalValue *Src); - /// If special LLVM prefix that is used to inform the asm printer to not emit - /// usual symbol prefix before the symbol name is used then return linkage - /// name after skipping this special LLVM prefix. - static StringRef getRealLinkageName(StringRef Name) { +public: + /// If the given string begins with the GlobalValue name mangling escape + /// character '\1', drop it. + /// + /// This function applies a specific mangling that is used in PGO profiles, + /// among other things. If you're trying to get a symbol name for an + /// arbitrary GlobalValue, this is not the function you're looking for; see + /// Mangler.h. + static StringRef dropLLVMManglingEscape(StringRef Name) { if (!Name.empty() && Name[0] == '\1') return Name.substr(1); return Name; @@ -530,10 +536,10 @@ public: /// This method unlinks 'this' from the containing module, but does not delete /// it. - virtual void removeFromParent() = 0; + void removeFromParent(); /// This method unlinks 'this' from the containing module and deletes it. - virtual void eraseFromParent() = 0; + void eraseFromParent(); /// Get the module that this global value is contained inside of... Module *getParent() { return Parent; } diff --git a/include/llvm/IR/GlobalVariable.h b/include/llvm/IR/GlobalVariable.h index 3b545d811d44..21d334c8f01d 100644 --- a/include/llvm/IR/GlobalVariable.h +++ b/include/llvm/IR/GlobalVariable.h @@ -24,6 +24,7 @@ #include "llvm/ADT/Twine.h" #include "llvm/ADT/ilist_node.h" #include "llvm/IR/GlobalObject.h" +#include "llvm/IR/Attributes.h" #include "llvm/IR/OperandTraits.h" #include "llvm/IR/Value.h" #include <cassert> @@ -41,6 +42,7 @@ class DIGlobalVariableExpression; class GlobalVariable : public GlobalObject, public ilist_node<GlobalVariable> { friend class SymbolTableListTraits<GlobalVariable>; + AttributeSet Attrs; bool isConstantGlobal : 1; // Is this a global constant? bool isExternallyInitializedConstant : 1; // Is this a global whose value // can change from its initial @@ -156,17 +158,17 @@ public: /// copyAttributesFrom - copy all additional attributes (those not needed to /// create a GlobalVariable) from the GlobalVariable Src to this one. - void copyAttributesFrom(const GlobalValue *Src) override; + void copyAttributesFrom(const GlobalVariable *Src); /// removeFromParent - This method unlinks 'this' from the containing module, /// but does not delete it. /// - void removeFromParent() override; + void removeFromParent(); /// eraseFromParent - This method unlinks 'this' from the containing module /// and deletes it. /// - void eraseFromParent() override; + void eraseFromParent(); /// Drop all references in preparation to destroy the GlobalVariable. This /// drops not only the reference to the initializer but also to any metadata. @@ -178,6 +180,61 @@ public: /// Fill the vector with all debug info attachements. void getDebugInfo(SmallVectorImpl<DIGlobalVariableExpression *> &GVs) const; + /// Add attribute to this global. + void addAttribute(Attribute::AttrKind Kind) { + Attrs = Attrs.addAttribute(getContext(), Kind); + } + + /// Add attribute to this global. + void addAttribute(StringRef Kind, StringRef Val = StringRef()) { + Attrs = Attrs.addAttribute(getContext(), Kind, Val); + } + + /// Return true if the attribute exists. + bool hasAttribute(Attribute::AttrKind Kind) const { + return Attrs.hasAttribute(Kind); + } + + /// Return true if the attribute exists. + bool hasAttribute(StringRef Kind) const { + return Attrs.hasAttribute(Kind); + } + + /// Return true if any attributes exist. + bool hasAttributes() const { + return Attrs.hasAttributes(); + } + + /// Return the attribute object. + Attribute getAttribute(Attribute::AttrKind Kind) const { + return Attrs.getAttribute(Kind); + } + + /// Return the attribute object. + Attribute getAttribute(StringRef Kind) const { + return Attrs.getAttribute(Kind); + } + + /// Return the attribute set for this global + AttributeSet getAttributes() const { + return Attrs; + } + + /// Return attribute set as list with index. + /// FIXME: This may not be required once ValueEnumerators + /// in bitcode-writer can enumerate attribute-set. + AttributeList getAttributesAsList(unsigned index) const { + if (!hasAttributes()) + return AttributeList(); + std::pair<unsigned, AttributeSet> AS[1] = {{index, Attrs}}; + return AttributeList::get(getContext(), AS); + } + + /// Set attribute list for this global + void setAttributes(AttributeSet A) { + Attrs = A; + } + // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Value *V) { return V->getValueID() == Value::GlobalVariableVal; diff --git a/include/llvm/IR/IRBuilder.h b/include/llvm/IR/IRBuilder.h index bc689f3b01d7..9d4c13c29f68 100644 --- a/include/llvm/IR/IRBuilder.h +++ b/include/llvm/IR/IRBuilder.h @@ -454,6 +454,45 @@ public: MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr); + /// \brief Create a vector fadd reduction intrinsic of the source vector. + /// The first parameter is a scalar accumulator value for ordered reductions. + CallInst *CreateFAddReduce(Value *Acc, Value *Src); + + /// \brief Create a vector fmul reduction intrinsic of the source vector. + /// The first parameter is a scalar accumulator value for ordered reductions. + CallInst *CreateFMulReduce(Value *Acc, Value *Src); + + /// \brief Create a vector int add reduction intrinsic of the source vector. + CallInst *CreateAddReduce(Value *Src); + + /// \brief Create a vector int mul reduction intrinsic of the source vector. + CallInst *CreateMulReduce(Value *Src); + + /// \brief Create a vector int AND reduction intrinsic of the source vector. + CallInst *CreateAndReduce(Value *Src); + + /// \brief Create a vector int OR reduction intrinsic of the source vector. + CallInst *CreateOrReduce(Value *Src); + + /// \brief Create a vector int XOR reduction intrinsic of the source vector. + CallInst *CreateXorReduce(Value *Src); + + /// \brief Create a vector integer max reduction intrinsic of the source + /// vector. + CallInst *CreateIntMaxReduce(Value *Src, bool IsSigned = false); + + /// \brief Create a vector integer min reduction intrinsic of the source + /// vector. + CallInst *CreateIntMinReduce(Value *Src, bool IsSigned = false); + + /// \brief Create a vector float max reduction intrinsic of the source + /// vector. + CallInst *CreateFPMaxReduce(Value *Src, bool NoNaN = false); + + /// \brief Create a vector float min reduction intrinsic of the source + /// vector. + CallInst *CreateFPMinReduce(Value *Src, bool NoNaN = false); + /// \brief Create a lifetime.start intrinsic. /// /// If the pointer isn't i8* it will be converted. diff --git a/include/llvm/IR/InstrTypes.h b/include/llvm/IR/InstrTypes.h index d16a5d318d78..61ca90de7393 100644 --- a/include/llvm/IR/InstrTypes.h +++ b/include/llvm/IR/InstrTypes.h @@ -65,27 +65,15 @@ protected: // Out of line virtual method, so the vtable, etc has a home. ~TerminatorInst() override; - /// Virtual methods - Terminators should overload these and provide inline - /// overrides of non-V methods. - virtual BasicBlock *getSuccessorV(unsigned idx) const = 0; - virtual unsigned getNumSuccessorsV() const = 0; - virtual void setSuccessorV(unsigned idx, BasicBlock *B) = 0; - public: /// Return the number of successors that this terminator has. - unsigned getNumSuccessors() const { - return getNumSuccessorsV(); - } + unsigned getNumSuccessors() const; /// Return the specified successor. - BasicBlock *getSuccessor(unsigned idx) const { - return getSuccessorV(idx); - } + BasicBlock *getSuccessor(unsigned idx) const; /// Update the specified successor to point at the provided block. - void setSuccessor(unsigned idx, BasicBlock *B) { - setSuccessorV(idx, B); - } + void setSuccessor(unsigned idx, BasicBlock *B); // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *I) { diff --git a/include/llvm/IR/Instruction.h b/include/llvm/IR/Instruction.h index 90c3175122fd..fca29900f4c2 100644 --- a/include/llvm/IR/Instruction.h +++ b/include/llvm/IR/Instruction.h @@ -456,6 +456,12 @@ public: /// higher. bool isAtomic() const; + /// Return true if this atomic instruction loads from memory. + bool hasAtomicLoad() const; + + /// Return true if this atomic instruction stores to memory. + bool hasAtomicStore() const; + /// Return true if this instruction may throw an exception. bool mayThrow() const; diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h index 844a7273eca9..c26701af27ce 100644 --- a/include/llvm/IR/Instructions.h +++ b/include/llvm/IR/Instructions.h @@ -1,4 +1,4 @@ -//===-- llvm/Instructions.h - Instruction subclass definitions --*- C++ -*-===// +//===- llvm/Instructions.h - Instruction subclass definitions ---*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -17,6 +17,7 @@ #define LLVM_IR_INSTRUCTIONS_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/iterator.h" #include "llvm/ADT/iterator_range.h" #include "llvm/ADT/None.h" #include "llvm/ADT/SmallVector.h" @@ -24,21 +25,25 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" #include "llvm/IR/Attributes.h" +#include "llvm/IR/BasicBlock.h" #include "llvm/IR/CallingConv.h" #include "llvm/IR/Constant.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" #include "llvm/IR/InstrTypes.h" +#include "llvm/IR/Instruction.h" #include "llvm/IR/OperandTraits.h" #include "llvm/IR/Type.h" #include "llvm/IR/Use.h" #include "llvm/IR/User.h" +#include "llvm/IR/Value.h" #include "llvm/Support/AtomicOrdering.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" #include <cassert> #include <cstddef> #include <cstdint> +#include <iterator> namespace llvm { @@ -264,6 +269,7 @@ public: } bool isSimple() const { return !isAtomic() && !isVolatile(); } + bool isUnordered() const { return (getOrdering() == AtomicOrdering::NotAtomic || getOrdering() == AtomicOrdering::Unordered) && @@ -386,6 +392,7 @@ public: } bool isSimple() const { return !isAtomic() && !isVolatile(); } + bool isUnordered() const { return (getOrdering() == AtomicOrdering::NotAtomic || getOrdering() == AtomicOrdering::Unordered) && @@ -836,10 +843,7 @@ class GetElementPtrInst : public Instruction { Type *SourceElementType; Type *ResultElementType; - void anchor() override; - GetElementPtrInst(const GetElementPtrInst &GEPI); - void init(Value *Ptr, ArrayRef<Value *> IdxList, const Twine &NameStr); /// Constructors - Create a getelementptr instruction with a base pointer an /// list of indices. The first ctor can optionally insert before an existing @@ -852,6 +856,9 @@ class GetElementPtrInst : public Instruction { ArrayRef<Value *> IdxList, unsigned Values, const Twine &NameStr, BasicBlock *InsertAtEnd); + void anchor() override; + void init(Value *Ptr, ArrayRef<Value *> IdxList, const Twine &NameStr); + protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; @@ -2261,6 +2268,19 @@ public: return Mask; } + /// Change values in a shuffle permute mask assuming the two vector operands + /// of length InVecNumElts have swapped position. + static void commuteShuffleMask(MutableArrayRef<int> Mask, + unsigned InVecNumElts) { + for (int &Idx : Mask) { + if (Idx == -1) + continue; + Idx = Idx < (int)InVecNumElts ? Idx + InVecNumElts : Idx - InVecNumElts; + assert(Idx >= 0 && Idx < (int)InVecNumElts * 2 && + "shufflevector mask index out of range"); + } + } + // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *I) { return I->getOpcode() == Instruction::ShuffleVector; @@ -2288,6 +2308,7 @@ class ExtractValueInst : public UnaryInstruction { SmallVector<unsigned, 4> Indices; ExtractValueInst(const ExtractValueInst &EVI); + /// Constructors - Create a extractvalue instruction with a base aggregate /// value and a list of indices. The first ctor can optionally insert before /// an existing instruction, the second appends the new instruction to the @@ -2333,7 +2354,8 @@ public: /// Null is returned if the indices are invalid for the specified type. static Type *getIndexedType(Type *Agg, ArrayRef<unsigned> Idxs); - typedef const unsigned* idx_iterator; + using idx_iterator = const unsigned*; + inline idx_iterator idx_begin() const { return Indices.begin(); } inline idx_iterator idx_end() const { return Indices.end(); } inline iterator_range<idx_iterator> indices() const { @@ -2455,7 +2477,8 @@ public: /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); - typedef const unsigned* idx_iterator; + using idx_iterator = const unsigned*; + inline idx_iterator idx_begin() const { return Indices.begin(); } inline idx_iterator idx_end() const { return Indices.end(); } inline iterator_range<idx_iterator> indices() const { @@ -2606,8 +2629,8 @@ public: // Block iterator interface. This provides access to the list of incoming // basic blocks, which parallels the list of incoming values. - typedef BasicBlock **block_iterator; - typedef BasicBlock * const *const_block_iterator; + using block_iterator = BasicBlock **; + using const_block_iterator = BasicBlock * const *; block_iterator block_begin() { Use::UserRef *ref = @@ -2656,9 +2679,11 @@ public: "All operands to PHI node must be the same type as the PHI node!"); setOperand(i, V); } + static unsigned getOperandNumForIncomingValue(unsigned i) { return i; } + static unsigned getIncomingValueNumForOperand(unsigned i) { return i; } @@ -2937,9 +2962,11 @@ public: } private: - BasicBlock *getSuccessorV(unsigned idx) const override; - unsigned getNumSuccessorsV() const override; - void setSuccessorV(unsigned idx, BasicBlock *B) override; + friend TerminatorInst; + + BasicBlock *getSuccessorV(unsigned idx) const; + unsigned getNumSuccessorsV() const; + void setSuccessorV(unsigned idx, BasicBlock *B); }; template <> @@ -3047,9 +3074,11 @@ public: } private: - BasicBlock *getSuccessorV(unsigned idx) const override; - unsigned getNumSuccessorsV() const override; - void setSuccessorV(unsigned idx, BasicBlock *B) override; + friend TerminatorInst; + + BasicBlock *getSuccessorV(unsigned idx) const; + unsigned getNumSuccessorsV() const; + void setSuccessorV(unsigned idx, BasicBlock *B); }; template <> @@ -3123,7 +3152,7 @@ public: protected: // Expose the switch type we're parameterized with to the iterator. - typedef SwitchInstT SwitchInstType; + using SwitchInstType = SwitchInstT; SwitchInstT *SI; ptrdiff_t Index; @@ -3164,8 +3193,8 @@ public: } }; - typedef CaseHandleImpl<const SwitchInst, const ConstantInt, const BasicBlock> - ConstCaseHandle; + using ConstCaseHandle = + CaseHandleImpl<const SwitchInst, const ConstantInt, const BasicBlock>; class CaseHandle : public CaseHandleImpl<SwitchInst, ConstantInt, BasicBlock> { @@ -3192,7 +3221,7 @@ public: : public iterator_facade_base<CaseIteratorImpl<CaseHandleT>, std::random_access_iterator_tag, CaseHandleT> { - typedef typename CaseHandleT::SwitchInstType SwitchInstT; + using SwitchInstT = typename CaseHandleT::SwitchInstType; CaseHandleT Case; @@ -3254,8 +3283,8 @@ public: const CaseHandleT &operator*() const { return Case; } }; - typedef CaseIteratorImpl<CaseHandle> CaseIt; - typedef CaseIteratorImpl<ConstCaseHandle> ConstCaseIt; + using CaseIt = CaseIteratorImpl<CaseHandle>; + using ConstCaseIt = CaseIteratorImpl<ConstCaseHandle>; static SwitchInst *Create(Value *Value, BasicBlock *Default, unsigned NumCases, @@ -3411,9 +3440,11 @@ public: } private: - BasicBlock *getSuccessorV(unsigned idx) const override; - unsigned getNumSuccessorsV() const override; - void setSuccessorV(unsigned idx, BasicBlock *B) override; + friend TerminatorInst; + + BasicBlock *getSuccessorV(unsigned idx) const; + unsigned getNumSuccessorsV() const; + void setSuccessorV(unsigned idx, BasicBlock *B); }; template <> @@ -3516,9 +3547,11 @@ public: } private: - BasicBlock *getSuccessorV(unsigned idx) const override; - unsigned getNumSuccessorsV() const override; - void setSuccessorV(unsigned idx, BasicBlock *B) override; + friend TerminatorInst; + + BasicBlock *getSuccessorV(unsigned idx) const; + unsigned getNumSuccessorsV() const; + void setSuccessorV(unsigned idx, BasicBlock *B); }; template <> @@ -3639,6 +3672,7 @@ public: return new (Values) InvokeInst(Func, IfNormal, IfException, Args, None, Values, NameStr, InsertAtEnd); } + static InvokeInst *Create(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef<Value *> Args, ArrayRef<OperandBundleDef> Bundles, @@ -3996,9 +4030,11 @@ public: } private: - BasicBlock *getSuccessorV(unsigned idx) const override; - unsigned getNumSuccessorsV() const override; - void setSuccessorV(unsigned idx, BasicBlock *B) override; + friend TerminatorInst; + + BasicBlock *getSuccessorV(unsigned idx) const; + unsigned getNumSuccessorsV() const; + void setSuccessorV(unsigned idx, BasicBlock *B); template <typename AttrKind> bool hasFnAttrImpl(AttrKind Kind) const { if (Attrs.hasAttribute(AttributeList::FunctionIndex, Kind)) @@ -4095,9 +4131,11 @@ public: } private: - BasicBlock *getSuccessorV(unsigned idx) const override; - unsigned getNumSuccessorsV() const override; - void setSuccessorV(unsigned idx, BasicBlock *B) override; + friend TerminatorInst; + + BasicBlock *getSuccessorV(unsigned idx) const; + unsigned getNumSuccessorsV() const; + void setSuccessorV(unsigned idx, BasicBlock *B); }; template <> @@ -4202,13 +4240,14 @@ private: } public: - typedef std::pointer_to_unary_function<Value *, BasicBlock *> DerefFnTy; - typedef mapped_iterator<op_iterator, DerefFnTy> handler_iterator; - typedef iterator_range<handler_iterator> handler_range; - typedef std::pointer_to_unary_function<const Value *, const BasicBlock *> - ConstDerefFnTy; - typedef mapped_iterator<const_op_iterator, ConstDerefFnTy> const_handler_iterator; - typedef iterator_range<const_handler_iterator> const_handler_range; + using DerefFnTy = std::pointer_to_unary_function<Value *, BasicBlock *>; + using handler_iterator = mapped_iterator<op_iterator, DerefFnTy>; + using handler_range = iterator_range<handler_iterator>; + using ConstDerefFnTy = + std::pointer_to_unary_function<const Value *, const BasicBlock *>; + using const_handler_iterator = + mapped_iterator<const_op_iterator, ConstDerefFnTy>; + using const_handler_range = iterator_range<const_handler_iterator>; /// Returns an iterator that points to the first handler in CatchSwitchInst. handler_iterator handler_begin() { @@ -4278,9 +4317,11 @@ public: } private: - BasicBlock *getSuccessorV(unsigned Idx) const override; - unsigned getNumSuccessorsV() const override; - void setSuccessorV(unsigned Idx, BasicBlock *B) override; + friend TerminatorInst; + + BasicBlock *getSuccessorV(unsigned Idx) const; + unsigned getNumSuccessorsV() const; + void setSuccessorV(unsigned Idx, BasicBlock *B); }; template <> @@ -4443,9 +4484,11 @@ public: } private: - BasicBlock *getSuccessorV(unsigned Idx) const override; - unsigned getNumSuccessorsV() const override; - void setSuccessorV(unsigned Idx, BasicBlock *B) override; + friend TerminatorInst; + + BasicBlock *getSuccessorV(unsigned Idx) const; + unsigned getNumSuccessorsV() const; + void setSuccessorV(unsigned Idx, BasicBlock *B); }; template <> @@ -4531,9 +4574,11 @@ public: } private: - BasicBlock *getSuccessorV(unsigned Idx) const override; - unsigned getNumSuccessorsV() const override; - void setSuccessorV(unsigned Idx, BasicBlock *B) override; + friend TerminatorInst; + + BasicBlock *getSuccessorV(unsigned Idx) const; + unsigned getNumSuccessorsV() const; + void setSuccessorV(unsigned Idx, BasicBlock *B); // Shadow Instruction::setInstructionSubclassData with a private forwarding // method so that subclasses cannot accidentally use it. @@ -4586,9 +4631,11 @@ public: } private: - BasicBlock *getSuccessorV(unsigned idx) const override; - unsigned getNumSuccessorsV() const override; - void setSuccessorV(unsigned idx, BasicBlock *B) override; + friend TerminatorInst; + + BasicBlock *getSuccessorV(unsigned idx) const; + unsigned getNumSuccessorsV() const; + void setSuccessorV(unsigned idx, BasicBlock *B); }; //===----------------------------------------------------------------------===// diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td index 7b78d4d3d34a..19f6045568f4 100644 --- a/include/llvm/IR/Intrinsics.td +++ b/include/llvm/IR/Intrinsics.td @@ -812,6 +812,50 @@ def int_memcpy_element_atomic : Intrinsic<[], [IntrArgMemOnly, NoCapture<0>, NoCapture<1>, WriteOnly<0>, ReadOnly<1>]>; +//===------------------------ Reduction Intrinsics ------------------------===// +// +def int_experimental_vector_reduce_fadd : Intrinsic<[llvm_anyfloat_ty], + [llvm_anyfloat_ty, + llvm_anyvector_ty], + [IntrNoMem]>; +def int_experimental_vector_reduce_fmul : Intrinsic<[llvm_anyfloat_ty], + [llvm_anyfloat_ty, + llvm_anyvector_ty], + [IntrNoMem]>; +def int_experimental_vector_reduce_add : Intrinsic<[llvm_anyint_ty], + [llvm_anyvector_ty], + [IntrNoMem]>; +def int_experimental_vector_reduce_mul : Intrinsic<[llvm_anyint_ty], + [llvm_anyvector_ty], + [IntrNoMem]>; +def int_experimental_vector_reduce_and : Intrinsic<[llvm_anyint_ty], + [llvm_anyvector_ty], + [IntrNoMem]>; +def int_experimental_vector_reduce_or : Intrinsic<[llvm_anyint_ty], + [llvm_anyvector_ty], + [IntrNoMem]>; +def int_experimental_vector_reduce_xor : Intrinsic<[llvm_anyint_ty], + [llvm_anyvector_ty], + [IntrNoMem]>; +def int_experimental_vector_reduce_smax : Intrinsic<[llvm_anyint_ty], + [llvm_anyvector_ty], + [IntrNoMem]>; +def int_experimental_vector_reduce_smin : Intrinsic<[llvm_anyint_ty], + [llvm_anyvector_ty], + [IntrNoMem]>; +def int_experimental_vector_reduce_umax : Intrinsic<[llvm_anyint_ty], + [llvm_anyvector_ty], + [IntrNoMem]>; +def int_experimental_vector_reduce_umin : Intrinsic<[llvm_anyint_ty], + [llvm_anyvector_ty], + [IntrNoMem]>; +def int_experimental_vector_reduce_fmax : Intrinsic<[llvm_anyfloat_ty], + [llvm_anyvector_ty], + [IntrNoMem]>; +def int_experimental_vector_reduce_fmin : Intrinsic<[llvm_anyfloat_ty], + [llvm_anyvector_ty], + [IntrNoMem]>; + //===----- Intrinsics that are used to provide predicate information -----===// def int_ssa_copy : Intrinsic<[llvm_any_ty], [LLVMMatchType<0>], diff --git a/include/llvm/IR/LLVMContext.h b/include/llvm/IR/LLVMContext.h index d13d5ddaeb3c..ad011fb72e6a 100644 --- a/include/llvm/IR/LLVMContext.h +++ b/include/llvm/IR/LLVMContext.h @@ -1,4 +1,4 @@ -//===-- llvm/LLVMContext.h - Class for managing "global" state --*- C++ -*-===// +//===- llvm/LLVMContext.h - Class for managing "global" state ---*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -37,7 +37,9 @@ class StringRef; class Twine; namespace yaml { + class Output; + } // end namespace yaml /// This is an important class for using LLVM in a threaded context. It @@ -134,17 +136,17 @@ public: void enableDebugTypeODRUniquing(); void disableDebugTypeODRUniquing(); - typedef void (*InlineAsmDiagHandlerTy)(const SMDiagnostic&, void *Context, - unsigned LocCookie); + using InlineAsmDiagHandlerTy = void (*)(const SMDiagnostic&, void *Context, + unsigned LocCookie); /// Defines the type of a diagnostic handler. /// \see LLVMContext::setDiagnosticHandler. /// \see LLVMContext::diagnose. - typedef void (*DiagnosticHandlerTy)(const DiagnosticInfo &DI, void *Context); + using DiagnosticHandlerTy = void (*)(const DiagnosticInfo &DI, void *Context); /// Defines the type of a yield callback. /// \see LLVMContext::setYieldCallback. - typedef void (*YieldCallbackTy)(LLVMContext *Context, void *OpaqueHandle); + using YieldCallbackTy = void (*)(LLVMContext *Context, void *OpaqueHandle); /// setInlineAsmDiagnosticHandler - This method sets a handler that is invoked /// when problems with inline asm are detected by the backend. The first diff --git a/include/llvm/IR/LegacyPassManager.h b/include/llvm/IR/LegacyPassManager.h index 5257a0eed488..9a376a151505 100644 --- a/include/llvm/IR/LegacyPassManager.h +++ b/include/llvm/IR/LegacyPassManager.h @@ -98,6 +98,9 @@ private: // Create wrappers for C Binding types (see CBindingWrapping.h). DEFINE_STDCXX_CONVERSION_FUNCTIONS(legacy::PassManagerBase, LLVMPassManagerRef) +/// If -time-passes has been specified, report the timings immediately and then +/// reset the timers to zero. +void reportAndResetTimings(); } // End llvm namespace #endif diff --git a/include/llvm/IR/Module.h b/include/llvm/IR/Module.h index 67c35cd22b34..3024d9e27a2f 100644 --- a/include/llvm/IR/Module.h +++ b/include/llvm/IR/Module.h @@ -1,4 +1,4 @@ -//===-- llvm/Module.h - C++ class to represent a VM module ------*- C++ -*-===// +//===- llvm/Module.h - C++ class to represent a VM module -------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -16,6 +16,10 @@ #define LLVM_IR_MODULE_H #include "llvm/ADT/iterator_range.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/IR/Attributes.h" #include "llvm/IR/Comdat.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Function.h" @@ -23,20 +27,27 @@ #include "llvm/IR/GlobalIFunc.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/Metadata.h" +#include "llvm/IR/SymbolTableListTraits.h" #include "llvm/Support/CBindingWrapping.h" #include "llvm/Support/CodeGen.h" -#include "llvm/Support/DataTypes.h" +#include "llvm-c/Types.h" +#include <cstddef> +#include <cstdint> +#include <iterator> +#include <memory> +#include <string> +#include <vector> namespace llvm { -template <typename T> class Optional; + class Error; class FunctionType; class GVMaterializer; class LLVMContext; class MemoryBuffer; class RandomNumberGenerator; -class StructType; template <class PtrType> class SmallPtrSetImpl; +class StructType; /// A Module instance is used to store all the information related to an /// LLVM module. Modules are the top level container of all other LLVM @@ -54,47 +65,47 @@ class Module { /// @{ public: /// The type for the list of global variables. - typedef SymbolTableList<GlobalVariable> GlobalListType; + using GlobalListType = SymbolTableList<GlobalVariable>; /// The type for the list of functions. - typedef SymbolTableList<Function> FunctionListType; + using FunctionListType = SymbolTableList<Function>; /// The type for the list of aliases. - typedef SymbolTableList<GlobalAlias> AliasListType; + using AliasListType = SymbolTableList<GlobalAlias>; /// The type for the list of ifuncs. - typedef SymbolTableList<GlobalIFunc> IFuncListType; + using IFuncListType = SymbolTableList<GlobalIFunc>; /// The type for the list of named metadata. - typedef ilist<NamedMDNode> NamedMDListType; + using NamedMDListType = ilist<NamedMDNode>; /// The type of the comdat "symbol" table. - typedef StringMap<Comdat> ComdatSymTabType; + using ComdatSymTabType = StringMap<Comdat>; /// The Global Variable iterator. - typedef GlobalListType::iterator global_iterator; + using global_iterator = GlobalListType::iterator; /// The Global Variable constant iterator. - typedef GlobalListType::const_iterator const_global_iterator; + using const_global_iterator = GlobalListType::const_iterator; /// The Function iterators. - typedef FunctionListType::iterator iterator; + using iterator = FunctionListType::iterator; /// The Function constant iterator - typedef FunctionListType::const_iterator const_iterator; + using const_iterator = FunctionListType::const_iterator; /// The Function reverse iterator. - typedef FunctionListType::reverse_iterator reverse_iterator; + using reverse_iterator = FunctionListType::reverse_iterator; /// The Function constant reverse iterator. - typedef FunctionListType::const_reverse_iterator const_reverse_iterator; + using const_reverse_iterator = FunctionListType::const_reverse_iterator; /// The Global Alias iterators. - typedef AliasListType::iterator alias_iterator; + using alias_iterator = AliasListType::iterator; /// The Global Alias constant iterator - typedef AliasListType::const_iterator const_alias_iterator; + using const_alias_iterator = AliasListType::const_iterator; /// The Global IFunc iterators. - typedef IFuncListType::iterator ifunc_iterator; + using ifunc_iterator = IFuncListType::iterator; /// The Global IFunc constant iterator - typedef IFuncListType::const_iterator const_ifunc_iterator; + using const_ifunc_iterator = IFuncListType::const_iterator; /// The named metadata iterators. - typedef NamedMDListType::iterator named_metadata_iterator; + using named_metadata_iterator = NamedMDListType::iterator; /// The named metadata constant iterators. - typedef NamedMDListType::const_iterator const_named_metadata_iterator; + using const_named_metadata_iterator = NamedMDListType::const_iterator; /// This enumeration defines the supported behaviors of module flags. enum ModFlagBehavior { @@ -141,6 +152,7 @@ public: ModFlagBehavior Behavior; MDString *Key; Metadata *Val; + ModuleFlagEntry(ModFlagBehavior B, MDString *K, Metadata *V) : Behavior(B), Key(K), Val(V) {} }; @@ -483,9 +495,11 @@ public: const GlobalListType &getGlobalList() const { return GlobalList; } /// Get the Module's list of global variables. GlobalListType &getGlobalList() { return GlobalList; } + static GlobalListType Module::*getSublistAccess(GlobalVariable*) { return &Module::GlobalList; } + /// Get the Module's list of functions (constant). const FunctionListType &getFunctionList() const { return FunctionList; } /// Get the Module's list of functions. @@ -493,31 +507,39 @@ public: static FunctionListType Module::*getSublistAccess(Function*) { return &Module::FunctionList; } + /// Get the Module's list of aliases (constant). const AliasListType &getAliasList() const { return AliasList; } /// Get the Module's list of aliases. AliasListType &getAliasList() { return AliasList; } + static AliasListType Module::*getSublistAccess(GlobalAlias*) { return &Module::AliasList; } + /// Get the Module's list of ifuncs (constant). const IFuncListType &getIFuncList() const { return IFuncList; } /// Get the Module's list of ifuncs. IFuncListType &getIFuncList() { return IFuncList; } + static IFuncListType Module::*getSublistAccess(GlobalIFunc*) { return &Module::IFuncList; } + /// Get the Module's list of named metadata (constant). const NamedMDListType &getNamedMDList() const { return NamedMDList; } /// Get the Module's list of named metadata. NamedMDListType &getNamedMDList() { return NamedMDList; } + static NamedMDListType Module::*getSublistAccess(NamedMDNode*) { return &Module::NamedMDList; } + /// Get the symbol table of global variable and function identifiers const ValueSymbolTable &getValueSymbolTable() const { return *ValSymTab; } /// Get the Module's symbol table of global variable and function identifiers. ValueSymbolTable &getValueSymbolTable() { return *ValSymTab; } + /// Get the Module's symbol table for COMDATs (constant). const ComdatSymTabType &getComdatSymbolTable() const { return ComdatSymTab; } /// Get the Module's symbol table for COMDATs. @@ -602,11 +624,11 @@ public: /// @name Convenience iterators /// @{ - typedef concat_iterator<GlobalObject, iterator, global_iterator> - global_object_iterator; - typedef concat_iterator<const GlobalObject, const_iterator, - const_global_iterator> - const_global_object_iterator; + using global_object_iterator = + concat_iterator<GlobalObject, iterator, global_iterator>; + using const_global_object_iterator = + concat_iterator<const GlobalObject, const_iterator, + const_global_iterator>; iterator_range<global_object_iterator> global_objects() { return concat<GlobalObject>(functions(), globals()); @@ -627,13 +649,12 @@ public: return global_objects().end(); } - typedef concat_iterator<GlobalValue, iterator, global_iterator, - alias_iterator, ifunc_iterator> - global_value_iterator; - typedef concat_iterator<const GlobalValue, const_iterator, - const_global_iterator, const_alias_iterator, - const_ifunc_iterator> - const_global_value_iterator; + using global_value_iterator = + concat_iterator<GlobalValue, iterator, global_iterator, alias_iterator, + ifunc_iterator>; + using const_global_value_iterator = + concat_iterator<const GlobalValue, const_iterator, const_global_iterator, + const_alias_iterator, const_ifunc_iterator>; iterator_range<global_value_iterator> global_values() { return concat<GlobalValue>(functions(), globals(), aliases(), ifuncs()); @@ -682,28 +703,35 @@ public: : public std::iterator<std::input_iterator_tag, DICompileUnit *> { NamedMDNode *CUs; unsigned Idx; + void SkipNoDebugCUs(); + public: explicit debug_compile_units_iterator(NamedMDNode *CUs, unsigned Idx) : CUs(CUs), Idx(Idx) { SkipNoDebugCUs(); } + debug_compile_units_iterator &operator++() { ++Idx; SkipNoDebugCUs(); return *this; } + debug_compile_units_iterator operator++(int) { debug_compile_units_iterator T(*this); ++Idx; return T; } + bool operator==(const debug_compile_units_iterator &I) const { return Idx == I.Idx; } + bool operator!=(const debug_compile_units_iterator &I) const { return Idx != I.Idx; } + DICompileUnit *operator*() const; DICompileUnit *operator->() const; }; @@ -833,6 +861,6 @@ inline Module *unwrap(LLVMModuleProviderRef MP) { return reinterpret_cast<Module*>(MP); } -} // End llvm namespace +} // end namespace llvm -#endif +#endif // LLVM_IR_MODULE_H diff --git a/include/llvm/IR/ModuleSummaryIndex.h b/include/llvm/IR/ModuleSummaryIndex.h index 53570bdf16f4..c46c609609e2 100644 --- a/include/llvm/IR/ModuleSummaryIndex.h +++ b/include/llvm/IR/ModuleSummaryIndex.h @@ -1,4 +1,4 @@ -//===-- llvm/ModuleSummaryIndex.h - Module Summary Index --------*- C++ -*-===// +//===- llvm/ModuleSummaryIndex.h - Module Summary Index ---------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -16,21 +16,33 @@ #ifndef LLVM_IR_MODULESUMMARYINDEX_H #define LLVM_IR_MODULESUMMARYINDEX_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" #include "llvm/IR/Module.h" - +#include "llvm/IR/GlobalValue.h" +#include <algorithm> #include <array> +#include <cassert> +#include <cstddef> +#include <cstdint> +#include <map> +#include <memory> +#include <string> +#include <utility> +#include <vector> namespace llvm { namespace yaml { + template <typename T> struct MappingTraits; -} + +} // end namespace yaml /// \brief Class to accumulate and hold information about a callee. struct CalleeInfo { @@ -47,7 +59,7 @@ struct CalleeInfo { class GlobalValueSummary; -typedef std::vector<std::unique_ptr<GlobalValueSummary>> GlobalValueSummaryList; +using GlobalValueSummaryList = std::vector<std::unique_ptr<GlobalValueSummary>>; struct GlobalValueSummaryInfo { /// The GlobalValue corresponding to this summary. This is only used in @@ -66,19 +78,22 @@ struct GlobalValueSummaryInfo { /// likely incur less overhead, as the value type is not very small and the size /// of the map is unknown, resulting in inefficiencies due to repeated /// insertions and resizing. -typedef std::map<GlobalValue::GUID, GlobalValueSummaryInfo> - GlobalValueSummaryMapTy; +using GlobalValueSummaryMapTy = + std::map<GlobalValue::GUID, GlobalValueSummaryInfo>; /// Struct that holds a reference to a particular GUID in a global value /// summary. struct ValueInfo { const GlobalValueSummaryMapTy::value_type *Ref = nullptr; + ValueInfo() = default; ValueInfo(const GlobalValueSummaryMapTy::value_type *Ref) : Ref(Ref) {} + operator bool() const { return Ref; } GlobalValue::GUID getGUID() const { return Ref->first; } const GlobalValue *getValue() const { return Ref->second.GV; } + ArrayRef<std::unique_ptr<GlobalValueSummary>> getSummaryList() const { return Ref->second.SummaryList; } @@ -88,9 +103,11 @@ template <> struct DenseMapInfo<ValueInfo> { static inline ValueInfo getEmptyKey() { return ValueInfo((GlobalValueSummaryMapTy::value_type *)-1); } + static inline ValueInfo getTombstoneKey() { return ValueInfo((GlobalValueSummaryMapTy::value_type *)-2); } + static bool isEqual(ValueInfo L, ValueInfo R) { return L.Ref == R.Ref; } static unsigned getHashValue(ValueInfo I) { return (uintptr_t)I.Ref; } }; @@ -138,7 +155,7 @@ private: /// This is the hash of the name of the symbol in the original file. It is /// identical to the GUID for global symbols, but differs for local since the /// GUID includes the module level id in the hash. - GlobalValue::GUID OriginalName; + GlobalValue::GUID OriginalName = 0; /// \brief Path of module IR containing value's definition, used to locate /// module during importing. @@ -157,7 +174,7 @@ private: protected: GlobalValueSummary(SummaryKind K, GVFlags Flags, std::vector<ValueInfo> Refs) - : Kind(K), Flags(Flags), OriginalName(0), RefEdgeList(std::move(Refs)) {} + : Kind(K), Flags(Flags), RefEdgeList(std::move(Refs)) {} public: virtual ~GlobalValueSummary() = default; @@ -242,7 +259,7 @@ public: class FunctionSummary : public GlobalValueSummary { public: /// <CalleeValueInfo, CalleeInfo> call edge pair. - typedef std::pair<ValueInfo, CalleeInfo> EdgeTy; + using EdgeTy = std::pair<ValueInfo, CalleeInfo>; /// An "identifier" for a virtual function. This contains the type identifier /// represented as a GUID and the offset from the address point to the virtual @@ -376,12 +393,15 @@ public: template <> struct DenseMapInfo<FunctionSummary::VFuncId> { static FunctionSummary::VFuncId getEmptyKey() { return {0, uint64_t(-1)}; } + static FunctionSummary::VFuncId getTombstoneKey() { return {0, uint64_t(-2)}; } + static bool isEqual(FunctionSummary::VFuncId L, FunctionSummary::VFuncId R) { return L.GUID == R.GUID && L.Offset == R.Offset; } + static unsigned getHashValue(FunctionSummary::VFuncId I) { return I.GUID; } }; @@ -389,14 +409,17 @@ template <> struct DenseMapInfo<FunctionSummary::ConstVCall> { static FunctionSummary::ConstVCall getEmptyKey() { return {{0, uint64_t(-1)}, {}}; } + static FunctionSummary::ConstVCall getTombstoneKey() { return {{0, uint64_t(-2)}, {}}; } + static bool isEqual(FunctionSummary::ConstVCall L, FunctionSummary::ConstVCall R) { return DenseMapInfo<FunctionSummary::VFuncId>::isEqual(L.VFunc, R.VFunc) && L.Args == R.Args; } + static unsigned getHashValue(FunctionSummary::ConstVCall I) { return I.VFunc.GUID; } @@ -477,20 +500,20 @@ struct TypeIdSummary { }; /// 160 bits SHA1 -typedef std::array<uint32_t, 5> ModuleHash; +using ModuleHash = std::array<uint32_t, 5>; /// Type used for iterating through the global value summary map. -typedef GlobalValueSummaryMapTy::const_iterator const_gvsummary_iterator; -typedef GlobalValueSummaryMapTy::iterator gvsummary_iterator; +using const_gvsummary_iterator = GlobalValueSummaryMapTy::const_iterator; +using gvsummary_iterator = GlobalValueSummaryMapTy::iterator; /// String table to hold/own module path strings, which additionally holds the /// module ID assigned to each module during the plugin step, as well as a hash /// of the module. The StringMap makes a copy of and owns inserted strings. -typedef StringMap<std::pair<uint64_t, ModuleHash>> ModulePathStringTableTy; +using ModulePathStringTableTy = StringMap<std::pair<uint64_t, ModuleHash>>; /// Map of global value GUID to its summary, used to identify values defined in /// a particular module, and provide efficient access to their summary. -typedef std::map<GlobalValue::GUID, GlobalValueSummary *> GVSummaryMapTy; +using GVSummaryMapTy = std::map<GlobalValue::GUID, GlobalValueSummary *>; /// Class to hold module path string table and global value map, /// and encapsulate methods for operating on them. @@ -697,6 +720,6 @@ public: StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries) const; }; -} // End llvm namespace +} // end namespace llvm -#endif +#endif // LLVM_IR_MODULESUMMARYINDEX_H diff --git a/include/llvm/IR/PassManager.h b/include/llvm/IR/PassManager.h index c845112baa45..d03b7b65f81e 100644 --- a/include/llvm/IR/PassManager.h +++ b/include/llvm/IR/PassManager.h @@ -39,8 +39,8 @@ #define LLVM_IR_PASSMANAGER_H #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/TinyPtrVector.h" #include "llvm/IR/Function.h" #include "llvm/IR/Module.h" @@ -48,9 +48,15 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/TypeName.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Support/type_traits.h" +#include <algorithm> +#include <cassert> +#include <cstring> +#include <iterator> #include <list> #include <memory> +#include <tuple> +#include <type_traits> +#include <utility> #include <vector> namespace llvm { @@ -469,15 +475,16 @@ public: } template <typename PassT> void addPass(PassT Pass) { - typedef detail::PassModel<IRUnitT, PassT, PreservedAnalyses, - AnalysisManagerT, ExtraArgTs...> - PassModelT; + using PassModelT = + detail::PassModel<IRUnitT, PassT, PreservedAnalyses, AnalysisManagerT, + ExtraArgTs...>; + Passes.emplace_back(new PassModelT(std::move(Pass))); } private: - typedef detail::PassConcept<IRUnitT, AnalysisManagerT, ExtraArgTs...> - PassConceptT; + using PassConceptT = + detail::PassConcept<IRUnitT, AnalysisManagerT, ExtraArgTs...>; std::vector<std::unique_ptr<PassConceptT>> Passes; @@ -486,12 +493,14 @@ private: }; extern template class PassManager<Module>; + /// \brief Convenience typedef for a pass manager over modules. -typedef PassManager<Module> ModulePassManager; +using ModulePassManager = PassManager<Module>; extern template class PassManager<Function>; + /// \brief Convenience typedef for a pass manager over functions. -typedef PassManager<Function> FunctionPassManager; +using FunctionPassManager = PassManager<Function>; /// \brief A container for analyses that lazily runs them and caches their /// results. @@ -504,11 +513,11 @@ public: private: // Now that we've defined our invalidator, we can define the concept types. - typedef detail::AnalysisResultConcept<IRUnitT, PreservedAnalyses, Invalidator> - ResultConceptT; - typedef detail::AnalysisPassConcept<IRUnitT, PreservedAnalyses, Invalidator, - ExtraArgTs...> - PassConceptT; + using ResultConceptT = + detail::AnalysisResultConcept<IRUnitT, PreservedAnalyses, Invalidator>; + using PassConceptT = + detail::AnalysisPassConcept<IRUnitT, PreservedAnalyses, Invalidator, + ExtraArgTs...>; /// \brief List of analysis pass IDs and associated concept pointers. /// @@ -516,18 +525,18 @@ private: /// erases. Provides the analysis ID to enable finding iterators to a given /// entry in maps below, and provides the storage for the actual result /// concept. - typedef std::list<std::pair<AnalysisKey *, std::unique_ptr<ResultConceptT>>> - AnalysisResultListT; + using AnalysisResultListT = + std::list<std::pair<AnalysisKey *, std::unique_ptr<ResultConceptT>>>; /// \brief Map type from IRUnitT pointer to our custom list type. - typedef DenseMap<IRUnitT *, AnalysisResultListT> AnalysisResultListMapT; + using AnalysisResultListMapT = DenseMap<IRUnitT *, AnalysisResultListT>; /// \brief Map type from a pair of analysis ID and IRUnitT pointer to an /// iterator into a particular result list (which is where the actual analysis /// result is stored). - typedef DenseMap<std::pair<AnalysisKey *, IRUnitT *>, - typename AnalysisResultListT::iterator> - AnalysisResultMapT; + using AnalysisResultMapT = + DenseMap<std::pair<AnalysisKey *, IRUnitT *>, + typename AnalysisResultListT::iterator>; public: /// API to communicate dependencies between analyses during invalidation. @@ -558,10 +567,10 @@ public: /// dependecies on it will become invalid as a result. template <typename PassT> bool invalidate(IRUnitT &IR, const PreservedAnalyses &PA) { - typedef detail::AnalysisResultModel<IRUnitT, PassT, - typename PassT::Result, - PreservedAnalyses, Invalidator> - ResultModelT; + using ResultModelT = + detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result, + PreservedAnalyses, Invalidator>; + return invalidateImpl<ResultModelT>(PassT::ID(), IR, PA); } @@ -672,9 +681,11 @@ public: "This analysis pass was not registered prior to being queried"); ResultConceptT &ResultConcept = getResultImpl(PassT::ID(), IR, ExtraArgs...); - typedef detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result, - PreservedAnalyses, Invalidator> - ResultModelT; + + using ResultModelT = + detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result, + PreservedAnalyses, Invalidator>; + return static_cast<ResultModelT &>(ResultConcept).Result; } @@ -692,9 +703,10 @@ public: if (!ResultConcept) return nullptr; - typedef detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result, - PreservedAnalyses, Invalidator> - ResultModelT; + using ResultModelT = + detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result, + PreservedAnalyses, Invalidator>; + return &static_cast<ResultModelT *>(ResultConcept)->Result; } @@ -717,10 +729,10 @@ public: /// hashtable.) template <typename PassBuilderT> bool registerPass(PassBuilderT &&PassBuilder) { - typedef decltype(PassBuilder()) PassT; - typedef detail::AnalysisPassModel<IRUnitT, PassT, PreservedAnalyses, - Invalidator, ExtraArgTs...> - PassModelT; + using PassT = decltype(PassBuilder()); + using PassModelT = + detail::AnalysisPassModel<IRUnitT, PassT, PreservedAnalyses, + Invalidator, ExtraArgTs...>; auto &PassPtr = AnalysisPasses[PassT::ID()]; if (PassPtr) @@ -876,7 +888,8 @@ private: } /// \brief Map type from module analysis pass ID to pass concept pointer. - typedef DenseMap<AnalysisKey *, std::unique_ptr<PassConceptT>> AnalysisPassMapT; + using AnalysisPassMapT = + DenseMap<AnalysisKey *, std::unique_ptr<PassConceptT>>; /// \brief Collection of module analysis passes, indexed by ID. AnalysisPassMapT AnalysisPasses; @@ -896,12 +909,14 @@ private: }; extern template class AnalysisManager<Module>; + /// \brief Convenience typedef for the Module analysis manager. -typedef AnalysisManager<Module> ModuleAnalysisManager; +using ModuleAnalysisManager = AnalysisManager<Module>; extern template class AnalysisManager<Function>; + /// \brief Convenience typedef for the Function analysis manager. -typedef AnalysisManager<Function> FunctionAnalysisManager; +using FunctionAnalysisManager = AnalysisManager<Function>; /// \brief An analysis over an "outer" IR unit that provides access to an /// analysis manager over an "inner" IR unit. The inner unit must be contained @@ -927,20 +942,14 @@ public: class Result { public: explicit Result(AnalysisManagerT &InnerAM) : InnerAM(&InnerAM) {} + Result(Result &&Arg) : InnerAM(std::move(Arg.InnerAM)) { // We have to null out the analysis manager in the moved-from state // because we are taking ownership of the responsibilty to clear the // analysis state. Arg.InnerAM = nullptr; } - Result &operator=(Result &&RHS) { - InnerAM = RHS.InnerAM; - // We have to null out the analysis manager in the moved-from state - // because we are taking ownership of the responsibilty to clear the - // analysis state. - RHS.InnerAM = nullptr; - return *this; - } + ~Result() { // InnerAM is cleared in a moved from state where there is nothing to do. if (!InnerAM) @@ -951,6 +960,15 @@ public: InnerAM->clear(); } + Result &operator=(Result &&RHS) { + InnerAM = RHS.InnerAM; + // We have to null out the analysis manager in the moved-from state + // because we are taking ownership of the responsibilty to clear the + // analysis state. + RHS.InnerAM = nullptr; + return *this; + } + /// \brief Accessor for the analysis manager. AnalysisManagerT &getManager() { return *InnerAM; } @@ -988,6 +1006,7 @@ public: private: friend AnalysisInfoMixin< InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT>>; + static AnalysisKey Key; AnalysisManagerT *InnerAM; @@ -998,8 +1017,8 @@ AnalysisKey InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT, ExtraArgTs...>::Key; /// Provide the \c FunctionAnalysisManager to \c Module proxy. -typedef InnerAnalysisManagerProxy<FunctionAnalysisManager, Module> - FunctionAnalysisManagerModuleProxy; +using FunctionAnalysisManagerModuleProxy = + InnerAnalysisManagerProxy<FunctionAnalysisManager, Module>; /// Specialization of the invalidate method for the \c /// FunctionAnalysisManagerModuleProxy's result. @@ -1097,6 +1116,7 @@ public: private: friend AnalysisInfoMixin< OuterAnalysisManagerProxy<AnalysisManagerT, IRUnitT, ExtraArgTs...>>; + static AnalysisKey Key; const AnalysisManagerT *AM; @@ -1109,8 +1129,8 @@ AnalysisKey extern template class OuterAnalysisManagerProxy<ModuleAnalysisManager, Function>; /// Provide the \c ModuleAnalysisManager to \c Function proxy. -typedef OuterAnalysisManagerProxy<ModuleAnalysisManager, Function> - ModuleAnalysisManagerFunctionProxy; +using ModuleAnalysisManagerFunctionProxy = + OuterAnalysisManagerProxy<ModuleAnalysisManager, Function>; /// \brief Trivial adaptor that maps from a module to its functions. /// @@ -1274,6 +1294,6 @@ RepeatedPass<PassT> createRepeatedPass(int Count, PassT P) { return RepeatedPass<PassT>(Count, std::move(P)); } -} +} // end namespace llvm -#endif +#endif // LLVM_IR_PASSMANAGER_H diff --git a/include/llvm/IR/PassManagerInternal.h b/include/llvm/IR/PassManagerInternal.h index 387dc4c65c43..9195d4dfa428 100644 --- a/include/llvm/IR/PassManagerInternal.h +++ b/include/llvm/IR/PassManagerInternal.h @@ -27,7 +27,6 @@ namespace llvm { template <typename IRUnitT> class AllAnalysesOn; template <typename IRUnitT, typename... ExtraArgTs> class AnalysisManager; -class Invalidator; class PreservedAnalyses; /// \brief Implementation details of the pass manager interfaces. @@ -116,7 +115,7 @@ struct AnalysisResultConcept { /// \brief SFINAE metafunction for computing whether \c ResultT provides an /// \c invalidate member function. template <typename IRUnitT, typename ResultT> class ResultHasInvalidateMethod { - typedef char EnabledType; + using EnabledType = char; struct DisabledType { char a, b; }; @@ -124,7 +123,7 @@ template <typename IRUnitT, typename ResultT> class ResultHasInvalidateMethod { // Purely to help out MSVC which fails to disable the below specialization, // explicitly enable using the result type's invalidate routine if we can // successfully call that routine. - template <typename T> struct Nonce { typedef EnabledType Type; }; + template <typename T> struct Nonce { using Type = EnabledType; }; template <typename T> static typename Nonce<decltype(std::declval<T>().invalidate( std::declval<IRUnitT &>(), std::declval<PreservedAnalyses>()))>::Type @@ -280,9 +279,9 @@ struct AnalysisPassModel : AnalysisPassConcept<IRUnitT, PreservedAnalysesT, } // FIXME: Replace PassT::Result with type traits when we use C++11. - typedef AnalysisResultModel<IRUnitT, PassT, typename PassT::Result, - PreservedAnalysesT, InvalidatorT> - ResultModelT; + using ResultModelT = + AnalysisResultModel<IRUnitT, PassT, typename PassT::Result, + PreservedAnalysesT, InvalidatorT>; /// \brief The model delegates to the \c PassT::run method. /// diff --git a/include/llvm/IR/PatternMatch.h b/include/llvm/IR/PatternMatch.h index 31a76b4ed6c3..6b2b22e82b95 100644 --- a/include/llvm/IR/PatternMatch.h +++ b/include/llvm/IR/PatternMatch.h @@ -29,11 +29,19 @@ #ifndef LLVM_IR_PATTERNMATCH_H #define LLVM_IR_PATTERNMATCH_H +#include "llvm/ADT/APFloat.h" +#include "llvm/ADT/APInt.h" #include "llvm/IR/CallSite.h" +#include "llvm/IR/Constant.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/InstrTypes.h" +#include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/Operator.h" +#include "llvm/IR/Value.h" +#include "llvm/Support/Casting.h" +#include <cstdint> namespace llvm { namespace PatternMatch { @@ -172,7 +180,9 @@ inline match_nan m_NaN() { return match_nan(); } struct apint_match { const APInt *&Res; + apint_match(const APInt *&R) : Res(R) {} + template <typename ITy> bool match(ITy *V) { if (auto *CI = dyn_cast<ConstantInt>(V)) { Res = &CI->getValue(); @@ -230,7 +240,9 @@ template <typename Predicate> struct cst_pred_ty : public Predicate { /// satisfy a specified predicate, and bind them to an APInt. template <typename Predicate> struct api_pred_ty : public Predicate { const APInt *&Res; + api_pred_ty(const APInt *&R) : Res(R) {} + template <typename ITy> bool match(ITy *V) { if (const auto *CI = dyn_cast<ConstantInt>(V)) if (this->isValue(CI->getValue())) { @@ -294,6 +306,7 @@ inline api_pred_ty<is_maxsignedvalue> m_MaxSignedValue(const APInt *&V) { return template <typename Class> struct bind_ty { Class *&VR; + bind_ty(Class *&V) : VR(V) {} template <typename ITy> bool match(ITy *V) { @@ -326,6 +339,7 @@ inline bind_ty<ConstantFP> m_ConstantFP(ConstantFP *&C) { return C; } /// \brief Match a specified Value*. struct specificval_ty { const Value *Val; + specificval_ty(const Value *V) : Val(V) {} template <typename ITy> bool match(ITy *V) { return V == Val; } @@ -338,6 +352,7 @@ inline specificval_ty m_Specific(const Value *V) { return V; } /// that value. struct specific_fpval { double Val; + specific_fpval(double V) : Val(V) {} template <typename ITy> bool match(ITy *V) { @@ -360,6 +375,7 @@ inline specific_fpval m_FPOne() { return m_SpecificFP(1.0); } struct bind_const_intval_ty { uint64_t &VR; + bind_const_intval_ty(uint64_t &V) : VR(V) {} template <typename ITy> bool match(ITy *V) { @@ -376,6 +392,7 @@ struct bind_const_intval_ty { // value. struct specific_intval { uint64_t Val; + specific_intval(uint64_t V) : Val(V) {} template <typename ITy> bool match(ITy *V) { @@ -939,6 +956,7 @@ template <typename LHS> inline fneg_match<LHS> m_FNeg(const LHS &L) { struct br_match { BasicBlock *&Succ; + br_match(BasicBlock *&Succ) : Succ(Succ) {} template <typename OpTy> bool match(OpTy *V) { @@ -956,6 +974,7 @@ inline br_match m_UnconditionalBr(BasicBlock *&Succ) { return br_match(Succ); } template <typename Cond_t> struct brc_match { Cond_t Cond; BasicBlock *&T, *&F; + brc_match(const Cond_t &C, BasicBlock *&t, BasicBlock *&f) : Cond(C), T(t), F(f) {} @@ -1202,6 +1221,7 @@ m_UnordFMin(const LHS &L, const RHS &R) { template <typename Opnd_t> struct Argument_match { unsigned OpI; Opnd_t Val; + Argument_match(unsigned OpIdx, const Opnd_t &V) : OpI(OpIdx), Val(V) {} template <typename OpTy> bool match(OpTy *V) { @@ -1219,6 +1239,7 @@ inline Argument_match<Opnd_t> m_Argument(const Opnd_t &Op) { /// \brief Intrinsic matchers. struct IntrinsicID_match { unsigned ID; + IntrinsicID_match(Intrinsic::ID IntrID) : ID(IntrID) {} template <typename OpTy> bool match(OpTy *V) { @@ -1239,21 +1260,23 @@ template <typename T0 = void, typename T1 = void, typename T2 = void, typename T9 = void, typename T10 = void> struct m_Intrinsic_Ty; template <typename T0> struct m_Intrinsic_Ty<T0> { - typedef match_combine_and<IntrinsicID_match, Argument_match<T0>> Ty; + using Ty = match_combine_and<IntrinsicID_match, Argument_match<T0>>; }; template <typename T0, typename T1> struct m_Intrinsic_Ty<T0, T1> { - typedef match_combine_and<typename m_Intrinsic_Ty<T0>::Ty, Argument_match<T1>> - Ty; + using Ty = + match_combine_and<typename m_Intrinsic_Ty<T0>::Ty, Argument_match<T1>>; }; template <typename T0, typename T1, typename T2> struct m_Intrinsic_Ty<T0, T1, T2> { - typedef match_combine_and<typename m_Intrinsic_Ty<T0, T1>::Ty, - Argument_match<T2>> Ty; + using Ty = + match_combine_and<typename m_Intrinsic_Ty<T0, T1>::Ty, + Argument_match<T2>>; }; template <typename T0, typename T1, typename T2, typename T3> struct m_Intrinsic_Ty<T0, T1, T2, T3> { - typedef match_combine_and<typename m_Intrinsic_Ty<T0, T1, T2>::Ty, - Argument_match<T3>> Ty; + using Ty = + match_combine_and<typename m_Intrinsic_Ty<T0, T1, T2>::Ty, + Argument_match<T3>>; }; /// \brief Match intrinsic calls like this: @@ -1437,4 +1460,4 @@ m_c_UMax(const LHS &L, const RHS &R) { } // end namespace PatternMatch } // end namespace llvm -#endif +#endif // LLVM_IR_PATTERNMATCH_H diff --git a/include/llvm/IR/ProfileSummary.h b/include/llvm/IR/ProfileSummary.h index f4248014c6e1..d85ce8c443ec 100644 --- a/include/llvm/IR/ProfileSummary.h +++ b/include/llvm/IR/ProfileSummary.h @@ -1,4 +1,4 @@ -//===-- ProfileSummary.h - Profile summary data structure. ------*- C++ -*-===// +//===- ProfileSummary.h - Profile summary data structure. -------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -11,21 +11,17 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SUPPORT_PROFILE_SUMMARY_H -#define LLVM_SUPPORT_PROFILE_SUMMARY_H +#ifndef LLVM_IR_PROFILESUMMARY_H +#define LLVM_IR_PROFILESUMMARY_H +#include <algorithm> #include <cstdint> -#include <utility> #include <vector> -#include "llvm/Support/Casting.h" - namespace llvm { class LLVMContext; class Metadata; -class MDTuple; -class MDNode; // The profile summary is one or more (Cutoff, MinCount, NumCounts) triplets. // The semantics of counts depend on the type of profile. For instrumentation @@ -37,12 +33,13 @@ struct ProfileSummaryEntry { uint32_t Cutoff; ///< The required percentile of counts. uint64_t MinCount; ///< The minimum count for this percentile. uint64_t NumCounts; ///< Number of counts >= the minimum count. + ProfileSummaryEntry(uint32_t TheCutoff, uint64_t TheMinCount, uint64_t TheNumCounts) : Cutoff(TheCutoff), MinCount(TheMinCount), NumCounts(TheNumCounts) {} }; -typedef std::vector<ProfileSummaryEntry> SummaryEntryVector; +using SummaryEntryVector = std::vector<ProfileSummaryEntry>; class ProfileSummary { public: @@ -59,6 +56,7 @@ private: public: static const int Scale = 1000000; + ProfileSummary(Kind K, SummaryEntryVector DetailedSummary, uint64_t TotalCount, uint64_t MaxCount, uint64_t MaxInternalCount, uint64_t MaxFunctionCount, @@ -67,6 +65,7 @@ public: TotalCount(TotalCount), MaxCount(MaxCount), MaxInternalCount(MaxInternalCount), MaxFunctionCount(MaxFunctionCount), NumCounts(NumCounts), NumFunctions(NumFunctions) {} + Kind getKind() const { return PSK; } /// \brief Return summary information as metadata. Metadata *getMD(LLVMContext &Context); @@ -82,4 +81,5 @@ public: }; } // end namespace llvm -#endif + +#endif // LLVM_IR_PROFILESUMMARY_H diff --git a/include/llvm/IR/Statepoint.h b/include/llvm/IR/Statepoint.h index 03151cd7c8f7..f01607614a0c 100644 --- a/include/llvm/IR/Statepoint.h +++ b/include/llvm/IR/Statepoint.h @@ -1,4 +1,4 @@ -//===-- llvm/IR/Statepoint.h - gc.statepoint utilities ----------*- C++ -*-===// +//===- llvm/IR/Statepoint.h - gc.statepoint utilities -----------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -24,10 +24,12 @@ #include "llvm/IR/CallSite.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Function.h" +#include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Intrinsics.h" #include "llvm/Support/Casting.h" +#include "llvm/Support/MathExtras.h" #include <cassert> #include <cstddef> #include <cstdint> @@ -87,7 +89,7 @@ protected: } public: - typedef typename CallSiteTy::arg_iterator arg_iterator; + using arg_iterator = typename CallSiteTy::arg_iterator; enum { IDPos = 0, @@ -300,8 +302,9 @@ public: class ImmutableStatepoint : public StatepointBase<const Function, const Instruction, const Value, ImmutableCallSite> { - typedef StatepointBase<const Function, const Instruction, const Value, - ImmutableCallSite> Base; + using Base = + StatepointBase<const Function, const Instruction, const Value, + ImmutableCallSite>; public: explicit ImmutableStatepoint(const Instruction *I) : Base(I) {} @@ -312,7 +315,7 @@ public: /// to a gc.statepoint. class Statepoint : public StatepointBase<Function, Instruction, Value, CallSite> { - typedef StatepointBase<Function, Instruction, Value, CallSite> Base; + using Base = StatepointBase<Function, Instruction, Value, CallSite>; public: explicit Statepoint(Instruction *I) : Base(I) {} @@ -327,6 +330,7 @@ public: return I->getIntrinsicID() == Intrinsic::experimental_gc_relocate || I->getIntrinsicID() == Intrinsic::experimental_gc_result; } + static inline bool classof(const Value *V) { return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); } @@ -369,6 +373,7 @@ public: static inline bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::experimental_gc_relocate; } + static inline bool classof(const Value *V) { return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); } @@ -403,6 +408,7 @@ public: static inline bool classof(const IntrinsicInst *I) { return I->getIntrinsicID() == Intrinsic::experimental_gc_result; } + static inline bool classof(const Value *V) { return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); } diff --git a/include/llvm/IR/SymbolTableListTraits.h b/include/llvm/IR/SymbolTableListTraits.h index 49a5fb21297d..87ce902c2811 100644 --- a/include/llvm/IR/SymbolTableListTraits.h +++ b/include/llvm/IR/SymbolTableListTraits.h @@ -48,7 +48,7 @@ class ValueSymbolTable; template <typename NodeTy> struct SymbolTableListParentType {}; #define DEFINE_SYMBOL_TABLE_PARENT_TYPE(NODE, PARENT) \ - template <> struct SymbolTableListParentType<NODE> { typedef PARENT type; }; + template <> struct SymbolTableListParentType<NODE> { using type = PARENT; }; DEFINE_SYMBOL_TABLE_PARENT_TYPE(Instruction, BasicBlock) DEFINE_SYMBOL_TABLE_PARENT_TYPE(BasicBlock, Function) DEFINE_SYMBOL_TABLE_PARENT_TYPE(Argument, Function) @@ -65,10 +65,10 @@ template <typename NodeTy> class SymbolTableList; // template <typename ValueSubClass> class SymbolTableListTraits : public ilist_alloc_traits<ValueSubClass> { - typedef SymbolTableList<ValueSubClass> ListTy; - typedef typename simple_ilist<ValueSubClass>::iterator iterator; - typedef - typename SymbolTableListParentType<ValueSubClass>::type ItemParentClass; + using ListTy = SymbolTableList<ValueSubClass>; + using iterator = typename simple_ilist<ValueSubClass>::iterator; + using ItemParentClass = + typename SymbolTableListParentType<ValueSubClass>::type; public: SymbolTableListTraits() = default; diff --git a/include/llvm/IR/TrackingMDRef.h b/include/llvm/IR/TrackingMDRef.h index 12b196432006..bdec904ad1e1 100644 --- a/include/llvm/IR/TrackingMDRef.h +++ b/include/llvm/IR/TrackingMDRef.h @@ -139,31 +139,35 @@ public: bool hasTrivialDestructor() const { return Ref.hasTrivialDestructor(); } }; -typedef TypedTrackingMDRef<MDNode> TrackingMDNodeRef; -typedef TypedTrackingMDRef<ValueAsMetadata> TrackingValueAsMetadataRef; +using TrackingMDNodeRef = TypedTrackingMDRef<MDNode>; +using TrackingValueAsMetadataRef = TypedTrackingMDRef<ValueAsMetadata>; // Expose the underlying metadata to casting. template <> struct simplify_type<TrackingMDRef> { - typedef Metadata *SimpleType; + using SimpleType = Metadata *; + static SimpleType getSimplifiedValue(TrackingMDRef &MD) { return MD.get(); } }; template <> struct simplify_type<const TrackingMDRef> { - typedef Metadata *SimpleType; + using SimpleType = Metadata *; + static SimpleType getSimplifiedValue(const TrackingMDRef &MD) { return MD.get(); } }; template <class T> struct simplify_type<TypedTrackingMDRef<T>> { - typedef T *SimpleType; + using SimpleType = T *; + static SimpleType getSimplifiedValue(TypedTrackingMDRef<T> &MD) { return MD.get(); } }; template <class T> struct simplify_type<const TypedTrackingMDRef<T>> { - typedef T *SimpleType; + using SimpleType = T *; + static SimpleType getSimplifiedValue(const TypedTrackingMDRef<T> &MD) { return MD.get(); } diff --git a/include/llvm/IR/Type.h b/include/llvm/IR/Type.h index e6a0df937e9b..82362107e41e 100644 --- a/include/llvm/IR/Type.h +++ b/include/llvm/IR/Type.h @@ -1,4 +1,4 @@ -//===-- llvm/Type.h - Classes for handling data types -----------*- C++ -*-===// +//===- llvm/Type.h - Classes for handling data types ------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -18,21 +18,22 @@ #include "llvm/ADT/APFloat.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallPtrSet.h" -#include "llvm/Support/CBindingWrapping.h" #include "llvm/Support/Casting.h" -#include "llvm/Support/DataTypes.h" +#include "llvm/Support/CBindingWrapping.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" +#include <cassert> +#include <cstdint> +#include <iterator> namespace llvm { -class PointerType; +template<class GraphType> struct GraphTraits; class IntegerType; -class raw_ostream; -class Module; class LLVMContext; -class LLVMContextImpl; +class PointerType; +class raw_ostream; class StringRef; -template<class GraphType> struct GraphTraits; /// The instances of the Type class are immutable: once they are created, /// they are never changed. Also note that only one instance of a particular @@ -86,9 +87,9 @@ private: protected: friend class LLVMContextImpl; + explicit Type(LLVMContext &C, TypeID tid) - : Context(C), ID(tid), SubclassData(0), - NumContainedTys(0), ContainedTys(nullptr) {} + : Context(C), ID(tid), SubclassData(0) {} ~Type() = default; unsigned getSubclassData() const { return SubclassData; } @@ -100,14 +101,14 @@ protected: } /// Keeps track of how many Type*'s there are in the ContainedTys list. - unsigned NumContainedTys; + unsigned NumContainedTys = 0; /// A pointer to the array of Types contained by this Type. For example, this /// includes the arguments of a function type, the elements of a structure, /// the pointee of a pointer, the element type of an array, etc. This pointer /// may be 0 for types that don't contain other types (Integer, Double, /// Float). - Type * const *ContainedTys; + Type * const *ContainedTys = nullptr; static bool isSequentialType(TypeID TyID) { return TyID == ArrayTyID || TyID == VectorTyID; @@ -122,6 +123,7 @@ public: /// inlined with the operands when printing an instruction. void print(raw_ostream &O, bool IsForDebug = false, bool NoDetails = false) const; + void dump() const; /// Return the LLVMContext in which this type was uniqued. @@ -299,14 +301,16 @@ public: //===--------------------------------------------------------------------===// // Type Iteration support. // - typedef Type * const *subtype_iterator; + using subtype_iterator = Type * const *; + subtype_iterator subtype_begin() const { return ContainedTys; } subtype_iterator subtype_end() const { return &ContainedTys[NumContainedTys];} ArrayRef<Type*> subtypes() const { return makeArrayRef(subtype_begin(), subtype_end()); } - typedef std::reverse_iterator<subtype_iterator> subtype_reverse_iterator; + using subtype_reverse_iterator = std::reverse_iterator<subtype_iterator>; + subtype_reverse_iterator subtype_rbegin() const { return subtype_reverse_iterator(subtype_end()); } @@ -348,6 +352,7 @@ public: } inline uint64_t getArrayNumElements() const; + Type *getArrayElementType() const { assert(getTypeID() == ArrayTyID); return ContainedTys[0]; @@ -444,8 +449,8 @@ template <> struct isa_impl<PointerType, Type> { // graph of sub types. template <> struct GraphTraits<Type *> { - typedef Type *NodeRef; - typedef Type::subtype_iterator ChildIteratorType; + using NodeRef = Type *; + using ChildIteratorType = Type::subtype_iterator; static NodeRef getEntryNode(Type *T) { return T; } static ChildIteratorType child_begin(NodeRef N) { return N->subtype_begin(); } @@ -453,8 +458,8 @@ template <> struct GraphTraits<Type *> { }; template <> struct GraphTraits<const Type*> { - typedef const Type *NodeRef; - typedef Type::subtype_iterator ChildIteratorType; + using NodeRef = const Type *; + using ChildIteratorType = Type::subtype_iterator; static NodeRef getEntryNode(NodeRef T) { return T; } static ChildIteratorType child_begin(NodeRef N) { return N->subtype_begin(); } @@ -474,6 +479,6 @@ inline LLVMTypeRef *wrap(Type **Tys) { return reinterpret_cast<LLVMTypeRef*>(const_cast<Type**>(Tys)); } -} // End llvm namespace +} // end namespace llvm -#endif +#endif // LLVM_IR_TYPE_H diff --git a/include/llvm/IR/TypeFinder.h b/include/llvm/IR/TypeFinder.h index 48c4f1161aa1..c050c388d398 100644 --- a/include/llvm/IR/TypeFinder.h +++ b/include/llvm/IR/TypeFinder.h @@ -44,8 +44,8 @@ public: void run(const Module &M, bool onlyNamed); void clear(); - typedef std::vector<StructType*>::iterator iterator; - typedef std::vector<StructType*>::const_iterator const_iterator; + using iterator = std::vector<StructType*>::iterator; + using const_iterator = std::vector<StructType*>::const_iterator; iterator begin() { return StructTypes.begin(); } iterator end() { return StructTypes.end(); } diff --git a/include/llvm/IR/Use.h b/include/llvm/IR/Use.h index 6b56546f4421..d3a59d8a060e 100644 --- a/include/llvm/IR/Use.h +++ b/include/llvm/IR/Use.h @@ -1,4 +1,4 @@ -//===-- llvm/Use.h - Definition of the Use class ----------------*- C++ -*-===// +//===- llvm/Use.h - Definition of the Use class -----------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -27,14 +27,14 @@ #include "llvm/ADT/PointerIntPair.h" #include "llvm/Support/CBindingWrapping.h" +#include "llvm/Support/Compiler.h" #include "llvm-c/Types.h" namespace llvm { -class Value; -class User; -class Use; template <typename> struct simplify_type; +class User; +class Value; /// \brief A Use represents the edge between a Value definition and its users. /// @@ -65,23 +65,27 @@ public: /// use the LSB regardless of pointer alignment on different targets. struct UserRefPointerTraits { static inline void *getAsVoidPointer(User *P) { return P; } + static inline User *getFromVoidPointer(void *P) { return (User *)P; } + enum { NumLowBitsAvailable = 1 }; }; // A type for the word following an array of hung-off Uses in memory, which is // a pointer back to their User with the bottom bit set. - typedef PointerIntPair<User *, 1, unsigned, UserRefPointerTraits> UserRef; + using UserRef = PointerIntPair<User *, 1, unsigned, UserRefPointerTraits>; /// Pointer traits for the Prev PointerIntPair. This ensures we always use /// the two LSBs regardless of pointer alignment on different targets. struct PrevPointerTraits { static inline void *getAsVoidPointer(Use **P) { return P; } + static inline Use **getFromVoidPointer(void *P) { return (Use **)P; } + enum { NumLowBitsAvailable = 2 }; }; @@ -95,9 +99,11 @@ private: enum PrevPtrTag { zeroDigitTag, oneDigitTag, stopTag, fullStopTag }; /// Constructor - Use(PrevPtrTag tag) : Val(nullptr) { Prev.setInt(tag); } + Use(PrevPtrTag tag) { Prev.setInt(tag); } public: + friend class Value; + operator Value *() const { return Val; } Value *get() const { return Val; } @@ -133,7 +139,7 @@ public: private: const Use *getImpliedUser() const LLVM_READONLY; - Value *Val; + Value *Val = nullptr; Use *Next; PointerIntPair<Use **, 2, PrevPtrTag, PrevPointerTraits> Prev; @@ -153,18 +159,18 @@ private: if (Next) Next->setPrev(StrippedPrev); } - - friend class Value; }; /// \brief Allow clients to treat uses just like values when using /// casting operators. template <> struct simplify_type<Use> { - typedef Value *SimpleType; + using SimpleType = Value *; + static SimpleType getSimplifiedValue(Use &Val) { return Val.get(); } }; template <> struct simplify_type<const Use> { - typedef /*const*/ Value *SimpleType; + using SimpleType = /*const*/ Value *; + static SimpleType getSimplifiedValue(const Use &Val) { return Val.get(); } }; diff --git a/include/llvm/IR/UseListOrder.h b/include/llvm/IR/UseListOrder.h index ebe99223facd..a8b394fc6302 100644 --- a/include/llvm/IR/UseListOrder.h +++ b/include/llvm/IR/UseListOrder.h @@ -37,7 +37,7 @@ struct UseListOrder { UseListOrder &operator=(UseListOrder &&) = default; }; -typedef std::vector<UseListOrder> UseListOrderStack; +using UseListOrderStack = std::vector<UseListOrder>; } // end namespace llvm diff --git a/include/llvm/IR/User.h b/include/llvm/IR/User.h index 54758a9b6d6a..7b9d451aaf53 100644 --- a/include/llvm/IR/User.h +++ b/include/llvm/IR/User.h @@ -1,4 +1,4 @@ -//===-- llvm/User.h - User class definition ---------------------*- C++ -*-===// +//===- llvm/User.h - User class definition ----------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -114,6 +114,7 @@ protected: ? OperandTraits<U>::op_end(const_cast<U*>(that))[Idx] : OperandTraits<U>::op_begin(const_cast<U*>(that))[Idx]; } + template <int Idx> Use &Op() { return OpFrom<Idx>(this); } @@ -205,10 +206,10 @@ public: // --------------------------------------------------------------------------- // Operand Iterator interface... // - typedef Use* op_iterator; - typedef const Use* const_op_iterator; - typedef iterator_range<op_iterator> op_range; - typedef iterator_range<const_op_iterator> const_op_range; + using op_iterator = Use*; + using const_op_iterator = const Use*; + using op_range = iterator_range<op_iterator>; + using const_op_range = iterator_range<const_op_iterator>; op_iterator op_begin() { return getOperandList(); } const_op_iterator op_begin() const { return getOperandList(); } @@ -252,6 +253,7 @@ public: ptrdiff_t, const Value *, const Value *> { explicit const_value_op_iterator(const Use *U = nullptr) : iterator_adaptor_base(U) {} + const Value *operator*() const { return *I; } const Value *operator->() const { return operator*(); } }; @@ -290,6 +292,7 @@ public: return isa<Instruction>(V) || isa<Constant>(V); } }; + // Either Use objects, or a Use pointer can be prepended to User. static_assert(alignof(Use) >= alignof(User), "Alignment is insufficient after objects prepended to User"); @@ -297,13 +300,15 @@ static_assert(alignof(Use *) >= alignof(User), "Alignment is insufficient after objects prepended to User"); template<> struct simplify_type<User::op_iterator> { - typedef Value* SimpleType; + using SimpleType = Value*; + static SimpleType getSimplifiedValue(User::op_iterator &Val) { return Val->get(); } }; template<> struct simplify_type<User::const_op_iterator> { - typedef /*const*/ Value* SimpleType; + using SimpleType = /*const*/ Value*; + static SimpleType getSimplifiedValue(User::const_op_iterator &Val) { return Val->get(); } diff --git a/include/llvm/IR/Value.h b/include/llvm/IR/Value.h index 00f821399257..96a370dcc35f 100644 --- a/include/llvm/IR/Value.h +++ b/include/llvm/IR/Value.h @@ -1,4 +1,4 @@ -//===-- llvm/Value.h - Definition of the Value class ------------*- C++ -*-===// +//===- llvm/Value.h - Definition of the Value class -------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -44,12 +44,12 @@ class LLVMContext; class Module; class ModuleSlotTracker; class raw_ostream; +template<typename ValueTy> class StringMapEntry; class StringRef; class Twine; class Type; -template<typename ValueTy> class StringMapEntry; -typedef StringMapEntry<Value*> ValueName; +using ValueName = StringMapEntry<Value*>; //===----------------------------------------------------------------------===// // Value Class @@ -120,9 +120,11 @@ private: template <typename UseT> // UseT == 'Use' or 'const Use' class use_iterator_impl : public std::iterator<std::forward_iterator_tag, UseT *> { + friend class Value; + UseT *U; + explicit use_iterator_impl(UseT *u) : U(u) {} - friend class Value; public: use_iterator_impl() : U() {} @@ -309,8 +311,9 @@ public: return UseList == nullptr; } - typedef use_iterator_impl<Use> use_iterator; - typedef use_iterator_impl<const Use> const_use_iterator; + using use_iterator = use_iterator_impl<Use>; + using const_use_iterator = use_iterator_impl<const Use>; + use_iterator materialized_use_begin() { return use_iterator(UseList); } const_use_iterator materialized_use_begin() const { return const_use_iterator(UseList); @@ -345,8 +348,9 @@ public: return UseList == nullptr; } - typedef user_iterator_impl<User> user_iterator; - typedef user_iterator_impl<const User> const_user_iterator; + using user_iterator = user_iterator_impl<User>; + using const_user_iterator = user_iterator_impl<const User>; + user_iterator materialized_user_begin() { return user_iterator(UseList); } const_user_iterator materialized_user_begin() const { return const_user_iterator(UseList); @@ -560,7 +564,6 @@ public: /// block. const Value *DoPHITranslation(const BasicBlock *CurBB, const BasicBlock *PredBB) const; - Value *DoPHITranslation(const BasicBlock *CurBB, const BasicBlock *PredBB) { return const_cast<Value *>( static_cast<const Value *>(this)->DoPHITranslation(CurBB, PredBB)); @@ -606,7 +609,7 @@ private: Use *Merged; Use **Next = &Merged; - for (;;) { + while (true) { if (!L) { *Next = R; break; diff --git a/include/llvm/IR/ValueHandle.h b/include/llvm/IR/ValueHandle.h index 393618d5511b..b45cc7b6dc02 100644 --- a/include/llvm/IR/ValueHandle.h +++ b/include/llvm/IR/ValueHandle.h @@ -17,10 +17,10 @@ #include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/IR/Value.h" +#include "llvm/Support/Casting.h" +#include <cassert> namespace llvm { -class ValueHandleBase; -template<typename From> struct simplify_type; /// \brief This is the common base class of value handles. /// @@ -29,6 +29,7 @@ template<typename From> struct simplify_type; /// below for details. class ValueHandleBase { friend class Value; + protected: /// \brief This indicates what sub class the handle actually is. /// @@ -40,24 +41,23 @@ protected: : ValueHandleBase(RHS.PrevPair.getInt(), RHS) {} ValueHandleBase(HandleBaseKind Kind, const ValueHandleBase &RHS) - : PrevPair(nullptr, Kind), Next(nullptr), Val(RHS.getValPtr()) { + : PrevPair(nullptr, Kind), Val(RHS.getValPtr()) { if (isValid(getValPtr())) AddToExistingUseList(RHS.getPrevPtr()); } private: PointerIntPair<ValueHandleBase**, 2, HandleBaseKind> PrevPair; - ValueHandleBase *Next; - - Value *Val; + ValueHandleBase *Next = nullptr; + Value *Val = nullptr; void setValPtr(Value *V) { Val = V; } public: explicit ValueHandleBase(HandleBaseKind Kind) - : PrevPair(nullptr, Kind), Next(nullptr), Val(nullptr) {} + : PrevPair(nullptr, Kind) {} ValueHandleBase(HandleBaseKind Kind, Value *V) - : PrevPair(nullptr, Kind), Next(nullptr), Val(V) { + : PrevPair(nullptr, Kind), Val(V) { if (isValid(getValPtr())) AddToUseList(); } @@ -162,11 +162,13 @@ public: // Specialize simplify_type to allow WeakVH to participate in // dyn_cast, isa, etc. template <> struct simplify_type<WeakVH> { - typedef Value *SimpleType; + using SimpleType = Value *; + static SimpleType getSimplifiedValue(WeakVH &WVH) { return WVH; } }; template <> struct simplify_type<const WeakVH> { - typedef Value *SimpleType; + using SimpleType = Value *; + static SimpleType getSimplifiedValue(const WeakVH &WVH) { return WVH; } }; @@ -205,11 +207,13 @@ public: // Specialize simplify_type to allow WeakTrackingVH to participate in // dyn_cast, isa, etc. template <> struct simplify_type<WeakTrackingVH> { - typedef Value *SimpleType; + using SimpleType = Value *; + static SimpleType getSimplifiedValue(WeakTrackingVH &WVH) { return WVH; } }; template <> struct simplify_type<const WeakTrackingVH> { - typedef Value *SimpleType; + using SimpleType = Value *; + static SimpleType getSimplifiedValue(const WeakTrackingVH &WVH) { return WVH; } @@ -236,7 +240,7 @@ class AssertingVH : public ValueHandleBase #endif { - friend struct DenseMapInfo<AssertingVH<ValueTy> >; + friend struct DenseMapInfo<AssertingVH<ValueTy>>; #ifndef NDEBUG Value *getRawValPtr() const { return ValueHandleBase::getValPtr(); } @@ -282,20 +286,23 @@ public: // Specialize DenseMapInfo to allow AssertingVH to participate in DenseMap. template<typename T> -struct DenseMapInfo<AssertingVH<T> > { +struct DenseMapInfo<AssertingVH<T>> { static inline AssertingVH<T> getEmptyKey() { AssertingVH<T> Res; Res.setRawValPtr(DenseMapInfo<Value *>::getEmptyKey()); return Res; } + static inline AssertingVH<T> getTombstoneKey() { AssertingVH<T> Res; Res.setRawValPtr(DenseMapInfo<Value *>::getTombstoneKey()); return Res; } + static unsigned getHashValue(const AssertingVH<T> &Val) { return DenseMapInfo<Value *>::getHashValue(Val.getRawValPtr()); } + static bool isEqual(const AssertingVH<T> &LHS, const AssertingVH<T> &RHS) { return DenseMapInfo<Value *>::isEqual(LHS.getRawValPtr(), RHS.getRawValPtr()); @@ -303,7 +310,7 @@ struct DenseMapInfo<AssertingVH<T> > { }; template <typename T> -struct isPodLike<AssertingVH<T> > { +struct isPodLike<AssertingVH<T>> { #ifdef NDEBUG static const bool value = true; #else @@ -356,7 +363,7 @@ public: static Value *GetAsValue(const Value *V) { return const_cast<Value*>(V); } public: - TrackingVH() {} + TrackingVH() = default; TrackingVH(ValueTy *P) { setValPtr(P); } operator ValueTy*() const { @@ -495,10 +502,12 @@ public: PoisoningVH(ValueTy *P) : CallbackVH(GetAsValue(P)) {} PoisoningVH(const PoisoningVH &RHS) : CallbackVH(RHS), Poisoned(RHS.Poisoned) {} + ~PoisoningVH() { if (Poisoned) clearValPtr(); } + PoisoningVH &operator=(const PoisoningVH &RHS) { if (Poisoned) clearValPtr(); @@ -523,14 +532,17 @@ template <typename T> struct DenseMapInfo<PoisoningVH<T>> { Res.setRawValPtr(DenseMapInfo<Value *>::getEmptyKey()); return Res; } + static inline PoisoningVH<T> getTombstoneKey() { PoisoningVH<T> Res; Res.setRawValPtr(DenseMapInfo<Value *>::getTombstoneKey()); return Res; } + static unsigned getHashValue(const PoisoningVH<T> &Val) { return DenseMapInfo<Value *>::getHashValue(Val.getRawValPtr()); } + static bool isEqual(const PoisoningVH<T> &LHS, const PoisoningVH<T> &RHS) { return DenseMapInfo<Value *>::isEqual(LHS.getRawValPtr(), RHS.getRawValPtr()); @@ -545,6 +557,6 @@ template <typename T> struct isPodLike<PoisoningVH<T>> { #endif }; -} // End llvm namespace +} // end namespace llvm -#endif +#endif // LLVM_IR_VALUEHANDLE_H diff --git a/include/llvm/IR/ValueMap.h b/include/llvm/IR/ValueMap.h index 9648e1989f94..11d5823ee479 100644 --- a/include/llvm/IR/ValueMap.h +++ b/include/llvm/IR/ValueMap.h @@ -46,7 +46,6 @@ namespace llvm { template<typename KeyT, typename ValueT, typename Config> class ValueMapCallbackVH; - template<typename DenseMapT, typename KeyT> class ValueMapIterator; template<typename DenseMapT, typename KeyT> @@ -57,7 +56,7 @@ class ValueMapConstIterator; /// as possible with future versions of ValueMap. template<typename KeyT, typename MutexT = sys::Mutex> struct ValueMapConfig { - typedef MutexT mutex_type; + using mutex_type = MutexT; /// If FollowRAUW is true, the ValueMap will update mappings on RAUW. If it's /// false, the ValueMap will leave the original mapping in place. @@ -87,21 +86,21 @@ template<typename KeyT, typename ValueT, typename Config =ValueMapConfig<KeyT>> class ValueMap { friend class ValueMapCallbackVH<KeyT, ValueT, Config>; - typedef ValueMapCallbackVH<KeyT, ValueT, Config> ValueMapCVH; - typedef DenseMap<ValueMapCVH, ValueT, DenseMapInfo<ValueMapCVH>> MapT; - typedef DenseMap<const Metadata *, TrackingMDRef> MDMapT; - typedef typename Config::ExtraData ExtraData; + using ValueMapCVH = ValueMapCallbackVH<KeyT, ValueT, Config>; + using MapT = DenseMap<ValueMapCVH, ValueT, DenseMapInfo<ValueMapCVH>>; + using MDMapT = DenseMap<const Metadata *, TrackingMDRef>; + using ExtraData = typename Config::ExtraData; + MapT Map; Optional<MDMapT> MDMap; ExtraData Data; - bool MayMapMetadata = true; public: - typedef KeyT key_type; - typedef ValueT mapped_type; - typedef std::pair<KeyT, ValueT> value_type; - typedef unsigned size_type; + using key_type = KeyT; + using mapped_type = ValueT; + using value_type = std::pair<KeyT, ValueT>; + using size_type = unsigned; explicit ValueMap(unsigned NumInitBuckets = 64) : Map(NumInitBuckets), Data() {} @@ -132,8 +131,9 @@ public: return Where->second.get(); } - typedef ValueMapIterator<MapT, KeyT> iterator; - typedef ValueMapConstIterator<MapT, KeyT> const_iterator; + using iterator = ValueMapIterator<MapT, KeyT>; + using const_iterator = ValueMapConstIterator<MapT, KeyT>; + inline iterator begin() { return iterator(Map.begin()); } inline iterator end() { return iterator(Map.end()); } inline const_iterator begin() const { return const_iterator(Map.begin()); } @@ -244,8 +244,8 @@ class ValueMapCallbackVH final : public CallbackVH { friend class ValueMap<KeyT, ValueT, Config>; friend struct DenseMapInfo<ValueMapCallbackVH>; - typedef ValueMap<KeyT, ValueT, Config> ValueMapT; - typedef typename std::remove_pointer<KeyT>::type KeySansPointerT; + using ValueMapT = ValueMap<KeyT, ValueT, Config>; + using KeySansPointerT = typename std::remove_pointer<KeyT>::type; ValueMapT *Map; @@ -298,7 +298,7 @@ public: template<typename KeyT, typename ValueT, typename Config> struct DenseMapInfo<ValueMapCallbackVH<KeyT, ValueT, Config>> { - typedef ValueMapCallbackVH<KeyT, ValueT, Config> VH; + using VH = ValueMapCallbackVH<KeyT, ValueT, Config>; static inline VH getEmptyKey() { return VH(DenseMapInfo<Value *>::getEmptyKey()); @@ -330,8 +330,8 @@ class ValueMapIterator : public std::iterator<std::forward_iterator_tag, std::pair<KeyT, typename DenseMapT::mapped_type>, ptrdiff_t> { - typedef typename DenseMapT::iterator BaseT; - typedef typename DenseMapT::mapped_type ValueT; + using BaseT = typename DenseMapT::iterator; + using ValueT = typename DenseMapT::mapped_type; BaseT I; @@ -344,7 +344,9 @@ public: struct ValueTypeProxy { const KeyT first; ValueT& second; + ValueTypeProxy *operator->() { return this; } + operator std::pair<KeyT, ValueT>() const { return std::make_pair(first, second); } @@ -380,8 +382,8 @@ class ValueMapConstIterator : public std::iterator<std::forward_iterator_tag, std::pair<KeyT, typename DenseMapT::mapped_type>, ptrdiff_t> { - typedef typename DenseMapT::const_iterator BaseT; - typedef typename DenseMapT::mapped_type ValueT; + using BaseT = typename DenseMapT::const_iterator; + using ValueT = typename DenseMapT::mapped_type; BaseT I; diff --git a/include/llvm/IR/ValueSymbolTable.h b/include/llvm/IR/ValueSymbolTable.h index 9e86751dae6f..26cbbfabfc0c 100644 --- a/include/llvm/IR/ValueSymbolTable.h +++ b/include/llvm/IR/ValueSymbolTable.h @@ -49,13 +49,13 @@ class ValueSymbolTable { /// @{ public: /// @brief A mapping of names to values. - typedef StringMap<Value*> ValueMap; + using ValueMap = StringMap<Value*>; /// @brief An iterator over a ValueMap. - typedef ValueMap::iterator iterator; + using iterator = ValueMap::iterator; /// @brief A const_iterator over a ValueMap. - typedef ValueMap::const_iterator const_iterator; + using const_iterator = ValueMap::const_iterator; /// @} /// @name Constructors diff --git a/include/llvm/IR/Verifier.h b/include/llvm/IR/Verifier.h index 71f727c3d4fc..15e52d9e0742 100644 --- a/include/llvm/IR/Verifier.h +++ b/include/llvm/IR/Verifier.h @@ -21,13 +21,17 @@ #ifndef LLVM_IR_VERIFIER_H #define LLVM_IR_VERIFIER_H +#include "llvm/ADT/DenseMap.h" #include "llvm/IR/PassManager.h" +#include <utility> namespace llvm { +class APInt; class Function; class FunctionPass; -class ModulePass; +class Instruction; +class MDNode; class Module; class raw_ostream; struct VerifierSupport; @@ -47,7 +51,7 @@ class TBAAVerifier { /// the offset of the access. If zero, only a zero offset is allowed. /// /// \c BitWidth has no meaning if \c IsInvalid is true. - typedef std::pair<bool, unsigned> TBAABaseNodeSummary; + using TBAABaseNodeSummary = std::pair<bool, unsigned>; DenseMap<const MDNode *, TBAABaseNodeSummary> TBAABaseNodes; /// Maps an alleged scalar TBAA node to a boolean that is true if the said @@ -101,12 +105,14 @@ FunctionPass *createVerifierPass(bool FatalErrors = true); /// and debug info errors. class VerifierAnalysis : public AnalysisInfoMixin<VerifierAnalysis> { friend AnalysisInfoMixin<VerifierAnalysis>; + static AnalysisKey Key; public: struct Result { bool IRBroken, DebugInfoBroken; }; + Result run(Module &M, ModuleAnalysisManager &); Result run(Function &F, FunctionAnalysisManager &); }; @@ -136,7 +142,6 @@ public: PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); }; +} // end namespace llvm -} // End llvm namespace - -#endif +#endif // LLVM_IR_VERIFIER_H diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index 44ff4c1a581b..cf314e19d1ca 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -130,6 +130,7 @@ void initializeEfficiencySanitizerPass(PassRegistry&); void initializeEliminateAvailableExternallyLegacyPassPass(PassRegistry&); void initializeExpandISelPseudosPass(PassRegistry&); void initializeExpandPostRAPass(PassRegistry&); +void initializeExpandReductionsPass(PassRegistry&); void initializeExternalAAWrapperPassPass(PassRegistry&); void initializeFEntryInserterPass(PassRegistry&); void initializeFinalizeMachineBundlesPass(PassRegistry&); @@ -186,6 +187,7 @@ void initializeLintPass(PassRegistry&); void initializeLiveDebugValuesPass(PassRegistry&); void initializeLiveDebugVariablesPass(PassRegistry&); void initializeLiveIntervalsPass(PassRegistry&); +void initializeLiveRangeShrinkPass(PassRegistry&); void initializeLiveRegMatrixPass(PassRegistry&); void initializeLiveStacksPass(PassRegistry&); void initializeLiveVariablesPass(PassRegistry&); @@ -319,11 +321,12 @@ void initializeSCCPLegacyPassPass(PassRegistry&); void initializeSCEVAAWrapperPassPass(PassRegistry&); void initializeSLPVectorizerPass(PassRegistry&); void initializeSROALegacyPassPass(PassRegistry&); -void initializeSafeStackPass(PassRegistry&); +void initializeSafeStackLegacyPassPass(PassRegistry&); void initializeSampleProfileLoaderLegacyPassPass(PassRegistry&); void initializeSanitizerCoverageModulePass(PassRegistry&); void initializeScalarEvolutionWrapperPassPass(PassRegistry&); void initializeScalarizerPass(PassRegistry&); +void initializeScalarizeMaskedMemIntrinPass(PassRegistry&); void initializeScopedNoAliasAAWrapperPassPass(PassRegistry&); void initializeSeparateConstOffsetFromGEPPass(PassRegistry&); void initializeShadowStackGCLoweringPass(PassRegistry&); diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h index 39a86e838bde..5c398b2ab567 100644 --- a/include/llvm/LinkAllPasses.h +++ b/include/llvm/LinkAllPasses.h @@ -206,6 +206,7 @@ namespace { (void) llvm::createMemDerefPrinter(); (void) llvm::createFloat2IntPass(); (void) llvm::createEliminateAvailableExternallyPass(); + (void) llvm::createScalarizeMaskedMemIntrinPass(); (void)new llvm::IntervalPartition(); (void)new llvm::ScalarEvolutionWrapperPass(); diff --git a/include/llvm/Object/Wasm.h b/include/llvm/Object/Wasm.h index 4bc39d98b7af..d200d4a148e3 100644 --- a/include/llvm/Object/Wasm.h +++ b/include/llvm/Object/Wasm.h @@ -67,7 +67,8 @@ public: WasmObjectFile(MemoryBufferRef Object, Error &Err); const wasm::WasmObjectHeader &getHeader() const; - const WasmSymbol &getWasmSymbol(DataRefImpl Symb) const; + const WasmSymbol &getWasmSymbol(const DataRefImpl &Symb) const; + const WasmSymbol &getWasmSymbol(const SymbolRef &Symbol) const; const WasmSection &getWasmSection(const SectionRef &Section) const; const wasm::WasmRelocation &getWasmRelocation(const RelocationRef& Ref) const; @@ -81,6 +82,10 @@ public: const std::vector<wasm::WasmGlobal>& globals() const { return Globals; } const std::vector<wasm::WasmExport>& exports() const { return Exports; } + uint32_t getNumberOfSymbols() const { + return Symbols.size(); + } + const std::vector<wasm::WasmElemSegment>& elements() const { return ElemSegments; } diff --git a/include/llvm/ObjectYAML/WasmYAML.h b/include/llvm/ObjectYAML/WasmYAML.h index bd7d72be4dbc..7b70c9537827 100644 --- a/include/llvm/ObjectYAML/WasmYAML.h +++ b/include/llvm/ObjectYAML/WasmYAML.h @@ -34,17 +34,6 @@ struct FileHeader { yaml::Hex32 Version; }; -struct Import { - StringRef Module; - StringRef Field; - ExportKind Kind; - union { - uint32_t SigIndex; - ValueType GlobalType; - }; - bool GlobalMutable; -}; - struct Limits { yaml::Hex32 Flags; yaml::Hex32 Initial; @@ -74,6 +63,18 @@ struct Global { wasm::WasmInitExpr InitExpr; }; +struct Import { + StringRef Module; + StringRef Field; + ExportKind Kind; + union { + uint32_t SigIndex; + Global GlobalImport; + Table TableImport; + Limits Memory; + }; +}; + struct LocalDecl { ValueType Type; uint32_t Count; diff --git a/include/llvm/ProfileData/SampleProfWriter.h b/include/llvm/ProfileData/SampleProfWriter.h index 9d69af32dd46..86af1038d74e 100644 --- a/include/llvm/ProfileData/SampleProfWriter.h +++ b/include/llvm/ProfileData/SampleProfWriter.h @@ -43,16 +43,7 @@ public: /// Write all the sample profiles in the given map of samples. /// /// \returns status code of the file update operation. - std::error_code write(const StringMap<FunctionSamples> &ProfileMap) { - if (std::error_code EC = writeHeader(ProfileMap)) - return EC; - for (const auto &I : ProfileMap) { - const FunctionSamples &Profile = I.second; - if (std::error_code EC = write(Profile)) - return EC; - } - return sampleprof_error::success; - } + std::error_code write(const StringMap<FunctionSamples> &ProfileMap); raw_ostream &getOutputStream() { return *OutputStream; } diff --git a/include/llvm/Support/BinaryStreamArray.h b/include/llvm/Support/BinaryStreamArray.h index bad31cd38d6a..77c99ffff919 100644 --- a/include/llvm/Support/BinaryStreamArray.h +++ b/include/llvm/Support/BinaryStreamArray.h @@ -139,6 +139,7 @@ public: } uint32_t offset() const { return AbsOffset; } + uint32_t getRecordLength() const { return ThisLen; } private: void moveToEnd() { @@ -294,6 +295,8 @@ template <typename T> class FixedStreamArray { friend class FixedStreamArrayIterator<T>; public: + typedef FixedStreamArrayIterator<T> Iterator; + FixedStreamArray() = default; explicit FixedStreamArray(BinaryStreamRef Stream) : Stream(Stream) { assert(Stream.getLength() % sizeof(T) == 0); @@ -371,7 +374,7 @@ public: } FixedStreamArrayIterator<T> &operator-=(std::ptrdiff_t N) { - assert(Index >= N); + assert(std::ptrdiff_t(Index) >= N); Index -= N; return *this; } diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h index a56bc93e111b..be9e46540016 100644 --- a/include/llvm/Support/Compiler.h +++ b/include/llvm/Support/Compiler.h @@ -111,12 +111,6 @@ #define LLVM_PREFETCH(addr, rw, locality) #endif -#if __has_attribute(sentinel) || LLVM_GNUC_PREREQ(3, 0, 0) -#define LLVM_END_WITH_NULL __attribute__((sentinel)) -#else -#define LLVM_END_WITH_NULL -#endif - #if __has_attribute(used) || LLVM_GNUC_PREREQ(3, 1, 0) #define LLVM_ATTRIBUTE_USED __attribute__((__used__)) #else @@ -233,6 +227,8 @@ /// LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements. #if __cplusplus > 201402L && __has_cpp_attribute(fallthrough) #define LLVM_FALLTHROUGH [[fallthrough]] +#elif __has_cpp_attribute(gnu::fallthrough) +#define LLVM_FALLTHROUGH [[gnu::fallthrough]] #elif !__cplusplus // Workaround for llvm.org/PR23435, since clang 3.6 and below emit a spurious // error when __has_cpp_attribute is given a scoped attribute in C mode. diff --git a/include/llvm/Support/KnownBits.h b/include/llvm/Support/KnownBits.h index 3d38cf878538..2c77d40559b9 100644 --- a/include/llvm/Support/KnownBits.h +++ b/include/llvm/Support/KnownBits.h @@ -133,6 +133,66 @@ public: KnownBits zextOrTrunc(unsigned BitWidth) { return KnownBits(Zero.zextOrTrunc(BitWidth), One.zextOrTrunc(BitWidth)); } + + /// Returns the minimum number of trailing zero bits. + unsigned countMinTrailingZeros() const { + return Zero.countTrailingOnes(); + } + + /// Returns the minimum number of trailing one bits. + unsigned countMinTrailingOnes() const { + return One.countTrailingOnes(); + } + + /// Returns the minimum number of leading zero bits. + unsigned countMinLeadingZeros() const { + return Zero.countLeadingOnes(); + } + + /// Returns the minimum number of leading one bits. + unsigned countMinLeadingOnes() const { + return One.countLeadingOnes(); + } + + /// Returns the number of times the sign bit is replicated into the other + /// bits. + unsigned countMinSignBits() const { + if (isNonNegative()) + return countMinLeadingZeros(); + if (isNegative()) + return countMinLeadingOnes(); + return 0; + } + + /// Returns the maximum number of trailing zero bits possible. + unsigned countMaxTrailingZeros() const { + return One.countTrailingZeros(); + } + + /// Returns the maximum number of trailing one bits possible. + unsigned countMaxTrailingOnes() const { + return Zero.countTrailingZeros(); + } + + /// Returns the maximum number of leading zero bits possible. + unsigned countMaxLeadingZeros() const { + return One.countLeadingZeros(); + } + + /// Returns the maximum number of leading one bits possible. + unsigned countMaxLeadingOnes() const { + return Zero.countLeadingZeros(); + } + + /// Returns the number of bits known to be one. + unsigned countMinPopulation() const { + return One.countPopulation(); + } + + /// Returns the maximum number of bits that could be one. + unsigned countMaxPopulation() const { + return getBitWidth() - Zero.countPopulation(); + } }; } // end namespace llvm diff --git a/include/llvm/Support/Parallel.h b/include/llvm/Support/Parallel.h new file mode 100644 index 000000000000..e36e0cc29e14 --- /dev/null +++ b/include/llvm/Support/Parallel.h @@ -0,0 +1,249 @@ +//===- llvm/Support/Parallel.h - Parallel algorithms ----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_PARALLEL_H +#define LLVM_SUPPORT_PARALLEL_H + +#include "llvm/ADT/STLExtras.h" +#include "llvm/Config/llvm-config.h" +#include "llvm/Support/MathExtras.h" + +#include <algorithm> +#include <condition_variable> +#include <functional> +#include <mutex> + +#if defined(_MSC_VER) && LLVM_ENABLE_THREADS +#pragma warning(push) +#pragma warning(disable : 4530) +#include <concrt.h> +#include <ppl.h> +#pragma warning(pop) +#endif + +namespace llvm { + +namespace parallel { +struct sequential_execution_policy {}; +struct parallel_execution_policy {}; + +template <typename T> +struct is_execution_policy + : public std::integral_constant< + bool, llvm::is_one_of<T, sequential_execution_policy, + parallel_execution_policy>::value> {}; + +constexpr sequential_execution_policy seq{}; +constexpr parallel_execution_policy par{}; + +namespace detail { + +#if LLVM_ENABLE_THREADS + +class Latch { + uint32_t Count; + mutable std::mutex Mutex; + mutable std::condition_variable Cond; + +public: + explicit Latch(uint32_t Count = 0) : Count(Count) {} + ~Latch() { sync(); } + + void inc() { + std::unique_lock<std::mutex> lock(Mutex); + ++Count; + } + + void dec() { + std::unique_lock<std::mutex> lock(Mutex); + if (--Count == 0) + Cond.notify_all(); + } + + void sync() const { + std::unique_lock<std::mutex> lock(Mutex); + Cond.wait(lock, [&] { return Count == 0; }); + } +}; + +class TaskGroup { + Latch L; + +public: + void spawn(std::function<void()> f); + + void sync() const { L.sync(); } +}; + +#if defined(_MSC_VER) +template <class RandomAccessIterator, class Comparator> +void parallel_sort(RandomAccessIterator Start, RandomAccessIterator End, + const Comparator &Comp) { + concurrency::parallel_sort(Start, End, Comp); +} +template <class IterTy, class FuncTy> +void parallel_for_each(IterTy Begin, IterTy End, FuncTy Fn) { + concurrency::parallel_for_each(Begin, End, Fn); +} + +template <class IndexTy, class FuncTy> +void parallel_for_each_n(IndexTy Begin, IndexTy End, FuncTy Fn) { + concurrency::parallel_for(Begin, End, Fn); +} + +#else +const ptrdiff_t MinParallelSize = 1024; + +/// \brief Inclusive median. +template <class RandomAccessIterator, class Comparator> +RandomAccessIterator medianOf3(RandomAccessIterator Start, + RandomAccessIterator End, + const Comparator &Comp) { + RandomAccessIterator Mid = Start + (std::distance(Start, End) / 2); + return Comp(*Start, *(End - 1)) + ? (Comp(*Mid, *(End - 1)) ? (Comp(*Start, *Mid) ? Mid : Start) + : End - 1) + : (Comp(*Mid, *Start) ? (Comp(*(End - 1), *Mid) ? Mid : End - 1) + : Start); +} + +template <class RandomAccessIterator, class Comparator> +void parallel_quick_sort(RandomAccessIterator Start, RandomAccessIterator End, + const Comparator &Comp, TaskGroup &TG, size_t Depth) { + // Do a sequential sort for small inputs. + if (std::distance(Start, End) < detail::MinParallelSize || Depth == 0) { + std::sort(Start, End, Comp); + return; + } + + // Partition. + auto Pivot = medianOf3(Start, End, Comp); + // Move Pivot to End. + std::swap(*(End - 1), *Pivot); + Pivot = std::partition(Start, End - 1, [&Comp, End](decltype(*Start) V) { + return Comp(V, *(End - 1)); + }); + // Move Pivot to middle of partition. + std::swap(*Pivot, *(End - 1)); + + // Recurse. + TG.spawn([=, &Comp, &TG] { + parallel_quick_sort(Start, Pivot, Comp, TG, Depth - 1); + }); + parallel_quick_sort(Pivot + 1, End, Comp, TG, Depth - 1); +} + +template <class RandomAccessIterator, class Comparator> +void parallel_sort(RandomAccessIterator Start, RandomAccessIterator End, + const Comparator &Comp) { + TaskGroup TG; + parallel_quick_sort(Start, End, Comp, TG, + llvm::Log2_64(std::distance(Start, End)) + 1); +} + +template <class IterTy, class FuncTy> +void parallel_for_each(IterTy Begin, IterTy End, FuncTy Fn) { + // TaskGroup has a relatively high overhead, so we want to reduce + // the number of spawn() calls. We'll create up to 1024 tasks here. + // (Note that 1024 is an arbitrary number. This code probably needs + // improving to take the number of available cores into account.) + ptrdiff_t TaskSize = std::distance(Begin, End) / 1024; + if (TaskSize == 0) + TaskSize = 1; + + TaskGroup TG; + while (TaskSize <= std::distance(Begin, End)) { + TG.spawn([=, &Fn] { std::for_each(Begin, Begin + TaskSize, Fn); }); + Begin += TaskSize; + } + TG.spawn([=, &Fn] { std::for_each(Begin, End, Fn); }); +} + +template <class IndexTy, class FuncTy> +void parallel_for_each_n(IndexTy Begin, IndexTy End, FuncTy Fn) { + ptrdiff_t TaskSize = (End - Begin) / 1024; + if (TaskSize == 0) + TaskSize = 1; + + TaskGroup TG; + IndexTy I = Begin; + for (; I + TaskSize < End; I += TaskSize) { + TG.spawn([=, &Fn] { + for (IndexTy J = I, E = I + TaskSize; J != E; ++J) + Fn(J); + }); + } + TG.spawn([=, &Fn] { + for (IndexTy J = I; J < End; ++J) + Fn(J); + }); +} + +#endif + +#endif + +template <typename Iter> +using DefComparator = + std::less<typename std::iterator_traits<Iter>::value_type>; + +} // namespace detail + +// sequential algorithm implementations. +template <class Policy, class RandomAccessIterator, + class Comparator = detail::DefComparator<RandomAccessIterator>> +void sort(Policy policy, RandomAccessIterator Start, RandomAccessIterator End, + const Comparator &Comp = Comparator()) { + static_assert(is_execution_policy<Policy>::value, + "Invalid execution policy!"); + std::sort(Start, End, Comp); +} + +template <class Policy, class IterTy, class FuncTy> +void for_each(Policy policy, IterTy Begin, IterTy End, FuncTy Fn) { + static_assert(is_execution_policy<Policy>::value, + "Invalid execution policy!"); + std::for_each(Begin, End, Fn); +} + +template <class Policy, class IndexTy, class FuncTy> +void for_each_n(Policy policy, IndexTy Begin, IndexTy End, FuncTy Fn) { + static_assert(is_execution_policy<Policy>::value, + "Invalid execution policy!"); + for (IndexTy I = Begin; I != End; ++I) + Fn(I); +} + +// Parallel algorithm implementations, only available when LLVM_ENABLE_THREADS +// is true. +#if LLVM_ENABLE_THREADS +template <class RandomAccessIterator, + class Comparator = detail::DefComparator<RandomAccessIterator>> +void sort(parallel_execution_policy policy, RandomAccessIterator Start, + RandomAccessIterator End, const Comparator &Comp = Comparator()) { + detail::parallel_sort(Start, End, Comp); +} + +template <class IterTy, class FuncTy> +void for_each(parallel_execution_policy policy, IterTy Begin, IterTy End, + FuncTy Fn) { + detail::parallel_for_each(Begin, End, Fn); +} + +template <class IndexTy, class FuncTy> +void for_each_n(parallel_execution_policy policy, IndexTy Begin, IndexTy End, + FuncTy Fn) { + detail::parallel_for_each_n(Begin, End, Fn); +} +#endif + +} // namespace parallel +} // namespace llvm + +#endif // LLVM_SUPPORT_PARALLEL_H diff --git a/include/llvm/Support/Wasm.h b/include/llvm/Support/Wasm.h index a48dfe10b3bb..e3831827062c 100644 --- a/include/llvm/Support/Wasm.h +++ b/include/llvm/Support/Wasm.h @@ -37,17 +37,6 @@ struct WasmSignature { int32_t ReturnType; }; -struct WasmImport { - StringRef Module; - StringRef Field; - uint32_t Kind; - union { - uint32_t SigIndex; - int32_t GlobalType; - }; - bool GlobalMutable; -}; - struct WasmExport { StringRef Name; uint32_t Kind; @@ -82,6 +71,18 @@ struct WasmGlobal { WasmInitExpr InitExpr; }; +struct WasmImport { + StringRef Module; + StringRef Field; + uint32_t Kind; + union { + uint32_t SigIndex; + WasmGlobal Global; + WasmTable Table; + WasmLimits Memory; + }; +}; + struct WasmLocalDecl { int32_t Type; uint32_t Count; diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index fc35b4527bc3..6f44292c47ed 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -680,6 +680,11 @@ class RegisterOperand<RegisterClass regclass, string pm = "printOperand"> // this type. The method normally will just use an alt-name index to look // up the name to print. Default to the generic printOperand(). string PrintMethod = pm; + + // EncoderMethod - The target method name to call to encode this register + // operand. + string EncoderMethod = ""; + // ParserMatchClass - The "match class" that operands of this type fit // in. Match classes are used to define the order in which instructions are // match, to ensure that which instructions gets matched is deterministic. diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index 82a682cf1f7e..97a6f0c6e3ae 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -172,11 +172,22 @@ public: /// inalloca arguments. This function reports only the size of the frame part /// that is set up between the frame setup and destroy pseudo instructions. int64_t getFrameSize(const MachineInstr &I) const { - assert(isFrameInstr(I)); + assert(isFrameInstr(I) && "Not a frame instruction"); assert(I.getOperand(0).getImm() >= 0); return I.getOperand(0).getImm(); } + /// Returns the total frame size, which is made up of the space set up inside + /// the pair of frame start-stop instructions and the space that is set up + /// prior to the pair. + int64_t getFrameTotalSize(const MachineInstr &I) const { + if (isFrameSetup(I)) { + assert(I.getOperand(1).getImm() >= 0 && "Frame size must not be negative"); + return getFrameSize(I) + I.getOperand(1).getImm(); + } + return getFrameSize(I); + } + unsigned getCatchReturnOpcode() const { return CatchRetOpcode; } unsigned getReturnOpcode() const { return ReturnOpcode; } diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index ced183852146..1ca32d4c3589 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -1396,7 +1396,10 @@ public: /// It is called by AtomicExpandPass before expanding an /// AtomicRMW/AtomicCmpXchg/AtomicStore/AtomicLoad /// if shouldInsertFencesForAtomic returns true. - /// RMW and CmpXchg set both IsStore and IsLoad to true. + /// + /// Inst is the original atomic instruction, prior to other expansions that + /// may be performed. + /// /// This function should either return a nullptr, or a pointer to an IR-level /// Instruction*. Even complex fence sequences can be represented by a /// single Instruction* through an intrinsic to be lowered later. @@ -1422,18 +1425,17 @@ 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 { - if (isReleaseOrStronger(Ord) && IsStore) + virtual Instruction *emitLeadingFence(IRBuilder<> &Builder, Instruction *Inst, + AtomicOrdering Ord) const { + if (isReleaseOrStronger(Ord) && Inst->hasAtomicStore()) return Builder.CreateFence(Ord); else return nullptr; } virtual Instruction *emitTrailingFence(IRBuilder<> &Builder, - AtomicOrdering Ord, bool IsStore, - bool IsLoad) const { + Instruction *Inst, + AtomicOrdering Ord) const { if (isAcquireOrStronger(Ord)) return Builder.CreateFence(Ord); else @@ -2061,14 +2063,6 @@ public: return false; } - // Return true if the instruction that performs a << b actually performs - // a << (b % (sizeof(a) * 8)). - virtual bool supportsModuloShift(ISD::NodeType Inst, EVT ReturnType) const { - assert((Inst == ISD::SHL || Inst == ISD::SRA || Inst == ISD::SRL) && - "Expect a shift instruction"); - return false; - } - //===--------------------------------------------------------------------===// // Runtime Library hooks // diff --git a/include/llvm/Target/TargetSchedule.td b/include/llvm/Target/TargetSchedule.td index d342e4fe2613..7b00c9420e35 100644 --- a/include/llvm/Target/TargetSchedule.td +++ b/include/llvm/Target/TargetSchedule.td @@ -334,7 +334,7 @@ class ReadAdvance<SchedRead read, int cycles, list<SchedWrite> writes = []> } // Directly associate a new SchedRead type with a delay and optional -// pipeline bypess. For use with InstRW or ItinRW. +// pipeline bypass. For use with InstRW or ItinRW. class SchedReadAdvance<int cycles, list<SchedWrite> writes = []> : SchedRead, ProcReadAdvance<cycles, writes>; diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td index 45a842f77a21..9ed614ccee17 100644 --- a/include/llvm/Target/TargetSelectionDAG.td +++ b/include/llvm/Target/TargetSelectionDAG.td @@ -281,7 +281,7 @@ def SDTConvertOp : SDTypeProfile<1, 5, [ //cvtss, su, us, uu, ff, fs, fu, sf, su ]>; class SDCallSeqStart<list<SDTypeConstraint> constraints> : - SDTypeProfile<0, 1, constraints>; + SDTypeProfile<0, 2, constraints>; class SDCallSeqEnd<list<SDTypeConstraint> constraints> : SDTypeProfile<0, 2, constraints>; diff --git a/include/llvm/LibDriver/LibDriver.h b/include/llvm/ToolDrivers/llvm-lib/LibDriver.h index 95feb60be403..a4806ac4ad69 100644 --- a/include/llvm/LibDriver/LibDriver.h +++ b/include/llvm/ToolDrivers/llvm-lib/LibDriver.h @@ -1,4 +1,4 @@ -//===- llvm/LibDriver/LibDriver.h - lib.exe-compatible driver ---*- C++ -*-===// +//===- llvm-lib/LibDriver.h - lib.exe-compatible driver ---------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIBDRIVER_LIBDRIVER_H -#define LLVM_LIBDRIVER_LIBDRIVER_H +#ifndef LLVM_TOOLDRIVERS_LLVM_LIB_LIBDRIVER_H +#define LLVM_TOOLDRIVERS_LLVM_LIB_LIBDRIVER_H namespace llvm { template <typename T> class ArrayRef; diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h index 0a8903a6ed7b..91c9d255302f 100644 --- a/include/llvm/Transforms/Utils/Cloning.h +++ b/include/llvm/Transforms/Utils/Cloning.h @@ -43,6 +43,7 @@ class InvokeInst; class Loop; class LoopInfo; class Module; +class ProfileSummaryInfo; class ReturnInst; /// Return an exact copy of the specified module @@ -175,15 +176,17 @@ public: explicit InlineFunctionInfo(CallGraph *cg = nullptr, std::function<AssumptionCache &(Function &)> *GetAssumptionCache = nullptr, + ProfileSummaryInfo *PSI = nullptr, BlockFrequencyInfo *CallerBFI = nullptr, BlockFrequencyInfo *CalleeBFI = nullptr) - : CG(cg), GetAssumptionCache(GetAssumptionCache), CallerBFI(CallerBFI), - CalleeBFI(CalleeBFI) {} + : CG(cg), GetAssumptionCache(GetAssumptionCache), PSI(PSI), + CallerBFI(CallerBFI), CalleeBFI(CalleeBFI) {} /// CG - If non-null, InlineFunction will update the callgraph to reflect the /// changes it makes. CallGraph *CG; std::function<AssumptionCache &(Function &)> *GetAssumptionCache; + ProfileSummaryInfo *PSI; BlockFrequencyInfo *CallerBFI, *CalleeBFI; /// StaticAllocas - InlineFunction fills this in with all static allocas that diff --git a/include/llvm/Transforms/Utils/LoopUtils.h b/include/llvm/Transforms/Utils/LoopUtils.h index a1cf41d6f931..561f94880624 100644 --- a/include/llvm/Transforms/Utils/LoopUtils.h +++ b/include/llvm/Transforms/Utils/LoopUtils.h @@ -21,6 +21,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/EHPersonalities.h" +#include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/InstrTypes.h" @@ -42,6 +43,7 @@ class PredIteratorCache; class ScalarEvolution; class SCEV; class TargetLibraryInfo; +class TargetTransformInfo; /// \brief Captures loop safety information. /// It keep information for loop & its header may throw exception. @@ -489,6 +491,36 @@ bool canSinkOrHoistInst(Instruction &I, AAResults *AA, DominatorTree *DT, LoopSafetyInfo *SafetyInfo, OptimizationRemarkEmitter *ORE = nullptr); +/// Generates a vector reduction using shufflevectors to reduce the value. +Value *getShuffleReduction(IRBuilder<> &Builder, Value *Src, unsigned Op, + RecurrenceDescriptor::MinMaxRecurrenceKind + MinMaxKind = RecurrenceDescriptor::MRK_Invalid, + ArrayRef<Value *> RedOps = ArrayRef<Value *>()); + +/// Create a target reduction of the given vector. The reduction operation +/// is described by the \p Opcode parameter. min/max reductions require +/// additional information supplied in \p Flags. +/// The target is queried to determine if intrinsics or shuffle sequences are +/// required to implement the reduction. +Value * +createSimpleTargetReduction(IRBuilder<> &B, const TargetTransformInfo *TTI, + unsigned Opcode, Value *Src, + TargetTransformInfo::ReductionFlags Flags = + TargetTransformInfo::ReductionFlags(), + ArrayRef<Value *> RedOps = ArrayRef<Value *>()); + +/// Create a generic target reduction using a recurrence descriptor \p Desc +/// The target is queried to determine if intrinsics or shuffle sequences are +/// required to implement the reduction. +Value *createTargetReduction(IRBuilder<> &B, const TargetTransformInfo *TTI, + RecurrenceDescriptor &Desc, Value *Src, + bool NoNaN = false); + +/// Get the intersection (logical and) of all of the potential IR flags +/// of each scalar operation (VL) that will be converted into a vector (I). +/// Flag set: NSW, NUW, exact, and all of fast-math. +void propagateIRFlags(Value *I, ArrayRef<Value *> VL); + } // end namespace llvm #endif // LLVM_TRANSFORMS_UTILS_LOOPUTILS_H diff --git a/include/llvm/Transforms/Vectorize/SLPVectorizer.h b/include/llvm/Transforms/Vectorize/SLPVectorizer.h index 10338f7937e8..c514db41623c 100644 --- a/include/llvm/Transforms/Vectorize/SLPVectorizer.h +++ b/include/llvm/Transforms/Vectorize/SLPVectorizer.h @@ -24,6 +24,7 @@ #include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/DemandedBits.h" #include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/OptimizationDiagnosticInfo.h" #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/IR/Function.h" @@ -59,7 +60,8 @@ public: // Glue for old PM. bool runImpl(Function &F, ScalarEvolution *SE_, TargetTransformInfo *TTI_, TargetLibraryInfo *TLI_, AliasAnalysis *AA_, LoopInfo *LI_, - DominatorTree *DT_, AssumptionCache *AC_, DemandedBits *DB_); + DominatorTree *DT_, AssumptionCache *AC_, DemandedBits *DB_, + OptimizationRemarkEmitter *ORE_); private: /// \brief Collect store and getelementptr instructions and organize them diff --git a/include/llvm/module.modulemap b/include/llvm/module.modulemap index 59b1f1621039..5e15e8d49802 100644 --- a/include/llvm/module.modulemap +++ b/include/llvm/module.modulemap @@ -148,6 +148,7 @@ module LLVM_intrinsic_gen { module IR_Attributes { header "IR/Attributes.h" export * } module IR_CallSite { header "IR/CallSite.h" export * } module IR_ConstantFolder { header "IR/ConstantFolder.h" export * } + module IR_GlobalVariable { header "IR/GlobalVariable.h" export * } module IR_NoFolder { header "IR/NoFolder.h" export * } module IR_Module { header "IR/Module.h" export * } module IR_ModuleSummaryIndex { header "IR/ModuleSummaryIndex.h" export * } |