diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2022-10-15 15:58:31 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2022-10-15 15:58:31 +0000 |
commit | 7f04c68256951282ce8e0136371ef97410ed7db6 (patch) | |
tree | 9ef7896b615b2bc63e52c31912a020340b333d1a | |
parent | 5bf671d658572f2de62bde5767e63873cb5fc708 (diff) |
Vendor import of llvm-project branch release/15.x llvmorg-15.0.1-0-gb73d2c8c720a.vendor/llvm-project/llvmorg-15.0.1-0-gb73d2c8c720a
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 8 | ||||
-rw-r--r-- | clang/lib/CodeGen/CoverageMappingGen.cpp | 32 | ||||
-rw-r--r-- | clang/lib/Tooling/InterpolatingCompilationDatabase.cpp | 4 | ||||
-rw-r--r-- | libcxx/include/__config | 2 | ||||
-rw-r--r-- | libcxx/include/atomic | 46 | ||||
-rw-r--r-- | libcxx/include/version | 2 | ||||
-rw-r--r-- | lld/COFF/Symbols.h | 5 | ||||
-rw-r--r-- | lld/COFF/Writer.cpp | 2 | ||||
-rw-r--r-- | lld/MachO/InputFiles.cpp | 9 | ||||
-rw-r--r-- | lld/MachO/UnwindInfoSection.cpp | 45 | ||||
-rw-r--r-- | llvm/include/llvm/Object/ELF.h | 2 | ||||
-rw-r--r-- | llvm/lib/CodeGen/DwarfEHPrepare.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/CodeGen/PrologEpilogInserter.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | 14 | ||||
-rw-r--r-- | llvm/lib/Transforms/Vectorize/VPlan.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Transforms/Vectorize/VPlan.h | 10 | ||||
-rw-r--r-- | llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp | 7 | ||||
-rw-r--r-- | llvm/tools/llvm-objdump/ELFDump.cpp | 39 |
18 files changed, 136 insertions, 108 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 6ff5b8de57fd..cb460401eb47 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -419,7 +419,7 @@ def warn_implicit_function_decl : Warning< InGroup<ImplicitFunctionDeclare>, DefaultIgnore; def ext_implicit_function_decl_c99 : ExtWarn< "call to undeclared function %0; ISO C99 and later do not support implicit " - "function declarations">, InGroup<ImplicitFunctionDeclare>, DefaultError; + "function declarations">, InGroup<ImplicitFunctionDeclare>; def note_function_suggestion : Note<"did you mean %0?">; def err_ellipsis_first_param : Error< @@ -705,7 +705,7 @@ def ext_implicit_lib_function_decl : ExtWarn< def ext_implicit_lib_function_decl_c99 : ExtWarn< "call to undeclared library function '%0' with type %1; ISO C99 and later " "do not support implicit function declarations">, - InGroup<ImplicitFunctionDeclare>, DefaultError; + InGroup<ImplicitFunctionDeclare>; def note_include_header_or_declare : Note< "include the header <%0> or explicitly provide a declaration for '%1'">; def note_previous_builtin_declaration : Note<"%0 is a builtin with type %1">; @@ -4359,7 +4359,7 @@ def err_ident_list_in_fn_declaration : Error< "a parameter list without types is only allowed in a function definition">; def ext_param_not_declared : ExtWarn< "parameter %0 was not declared, defaults to 'int'; ISO C99 and later do not " - "support implicit int">, InGroup<ImplicitInt>, DefaultError; + "support implicit int">, InGroup<ImplicitInt>; def err_param_default_argument : Error< "C does not support default arguments">; def err_param_default_argument_redefinition : Error< @@ -10029,7 +10029,7 @@ def warn_receiver_forward_class : Warning< def note_method_sent_forward_class : Note<"method %0 is used for the forward class">; def ext_missing_type_specifier : ExtWarn< "type specifier missing, defaults to 'int'; ISO C99 and later do not support " - "implicit int">, InGroup<ImplicitInt>, DefaultError; + "implicit int">, InGroup<ImplicitInt>; def err_missing_type_specifier : Error< "a type specifier is required for all declarations">; def err_decimal_unsupported : Error< diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index 0fe084b628da..836aabf80179 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -1377,19 +1377,23 @@ struct CounterCoverageMappingBuilder // Extend into the condition before we propagate through it below - this is // needed to handle macros that generate the "if" but not the condition. - extendRegion(S->getCond()); + if (!S->isConsteval()) + extendRegion(S->getCond()); Counter ParentCount = getRegion().getCounter(); Counter ThenCount = getRegionCounter(S); - // Emitting a counter for the condition makes it easier to interpret the - // counter for the body when looking at the coverage. - propagateCounts(ParentCount, S->getCond()); + if (!S->isConsteval()) { + // Emitting a counter for the condition makes it easier to interpret the + // counter for the body when looking at the coverage. + propagateCounts(ParentCount, S->getCond()); - // The 'then' count applies to the area immediately after the condition. - auto Gap = findGapAreaBetween(S->getRParenLoc(), getStart(S->getThen())); - if (Gap) - fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), ThenCount); + // The 'then' count applies to the area immediately after the condition. + Optional<SourceRange> Gap = + findGapAreaBetween(S->getRParenLoc(), getStart(S->getThen())); + if (Gap) + fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), ThenCount); + } extendRegion(S->getThen()); Counter OutCount = propagateCounts(ThenCount, S->getThen()); @@ -1398,9 +1402,9 @@ struct CounterCoverageMappingBuilder if (const Stmt *Else = S->getElse()) { bool ThenHasTerminateStmt = HasTerminateStmt; HasTerminateStmt = false; - // The 'else' count applies to the area immediately after the 'then'. - Gap = findGapAreaBetween(getEnd(S->getThen()), getStart(Else)); + Optional<SourceRange> Gap = + findGapAreaBetween(getEnd(S->getThen()), getStart(Else)); if (Gap) fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), ElseCount); extendRegion(Else); @@ -1416,9 +1420,11 @@ struct CounterCoverageMappingBuilder GapRegionCounter = OutCount; } - // Create Branch Region around condition. - createBranchRegion(S->getCond(), ThenCount, - subtractCounters(ParentCount, ThenCount)); + if (!S->isConsteval()) { + // Create Branch Region around condition. + createBranchRegion(S->getCond(), ThenCount, + subtractCounters(ParentCount, ThenCount)); + } } void VisitCXXTryStmt(const CXXTryStmt *S) { diff --git a/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp b/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp index 0143b5f8df6b..655be20572b6 100644 --- a/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp +++ b/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp @@ -165,8 +165,8 @@ struct TransferableCommand { const unsigned OldPos = Pos; std::unique_ptr<llvm::opt::Arg> Arg(OptTable.ParseOneArg( ArgList, Pos, - /* Include */ ClangCLMode ? CoreOption | CLOption : 0, - /* Exclude */ ClangCLMode ? 0 : CLOption)); + /* Include */ ClangCLMode ? CoreOption | CLOption | CLDXCOption : 0, + /* Exclude */ ClangCLMode ? 0 : CLOption | CLDXCOption)); if (!Arg) continue; diff --git a/libcxx/include/__config b/libcxx/include/__config index 8c2f7614af53..2f80df35f909 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -24,7 +24,7 @@ #ifdef __cplusplus -# define _LIBCPP_VERSION 15000 +# define _LIBCPP_VERSION 15001 # define _LIBCPP_CONCAT_IMPL(_X, _Y) _X##_Y # define _LIBCPP_CONCAT(_X, _Y) _LIBCPP_CONCAT_IMPL(_X, _Y) diff --git a/libcxx/include/atomic b/libcxx/include/atomic index 92da4820e928..3a93b9b0a108 100644 --- a/libcxx/include/atomic +++ b/libcxx/include/atomic @@ -1113,6 +1113,12 @@ _Tp kill_dependency(_Tp __y) _NOEXCEPT # define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE #endif +template <class _Tp> +struct __libcpp_is_always_lock_free { + // __atomic_always_lock_free is available in all Standard modes + static const bool __value = __atomic_always_lock_free(sizeof(_Tp), 0); +}; + #ifdef _LIBCPP_ATOMIC_ONLY_USE_BUILTINS template<typename _Tp> @@ -1404,42 +1410,8 @@ _Tp __cxx_atomic_fetch_xor(__cxx_atomic_lock_impl<_Tp>* __a, return __old; } -#ifdef __cpp_lib_atomic_is_always_lock_free - -template<typename _Tp> struct __cxx_is_always_lock_free { - enum { __value = __atomic_always_lock_free(sizeof(_Tp), 0) }; }; - -#else - -template<typename _Tp> struct __cxx_is_always_lock_free { enum { __value = false }; }; -// Implementations must match the C ATOMIC_*_LOCK_FREE macro values. -template<> struct __cxx_is_always_lock_free<bool> { enum { __value = 2 == ATOMIC_BOOL_LOCK_FREE }; }; -template<> struct __cxx_is_always_lock_free<char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; }; -template<> struct __cxx_is_always_lock_free<signed char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; }; -template<> struct __cxx_is_always_lock_free<unsigned char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; }; -#ifndef _LIBCPP_HAS_NO_CHAR8_T -template<> struct __cxx_is_always_lock_free<char8_t> { enum { __value = 2 == ATOMIC_CHAR8_T_LOCK_FREE }; }; -#endif -template<> struct __cxx_is_always_lock_free<char16_t> { enum { __value = 2 == ATOMIC_CHAR16_T_LOCK_FREE }; }; -template<> struct __cxx_is_always_lock_free<char32_t> { enum { __value = 2 == ATOMIC_CHAR32_T_LOCK_FREE }; }; -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -template<> struct __cxx_is_always_lock_free<wchar_t> { enum { __value = 2 == ATOMIC_WCHAR_T_LOCK_FREE }; }; -#endif -template<> struct __cxx_is_always_lock_free<short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; }; -template<> struct __cxx_is_always_lock_free<unsigned short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; }; -template<> struct __cxx_is_always_lock_free<int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; }; -template<> struct __cxx_is_always_lock_free<unsigned int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; }; -template<> struct __cxx_is_always_lock_free<long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; }; -template<> struct __cxx_is_always_lock_free<unsigned long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; }; -template<> struct __cxx_is_always_lock_free<long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; }; -template<> struct __cxx_is_always_lock_free<unsigned long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; }; -template<typename _Tp> struct __cxx_is_always_lock_free<_Tp*> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; }; -template<> struct __cxx_is_always_lock_free<std::nullptr_t> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; }; - -#endif //__cpp_lib_atomic_is_always_lock_free - template <typename _Tp, - typename _Base = typename conditional<__cxx_is_always_lock_free<_Tp>::__value, + typename _Base = typename conditional<__libcpp_is_always_lock_free<_Tp>::__value, __cxx_atomic_base_impl<_Tp>, __cxx_atomic_lock_impl<_Tp> >::type> #else @@ -1561,7 +1533,7 @@ struct __atomic_base // false mutable __cxx_atomic_impl<_Tp> __a_; #if defined(__cpp_lib_atomic_is_always_lock_free) - static _LIBCPP_CONSTEXPR bool is_always_lock_free = __atomic_always_lock_free(sizeof(__a_), 0); + static _LIBCPP_CONSTEXPR bool is_always_lock_free = __libcpp_is_always_lock_free<__cxx_atomic_impl<_Tp> >::__value; #endif _LIBCPP_INLINE_VISIBILITY @@ -2664,7 +2636,7 @@ typedef atomic<uintmax_t> atomic_uintmax_t; // atomic_*_lock_free : prefer the contention type most highly, then the largest lock-free type #ifdef __cpp_lib_atomic_is_always_lock_free -# define _LIBCPP_CONTENTION_LOCK_FREE __atomic_always_lock_free(sizeof(__cxx_contention_t), 0) +# define _LIBCPP_CONTENTION_LOCK_FREE ::std::__libcpp_is_always_lock_free<__cxx_contention_t>::__value #else # define _LIBCPP_CONTENTION_LOCK_FREE false #endif diff --git a/libcxx/include/version b/libcxx/include/version index 8ffb1747eb27..d0c6fe466e70 100644 --- a/libcxx/include/version +++ b/libcxx/include/version @@ -332,7 +332,7 @@ __cpp_lib_void_t 201411L <type_traits> # undef __cpp_lib_execution // # define __cpp_lib_execution 201902L # if !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) -# define __cpp_lib_format 202106L +// # define __cpp_lib_format 202106L # endif # define __cpp_lib_generic_unordered_lookup 201811L # define __cpp_lib_int_pow2 202002L diff --git a/lld/COFF/Symbols.h b/lld/COFF/Symbols.h index c8865d128fb8..a4c6f893f10c 100644 --- a/lld/COFF/Symbols.h +++ b/lld/COFF/Symbols.h @@ -106,7 +106,10 @@ protected: : symbolKind(k), isExternal(true), isCOMDAT(false), writtenToSymtab(false), pendingArchiveLoad(false), isGCRoot(false), isRuntimePseudoReloc(false), deferUndefined(false), canInline(true), - nameSize(n.size()), nameData(n.empty() ? nullptr : n.data()) {} + nameSize(n.size()), nameData(n.empty() ? nullptr : n.data()) { + assert((!n.empty() || k <= LastDefinedCOFFKind) && + "If the name is empty, the Symbol must be a DefinedCOFF."); + } const unsigned symbolKind : 8; unsigned isExternal : 1; diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp index df60c9032b2d..f39697d5d381 100644 --- a/lld/COFF/Writer.cpp +++ b/lld/COFF/Writer.cpp @@ -395,7 +395,7 @@ getThunk(DenseMap<uint64_t, Defined *> &lastThunks, Defined *target, uint64_t p, default: llvm_unreachable("Unexpected architecture"); } - Defined *d = make<DefinedSynthetic>("", c); + Defined *d = make<DefinedSynthetic>("range_extension_thunk", c); lastThunk = d; return {d, true}; } diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp index fd0e4ec8834c..87034d41e87d 100644 --- a/lld/MachO/InputFiles.cpp +++ b/lld/MachO/InputFiles.cpp @@ -1587,6 +1587,15 @@ void ObjFile::registerEhFrames(Section &ehFrameSection) { funcSym->unwindEntry = isec; ehRelocator.commit(); } + + // __eh_frame is marked as S_ATTR_LIVE_SUPPORT in input files, because FDEs + // are normally required to be kept alive if they reference a live symbol. + // However, we've explicitly created a dependency from a symbol to its FDE, so + // dead-stripping will just work as usual, and S_ATTR_LIVE_SUPPORT will only + // serve to incorrectly prevent us from dead-stripping duplicate FDEs for a + // live symbol (e.g. if there were multiple weak copies). Remove this flag to + // let dead-stripping proceed correctly. + ehFrameSection.flags &= ~S_ATTR_LIVE_SUPPORT; } std::string ObjFile::sourceFile() const { diff --git a/lld/MachO/UnwindInfoSection.cpp b/lld/MachO/UnwindInfoSection.cpp index c3f563d5572b..ca6cbdfbb8bb 100644 --- a/lld/MachO/UnwindInfoSection.cpp +++ b/lld/MachO/UnwindInfoSection.cpp @@ -196,13 +196,13 @@ UnwindInfoSection::UnwindInfoSection() // Record function symbols that may need entries emitted in __unwind_info, which // stores unwind data for address ranges. // -// Note that if several adjacent functions have the same unwind encoding, LSDA, -// and personality function, they share one unwind entry. For this to work, -// functions without unwind info need explicit "no unwind info" unwind entries -// -- else the unwinder would think they have the unwind info of the closest -// function with unwind info right before in the image. Thus, we add function -// symbols for each unique address regardless of whether they have associated -// unwind info. +// Note that if several adjacent functions have the same unwind encoding and +// personality function and no LSDA, they share one unwind entry. For this to +// work, functions without unwind info need explicit "no unwind info" unwind +// entries -- else the unwinder would think they have the unwind info of the +// closest function with unwind info right before in the image. Thus, we add +// function symbols for each unique address regardless of whether they have +// associated unwind info. void UnwindInfoSection::addSymbol(const Defined *d) { if (d->unwindEntry) allEntriesAreOmitted = false; @@ -427,9 +427,9 @@ void UnwindInfoSectionImpl::finalize() { // assigned, so we can relocate the __LD,__compact_unwind entries // into a temporary buffer. Relocation is necessary in order to sort // the CU entries by function address. Sorting is necessary so that - // we can fold adjacent CU entries with identical - // encoding+personality+lsda. Folding is necessary because it reduces - // the number of CU entries by as much as 3 orders of magnitude! + // we can fold adjacent CU entries with identical encoding+personality + // and without any LSDA. Folding is necessary because it reduces the + // number of CU entries by as much as 3 orders of magnitude! cuEntries.resize(symbols.size()); // The "map" part of the symbols MapVector was only needed for deduplication // in addSymbol(). Now that we are done adding, move the contents to a plain @@ -445,7 +445,7 @@ void UnwindInfoSectionImpl::finalize() { return cuEntries[a].functionAddress < cuEntries[b].functionAddress; }); - // Fold adjacent entries with matching encoding+personality+lsda + // Fold adjacent entries with matching encoding+personality and without LSDA // We use three iterators on the same cuIndices to fold in-situ: // (1) `foldBegin` is the first of a potential sequence of matching entries // (2) `foldEnd` is the first non-matching entry after `foldBegin`. @@ -455,11 +455,32 @@ void UnwindInfoSectionImpl::finalize() { auto foldWrite = cuIndices.begin(); for (auto foldBegin = cuIndices.begin(); foldBegin < cuIndices.end();) { auto foldEnd = foldBegin; + // Common LSDA encodings (e.g. for C++ and Objective-C) contain offsets from + // a base address. The base address is normally not contained directly in + // the LSDA, and in that case, the personality function treats the starting + // address of the function (which is computed by the unwinder) as the base + // address and interprets the LSDA accordingly. The unwinder computes the + // starting address of a function as the address associated with its CU + // entry. For this reason, we cannot fold adjacent entries if they have an + // LSDA, because folding would make the unwinder compute the wrong starting + // address for the functions with the folded entries, which in turn would + // cause the personality function to misinterpret the LSDA for those + // functions. In the very rare case where the base address is encoded + // directly in the LSDA, two functions at different addresses would + // necessarily have different LSDAs, so their CU entries would not have been + // folded anyway. while (++foldEnd < cuIndices.end() && cuEntries[*foldBegin].encoding == cuEntries[*foldEnd].encoding && + !cuEntries[*foldBegin].lsda && !cuEntries[*foldEnd].lsda && + // If we've gotten to this point, we don't have an LSDA, which should + // also imply that we don't have a personality function, since in all + // likelihood a personality function needs the LSDA to do anything + // useful. It can be technically valid to have a personality function + // and no LSDA though (e.g. the C++ personality __gxx_personality_v0 + // is just a no-op without LSDA), so we still check for personality + // function equivalence to handle that case. cuEntries[*foldBegin].personality == cuEntries[*foldEnd].personality && - cuEntries[*foldBegin].lsda == cuEntries[*foldEnd].lsda && canFoldEncoding(cuEntries[*foldEnd].encoding)) ; *foldWrite++ = *foldBegin; diff --git a/llvm/include/llvm/Object/ELF.h b/llvm/include/llvm/Object/ELF.h index 794d29fd9913..5eb43777a951 100644 --- a/llvm/include/llvm/Object/ELF.h +++ b/llvm/include/llvm/Object/ELF.h @@ -1028,7 +1028,7 @@ ELFFile<ELFT>::getVersionDependencies(const Elf_Shdr &Sec, VN.Offset = VerneedBuf - Start; if (Verneed->vn_file < StrTab.size()) - VN.File = std::string(StrTab.drop_front(Verneed->vn_file)); + VN.File = std::string(StrTab.data() + Verneed->vn_file); else VN.File = ("<corrupt vn_file: " + Twine(Verneed->vn_file) + ">").str(); diff --git a/llvm/lib/CodeGen/DwarfEHPrepare.cpp b/llvm/lib/CodeGen/DwarfEHPrepare.cpp index fb8a3e383950..aa81f618dc59 100644 --- a/llvm/lib/CodeGen/DwarfEHPrepare.cpp +++ b/llvm/lib/CodeGen/DwarfEHPrepare.cpp @@ -25,6 +25,7 @@ #include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Function.h" @@ -247,6 +248,13 @@ bool DwarfEHPrepare::InsertUnwindResumeCalls() { // Call the rewind function. CallInst *CI = CallInst::Create(RewindFunction, RewindFunctionArgs, "", UnwindBB); + // The verifier requires that all calls of debug-info-bearing functions + // from debug-info-bearing functions have a debug location (for inlining + // purposes). Assign a dummy location to satisfy the constraint. + Function *RewindFn = dyn_cast<Function>(RewindFunction.getCallee()); + if (RewindFn && RewindFn->getSubprogram()) + if (DISubprogram *SP = F.getSubprogram()) + CI->setDebugLoc(DILocation::get(SP->getContext(), 0, 0, SP)); CI->setCallingConv(RewindFunctionCallingConv); // We never expect _Unwind_Resume to return. diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp index 89a43c4f57f6..85d051cfdbe7 100644 --- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp +++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp @@ -1262,9 +1262,10 @@ void PEI::insertZeroCallUsedRegs(MachineFunction &MF) { } } - // Don't clear registers that are reset before exiting. - for (const CalleeSavedInfo &CSI : MF.getFrameInfo().getCalleeSavedInfo()) - for (MCRegister Reg : TRI.sub_and_superregs_inclusive(CSI.getReg())) + // Don't clear registers that must be preserved. + for (const MCPhysReg *CSRegs = TRI.getCalleeSavedRegs(&MF); + MCPhysReg CSReg = *CSRegs; ++CSRegs) + for (MCRegister Reg : TRI.sub_and_superregs_inclusive(CSReg)) RegsToZero.reset(Reg); const TargetFrameLowering &TFI = *MF.getSubtarget().getFrameLowering(); diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index 91bc7dbad1d0..2cdae028ec7d 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -8149,9 +8149,15 @@ VPRecipeBase *VPRecipeBuilder::tryToOptimizeInductionPHI( *PSE.getSE(), *OrigLoop, Range); // Check if this is pointer induction. If so, build the recipe for it. - if (auto *II = Legal->getPointerInductionDescriptor(Phi)) - return new VPWidenPointerInductionRecipe(Phi, Operands[0], *II, - *PSE.getSE()); + if (auto *II = Legal->getPointerInductionDescriptor(Phi)) { + return new VPWidenPointerInductionRecipe( + Phi, Operands[0], *II, *PSE.getSE(), + LoopVectorizationPlanner::getDecisionAndClampRange( + [&](ElementCount VF) { + return !VF.isScalable() && CM.isScalarAfterVectorization(Phi, VF); + }, + Range)); + } return nullptr; } @@ -9332,7 +9338,7 @@ void VPWidenPointerInductionRecipe::execute(VPTransformState &State) { auto *IVR = getParent()->getPlan()->getCanonicalIV(); PHINode *CanonicalIV = cast<PHINode>(State.get(IVR, 0)); - if (onlyScalarsGenerated(State.VF)) { + if (onlyScalarsGenerated()) { // This is the normalized GEP that starts counting at zero. Value *PtrInd = State.Builder.CreateSExtOrTrunc( CanonicalIV, IndDesc.getStep()->getType()); diff --git a/llvm/lib/Transforms/Vectorize/VPlan.cpp b/llvm/lib/Transforms/Vectorize/VPlan.cpp index 30032dda7f60..0662ca883252 100644 --- a/llvm/lib/Transforms/Vectorize/VPlan.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlan.cpp @@ -698,7 +698,7 @@ void VPlan::execute(VPTransformState *State) { auto *WidenPhi = cast<VPWidenPointerInductionRecipe>(&R); // TODO: Split off the case that all users of a pointer phi are scalar // from the VPWidenPointerInductionRecipe. - if (WidenPhi->onlyScalarsGenerated(State->VF)) + if (WidenPhi->onlyScalarsGenerated()) continue; auto *GEP = cast<GetElementPtrInst>(State->get(WidenPhi, 0)); diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h index f009a7ee6b4b..329843bf977d 100644 --- a/llvm/lib/Transforms/Vectorize/VPlan.h +++ b/llvm/lib/Transforms/Vectorize/VPlan.h @@ -1187,15 +1187,19 @@ class VPWidenPointerInductionRecipe : public VPHeaderPHIRecipe { /// explicitly. ScalarEvolution &SE; + bool IsScalarAfterVectorization; + public: /// Create a new VPWidenPointerInductionRecipe for \p Phi with start value \p /// Start. VPWidenPointerInductionRecipe(PHINode *Phi, VPValue *Start, const InductionDescriptor &IndDesc, - ScalarEvolution &SE) + ScalarEvolution &SE, + bool IsScalarAfterVectorization) : VPHeaderPHIRecipe(VPVWidenPointerInductionSC, VPWidenPointerInductionSC, Phi), - IndDesc(IndDesc), SE(SE) { + IndDesc(IndDesc), SE(SE), + IsScalarAfterVectorization(IsScalarAfterVectorization) { addOperand(Start); } @@ -1216,7 +1220,7 @@ public: void execute(VPTransformState &State) override; /// Returns true if only scalar values will be generated. - bool onlyScalarsGenerated(ElementCount VF); + bool onlyScalarsGenerated(); #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) /// Print the recipe. diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp index cb7507264667..f214563af6cc 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp @@ -982,11 +982,8 @@ void VPCanonicalIVPHIRecipe::print(raw_ostream &O, const Twine &Indent, } #endif -bool VPWidenPointerInductionRecipe::onlyScalarsGenerated(ElementCount VF) { - bool IsUniform = vputils::onlyFirstLaneUsed(this); - return all_of(users(), - [&](const VPUser *U) { return U->usesScalars(this); }) && - (IsUniform || !VF.isScalable()); +bool VPWidenPointerInductionRecipe::onlyScalarsGenerated() { + return IsScalarAfterVectorization; } #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) diff --git a/llvm/tools/llvm-objdump/ELFDump.cpp b/llvm/tools/llvm-objdump/ELFDump.cpp index ca73dafe2b8e..61676b4323d2 100644 --- a/llvm/tools/llvm-objdump/ELFDump.cpp +++ b/llvm/tools/llvm-objdump/ELFDump.cpp @@ -282,27 +282,28 @@ static void printProgramHeaders(const ELFFile<ELFT> &Obj, StringRef FileName) { } template <class ELFT> -static void printSymbolVersionDependency(ArrayRef<uint8_t> Contents, - StringRef StrTab) { +static void printSymbolVersionDependency(StringRef FileName, + const ELFFile<ELFT> &Obj, + const typename ELFT::Shdr &Sec) { outs() << "\nVersion References:\n"; - const uint8_t *Buf = Contents.data(); - while (Buf) { - auto *Verneed = reinterpret_cast<const typename ELFT::Verneed *>(Buf); - outs() << " required from " - << StringRef(StrTab.drop_front(Verneed->vn_file).data()) << ":\n"; + auto WarningHandler = [&](const Twine &Msg) { + reportWarning(Msg, FileName); + return Error::success(); + }; + Expected<std::vector<VerNeed>> V = + Obj.getVersionDependencies(Sec, WarningHandler); + if (!V) { + reportWarning(toString(V.takeError()), FileName); + return; + } - const uint8_t *BufAux = Buf + Verneed->vn_aux; - while (BufAux) { - auto *Vernaux = reinterpret_cast<const typename ELFT::Vernaux *>(BufAux); - outs() << " " - << format("0x%08" PRIx32 " ", (uint32_t)Vernaux->vna_hash) - << format("0x%02" PRIx16 " ", (uint16_t)Vernaux->vna_flags) - << format("%02" PRIu16 " ", (uint16_t)Vernaux->vna_other) - << StringRef(StrTab.drop_front(Vernaux->vna_name).data()) << '\n'; - BufAux = Vernaux->vna_next ? BufAux + Vernaux->vna_next : nullptr; - } - Buf = Verneed->vn_next ? Buf + Verneed->vn_next : nullptr; + raw_fd_ostream &OS = outs(); + for (const VerNeed &VN : *V) { + OS << " required from " << VN.File << ":\n"; + for (const VernAux &Aux : VN.AuxV) + OS << format(" 0x%08x 0x%02x %02u %s\n", Aux.Hash, Aux.Flags, + Aux.Other, Aux.Name.c_str()); } } @@ -355,7 +356,7 @@ static void printSymbolVersionInfo(const ELFFile<ELFT> &Elf, StringRef StrTab = unwrapOrError(Elf.getStringTable(*StrTabSec), FileName); if (Shdr.sh_type == ELF::SHT_GNU_verneed) - printSymbolVersionDependency<ELFT>(Contents, StrTab); + printSymbolVersionDependency<ELFT>(FileName, Elf, Shdr); else printSymbolVersionDefinition<ELFT>(Shdr, Contents, StrTab); } |