summaryrefslogtreecommitdiff
path: root/devel/llvm60/files
diff options
context:
space:
mode:
Diffstat (limited to 'devel/llvm60/files')
-rw-r--r--devel/llvm60/files/clang/patch-fformat_extensions.diff44
-rw-r--r--devel/llvm60/files/clang/patch-fopenmp.diff14
-rw-r--r--devel/llvm60/files/clang/patch-head-r331066.diff40
-rw-r--r--devel/llvm60/files/clang/patch-head-r336227.diff42
-rw-r--r--devel/llvm60/files/clang/patch-head-r338697.diff104
-rw-r--r--devel/llvm60/files/clang/patch-head-r339019.diff30
-rw-r--r--devel/llvm60/files/clang/patch-stable12-r342281.diff834
-rw-r--r--devel/llvm60/files/clang/patch-tools_clang_lib_Headers_CMakeLists.txt32
-rw-r--r--devel/llvm60/files/clang/patch-tools_clang_tools_clang-format_clang-format-sublime.py14
-rw-r--r--devel/llvm60/files/clang/patch-tools_clang_tools_clang-format_clang-format.py11
-rw-r--r--devel/llvm60/files/clang/patch-tools_clang_tools_clang-format_git-clang-format32
-rw-r--r--devel/llvm60/files/clang/patch-tools_clang_tools_scan-build_libexec_ccc-analyzer12
-rw-r--r--devel/llvm60/files/lld/patch-head-r331731.diff67
-rw-r--r--devel/llvm60/files/lld/patch-head-r333401.diff34
-rw-r--r--devel/llvm60/files/lld/patch-head-r336664.diff52
-rw-r--r--devel/llvm60/files/lld/patch-head-r336972.diff146
-rw-r--r--devel/llvm60/files/lld/patch-head-r337282.diff39
-rw-r--r--devel/llvm60/files/lld/patch-head-r338251.diff123
-rw-r--r--devel/llvm60/files/lld/patch-head-r338682.diff55
-rw-r--r--devel/llvm60/files/lld/patch-head-r339013.diff39
-rw-r--r--devel/llvm60/files/lld/patch-head-r339304.diff37
-rw-r--r--devel/llvm60/files/lldb/patch-head-r332849.diff38
-rw-r--r--devel/llvm60/files/lldb/patch-head-r332965.diff22
-rw-r--r--devel/llvm60/files/llvm-wrapper.sh.in12
-rw-r--r--devel/llvm60/files/openmp/patch-bug3227929
-rw-r--r--devel/llvm60/files/openmp/patch-i38611
-rw-r--r--devel/llvm60/files/patch-cmake_modules_AddSphinxTarget.cmake11
-rw-r--r--devel/llvm60/files/patch-head-r308867.diff33
-rw-r--r--devel/llvm60/files/patch-head-r330686.diff80
-rw-r--r--devel/llvm60/files/patch-head-r331065.diff88
-rw-r--r--devel/llvm60/files/patch-head-r331366.diff609
-rw-r--r--devel/llvm60/files/patch-head-r336969.diff32
-rw-r--r--devel/llvm60/files/patch-head-r336970.diff24
-rw-r--r--devel/llvm60/files/patch-head-r337615.diff64
-rw-r--r--devel/llvm60/files/patch-head-r338689.diff32
-rw-r--r--devel/llvm60/files/patch-svn-r3223251589
36 files changed, 4475 insertions, 0 deletions
diff --git a/devel/llvm60/files/clang/patch-fformat_extensions.diff b/devel/llvm60/files/clang/patch-fformat_extensions.diff
new file mode 100644
index 000000000000..69093d923b6f
--- /dev/null
+++ b/devel/llvm60/files/clang/patch-fformat_extensions.diff
@@ -0,0 +1,44 @@
+diff -ruN tools/clang/include/clang/Basic/LangOptions.def tools/clang/include/clang/Basic/LangOptions.def
+--- tools/clang/include/clang/Basic/LangOptions.def 2015-07-30 22:47:41 UTC
++++ tools/clang/include/clang/Basic/LangOptions.def
+@@ -114,6 +114,7 @@
+ LANGOPT(RTTIData , 1, 1, "emit run-time type information data")
+ LANGOPT(MSBitfields , 1, 0, "Microsoft-compatible structure layout")
+ LANGOPT(Freestanding, 1, 0, "freestanding implementation")
++LANGOPT(FormatExtensions , 1, 0, "FreeBSD format extensions")
+ LANGOPT(NoBuiltin , 1, 0, "disable builtin functions")
+ LANGOPT(NoMathBuiltin , 1, 0, "disable math builtin functions")
+ LANGOPT(GNUAsm , 1, 1, "GNU-style inline assembly")
+diff -ruN tools/clang/include/clang/Driver/Options.td tools/clang/include/clang/Driver/Options.td
+--- tools/clang/include/clang/Driver/Options.td 2015-07-30 22:47:41 UTC
++++ tools/clang/include/clang/Driver/Options.td
+@@ -644,6 +644,8 @@
+
+ def ffreestanding : Flag<["-"], "ffreestanding">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Assert that the compilation takes place in a freestanding environment">;
++def fformat_extensions: Flag<["-"], "fformat-extensions">, Group<f_Group>, Flags<[CC1Option]>,
++ HelpText<"Enable FreeBSD kernel specific format string extensions">;
+ def fgnu_keywords : Flag<["-"], "fgnu-keywords">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Allow GNU-extension keywords regardless of language standard">;
+ def fgnu89_inline : Flag<["-"], "fgnu89-inline">, Group<f_Group>, Flags<[CC1Option]>,
+--- tools/clang/lib/Driver/ToolChains/Clang.cpp.orig 2017-09-14 19:36:28.212240000 +0100
++++ tools/clang/lib/Driver/ToolChains/Clang.cpp 2017-09-14 19:35:59.296165000 +0100
+@@ -3202,6 +3202,7 @@
+
+ // Forward -f (flag) options which we can pass directly.
+ Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls);
++ Args.AddLastArg(CmdArgs, options::OPT_fformat_extensions);
+ Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions);
+ Args.AddLastArg(CmdArgs, options::OPT_fno_operator_names);
+ // Emulated TLS is enabled by default on Android and OpenBSD, and can be enabled
+diff -ruN tools/clang/lib/Frontend/CompilerInvocation.cpp tools/clang/lib/Frontend/CompilerInvocation.cpp
+--- tools/clang/lib/Frontend/CompilerInvocation.cpp 2015-07-30 22:47:41 UTC
++++ tools/clang/lib/Frontend/CompilerInvocation.cpp
+@@ -1543,6 +1543,7 @@
+ Opts.ShortWChar = Args.hasFlag(OPT_fshort_wchar, OPT_fno_short_wchar, false);
+ Opts.ShortEnums = Args.hasArg(OPT_fshort_enums);
+ Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
++ Opts.FormatExtensions = Args.hasArg(OPT_fformat_extensions);
+ Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
+ Opts.NoMathBuiltin = Args.hasArg(OPT_fno_math_builtin);
+ Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
diff --git a/devel/llvm60/files/clang/patch-fopenmp.diff b/devel/llvm60/files/clang/patch-fopenmp.diff
new file mode 100644
index 000000000000..18932bd0d19c
--- /dev/null
+++ b/devel/llvm60/files/clang/patch-fopenmp.diff
@@ -0,0 +1,14 @@
+--- tools/clang/lib/Driver/ToolChains/CommonArgs.cpp.orig 2017-05-10 17:18:56.000000000 +0000
++++ tools/clang/lib/Driver/ToolChains/CommonArgs.cpp 2017-05-10 23:01:17.087686000 +0000
+@@ -441,7 +441,10 @@
+
+ switch (TC.getDriver().getOpenMPRuntime(Args)) {
+ case Driver::OMPRT_OMP:
+- CmdArgs.push_back("-lomp");
++ if (TC.getTriple().getOS() != llvm::Triple::FreeBSD || TC.isCrossCompiling() || !llvm::sys::fs::exists("%%LLVM_PREFIX%%/lib/libomp.so"))
++ CmdArgs.push_back("-lomp");
++ else
++ CmdArgs.push_back("%%LLVM_PREFIX%%/lib/libomp.so");
+ break;
+ case Driver::OMPRT_GOMP:
+ CmdArgs.push_back("-lgomp");
diff --git a/devel/llvm60/files/clang/patch-head-r331066.diff b/devel/llvm60/files/clang/patch-head-r331066.diff
new file mode 100644
index 000000000000..7296a087bfb0
--- /dev/null
+++ b/devel/llvm60/files/clang/patch-head-r331066.diff
@@ -0,0 +1,40 @@
+r331066 | dim | 2018-03-16 19:04:13 +0100 (Fri, 16 Mar 2018) | 19 lines
+
+Pull in r321999 from upstream clang trunk (by Ivan A. Kosarev):
+
+ [CodeGen] Fix TBAA info for accesses to members of base classes
+
+ Resolves:
+ Bug 35724 - regression (r315984): fatal error: error in backend:
+ Broken function found (Did not see access type in access path!)
+ https://bugs.llvm.org/show_bug.cgi?id=35724
+
+ Differential Revision: https://reviews.llvm.org/D41547
+
+This fixes "Did not see access type in access path" fatal errors when
+building the devel/gdb port (version 8.1).
+
+Reported by: jbeich
+PR: 226658
+MFC after: 3 months
+X-MFC-With: r327952
+
+Index: tools/clang/lib/CodeGen/CGExpr.cpp
+===================================================================
+--- tools/clang/lib/CodeGen/CGExpr.cpp (revision 331065)
++++ tools/clang/lib/CodeGen/CGExpr.cpp (revision 331066)
+@@ -1034,8 +1034,12 @@ Address CodeGenFunction::EmitPointerWithAlignment(
+ // Derived-to-base conversions.
+ case CK_UncheckedDerivedToBase:
+ case CK_DerivedToBase: {
+- Address Addr = EmitPointerWithAlignment(CE->getSubExpr(), BaseInfo,
+- TBAAInfo);
++ // TODO: Support accesses to members of base classes in TBAA. For now, we
++ // conservatively pretend that the complete object is of the base class
++ // type.
++ if (TBAAInfo)
++ *TBAAInfo = CGM.getTBAAAccessInfo(E->getType());
++ Address Addr = EmitPointerWithAlignment(CE->getSubExpr(), BaseInfo);
+ auto Derived = CE->getSubExpr()->getType()->getPointeeCXXRecordDecl();
+ return GetAddressOfBaseClass(Addr, Derived,
+ CE->path_begin(), CE->path_end(),
diff --git a/devel/llvm60/files/clang/patch-head-r336227.diff b/devel/llvm60/files/clang/patch-head-r336227.diff
new file mode 100644
index 000000000000..fd543dc38489
--- /dev/null
+++ b/devel/llvm60/files/clang/patch-head-r336227.diff
@@ -0,0 +1,42 @@
+r336227 | dim | 2018-07-12 21:02:59 +0200 (Thu, 12 Jul 2018) | 27 lines
+
+Pull in r336008 from upstream clang trunk:
+
+ Request init/fini array on FreeBSD 12 and later
+
+ Summary:
+
+ It seems a bad idea to change the default in the middle of a release
+ branch due to possible changes in global ctor / dtor ordering between
+ .ctors and .init_array. With FreeBSD 11.0's release imminent lets
+ change the default now for FreeBSD 12 (the current development
+ stream) and later.
+
+ FreeBSD rtld has supported .init_array / .fini_array for many years.
+ As of Jan 1 2017 all supported FreeBSD releases and branches will
+ have support.
+
+ Reviewers: dim, brooks, arichardson
+
+ Reviewed By: dim, brooks, arichardson
+
+ Subscribers: bsdjhb, krytarowski, emaste, cfe-commits
+
+ Differential Revision: https://reviews.llvm.org/D24867
+
+Requested by: jhb
+MFC after: 3 days
+
+Index: tools/clang/lib/Driver/ToolChains/Gnu.cpp
+===================================================================
+--- tools/clang/lib/Driver/ToolChains/Gnu.cpp (revision 336226)
++++ tools/clang/lib/Driver/ToolChains/Gnu.cpp (revision 336227)
+@@ -2375,6 +2375,8 @@ void Generic_ELF::addClangTargetOptions(const ArgL
+ bool UseInitArrayDefault =
+ getTriple().getArch() == llvm::Triple::aarch64 ||
+ getTriple().getArch() == llvm::Triple::aarch64_be ||
++ (getTriple().getOS() == llvm::Triple::FreeBSD &&
++ getTriple().getOSMajorVersion() >= 12) ||
+ (getTriple().getOS() == llvm::Triple::Linux &&
+ ((!GCCInstallation.isValid() || !V.isOlderThan(4, 7, 0)) ||
+ getTriple().isAndroid())) ||
diff --git a/devel/llvm60/files/clang/patch-head-r338697.diff b/devel/llvm60/files/clang/patch-head-r338697.diff
new file mode 100644
index 000000000000..eb7f11e83fcf
--- /dev/null
+++ b/devel/llvm60/files/clang/patch-head-r338697.diff
@@ -0,0 +1,104 @@
+r338697 | dim | 2018-09-15 23:22:50 +0200 (Sat, 15 Sep 2018) | 21 lines
+
+Pull in r325478 from upstream clang trunk (by Ivan A. Kosarev):
+
+ [CodeGen] Initialize large arrays by copying from a global
+
+ Currently, clang compiles explicit initializers for array elements
+ into series of store instructions. For large arrays of built-in types
+ this results in bloated output code and significant amount of time
+ spent on the instruction selection phase. This patch fixes the issue
+ by initializing such arrays with global constants that store the
+ binary image of the initializer.
+
+ Differential Revision: https://reviews.llvm.org/D43181
+
+This should fix a compiler hang (and excessive memory usage) while
+building the science/rmg port.
+
+Approved by: re (kib)
+Reported by: yuri@tsoft.com
+See also: https://bugs.llvm.org/show_bug.cgi?id=38798
+MFC after: 3 days
+
+Index: tools/clang/lib/CodeGen/CGExprAgg.cpp
+===================================================================
+--- tools/clang/lib/CodeGen/CGExprAgg.cpp (revision 338696)
++++ tools/clang/lib/CodeGen/CGExprAgg.cpp (revision 338697)
+@@ -14,6 +14,7 @@
+ #include "CodeGenFunction.h"
+ #include "CGObjCRuntime.h"
+ #include "CodeGenModule.h"
++#include "ConstantEmitter.h"
+ #include "clang/AST/ASTContext.h"
+ #include "clang/AST/DeclCXX.h"
+ #include "clang/AST/DeclTemplate.h"
+@@ -85,7 +86,7 @@ class AggExprEmitter : public StmtVisitor<AggExprE
+ void EmitMoveFromReturnSlot(const Expr *E, RValue Src);
+
+ void EmitArrayInit(Address DestPtr, llvm::ArrayType *AType,
+- QualType elementType, InitListExpr *E);
++ QualType ArrayQTy, InitListExpr *E);
+
+ AggValueSlot::NeedsGCBarriers_t needsGC(QualType T) {
+ if (CGF.getLangOpts().getGC() && TypeRequiresGCollection(T))
+@@ -392,12 +393,15 @@ static bool isTrivialFiller(Expr *E) {
+
+ /// \brief Emit initialization of an array from an initializer list.
+ void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType,
+- QualType elementType, InitListExpr *E) {
++ QualType ArrayQTy, InitListExpr *E) {
+ uint64_t NumInitElements = E->getNumInits();
+
+ uint64_t NumArrayElements = AType->getNumElements();
+ assert(NumInitElements <= NumArrayElements);
+
++ QualType elementType =
++ CGF.getContext().getAsArrayType(ArrayQTy)->getElementType();
++
+ // DestPtr is an array*. Construct an elementType* by drilling
+ // down a level.
+ llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0);
+@@ -409,6 +413,29 @@ void AggExprEmitter::EmitArrayInit(Address DestPtr
+ CharUnits elementAlign =
+ DestPtr.getAlignment().alignmentOfArrayElement(elementSize);
+
++ // Consider initializing the array by copying from a global. For this to be
++ // more efficient than per-element initialization, the size of the elements
++ // with explicit initializers should be large enough.
++ if (NumInitElements * elementSize.getQuantity() > 16 &&
++ elementType.isTriviallyCopyableType(CGF.getContext())) {
++ CodeGen::CodeGenModule &CGM = CGF.CGM;
++ ConstantEmitter Emitter(CGM);
++ LangAS AS = ArrayQTy.getAddressSpace();
++ if (llvm::Constant *C = Emitter.tryEmitForInitializer(E, AS, ArrayQTy)) {
++ auto GV = new llvm::GlobalVariable(
++ CGM.getModule(), C->getType(),
++ CGM.isTypeConstant(ArrayQTy, /* ExcludeCtorDtor= */ true),
++ llvm::GlobalValue::PrivateLinkage, C, "constinit",
++ /* InsertBefore= */ nullptr, llvm::GlobalVariable::NotThreadLocal,
++ CGM.getContext().getTargetAddressSpace(AS));
++ Emitter.finalize(GV);
++ CharUnits Align = CGM.getContext().getTypeAlignInChars(ArrayQTy);
++ GV->setAlignment(Align.getQuantity());
++ EmitFinalDestCopy(ArrayQTy, CGF.MakeAddrLValue(GV, ArrayQTy, Align));
++ return;
++ }
++ }
++
+ // Exception safety requires us to destroy all the
+ // already-constructed members if an initializer throws.
+ // For that, we'll need an EH cleanup.
+@@ -1156,11 +1183,8 @@ void AggExprEmitter::VisitInitListExpr(InitListExp
+
+ // Handle initialization of an array.
+ if (E->getType()->isArrayType()) {
+- QualType elementType =
+- CGF.getContext().getAsArrayType(E->getType())->getElementType();
+-
+ auto AType = cast<llvm::ArrayType>(Dest.getAddress().getElementType());
+- EmitArrayInit(Dest.getAddress(), AType, elementType, E);
++ EmitArrayInit(Dest.getAddress(), AType, E->getType(), E);
+ return;
+ }
+
diff --git a/devel/llvm60/files/clang/patch-head-r339019.diff b/devel/llvm60/files/clang/patch-head-r339019.diff
new file mode 100644
index 000000000000..240772d184c2
--- /dev/null
+++ b/devel/llvm60/files/clang/patch-head-r339019.diff
@@ -0,0 +1,30 @@
+r339019 | emaste | 2018-09-29 22:01:23 +0200 (Sat, 29 Sep 2018) | 15 lines
+
+clang: allow ifunc resolvers to accept arguments
+
+Previously Clang required ifunc resolution functions to take no
+arguments, presumably because GCC documented ifunc resolvers as taking
+no arguments. However, GCC accepts resolvers accepting arguments, and
+our rtld passes CPU ID information (cpuid, hwcap, etc.) to ifunc
+resolvers. Just remove the check from the in-tree compiler for our in-
+tree compiler; a different (per-OS) approach may be required upstream.
+
+Reported by: mjg
+Approved by: re (rgrimes)
+MFC after: 1 week
+Relnotes: Yes
+Sponsored by: The FreeBSD Foundation
+
+Index: tools/clang/lib/CodeGen/CodeGenModule.cpp
+===================================================================
+--- tools/clang/lib/CodeGen/CodeGenModule.cpp (revision 339018)
++++ tools/clang/lib/CodeGen/CodeGenModule.cpp (revision 339019)
+@@ -321,8 +321,6 @@ void CodeGenModule::checkAliases() {
+ assert(FTy);
+ if (!FTy->getReturnType()->isPointerTy())
+ Diags.Report(Location, diag::err_ifunc_resolver_return);
+- if (FTy->getNumParams())
+- Diags.Report(Location, diag::err_ifunc_resolver_params);
+ }
+
+ llvm::Constant *Aliasee = Alias->getIndirectSymbol();
diff --git a/devel/llvm60/files/clang/patch-stable12-r342281.diff b/devel/llvm60/files/clang/patch-stable12-r342281.diff
new file mode 100644
index 000000000000..4a6e9f615889
--- /dev/null
+++ b/devel/llvm60/files/clang/patch-stable12-r342281.diff
@@ -0,0 +1,834 @@
+r342281 | dim | 2018-12-20 19:28:53 +0100 (Thu, 20 Dec 2018) | 24 lines
+
+Pull in r329671 from upstream clang trunk (by Akira Hatanaka):
+
+ [ExprConstant] Use an AST node and a version number as a key to
+ create an APValue and retrieve it from map Temporaries.
+
+ The version number is needed when a single AST node is visited
+ multiple times and is used to create APValues that are required to be
+ distinct from each other (for example, MaterializeTemporaryExprs in
+ default arguments and VarDecls in loops).
+
+ rdar://problem/36505742
+
+ Differential Revision: https://reviews.llvm.org/D42776
+
+This should fix 'Assertion failed: (Result.isUninit() && "temporary
+created multiple times"), function createTemporary' errors (if
+assertions are enabled, otherwise the compiler internal state might go
+bad), when building the graphics/rawtherapee port.
+
+Direct commit to stable/11 and stable/12, since head already has clang
+7.0.1, which includes this change.
+
+PR: 234144
+
+Index: tools/clang/include/clang/AST/APValue.h
+===================================================================
+--- tools/clang/include/clang/AST/APValue.h (revision 342280)
++++ tools/clang/include/clang/AST/APValue.h (revision 342281)
+@@ -53,7 +53,58 @@ class APValue {
+ MemberPointer,
+ AddrLabelDiff
+ };
+- typedef llvm::PointerUnion<const ValueDecl *, const Expr *> LValueBase;
++
++ class LValueBase {
++ public:
++ typedef llvm::PointerUnion<const ValueDecl *, const Expr *> PtrTy;
++
++ LValueBase() : CallIndex(0), Version(0) {}
++
++ template <class T>
++ LValueBase(T P, unsigned I = 0, unsigned V = 0)
++ : Ptr(P), CallIndex(I), Version(V) {}
++
++ template <class T>
++ bool is() const { return Ptr.is<T>(); }
++
++ template <class T>
++ T get() const { return Ptr.get<T>(); }
++
++ template <class T>
++ T dyn_cast() const { return Ptr.dyn_cast<T>(); }
++
++ void *getOpaqueValue() const;
++
++ bool isNull() const;
++
++ explicit operator bool () const;
++
++ PtrTy getPointer() const {
++ return Ptr;
++ }
++
++ unsigned getCallIndex() const {
++ return CallIndex;
++ }
++
++ void setCallIndex(unsigned Index) {
++ CallIndex = Index;
++ }
++
++ unsigned getVersion() const {
++ return Version;
++ }
++
++ bool operator==(const LValueBase &Other) const {
++ return Ptr == Other.Ptr && CallIndex == Other.CallIndex &&
++ Version == Other.Version;
++ }
++
++ private:
++ PtrTy Ptr;
++ unsigned CallIndex, Version;
++ };
++
+ typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType;
+ union LValuePathEntry {
+ /// BaseOrMember - The FieldDecl or CXXRecordDecl indicating the next item
+@@ -135,15 +186,15 @@ class APValue {
+ }
+ APValue(const APValue &RHS);
+ APValue(APValue &&RHS) : Kind(Uninitialized) { swap(RHS); }
+- APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex,
++ APValue(LValueBase B, const CharUnits &O, NoLValuePath N,
+ bool IsNullPtr = false)
+ : Kind(Uninitialized) {
+- MakeLValue(); setLValue(B, O, N, CallIndex, IsNullPtr);
++ MakeLValue(); setLValue(B, O, N, IsNullPtr);
+ }
+ APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path,
+- bool OnePastTheEnd, unsigned CallIndex, bool IsNullPtr = false)
++ bool OnePastTheEnd, bool IsNullPtr = false)
+ : Kind(Uninitialized) {
+- MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, CallIndex, IsNullPtr);
++ MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, IsNullPtr);
+ }
+ APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(Uninitialized) {
+ MakeArray(InitElts, Size);
+@@ -255,6 +306,7 @@ class APValue {
+ bool hasLValuePath() const;
+ ArrayRef<LValuePathEntry> getLValuePath() const;
+ unsigned getLValueCallIndex() const;
++ unsigned getLValueVersion() const;
+ bool isNullPointer() const;
+
+ APValue &getVectorElt(unsigned I) {
+@@ -376,10 +428,10 @@ class APValue {
+ ((ComplexAPFloat *)(char *)Data.buffer)->Imag = std::move(I);
+ }
+ void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
+- unsigned CallIndex, bool IsNullPtr);
++ bool IsNullPtr);
+ void setLValue(LValueBase B, const CharUnits &O,
+ ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
+- unsigned CallIndex, bool IsNullPtr);
++ bool IsNullPtr);
+ void setUnion(const FieldDecl *Field, const APValue &Value) {
+ assert(isUnion() && "Invalid accessor");
+ ((UnionData*)(char*)Data.buffer)->Field = Field;
+@@ -451,4 +503,14 @@ class APValue {
+
+ } // end namespace clang.
+
++namespace llvm {
++template<> struct DenseMapInfo<clang::APValue::LValueBase> {
++ static clang::APValue::LValueBase getEmptyKey();
++ static clang::APValue::LValueBase getTombstoneKey();
++ static unsigned getHashValue(const clang::APValue::LValueBase &Base);
++ static bool isEqual(const clang::APValue::LValueBase &LHS,
++ const clang::APValue::LValueBase &RHS);
++};
++}
++
+ #endif
+Index: tools/clang/lib/AST/APValue.cpp
+===================================================================
+--- tools/clang/lib/AST/APValue.cpp (revision 342280)
++++ tools/clang/lib/AST/APValue.cpp (revision 342281)
+@@ -23,14 +23,57 @@ using namespace clang;
+
+ namespace {
+ struct LVBase {
+- llvm::PointerIntPair<APValue::LValueBase, 1, bool> BaseAndIsOnePastTheEnd;
++ APValue::LValueBase Base;
+ CharUnits Offset;
+ unsigned PathLength;
+- unsigned CallIndex;
+- bool IsNullPtr;
++ bool IsNullPtr : 1;
++ bool IsOnePastTheEnd : 1;
+ };
+ }
+
++void *APValue::LValueBase::getOpaqueValue() const {
++ return Ptr.getOpaqueValue();
++}
++
++bool APValue::LValueBase::isNull() const {
++ return Ptr.isNull();
++}
++
++APValue::LValueBase::operator bool () const {
++ return static_cast<bool>(Ptr);
++}
++
++clang::APValue::LValueBase
++llvm::DenseMapInfo<clang::APValue::LValueBase>::getEmptyKey() {
++ return clang::APValue::LValueBase(
++ DenseMapInfo<clang::APValue::LValueBase::PtrTy>::getEmptyKey(),
++ DenseMapInfo<unsigned>::getEmptyKey(),
++ DenseMapInfo<unsigned>::getEmptyKey());
++}
++
++clang::APValue::LValueBase
++llvm::DenseMapInfo<clang::APValue::LValueBase>::getTombstoneKey() {
++ return clang::APValue::LValueBase(
++ DenseMapInfo<clang::APValue::LValueBase::PtrTy>::getTombstoneKey(),
++ DenseMapInfo<unsigned>::getTombstoneKey(),
++ DenseMapInfo<unsigned>::getTombstoneKey());
++}
++
++unsigned llvm::DenseMapInfo<clang::APValue::LValueBase>::getHashValue(
++ const clang::APValue::LValueBase &Base) {
++ llvm::FoldingSetNodeID ID;
++ ID.AddPointer(Base.getOpaqueValue());
++ ID.AddInteger(Base.getCallIndex());
++ ID.AddInteger(Base.getVersion());
++ return ID.ComputeHash();
++}
++
++bool llvm::DenseMapInfo<clang::APValue::LValueBase>::isEqual(
++ const clang::APValue::LValueBase &LHS,
++ const clang::APValue::LValueBase &RHS) {
++ return LHS == RHS;
++}
++
+ struct APValue::LV : LVBase {
+ static const unsigned InlinePathSpace =
+ (DataSize - sizeof(LVBase)) / sizeof(LValuePathEntry);
+@@ -150,11 +193,10 @@ APValue::APValue(const APValue &RHS) : Kind(Uninit
+ MakeLValue();
+ if (RHS.hasLValuePath())
+ setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), RHS.getLValuePath(),
+- RHS.isLValueOnePastTheEnd(), RHS.getLValueCallIndex(),
+- RHS.isNullPointer());
++ RHS.isLValueOnePastTheEnd(), RHS.isNullPointer());
+ else
+ setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), NoLValuePath(),
+- RHS.getLValueCallIndex(), RHS.isNullPointer());
++ RHS.isNullPointer());
+ break;
+ case Array:
+ MakeArray(RHS.getArrayInitializedElts(), RHS.getArraySize());
+@@ -552,12 +594,12 @@ std::string APValue::getAsString(ASTContext &Ctx,
+
+ const APValue::LValueBase APValue::getLValueBase() const {
+ assert(isLValue() && "Invalid accessor");
+- return ((const LV*)(const void*)Data.buffer)->BaseAndIsOnePastTheEnd.getPointer();
++ return ((const LV*)(const void*)Data.buffer)->Base;
+ }
+
+ bool APValue::isLValueOnePastTheEnd() const {
+ assert(isLValue() && "Invalid accessor");
+- return ((const LV*)(const void*)Data.buffer)->BaseAndIsOnePastTheEnd.getInt();
++ return ((const LV*)(const void*)Data.buffer)->IsOnePastTheEnd;
+ }
+
+ CharUnits &APValue::getLValueOffset() {
+@@ -578,9 +620,14 @@ ArrayRef<APValue::LValuePathEntry> APValue::getLVa
+
+ unsigned APValue::getLValueCallIndex() const {
+ assert(isLValue() && "Invalid accessor");
+- return ((const LV*)(const char*)Data.buffer)->CallIndex;
++ return ((const LV*)(const char*)Data.buffer)->Base.getCallIndex();
+ }
+
++unsigned APValue::getLValueVersion() const {
++ assert(isLValue() && "Invalid accessor");
++ return ((const LV*)(const char*)Data.buffer)->Base.getVersion();
++}
++
+ bool APValue::isNullPointer() const {
+ assert(isLValue() && "Invalid usage");
+ return ((const LV*)(const char*)Data.buffer)->IsNullPtr;
+@@ -587,13 +634,12 @@ bool APValue::isNullPointer() const {
+ }
+
+ void APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
+- unsigned CallIndex, bool IsNullPtr) {
++ bool IsNullPtr) {
+ assert(isLValue() && "Invalid accessor");
+ LV &LVal = *((LV*)(char*)Data.buffer);
+- LVal.BaseAndIsOnePastTheEnd.setPointer(B);
+- LVal.BaseAndIsOnePastTheEnd.setInt(false);
++ LVal.Base = B;
++ LVal.IsOnePastTheEnd = false;
+ LVal.Offset = O;
+- LVal.CallIndex = CallIndex;
+ LVal.resizePath((unsigned)-1);
+ LVal.IsNullPtr = IsNullPtr;
+ }
+@@ -600,13 +646,12 @@ void APValue::setLValue(LValueBase B, const CharUn
+
+ void APValue::setLValue(LValueBase B, const CharUnits &O,
+ ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd,
+- unsigned CallIndex, bool IsNullPtr) {
++ bool IsNullPtr) {
+ assert(isLValue() && "Invalid accessor");
+ LV &LVal = *((LV*)(char*)Data.buffer);
+- LVal.BaseAndIsOnePastTheEnd.setPointer(B);
+- LVal.BaseAndIsOnePastTheEnd.setInt(IsOnePastTheEnd);
++ LVal.Base = B;
++ LVal.IsOnePastTheEnd = IsOnePastTheEnd;
+ LVal.Offset = O;
+- LVal.CallIndex = CallIndex;
+ LVal.resizePath(Path.size());
+ memcpy(LVal.getPath(), Path.data(), Path.size() * sizeof(LValuePathEntry));
+ LVal.IsNullPtr = IsNullPtr;
+Index: tools/clang/lib/AST/ExprConstant.cpp
+===================================================================
+--- tools/clang/lib/AST/ExprConstant.cpp (revision 342280)
++++ tools/clang/lib/AST/ExprConstant.cpp (revision 342281)
+@@ -446,8 +446,8 @@ namespace {
+
+ // Note that we intentionally use std::map here so that references to
+ // values are stable.
+- typedef std::map<const void*, APValue> MapTy;
+- typedef MapTy::const_iterator temp_iterator;
++ typedef std::pair<const void *, unsigned> MapKeyTy;
++ typedef std::map<MapKeyTy, APValue> MapTy;
+ /// Temporaries - Temporary lvalues materialized within this stack frame.
+ MapTy Temporaries;
+
+@@ -457,6 +457,20 @@ namespace {
+ /// Index - The call index of this call.
+ unsigned Index;
+
++ /// The stack of integers for tracking version numbers for temporaries.
++ SmallVector<unsigned, 2> TempVersionStack = {1};
++ unsigned CurTempVersion = TempVersionStack.back();
++
++ unsigned getTempVersion() const { return TempVersionStack.back(); }
++
++ void pushTempVersion() {
++ TempVersionStack.push_back(++CurTempVersion);
++ }
++
++ void popTempVersion() {
++ TempVersionStack.pop_back();
++ }
++
+ // FIXME: Adding this to every 'CallStackFrame' may have a nontrivial impact
+ // on the overall stack usage of deeply-recursing constexpr evaluataions.
+ // (We should cache this map rather than recomputing it repeatedly.)
+@@ -473,10 +487,36 @@ namespace {
+ APValue *Arguments);
+ ~CallStackFrame();
+
+- APValue *getTemporary(const void *Key) {
+- MapTy::iterator I = Temporaries.find(Key);
+- return I == Temporaries.end() ? nullptr : &I->second;
++ // Return the temporary for Key whose version number is Version.
++ APValue *getTemporary(const void *Key, unsigned Version) {
++ MapKeyTy KV(Key, Version);
++ auto LB = Temporaries.lower_bound(KV);
++ if (LB != Temporaries.end() && LB->first == KV)
++ return &LB->second;
++ // Pair (Key,Version) wasn't found in the map. Check that no elements
++ // in the map have 'Key' as their key.
++ assert((LB == Temporaries.end() || LB->first.first != Key) &&
++ (LB == Temporaries.begin() || std::prev(LB)->first.first != Key) &&
++ "Element with key 'Key' found in map");
++ return nullptr;
+ }
++
++ // Return the current temporary for Key in the map.
++ APValue *getCurrentTemporary(const void *Key) {
++ auto UB = Temporaries.upper_bound(MapKeyTy(Key, UINT_MAX));
++ if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
++ return &std::prev(UB)->second;
++ return nullptr;
++ }
++
++ // Return the version number of the current temporary for Key.
++ unsigned getCurrentTemporaryVersion(const void *Key) const {
++ auto UB = Temporaries.upper_bound(MapKeyTy(Key, UINT_MAX));
++ if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
++ return std::prev(UB)->first.second;
++ return 0;
++ }
++
+ APValue &createTemporary(const void *Key, bool IsLifetimeExtended);
+ };
+
+@@ -606,7 +646,8 @@ namespace {
+
+ /// EvaluatingObject - Pair of the AST node that an lvalue represents and
+ /// the call index that that lvalue was allocated in.
+- typedef std::pair<APValue::LValueBase, unsigned> EvaluatingObject;
++ typedef std::pair<APValue::LValueBase, std::pair<unsigned, unsigned>>
++ EvaluatingObject;
+
+ /// EvaluatingConstructors - Set of objects that are currently being
+ /// constructed.
+@@ -625,8 +666,10 @@ namespace {
+ }
+ };
+
+- bool isEvaluatingConstructor(APValue::LValueBase Decl, unsigned CallIndex) {
+- return EvaluatingConstructors.count(EvaluatingObject(Decl, CallIndex));
++ bool isEvaluatingConstructor(APValue::LValueBase Decl, unsigned CallIndex,
++ unsigned Version) {
++ return EvaluatingConstructors.count(
++ EvaluatingObject(Decl, {CallIndex, Version}));
+ }
+
+ /// The current array initialization index, if we're performing array
+@@ -722,7 +765,7 @@ namespace {
+ void setEvaluatingDecl(APValue::LValueBase Base, APValue &Value) {
+ EvaluatingDecl = Base;
+ EvaluatingDeclValue = &Value;
+- EvaluatingConstructors.insert({Base, 0});
++ EvaluatingConstructors.insert({Base, {0, 0}});
+ }
+
+ const LangOptions &getLangOpts() const { return Ctx.getLangOpts(); }
+@@ -1086,11 +1129,16 @@ namespace {
+ unsigned OldStackSize;
+ public:
+ ScopeRAII(EvalInfo &Info)
+- : Info(Info), OldStackSize(Info.CleanupStack.size()) {}
++ : Info(Info), OldStackSize(Info.CleanupStack.size()) {
++ // Push a new temporary version. This is needed to distinguish between
++ // temporaries created in different iterations of a loop.
++ Info.CurrentCall->pushTempVersion();
++ }
+ ~ScopeRAII() {
+ // Body moved to a static method to encourage the compiler to inline away
+ // instances of this class.
+ cleanup(Info, OldStackSize);
++ Info.CurrentCall->popTempVersion();
+ }
+ private:
+ static void cleanup(EvalInfo &Info, unsigned OldStackSize) {
+@@ -1170,7 +1218,8 @@ CallStackFrame::~CallStackFrame() {
+
+ APValue &CallStackFrame::createTemporary(const void *Key,
+ bool IsLifetimeExtended) {
+- APValue &Result = Temporaries[Key];
++ unsigned Version = Info.CurrentCall->getTempVersion();
++ APValue &Result = Temporaries[MapKeyTy(Key, Version)];
+ assert(Result.isUninit() && "temporary created multiple times");
+ Info.CleanupStack.push_back(Cleanup(&Result, IsLifetimeExtended));
+ return Result;
+@@ -1262,27 +1311,27 @@ namespace {
+ struct LValue {
+ APValue::LValueBase Base;
+ CharUnits Offset;
+- unsigned InvalidBase : 1;
+- unsigned CallIndex : 31;
+ SubobjectDesignator Designator;
+- bool IsNullPtr;
++ bool IsNullPtr : 1;
++ bool InvalidBase : 1;
+
+ const APValue::LValueBase getLValueBase() const { return Base; }
+ CharUnits &getLValueOffset() { return Offset; }
+ const CharUnits &getLValueOffset() const { return Offset; }
+- unsigned getLValueCallIndex() const { return CallIndex; }
+ SubobjectDesignator &getLValueDesignator() { return Designator; }
+ const SubobjectDesignator &getLValueDesignator() const { return Designator;}
+ bool isNullPointer() const { return IsNullPtr;}
+
++ unsigned getLValueCallIndex() const { return Base.getCallIndex(); }
++ unsigned getLValueVersion() const { return Base.getVersion(); }
++
+ void moveInto(APValue &V) const {
+ if (Designator.Invalid)
+- V = APValue(Base, Offset, APValue::NoLValuePath(), CallIndex,
+- IsNullPtr);
++ V = APValue(Base, Offset, APValue::NoLValuePath(), IsNullPtr);
+ else {
+ assert(!InvalidBase && "APValues can't handle invalid LValue bases");
+ V = APValue(Base, Offset, Designator.Entries,
+- Designator.IsOnePastTheEnd, CallIndex, IsNullPtr);
++ Designator.IsOnePastTheEnd, IsNullPtr);
+ }
+ }
+ void setFrom(ASTContext &Ctx, const APValue &V) {
+@@ -1290,12 +1339,11 @@ namespace {
+ Base = V.getLValueBase();
+ Offset = V.getLValueOffset();
+ InvalidBase = false;
+- CallIndex = V.getLValueCallIndex();
+ Designator = SubobjectDesignator(Ctx, V);
+ IsNullPtr = V.isNullPointer();
+ }
+
+- void set(APValue::LValueBase B, unsigned I = 0, bool BInvalid = false) {
++ void set(APValue::LValueBase B, bool BInvalid = false) {
+ #ifndef NDEBUG
+ // We only allow a few types of invalid bases. Enforce that here.
+ if (BInvalid) {
+@@ -1308,7 +1356,6 @@ namespace {
+ Base = B;
+ Offset = CharUnits::fromQuantity(0);
+ InvalidBase = BInvalid;
+- CallIndex = I;
+ Designator = SubobjectDesignator(getType(B));
+ IsNullPtr = false;
+ }
+@@ -1317,13 +1364,12 @@ namespace {
+ Base = (Expr *)nullptr;
+ Offset = CharUnits::fromQuantity(TargetVal);
+ InvalidBase = false;
+- CallIndex = 0;
+ Designator = SubobjectDesignator(PointerTy->getPointeeType());
+ IsNullPtr = true;
+ }
+
+ void setInvalid(APValue::LValueBase B, unsigned I = 0) {
+- set(B, I, true);
++ set(B, true);
+ }
+
+ // Check that this LValue is not based on a null pointer. If it is, produce
+@@ -1525,6 +1571,15 @@ static bool EvaluateAsRValue(EvalInfo &Info, const
+ // Misc utilities
+ //===----------------------------------------------------------------------===//
+
++/// A helper function to create a temporary and set an LValue.
++template <class KeyTy>
++static APValue &createTemporary(const KeyTy *Key, bool IsLifetimeExtended,
++ LValue &LV, CallStackFrame &Frame) {
++ LV.set({Key, Frame.Info.CurrentCall->Index,
++ Frame.Info.CurrentCall->getTempVersion()});
++ return Frame.createTemporary(Key, IsLifetimeExtended);
++}
++
+ /// Negate an APSInt in place, converting it to a signed form if necessary, and
+ /// preserving its value (by extending by up to one bit as needed).
+ static void negateAsSigned(APSInt &Int) {
+@@ -1854,7 +1909,7 @@ static const ValueDecl *GetLValueBaseDecl(const LV
+ }
+
+ static bool IsLiteralLValue(const LValue &Value) {
+- if (Value.CallIndex)
++ if (Value.getLValueCallIndex())
+ return false;
+ const Expr *E = Value.Base.dyn_cast<const Expr*>();
+ return E && !isa<MaterializeTemporaryExpr>(E);
+@@ -2404,7 +2459,7 @@ static bool handleLValueToRValueConversion(EvalInf
+ /// \param Result Filled in with a pointer to the value of the variable.
+ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E,
+ const VarDecl *VD, CallStackFrame *Frame,
+- APValue *&Result) {
++ APValue *&Result, const LValue *LVal) {
+
+ // If this is a parameter to an active constexpr function call, perform
+ // argument substitution.
+@@ -2423,7 +2478,8 @@ static bool evaluateVarDeclInit(EvalInfo &Info, co
+
+ // If this is a local variable, dig out its value.
+ if (Frame) {
+- Result = Frame->getTemporary(VD);
++ Result = LVal ? Frame->getTemporary(VD, LVal->getLValueVersion())
++ : Frame->getCurrentTemporary(VD);
+ if (!Result) {
+ // Assume variables referenced within a lambda's call operator that were
+ // not declared within the call operator are captures and during checking
+@@ -3000,8 +3056,8 @@ static CompleteObject findCompleteObject(EvalInfo
+ }
+
+ CallStackFrame *Frame = nullptr;
+- if (LVal.CallIndex) {
+- Frame = Info.getCallFrame(LVal.CallIndex);
++ if (LVal.getLValueCallIndex()) {
++ Frame = Info.getCallFrame(LVal.getLValueCallIndex());
+ if (!Frame) {
+ Info.FFDiag(E, diag::note_constexpr_lifetime_ended, 1)
+ << AK << LVal.Base.is<const ValueDecl*>();
+@@ -3113,7 +3169,7 @@ static CompleteObject findCompleteObject(EvalInfo
+ }
+ }
+
+- if (!evaluateVarDeclInit(Info, E, VD, Frame, BaseVal))
++ if (!evaluateVarDeclInit(Info, E, VD, Frame, BaseVal, &LVal))
+ return CompleteObject();
+ } else {
+ const Expr *Base = LVal.Base.dyn_cast<const Expr*>();
+@@ -3155,7 +3211,7 @@ static CompleteObject findCompleteObject(EvalInfo
+ return CompleteObject();
+ }
+ } else {
+- BaseVal = Frame->getTemporary(Base);
++ BaseVal = Frame->getTemporary(Base, LVal.Base.getVersion());
+ assert(BaseVal && "missing value for temporary");
+ }
+
+@@ -3175,7 +3231,9 @@ static CompleteObject findCompleteObject(EvalInfo
+ // During the construction of an object, it is not yet 'const'.
+ // FIXME: This doesn't do quite the right thing for const subobjects of the
+ // object under construction.
+- if (Info.isEvaluatingConstructor(LVal.getLValueBase(), LVal.CallIndex)) {
++ if (Info.isEvaluatingConstructor(LVal.getLValueBase(),
++ LVal.getLValueCallIndex(),
++ LVal.getLValueVersion())) {
+ BaseType = Info.Ctx.getCanonicalType(BaseType);
+ BaseType.removeLocalConst();
+ }
+@@ -3212,7 +3270,7 @@ static bool handleLValueToRValueConversion(EvalInf
+
+ // Check for special cases where there is no existing APValue to look at.
+ const Expr *Base = LVal.Base.dyn_cast<const Expr*>();
+- if (Base && !LVal.CallIndex && !Type.isVolatileQualified()) {
++ if (Base && !LVal.getLValueCallIndex() && !Type.isVolatileQualified()) {
+ if (const CompoundLiteralExpr *CLE = dyn_cast<CompoundLiteralExpr>(Base)) {
+ // In C99, a CompoundLiteralExpr is an lvalue, and we defer evaluating the
+ // initializer until now for such expressions. Such an expression can't be
+@@ -3715,8 +3773,7 @@ static bool EvaluateVarDecl(EvalInfo &Info, const
+ return true;
+
+ LValue Result;
+- Result.set(VD, Info.CurrentCall->Index);
+- APValue &Val = Info.CurrentCall->createTemporary(VD, true);
++ APValue &Val = createTemporary(VD, true, Result, *Info.CurrentCall);
+
+ const Expr *InitE = VD->getInit();
+ if (!InitE) {
+@@ -3772,6 +3829,19 @@ struct StmtResult {
+ /// The location containing the result, if any (used to support RVO).
+ const LValue *Slot;
+ };
++
++struct TempVersionRAII {
++ CallStackFrame &Frame;
++
++ TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
++ Frame.pushTempVersion();
++ }
++
++ ~TempVersionRAII() {
++ Frame.popTempVersion();
++ }
++};
++
+ }
+
+ static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info,
+@@ -4329,7 +4399,8 @@ static bool HandleConstructorCall(const Expr *E, c
+ }
+
+ EvalInfo::EvaluatingConstructorRAII EvalObj(
+- Info, {This.getLValueBase(), This.CallIndex});
++ Info, {This.getLValueBase(),
++ {This.getLValueCallIndex(), This.getLValueVersion()}});
+ CallStackFrame Frame(Info, CallLoc, Definition, &This, ArgValues);
+
+ // FIXME: Creating an APValue just to hold a nonexistent return value is
+@@ -4578,9 +4649,12 @@ class ExprEvaluatorBase
+ { return StmtVisitorTy::Visit(E->getResultExpr()); }
+ bool VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E)
+ { return StmtVisitorTy::Visit(E->getReplacement()); }
+- bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E)
+- { return StmtVisitorTy::Visit(E->getExpr()); }
++ bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) {
++ TempVersionRAII RAII(*Info.CurrentCall);
++ return StmtVisitorTy::Visit(E->getExpr());
++ }
+ bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E) {
++ TempVersionRAII RAII(*Info.CurrentCall);
+ // The initializer may not have been parsed yet, or might be erroneous.
+ if (!E->getExpr())
+ return Error(E);
+@@ -4658,7 +4732,7 @@ class ExprEvaluatorBase
+ }
+
+ bool VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
+- if (APValue *Value = Info.CurrentCall->getTemporary(E))
++ if (APValue *Value = Info.CurrentCall->getCurrentTemporary(E))
+ return DerivedSuccess(*Value, E);
+
+ const Expr *Source = E->getSourceExpr();
+@@ -5216,7 +5290,8 @@ bool LValueExprEvaluator::VisitVarDecl(const Expr
+
+ if (!VD->getType()->isReferenceType()) {
+ if (Frame) {
+- Result.set(VD, Frame->Index);
++ Result.set({VD, Frame->Index,
++ Info.CurrentCall->getCurrentTemporaryVersion(VD)});
+ return true;
+ }
+ return Success(VD);
+@@ -5223,7 +5298,7 @@ bool LValueExprEvaluator::VisitVarDecl(const Expr
+ }
+
+ APValue *V;
+- if (!evaluateVarDeclInit(Info, E, VD, Frame, V))
++ if (!evaluateVarDeclInit(Info, E, VD, Frame, V, nullptr))
+ return false;
+ if (V->isUninit()) {
+ if (!Info.checkingPotentialConstantExpression())
+@@ -5255,9 +5330,8 @@ bool LValueExprEvaluator::VisitMaterializeTemporar
+ *Value = APValue();
+ Result.set(E);
+ } else {
+- Value = &Info.CurrentCall->
+- createTemporary(E, E->getStorageDuration() == SD_Automatic);
+- Result.set(E, Info.CurrentCall->Index);
++ Value = &createTemporary(E, E->getStorageDuration() == SD_Automatic, Result,
++ *Info.CurrentCall);
+ }
+
+ QualType Type = Inner->getType();
+@@ -5736,7 +5810,6 @@ bool PointerExprEvaluator::VisitCastExpr(const Cas
+ Result.Base = (Expr*)nullptr;
+ Result.InvalidBase = false;
+ Result.Offset = CharUnits::fromQuantity(N);
+- Result.CallIndex = 0;
+ Result.Designator.setInvalid();
+ Result.IsNullPtr = false;
+ return true;
+@@ -5752,9 +5825,9 @@ bool PointerExprEvaluator::VisitCastExpr(const Cas
+ if (!evaluateLValue(SubExpr, Result))
+ return false;
+ } else {
+- Result.set(SubExpr, Info.CurrentCall->Index);
+- if (!EvaluateInPlace(Info.CurrentCall->createTemporary(SubExpr, false),
+- Info, Result, SubExpr))
++ APValue &Value = createTemporary(SubExpr, false, Result,
++ *Info.CurrentCall);
++ if (!EvaluateInPlace(Value, Info, Result, SubExpr))
+ return false;
+ }
+ // The result is a pointer to the first element of the array.
+@@ -6520,9 +6593,8 @@ class TemporaryExprEvaluator
+
+ /// Visit an expression which constructs the value of this temporary.
+ bool VisitConstructExpr(const Expr *E) {
+- Result.set(E, Info.CurrentCall->Index);
+- return EvaluateInPlace(Info.CurrentCall->createTemporary(E, false),
+- Info, Result, E);
++ APValue &Value = createTemporary(E, false, Result, *Info.CurrentCall);
++ return EvaluateInPlace(Value, Info, Result, E);
+ }
+
+ bool VisitCastExpr(const CastExpr *E) {
+@@ -8007,7 +8079,8 @@ static bool HasSameBase(const LValue &A, const LVa
+ }
+
+ return IsGlobalLValue(A.getLValueBase()) ||
+- A.getLValueCallIndex() == B.getLValueCallIndex();
++ (A.getLValueCallIndex() == B.getLValueCallIndex() &&
++ A.getLValueVersion() == B.getLValueVersion());
+ }
+
+ /// \brief Determine whether this is a pointer past the end of the complete
+@@ -9941,15 +10014,13 @@ static bool Evaluate(APValue &Result, EvalInfo &In
+ return true;
+ } else if (T->isArrayType()) {
+ LValue LV;
+- LV.set(E, Info.CurrentCall->Index);
+- APValue &Value = Info.CurrentCall->createTemporary(E, false);
++ APValue &Value = createTemporary(E, false, LV, *Info.CurrentCall);
+ if (!EvaluateArray(E, LV, Value, Info))
+ return false;
+ Result = Value;
+ } else if (T->isRecordType()) {
+ LValue LV;
+- LV.set(E, Info.CurrentCall->Index);
+- APValue &Value = Info.CurrentCall->createTemporary(E, false);
++ APValue &Value = createTemporary(E, false, LV, *Info.CurrentCall);
+ if (!EvaluateRecord(E, LV, Value, Info))
+ return false;
+ Result = Value;
+@@ -9963,8 +10034,7 @@ static bool Evaluate(APValue &Result, EvalInfo &In
+ QualType Unqual = T.getAtomicUnqualifiedType();
+ if (Unqual->isArrayType() || Unqual->isRecordType()) {
+ LValue LV;
+- LV.set(E, Info.CurrentCall->Index);
+- APValue &Value = Info.CurrentCall->createTemporary(E, false);
++ APValue &Value = createTemporary(E, false, LV, *Info.CurrentCall);
+ if (!EvaluateAtomic(E, &LV, Value, Info))
+ return false;
+ } else {
+@@ -10786,7 +10856,7 @@ bool Expr::isPotentialConstantExpr(const FunctionD
+ // is a temporary being used as the 'this' pointer.
+ LValue This;
+ ImplicitValueInitExpr VIE(RD ? Info.Ctx.getRecordType(RD) : Info.Ctx.IntTy);
+- This.set(&VIE, Info.CurrentCall->Index);
++ This.set({&VIE, Info.CurrentCall->Index});
+
+ ArrayRef<const Expr*> Args;
+
+Index: tools/clang/test/SemaCXX/constant-expression-cxx1y.cpp
+===================================================================
+--- tools/clang/test/SemaCXX/constant-expression-cxx1y.cpp (revision 342280)
++++ tools/clang/test/SemaCXX/constant-expression-cxx1y.cpp (revision 342281)
+@@ -852,7 +852,6 @@ namespace Lifetime {
+ static_assert(h(2) == 0, ""); // expected-error {{constant expression}} expected-note {{in call}}
+ static_assert(h(3) == 0, ""); // expected-error {{constant expression}} expected-note {{in call}}
+
+- // FIXME: This function should be treated as non-constant.
+ constexpr void lifetime_versus_loops() {
+ int *p = 0;
+ for (int i = 0; i != 2; ++i) {
+@@ -862,10 +861,10 @@ namespace Lifetime {
+ if (i)
+ // This modifies the 'n' from the previous iteration of the loop outside
+ // its lifetime.
+- ++*q;
++ ++*q; // expected-note {{increment of object outside its lifetime}}
+ }
+ }
+- static_assert((lifetime_versus_loops(), true), "");
++ static_assert((lifetime_versus_loops(), true), ""); // expected-error {{constant expression}} expected-note {{in call}}
+ }
+
+ namespace Bitfields {
+Index: tools/clang/test/SemaCXX/constexpr-default-arg.cpp
+===================================================================
+--- tools/clang/test/SemaCXX/constexpr-default-arg.cpp (nonexistent)
++++ tools/clang/test/SemaCXX/constexpr-default-arg.cpp (revision 342281)
+@@ -0,0 +1,38 @@
++// RUN: %clang_cc1 -std=c++1y -S -o - -emit-llvm -verify %s
++
++namespace default_arg_temporary {
++
++constexpr bool equals(const float& arg = 1.0f) {
++ return arg == 1.0f;
++}
++
++constexpr const int &x(const int &p = 0) {
++ return p;
++}
++
++struct S {
++ constexpr S(const int &a = 0) {}
++};
++
++void test_default_arg2() {
++ // This piece of code used to cause an assertion failure in
++ // CallStackFrame::createTemporary because the same MTE is used to initilize
++ // both elements of the array (see PR33140).
++ constexpr S s[2] = {};
++
++ // This piece of code used to cause an assertion failure in
++ // CallStackFrame::createTemporary because multiple CXXDefaultArgExpr share
++ // the same MTE (see PR33140).
++ static_assert(equals() && equals(), "");
++
++ // Test that constant expression evaluation produces distinct lvalues for
++ // each call.
++ static_assert(&x() != &x(), "");
++}
++
++// Check that multiple CXXDefaultInitExprs don't cause an assertion failure.
++struct A { int &&r = 0; }; // expected-warning {{binding reference member}} // expected-note {{reference member declared here}}
++struct B { A x, y; };
++B b = {};
++
++}
diff --git a/devel/llvm60/files/clang/patch-tools_clang_lib_Headers_CMakeLists.txt b/devel/llvm60/files/clang/patch-tools_clang_lib_Headers_CMakeLists.txt
new file mode 100644
index 000000000000..17043c6072cf
--- /dev/null
+++ b/devel/llvm60/files/clang/patch-tools_clang_lib_Headers_CMakeLists.txt
@@ -0,0 +1,32 @@
+--- tools/clang/lib/Headers/CMakeLists.txt.orig
++++ tools/clang/lib/Headers/CMakeLists.txt
+@@ -56,7 +56,6 @@
+ intrin.h
+ inttypes.h
+ iso646.h
+- limits.h
+ lwpintrin.h
+ lzcntintrin.h
+ mm3dnow.h
+@@ -76,21 +75,13 @@
+ s390intrin.h
+ shaintrin.h
+ smmintrin.h
+- stdalign.h
+- stdarg.h
+- stdatomic.h
+- stdbool.h
+- stddef.h
+ __stddef_max_align_t.h
+- stdint.h
+- stdnoreturn.h
+ tbmintrin.h
+ tgmath.h
+ tmmintrin.h
+ unwind.h
+ vadefs.h
+ vaesintrin.h
+- varargs.h
+ vecintrin.h
+ vpclmulqdqintrin.h
+ wmmintrin.h
diff --git a/devel/llvm60/files/clang/patch-tools_clang_tools_clang-format_clang-format-sublime.py b/devel/llvm60/files/clang/patch-tools_clang_tools_clang-format_clang-format-sublime.py
new file mode 100644
index 000000000000..2c8909f1e1d1
--- /dev/null
+++ b/devel/llvm60/files/clang/patch-tools_clang_tools_clang-format_clang-format-sublime.py
@@ -0,0 +1,14 @@
+
+$FreeBSD$
+
+--- tools/clang/tools/clang-format/clang-format-sublime.py.orig
++++ tools/clang/tools/clang-format/clang-format-sublime.py
+@@ -18,7 +18,7 @@
+ import subprocess
+
+ # Change this to the full path if clang-format is not on the path.
+-binary = 'clang-format'
++binary = 'clang-format%%LLVM_SUFFIX%%'
+
+ # Change this to format according to other formatting styles. See the output of
+ # 'clang-format --help' for a list of supported styles. The default looks for
diff --git a/devel/llvm60/files/clang/patch-tools_clang_tools_clang-format_clang-format.py b/devel/llvm60/files/clang/patch-tools_clang_tools_clang-format_clang-format.py
new file mode 100644
index 000000000000..2962d3f4cbcb
--- /dev/null
+++ b/devel/llvm60/files/clang/patch-tools_clang_tools_clang-format_clang-format.py
@@ -0,0 +1,11 @@
+--- tools/clang/tools/clang-format/clang-format.py.orig 2015-09-08 20:44:00 UTC
++++ tools/clang/tools/clang-format/clang-format.py
+@@ -34,7 +34,7 @@ import vim
+
+ # set g:clang_format_path to the path to clang-format if it is not on the path
+ # Change this to the full path if clang-format is not on the path.
+-binary = 'clang-format'
++binary = 'clang-format%%LLVM_SUFFIX%%'
+ if vim.eval('exists("g:clang_format_path")') == "1":
+ binary = vim.eval('g:clang_format_path')
+
diff --git a/devel/llvm60/files/clang/patch-tools_clang_tools_clang-format_git-clang-format b/devel/llvm60/files/clang/patch-tools_clang_tools_clang-format_git-clang-format
new file mode 100644
index 000000000000..5c5ae3581228
--- /dev/null
+++ b/devel/llvm60/files/clang/patch-tools_clang_tools_clang-format_git-clang-format
@@ -0,0 +1,32 @@
+
+$FreeBSD$
+
+--- tools/clang/tools/clang-format/git-clang-format.orig
++++ tools/clang/tools/clang-format/git-clang-format
+@@ -90,7 +90,7 @@
+ usage=usage, formatter_class=argparse.RawDescriptionHelpFormatter,
+ description=desc)
+ p.add_argument('--binary',
+- default=config.get('clangformat.binary', 'clang-format'),
++ default=config.get('clangformat.binary', 'clang-format%%LLVM_SUFFIX%%'),
+ help='path to clang-format'),
+ p.add_argument('--commit',
+ default=config.get('clangformat.commit', 'HEAD'),
+@@ -344,7 +344,7 @@
+
+
+ def run_clang_format_and_save_to_tree(changed_lines, revision=None,
+- binary='clang-format', style=None):
++ binary='clang-format%%LLVM_SUFFIX%%', style=None):
+ """Run clang-format on each file and save the result to a git tree.
+
+ Returns the object ID (SHA-1) of the created tree."""
+@@ -397,7 +397,7 @@
+
+
+ def clang_format_to_blob(filename, line_ranges, revision=None,
+- binary='clang-format', style=None):
++ binary='clang-format%%LLVM_SUFFIX%%', style=None):
+ """Run clang-format on the given file and save the result to a git blob.
+
+ Runs on the file in `revision` if not None, or on the file in the working
diff --git a/devel/llvm60/files/clang/patch-tools_clang_tools_scan-build_libexec_ccc-analyzer b/devel/llvm60/files/clang/patch-tools_clang_tools_scan-build_libexec_ccc-analyzer
new file mode 100644
index 000000000000..e1c65480ce2f
--- /dev/null
+++ b/devel/llvm60/files/clang/patch-tools_clang_tools_scan-build_libexec_ccc-analyzer
@@ -0,0 +1,12 @@
+--- tools/clang/tools/scan-build/libexec/ccc-analyzer.orig
++++ tools/clang/tools/scan-build/libexec/ccc-analyzer
+@@ -81,6 +81,9 @@
+ if (-x "/usr/bin/xcrun") {
+ $UseXCRUN = 1;
+ }
++} elsif (`uname -s` eq "FreeBSD\n") {
++ $DefaultCCompiler = 'cc';
++ $DefaultCXXCompiler = 'c++';
+ } else {
+ $DefaultCCompiler = 'gcc';
+ $DefaultCXXCompiler = 'g++';
diff --git a/devel/llvm60/files/lld/patch-head-r331731.diff b/devel/llvm60/files/lld/patch-head-r331731.diff
new file mode 100644
index 000000000000..6b162d89f6be
--- /dev/null
+++ b/devel/llvm60/files/lld/patch-head-r331731.diff
@@ -0,0 +1,67 @@
+r331731 | dim | 2018-03-29 15:55:23 +0200 (Thu, 29 Mar 2018) | 22 lines
+
+Pull in r328738 from upstream lld trunk (by Rafael Espindola):
+
+ Strip @VER suffices from the LTO output.
+
+ This fixes pr36623.
+
+ The problem is that we have to parse versions out of names before LTO
+ so that LTO can use that information.
+
+ When we get the LTO produced .o files, we replace the previous symbols
+ with the LTO produced ones, but they still have @ in their names.
+
+ We could just trim the name directly, but calling parseSymbolVersion
+ to do it is simpler.
+
+This is a follow-up to r331366, since we discovered that lld could
+append version strings to symbols twice, when using Link Time
+Optimization.
+
+MFC after: 3 months
+X-MFC-With: r327952
+
+Index: tools/lld/ELF/InputFiles.cpp
+===================================================================
+--- tools/lld/ELF/InputFiles.cpp (revision 331730)
++++ tools/lld/ELF/InputFiles.cpp (revision 331731)
+@@ -281,6 +281,10 @@ template <class ELFT> ArrayRef<Symbol *> ObjFile<E
+ return makeArrayRef(this->Symbols).slice(1, this->FirstNonLocal - 1);
+ }
+
++template <class ELFT> ArrayRef<Symbol *> ObjFile<ELFT>::getGlobalSymbols() {
++ return makeArrayRef(this->Symbols).slice(this->FirstNonLocal);
++}
++
+ template <class ELFT>
+ void ObjFile<ELFT>::parse(DenseSet<CachedHashStringRef> &ComdatGroups) {
+ // Read section and symbol tables.
+Index: tools/lld/ELF/InputFiles.h
+===================================================================
+--- tools/lld/ELF/InputFiles.h (revision 331730)
++++ tools/lld/ELF/InputFiles.h (revision 331731)
+@@ -167,6 +167,7 @@ template <class ELFT> class ObjFile : public ELFFi
+ static bool classof(const InputFile *F) { return F->kind() == Base::ObjKind; }
+
+ ArrayRef<Symbol *> getLocalSymbols();
++ ArrayRef<Symbol *> getGlobalSymbols();
+
+ ObjFile(MemoryBufferRef M, StringRef ArchiveName);
+ void parse(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
+Index: tools/lld/ELF/SymbolTable.cpp
+===================================================================
+--- tools/lld/ELF/SymbolTable.cpp (revision 331730)
++++ tools/lld/ELF/SymbolTable.cpp (revision 331731)
+@@ -130,7 +130,10 @@ template <class ELFT> void SymbolTable::addCombine
+
+ for (InputFile *File : LTO->compile()) {
+ DenseSet<CachedHashStringRef> DummyGroups;
+- cast<ObjFile<ELFT>>(File)->parse(DummyGroups);
++ auto *Obj = cast<ObjFile<ELFT>>(File);
++ Obj->parse(DummyGroups);
++ for (Symbol *Sym : Obj->getGlobalSymbols())
++ Sym->parseSymbolVersion();
+ ObjectFiles.push_back(File);
+ }
+ }
diff --git a/devel/llvm60/files/lld/patch-head-r333401.diff b/devel/llvm60/files/lld/patch-head-r333401.diff
new file mode 100644
index 000000000000..131f6a0ea274
--- /dev/null
+++ b/devel/llvm60/files/lld/patch-head-r333401.diff
@@ -0,0 +1,34 @@
+r333401 | emaste | 2018-05-09 13:17:01 +0200 (Wed, 09 May 2018) | 19 lines
+
+lld: Omit PT_NOTE for SHT_NOTE without SHF_ALLOC
+
+A non-alloc note section should not have a PT_NOTE program header.
+
+Found while linking ghc (Haskell compiler) with lld on FreeBSD. Haskell
+emits a .debug-ghc-link-info note section (as the name suggests, it
+contains link info) as a SHT_NOTE section without SHF_ALLOC set.
+
+For this case ld.bfd does not emit a PT_NOTE segment for
+.debug-ghc-link-info. lld previously emitted a PT_NOTE with p_vaddr = 0
+and FreeBSD's rtld segfaulted when trying to parse a note at address 0.
+
+LLVM PR: https://llvm.org/pr37361
+LLVM review: https://reviews.llvm.org/D46623
+
+PR: 226872
+Reviewed by: dim
+Sponsored by: The FreeBSD Foundation
+
+Index: tools/lld/ELF/Writer.cpp
+===================================================================
+--- tools/lld/ELF/Writer.cpp (revision 333400)
++++ tools/lld/ELF/Writer.cpp (revision 333401)
+@@ -1708,7 +1708,7 @@ template <class ELFT> std::vector<PhdrEntry *> Wri
+ // Create one PT_NOTE per a group of contiguous .note sections.
+ PhdrEntry *Note = nullptr;
+ for (OutputSection *Sec : OutputSections) {
+- if (Sec->Type == SHT_NOTE) {
++ if (Sec->Type == SHT_NOTE && (Sec->Flags & SHF_ALLOC)) {
+ if (!Note || Sec->LMAExpr)
+ Note = AddHdr(PT_NOTE, PF_R);
+ Note->add(Sec);
diff --git a/devel/llvm60/files/lld/patch-head-r336664.diff b/devel/llvm60/files/lld/patch-head-r336664.diff
new file mode 100644
index 000000000000..e26fd06d4c5e
--- /dev/null
+++ b/devel/llvm60/files/lld/patch-head-r336664.diff
@@ -0,0 +1,52 @@
+r336664 | emaste | 2018-07-24 13:35:22 +0200 (Tue, 24 Jul 2018) | 11 lines
+
+lld: fix addends with partial linking
+
+[ELF] Update addends in non-allocatable sections for REL targets when
+creating a relocatable output.
+
+LLVM PR: 37735
+LLVM Differential Revision: https://reviews.llvm.org/D48929
+
+PR: 225128
+Obtained from: LLVM r336799 by Igor Kudrin
+
+Index: tools/lld/ELF/InputSection.cpp
+===================================================================
+--- tools/lld/ELF/InputSection.cpp (revision 336663)
++++ tools/lld/ELF/InputSection.cpp (revision 336664)
+@@ -686,6 +686,23 @@ void InputSection::relocateNonAlloc(uint8_t *Buf,
+ }
+ }
+
++// This is used when '-r' is given.
++// For REL targets, InputSection::copyRelocations() may store artificial
++// relocations aimed to update addends. They are handled in relocateAlloc()
++// for allocatable sections, and this function does the same for
++// non-allocatable sections, such as sections with debug information.
++static void relocateNonAllocForRelocatable(InputSection *Sec, uint8_t *Buf) {
++ const unsigned Bits = Config->Is64 ? 64 : 32;
++
++ for (const Relocation &Rel : Sec->Relocations) {
++ // InputSection::copyRelocations() adds only R_ABS relocations.
++ assert(Rel.Expr == R_ABS);
++ uint8_t *BufLoc = Buf + Rel.Offset + Sec->OutSecOff;
++ uint64_t TargetVA = SignExtend64(Rel.Sym->getVA(Rel.Addend), Bits);
++ Target->relocateOne(BufLoc, Rel.Type, TargetVA);
++ }
++}
++
+ template <class ELFT>
+ void InputSectionBase::relocate(uint8_t *Buf, uint8_t *BufEnd) {
+ if (Flags & SHF_ALLOC) {
+@@ -694,7 +711,9 @@ void InputSectionBase::relocate(uint8_t *Buf, uint
+ }
+
+ auto *Sec = cast<InputSection>(this);
+- if (Sec->AreRelocsRela)
++ if (Config->Relocatable)
++ relocateNonAllocForRelocatable(Sec, Buf);
++ else if (Sec->AreRelocsRela)
+ Sec->relocateNonAlloc<ELFT>(Buf, Sec->template relas<ELFT>());
+ else
+ Sec->relocateNonAlloc<ELFT>(Buf, Sec->template rels<ELFT>());
diff --git a/devel/llvm60/files/lld/patch-head-r336972.diff b/devel/llvm60/files/lld/patch-head-r336972.diff
new file mode 100644
index 000000000000..d7497ce5390a
--- /dev/null
+++ b/devel/llvm60/files/lld/patch-head-r336972.diff
@@ -0,0 +1,146 @@
+r336972 | emaste | 2018-07-31 17:25:03 +0200 (Tue, 31 Jul 2018) | 37 lines
+
+lld: [ELF][ARM] Implement support for Tag_ABI_VFP_args
+
+The Tag_ABI_VFP_args build attribute controls the procedure call
+standard used for floating point parameters on ARM. The values are:
+
+0 - Base AAPCS (FP Parameters passed in Core (Integer) registers
+1 - VFP AAPCS (FP Parameters passed in FP registers)
+2 - Toolchain specific (Neither Base or VFP)
+3 - Compatible with all (No use of floating point parameters)
+
+If the Tag_ABI_VFP_args build attribute is missing it has an implicit
+value of 0.
+
+We use the attribute in two ways:
+
+* Detect a clash in calling convention between Base, VFP and Toolchain.
+
+we follow ld.bfd's lead and do not error if there is a clash between an
+implicit Base AAPCS caused by a missing attribute. Many projects
+including the hard-float (VFP AAPCS) version of glibc contain assembler
+files that do not use floating point but do not have Tag_ABI_VFP_args.
+
+* Set the EF_ARM_ABI_FLOAT_SOFT or EF_ARM_ABI_FLOAT_HARD ELF header flag
+
+for Base or VFP AAPCS respectively. This flag is used by some ELF
+loaders.
+
+References:
+* Addenda to, and Errata in, the ABI for the ARM Architecture for
+ Tag_ABI_VFP_args
+* Elf for the ARM Architecture for ELF header flags
+
+Fixes LLVM PR36009
+
+PR: 229050
+Obtained from: llvm r338377 by Peter Smith
+
+Index: tools/lld/ELF/Arch/ARM.cpp
+===================================================================
+--- tools/lld/ELF/Arch/ARM.cpp (revision 336971)
++++ tools/lld/ELF/Arch/ARM.cpp (revision 336972)
+@@ -97,10 +97,19 @@ ARM::ARM() {
+ }
+
+ uint32_t ARM::calcEFlags() const {
++ // The ABIFloatType is used by loaders to detect the floating point calling
++ // convention.
++ uint32_t ABIFloatType = 0;
++ if (Config->ARMVFPArgs == ARMVFPArgKind::Base ||
++ Config->ARMVFPArgs == ARMVFPArgKind::Default)
++ ABIFloatType = EF_ARM_ABI_FLOAT_SOFT;
++ else if (Config->ARMVFPArgs == ARMVFPArgKind::VFP)
++ ABIFloatType = EF_ARM_ABI_FLOAT_HARD;
++
+ // We don't currently use any features incompatible with EF_ARM_EABI_VER5,
+ // but we don't have any firm guarantees of conformance. Linux AArch64
+ // kernels (as of 2016) require an EABI version to be set.
+- return EF_ARM_EABI_VER5;
++ return EF_ARM_EABI_VER5 | ABIFloatType;
+ }
+
+ RelExpr ARM::getRelExpr(RelType Type, const Symbol &S,
+Index: tools/lld/ELF/Config.h
+===================================================================
+--- tools/lld/ELF/Config.h (revision 336971)
++++ tools/lld/ELF/Config.h (revision 336972)
+@@ -54,6 +54,9 @@ enum class SortSectionPolicy { Default, None, Alig
+ // For --target2
+ enum class Target2Policy { Abs, Rel, GotRel };
+
++// For tracking ARM Float Argument PCS
++enum class ARMVFPArgKind { Default, Base, VFP, ToolChain };
++
+ struct SymbolVersion {
+ llvm::StringRef Name;
+ bool IsExternCpp;
+@@ -169,6 +172,7 @@ struct Configuration {
+ StripPolicy Strip;
+ UnresolvedPolicy UnresolvedSymbols;
+ Target2Policy Target2;
++ ARMVFPArgKind ARMVFPArgs = ARMVFPArgKind::Default;
+ BuildIdKind BuildId = BuildIdKind::None;
+ ELFKind EKind = ELFNoneKind;
+ uint16_t DefaultSymbolVersion = llvm::ELF::VER_NDX_GLOBAL;
+Index: tools/lld/ELF/InputFiles.cpp
+===================================================================
+--- tools/lld/ELF/InputFiles.cpp (revision 336971)
++++ tools/lld/ELF/InputFiles.cpp (revision 336972)
+@@ -441,6 +441,46 @@ void ObjFile<ELFT>::initializeSections(
+ }
+ }
+
++// For ARM only, to set the EF_ARM_ABI_FLOAT_SOFT or EF_ARM_ABI_FLOAT_HARD
++// flag in the ELF Header we need to look at Tag_ABI_VFP_args to find out how
++// the input objects have been compiled.
++static void updateARMVFPArgs(const ARMAttributeParser &Attributes,
++ const InputFile *F) {
++ if (!Attributes.hasAttribute(ARMBuildAttrs::ABI_VFP_args))
++ // If an ABI tag isn't present then it is implicitly given the value of 0
++ // which maps to ARMBuildAttrs::BaseAAPCS. However many assembler files,
++ // including some in glibc that don't use FP args (and should have value 3)
++ // don't have the attribute so we do not consider an implicit value of 0
++ // as a clash.
++ return;
++
++ unsigned VFPArgs = Attributes.getAttributeValue(ARMBuildAttrs::ABI_VFP_args);
++ ARMVFPArgKind Arg;
++ switch (VFPArgs) {
++ case ARMBuildAttrs::BaseAAPCS:
++ Arg = ARMVFPArgKind::Base;
++ break;
++ case ARMBuildAttrs::HardFPAAPCS:
++ Arg = ARMVFPArgKind::VFP;
++ break;
++ case ARMBuildAttrs::ToolChainFPPCS:
++ // Tool chain specific convention that conforms to neither AAPCS variant.
++ Arg = ARMVFPArgKind::ToolChain;
++ break;
++ case ARMBuildAttrs::CompatibleFPAAPCS:
++ // Object compatible with all conventions.
++ return;
++ default:
++ error(toString(F) + ": unknown Tag_ABI_VFP_args value: " + Twine(VFPArgs));
++ return;
++ }
++ // Follow ld.bfd and error if there is a mix of calling conventions.
++ if (Config->ARMVFPArgs != Arg && Config->ARMVFPArgs != ARMVFPArgKind::Default)
++ error(toString(F) + ": incompatible Tag_ABI_VFP_args");
++ else
++ Config->ARMVFPArgs = Arg;
++}
++
+ // The ARM support in lld makes some use of instructions that are not available
+ // on all ARM architectures. Namely:
+ // - Use of BLX instruction for interworking between ARM and Thumb state.
+@@ -520,6 +560,8 @@ InputSectionBase *ObjFile<ELFT>::createInputSectio
+ ArrayRef<uint8_t> Contents = check(this->getObj().getSectionContents(&Sec));
+ Attributes.Parse(Contents, /*isLittle*/ Config->EKind == ELF32LEKind);
+ updateSupportedARMFeatures(Attributes);
++ updateARMVFPArgs(Attributes, this);
++
+ // FIXME: Retain the first attribute section we see. The eglibc ARM
+ // dynamic loaders require the presence of an attribute section for dlopen
+ // to work. In a full implementation we would merge all attribute sections.
diff --git a/devel/llvm60/files/lld/patch-head-r337282.diff b/devel/llvm60/files/lld/patch-head-r337282.diff
new file mode 100644
index 000000000000..1e046d6e2b17
--- /dev/null
+++ b/devel/llvm60/files/lld/patch-head-r337282.diff
@@ -0,0 +1,39 @@
+r337282 | alc | 2018-08-04 04:30:51 +0200 (Sat, 04 Aug 2018) | 7 lines
+
+Set the default image base on arm64 and i386 to a superpage-aligned
+address.
+
+Reviewed by: emaste, markj
+Discussed with: dim
+Differential Revision: https://reviews.freebsd.org/D16385
+
+Index: tools/lld/ELF/Arch/AArch64.cpp
+===================================================================
+--- tools/lld/ELF/Arch/AArch64.cpp (revision 337281)
++++ tools/lld/ELF/Arch/AArch64.cpp (revision 337282)
+@@ -66,6 +66,10 @@ AArch64::AArch64() {
+ PltHeaderSize = 32;
+ DefaultMaxPageSize = 65536;
+
++ // Align to the 2 MiB page size (known as a superpage or huge page).
++ // FreeBSD automatically promotes 2 MiB-aligned allocations.
++ DefaultImageBase = 0x200000;
++
+ // It doesn't seem to be documented anywhere, but tls on aarch64 uses variant
+ // 1 of the tls structures and the tcb size is 16.
+ TcbSize = 16;
+Index: tools/lld/ELF/Arch/X86.cpp
+===================================================================
+--- tools/lld/ELF/Arch/X86.cpp (revision 337281)
++++ tools/lld/ELF/Arch/X86.cpp (revision 337282)
+@@ -61,6 +61,10 @@ X86::X86() {
+ PltHeaderSize = 16;
+ TlsGdRelaxSkip = 2;
+ TrapInstr = 0xcccccccc; // 0xcc = INT3
++
++ // Align to the non-PAE large page size (known as a superpage or huge page).
++ // FreeBSD automatically promotes large, superpage-aligned allocations.
++ DefaultImageBase = 0x400000;
+ }
+
+ static bool hasBaseReg(uint8_t ModRM) { return (ModRM & 0xc7) != 0x5; }
diff --git a/devel/llvm60/files/lld/patch-head-r338251.diff b/devel/llvm60/files/lld/patch-head-r338251.diff
new file mode 100644
index 000000000000..1c3df02100cd
--- /dev/null
+++ b/devel/llvm60/files/lld/patch-head-r338251.diff
@@ -0,0 +1,123 @@
+r338251 | markj | 2018-08-23 16:58:19 +0200 (Thu, 23 Aug 2018) | 29 lines
+
+Add an lld option to emit PC-relative relocations for ifunc calls.
+
+The current kernel ifunc implementation creates a PLT entry for each
+ifunc definition. ifunc calls therefore consist of a call to the
+PLT entry followed by an indirect jump. The jump target is written
+during boot when the kernel linker resolves R_[*]_IRELATIVE relocations.
+This implementation is defined by requirements for userland code, where
+text relocations are avoided. This requirement is not present for the
+kernel, so the implementation has avoidable overhead (namely, an extra
+indirect jump per call).
+
+Address this for now by adding a special option to the static linker
+to inhibit PLT creation for ifuncs. Instead, relocations to ifunc call
+sites are passed through to the output file, so the kernel linker can
+enumerate such call sites and apply PC-relative relocations directly
+to the text section. Thus the overhead of an ifunc call becomes exactly
+the same as that of an ordinary function call. This option is only for
+use by the kernel and will not work for regular programs.
+
+The final form of this optimization is up for debate; for now, this
+change is simple and static enough to be acceptable as an interim
+solution.
+
+Reviewed by: emaste
+Discussed with: arichardson, dim
+MFC after: 1 month
+Sponsored by: The FreeBSD Foundation
+Differential Revision: https://reviews.freebsd.org/D16748
+
+Index: tools/lld/ELF/Config.h
+===================================================================
+--- tools/lld/ELF/Config.h (revision 338250)
++++ tools/lld/ELF/Config.h (revision 338251)
+@@ -155,6 +155,7 @@ struct Configuration {
+ bool ZCombreloc;
+ bool ZExecstack;
+ bool ZHazardplt;
++ bool ZIfuncnoplt;
+ bool ZNocopyreloc;
+ bool ZNodelete;
+ bool ZNodlopen;
+Index: tools/lld/ELF/Driver.cpp
+===================================================================
+--- tools/lld/ELF/Driver.cpp (revision 338250)
++++ tools/lld/ELF/Driver.cpp (revision 338251)
+@@ -669,6 +669,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &
+ Config->ZCombreloc = !hasZOption(Args, "nocombreloc");
+ Config->ZExecstack = hasZOption(Args, "execstack");
+ Config->ZHazardplt = hasZOption(Args, "hazardplt");
++ Config->ZIfuncnoplt = hasZOption(Args, "ifunc-noplt");
+ Config->ZNocopyreloc = hasZOption(Args, "nocopyreloc");
+ Config->ZNodelete = hasZOption(Args, "nodelete");
+ Config->ZNodlopen = hasZOption(Args, "nodlopen");
+Index: tools/lld/ELF/Relocations.cpp
+===================================================================
+--- tools/lld/ELF/Relocations.cpp (revision 338250)
++++ tools/lld/ELF/Relocations.cpp (revision 338251)
+@@ -374,6 +374,9 @@ static bool isStaticLinkTimeConstant(RelExpr E, Re
+ R_PPC_PLT_OPD, R_TLSDESC_CALL, R_TLSDESC_PAGE, R_HINT>(E))
+ return true;
+
++ if (Sym.isGnuIFunc() && Config->ZIfuncnoplt)
++ return false;
++
+ // These never do, except if the entire file is position dependent or if
+ // only the low bits are used.
+ if (E == R_GOT || E == R_PLT || E == R_TLSDESC)
+@@ -921,7 +924,9 @@ static void scanRelocs(InputSectionBase &Sec, Arra
+ // Strenghten or relax a PLT access.
+ //
+ // GNU ifunc symbols must be accessed via PLT because their addresses
+- // are determined by runtime.
++ // are determined by runtime. If the -z ifunc-noplt option is specified,
++ // we permit the optimization of ifunc calls by omitting the PLT entry
++ // and preserving relocations at ifunc call sites.
+ //
+ // On the other hand, if we know that a PLT entry will be resolved within
+ // the same ELF module, we can skip PLT access and directly jump to the
+@@ -929,7 +934,7 @@ static void scanRelocs(InputSectionBase &Sec, Arra
+ // all dynamic symbols that can be resolved within the executable will
+ // actually be resolved that way at runtime, because the main exectuable
+ // is always at the beginning of a search list. We can leverage that fact.
+- if (Sym.isGnuIFunc())
++ if (Sym.isGnuIFunc() && !Config->ZIfuncnoplt)
+ Expr = toPlt(Expr);
+ else if (!Preemptible && Expr == R_GOT_PC && !isAbsoluteValue(Sym))
+ Expr =
+@@ -1034,6 +1039,16 @@ static void scanRelocs(InputSectionBase &Sec, Arra
+ continue;
+ }
+
++ // Preserve relocations against ifuncs if we were asked to do so.
++ if (Sym.isGnuIFunc() && Config->ZIfuncnoplt) {
++ if (Config->IsRela)
++ InX::RelaDyn->addReloc({Type, &Sec, Offset, false, &Sym, Addend});
++ else
++ // Preserve the existing addend.
++ InX::RelaDyn->addReloc({Type, &Sec, Offset, false, &Sym, 0});
++ continue;
++ }
++
+ // If the output being produced is position independent, the final value
+ // is still not known. In that case we still need some help from the
+ // dynamic linker. We can however do better than just copying the incoming
+Index: tools/lld/ELF/Writer.cpp
+===================================================================
+--- tools/lld/ELF/Writer.cpp (revision 338250)
++++ tools/lld/ELF/Writer.cpp (revision 338251)
+@@ -1400,8 +1400,11 @@ template <class ELFT> void Writer<ELFT>::finalizeS
+ applySynthetic({InX::EhFrame},
+ [](SyntheticSection *SS) { SS->finalizeContents(); });
+
+- for (Symbol *S : Symtab->getSymbols())
++ for (Symbol *S : Symtab->getSymbols()) {
+ S->IsPreemptible |= computeIsPreemptible(*S);
++ if (S->isGnuIFunc() && Config->ZIfuncnoplt)
++ S->ExportDynamic = true;
++ }
+
+ // Scan relocations. This must be done after every symbol is declared so that
+ // we can correctly decide if a dynamic relocation is needed.
diff --git a/devel/llvm60/files/lld/patch-head-r338682.diff b/devel/llvm60/files/lld/patch-head-r338682.diff
new file mode 100644
index 000000000000..1783fe227489
--- /dev/null
+++ b/devel/llvm60/files/lld/patch-head-r338682.diff
@@ -0,0 +1,55 @@
+r338682 | emaste | 2018-09-14 17:15:16 +0200 (Fri, 14 Sep 2018) | 16 lines
+
+lld: add -z interpose support
+
+-z interpose sets the DF_1_INTERPOSE flag, marking the object as an
+interposer.
+
+Committed upstream as LLVM r342239.
+
+PR: 230604
+Reported by: jbeich
+Reviewed by: markj
+Approved by: re (kib)
+MFC after: 1 week
+Relnotes: Yes
+Sponsored by: The FreeBSD Foundation
+Differential Revision: https://reviews.freebsd.org/D17172
+
+Index: tools/lld/ELF/Config.h
+===================================================================
+--- tools/lld/ELF/Config.h (revision 338681)
++++ tools/lld/ELF/Config.h (revision 338682)
+@@ -156,6 +156,7 @@ struct Configuration {
+ bool ZExecstack;
+ bool ZHazardplt;
+ bool ZIfuncnoplt;
++ bool ZInterpose;
+ bool ZNocopyreloc;
+ bool ZNodelete;
+ bool ZNodlopen;
+Index: tools/lld/ELF/Driver.cpp
+===================================================================
+--- tools/lld/ELF/Driver.cpp (revision 338681)
++++ tools/lld/ELF/Driver.cpp (revision 338682)
+@@ -670,6 +670,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &
+ Config->ZExecstack = hasZOption(Args, "execstack");
+ Config->ZHazardplt = hasZOption(Args, "hazardplt");
+ Config->ZIfuncnoplt = hasZOption(Args, "ifunc-noplt");
++ Config->ZInterpose = hasZOption(Args, "interpose");
+ Config->ZNocopyreloc = hasZOption(Args, "nocopyreloc");
+ Config->ZNodelete = hasZOption(Args, "nodelete");
+ Config->ZNodlopen = hasZOption(Args, "nodlopen");
+Index: tools/lld/ELF/SyntheticSections.cpp
+===================================================================
+--- tools/lld/ELF/SyntheticSections.cpp (revision 338681)
++++ tools/lld/ELF/SyntheticSections.cpp (revision 338682)
+@@ -1034,6 +1034,8 @@ template <class ELFT> void DynamicSection<ELFT>::f
+ uint32_t DtFlags1 = 0;
+ if (Config->Bsymbolic)
+ DtFlags |= DF_SYMBOLIC;
++ if (Config->ZInterpose)
++ DtFlags1 |= DF_1_INTERPOSE;
+ if (Config->ZNodelete)
+ DtFlags1 |= DF_1_NODELETE;
+ if (Config->ZNodlopen)
diff --git a/devel/llvm60/files/lld/patch-head-r339013.diff b/devel/llvm60/files/lld/patch-head-r339013.diff
new file mode 100644
index 000000000000..ba614706a88d
--- /dev/null
+++ b/devel/llvm60/files/lld/patch-head-r339013.diff
@@ -0,0 +1,39 @@
+r339013 | dim | 2018-09-29 16:12:03 +0200 (Sat, 29 Sep 2018) | 24 lines
+
+Pull in r329557 from upstream lld trunk (by George Rimar):
+
+ [ELF] - Allow LLD to produce file symbols.
+
+ This is for PR36716 and
+ this enables emitting STT_FILE symbols.
+
+ Output size affect is minor:
+ lld binary size changes from 52,883,408 to 52,949,400
+ clang binary size changes from 83,136,456 to 83,219,600
+
+ Differential revision: https://reviews.llvm.org/D45261
+
+This fixes a regression in lld that made it stop emitting STT_FILE
+symbols, which ctfmerge relies upon to uniquify function table entries
+that reference STB_LOCAL symbols. Consequently, ctfmerge stopped
+emitting entries for static functions into the function table, and
+dtrace no longer gets type info for them.
+
+Approved by: re (kib)
+Reported by: markj
+PR: 230444
+MFC after: 3 days
+
+Index: tools/lld/ELF/Writer.cpp
+===================================================================
+--- tools/lld/ELF/Writer.cpp (revision 339012)
++++ tools/lld/ELF/Writer.cpp (revision 339013)
+@@ -487,7 +487,7 @@ template <class ELFT> void Writer<ELFT>::run() {
+
+ static bool shouldKeepInSymtab(SectionBase *Sec, StringRef SymName,
+ const Symbol &B) {
+- if (B.isFile() || B.isSection())
++ if (B.isSection())
+ return false;
+
+ // If sym references a section in a discarded group, don't keep it.
diff --git a/devel/llvm60/files/lld/patch-head-r339304.diff b/devel/llvm60/files/lld/patch-head-r339304.diff
new file mode 100644
index 000000000000..59ff933dfff6
--- /dev/null
+++ b/devel/llvm60/files/lld/patch-head-r339304.diff
@@ -0,0 +1,37 @@
+r339304 | emaste | 2018-10-11 15:19:17 +0200 (Thu, 11 Oct 2018) | 13 lines
+
+lld: set sh_link and sh_info for .rela.plt sections
+
+ELF spec says that for SHT_REL and SHT_RELA sh_link should reference the
+associated string table and sh_info should reference the "section to
+which the relocation applies." ELF Tool Chain's elfcopy / strip use
+this (in part) to control whether or not the relocation entry is copied
+to the output.
+
+LLVM PR 37538 https://bugs.llvm.org/show_bug.cgi?id=37538
+
+Approved by: re (kib)
+Obtained from: llvm r344226 (backported for 6.0)
+
+Index: tools/lld/ELF/SyntheticSections.cpp
+===================================================================
+--- tools/lld/ELF/SyntheticSections.cpp (revision 339303)
++++ tools/lld/ELF/SyntheticSections.cpp (revision 339304)
+@@ -1213,11 +1213,13 @@ void RelocationBaseSection::addReloc(const Dynamic
+ void RelocationBaseSection::finalizeContents() {
+ // If all relocations are R_*_RELATIVE they don't refer to any
+ // dynamic symbol and we don't need a dynamic symbol table. If that
+- // is the case, just use 0 as the link.
+- Link = InX::DynSymTab ? InX::DynSymTab->getParent()->SectionIndex : 0;
++ // is the case, just use the index of the regular symbol table section.
++ getParent()->Link = InX::DynSymTab ?
++ InX::DynSymTab->getParent()->SectionIndex :
++ InX::SymTab->getParent()->SectionIndex;
+
+- // Set required output section properties.
+- getParent()->Link = Link;
++ if (InX::RelaIplt == this || InX::RelaPlt == this)
++ getParent()->Info = InX::GotPlt->getParent()->SectionIndex;
+ }
+
+ template <class ELFT>
diff --git a/devel/llvm60/files/lldb/patch-head-r332849.diff b/devel/llvm60/files/lldb/patch-head-r332849.diff
new file mode 100644
index 000000000000..ced3a7a80319
--- /dev/null
+++ b/devel/llvm60/files/lldb/patch-head-r332849.diff
@@ -0,0 +1,38 @@
+r332849 | emaste | 2018-04-21 02:34:46 +0200 (Sat, 21 Apr 2018) | 20 lines
+
+lldb: propagate error to user if memory read fails
+
+Previously, an attempt to read an unreadable access reported zeros:
+
+(lldb) memory read -format hex -size 8 0
+0x00000000: 0x0000000000000000 0x0000000000000000
+0x00000010: 0x0000000000000000 0x0000000000000000
+...
+
+Now, if DoReadMemory encounters error then return 0 (bytes read) so we
+report the error to the user:
+
+(lldb) memory read -format hex -size 8 0
+error: Bad address
+
+LLVM PR: 37190
+
+MFC after: 1 week
+Sponsored by: The FreeBSD Foundation
+
+Index: tools/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
+===================================================================
+--- tools/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp (revision 332848)
++++ tools/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp (revision 332849)
+@@ -163,8 +163,10 @@ static size_t DoReadMemory(lldb::pid_t pid, lldb::
+ pi_desc.piod_addr = buf;
+ pi_desc.piod_len = size;
+
+- if (PTRACE(PT_IO, pid, (caddr_t)&pi_desc, 0) < 0)
++ if (PTRACE(PT_IO, pid, (caddr_t)&pi_desc, 0) < 0) {
+ error.SetErrorToErrno();
++ return 0;
++ }
+ return pi_desc.piod_len;
+ }
+
diff --git a/devel/llvm60/files/lldb/patch-head-r332965.diff b/devel/llvm60/files/lldb/patch-head-r332965.diff
new file mode 100644
index 000000000000..67e33f30e33a
--- /dev/null
+++ b/devel/llvm60/files/lldb/patch-head-r332965.diff
@@ -0,0 +1,22 @@
+r332965 | emaste | 2018-04-24 21:26:58 +0200 (Tue, 24 Apr 2018) | 8 lines
+
+lldb: remove assertion that target_arch is FreeBSD
+
+The target is not necessarily a FreeBSD binary - for example, it may be
+a Linux binary running under the linuxulator. Basic ptrace (live)
+debugging already worked in this case, except for the assertion.
+
+Sponsored by: Turing Robotic Industries Inc.
+
+Index: tools/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
+===================================================================
+--- tools/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp (revision 332964)
++++ tools/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp (revision 332965)
+@@ -169,7 +169,6 @@ lldb::RegisterContextSP FreeBSDThread::GetRegister
+ RegisterInfoInterface *reg_interface = NULL;
+ const ArchSpec &target_arch = GetProcess()->GetTarget().GetArchitecture();
+
+- assert(target_arch.GetTriple().getOS() == llvm::Triple::FreeBSD);
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::aarch64:
+ reg_interface = new RegisterInfoPOSIX_arm64(target_arch);
diff --git a/devel/llvm60/files/llvm-wrapper.sh.in b/devel/llvm60/files/llvm-wrapper.sh.in
new file mode 100644
index 000000000000..dfece2c0ced9
--- /dev/null
+++ b/devel/llvm60/files/llvm-wrapper.sh.in
@@ -0,0 +1,12 @@
+#!/bin/sh
+# $FreeBSD$
+
+LLVM_PREFIX="%%LLVM_PREFIX%%"
+LLVM_SUFFIX="%%LLVM_SUFFIX%%"
+
+tool=$0
+[ -L "$tool" ] && tool=$(/bin/realpath $tool)
+tool=${tool##*/}
+tool="${LLVM_PREFIX}/bin/${tool%${LLVM_SUFFIX}}"
+LD_LIBRARY_PATH="${LD_LIBRARY_PATH:+${LD_LIBRARY_PATH}:}${LLVM_PREFIX}/lib" \
+ exec "${tool}" "${@}"
diff --git a/devel/llvm60/files/openmp/patch-bug32279 b/devel/llvm60/files/openmp/patch-bug32279
new file mode 100644
index 000000000000..420402ab15a6
--- /dev/null
+++ b/devel/llvm60/files/openmp/patch-bug32279
@@ -0,0 +1,29 @@
+--- projects/openmp/runtime/cmake/LibompHandleFlags.cmake.orig 2017-03-16 15:50:48 UTC
++++ projects/openmp/runtime/cmake/LibompHandleFlags.cmake
+@@ -156,6 +156,11 @@ function(libomp_get_libflags libflags)
+ if(${IA32})
+ libomp_append(libflags_local -lirc_pic LIBOMP_HAVE_IRC_PIC_LIBRARY)
+ endif()
++ IF(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
++ libomp_append(libflags_local "-Wl,--no-as-needed" LIBOMP_HAVE_AS_NEEDED_FLAG)
++ libomp_append(libflags_local "-lm")
++ libomp_append(libflags_local "-Wl,--as-needed" LIBOMP_HAVE_AS_NEEDED_FLAG)
++ ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
+ IF(${CMAKE_SYSTEM_NAME} MATCHES "NetBSD")
+ libomp_append(libflags_local -lm)
+ ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "NetBSD")
+ runtime/cmake/LibompHandleFlags.cmake | 5 +++++
+ runtime/cmake/LibompMicroTests.cmake | 2 +-
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+--- projects/openmp/runtime/cmake/LibompMicroTests.cmake.orig 2017-03-16 15:50:48 UTC
++++ projects/openmp/runtime/cmake/LibompMicroTests.cmake
+@@ -171,7 +171,7 @@ add_custom_command(
+ add_custom_target(libomp-test-deps DEPENDS test-deps/.success)
+ set(libomp_expected_library_deps)
+ if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
+- set(libomp_expected_library_deps libc.so.7 libthr.so.3)
++ set(libomp_expected_library_deps libc.so.7 libthr.so.3 libm.so.5)
+ libomp_append(libomp_expected_library_deps libhwloc.so.5 LIBOMP_USE_HWLOC)
+ elseif(CMAKE_SYSTEM_NAME MATCHES "NetBSD")
+ set(libomp_expected_library_deps libc.so.12 libpthread.so.1 libm.so.0)
diff --git a/devel/llvm60/files/openmp/patch-i386 b/devel/llvm60/files/openmp/patch-i386
new file mode 100644
index 000000000000..9300640f6845
--- /dev/null
+++ b/devel/llvm60/files/openmp/patch-i386
@@ -0,0 +1,11 @@
+--- projects/openmp/runtime/src/kmp_runtime.cpp.orig 2017-07-17 09:03:14 UTC
++++ projects/openmp/runtime/src/kmp_runtime.cpp
+@@ -7535,7 +7535,7 @@ __kmp_determine_reduction_method(
+
+ #elif KMP_ARCH_X86 || KMP_ARCH_ARM || KMP_ARCH_AARCH || KMP_ARCH_MIPS
+
+-#if KMP_OS_LINUX || KMP_OS_WINDOWS
++#if KMP_OS_LINUX || KMP_OS_FREEBSD || KMP_OS_WINDOWS
+
+ // basic tuning
+
diff --git a/devel/llvm60/files/patch-cmake_modules_AddSphinxTarget.cmake b/devel/llvm60/files/patch-cmake_modules_AddSphinxTarget.cmake
new file mode 100644
index 000000000000..f4fc8f25e306
--- /dev/null
+++ b/devel/llvm60/files/patch-cmake_modules_AddSphinxTarget.cmake
@@ -0,0 +1,11 @@
+--- cmake/modules/AddSphinxTarget.cmake.orig
++++ cmake/modules/AddSphinxTarget.cmake
+@@ -29,6 +29,8 @@
+ endif()
+
+ add_custom_target(${SPHINX_TARGET_NAME}
++ COMMAND ${CMAKE_COMMAND}
++ -E make_directory ${SPHINX_BUILD_DIR}
+ COMMAND ${SPHINX_EXECUTABLE}
+ -b ${builder}
+ -d "${SPHINX_DOC_TREE_DIR}"
diff --git a/devel/llvm60/files/patch-head-r308867.diff b/devel/llvm60/files/patch-head-r308867.diff
new file mode 100644
index 000000000000..07efefa7c899
--- /dev/null
+++ b/devel/llvm60/files/patch-head-r308867.diff
@@ -0,0 +1,33 @@
+r308867 | dim | 2016-11-19 22:05:17 +0100 (Sat, 19 Nov 2016) | 15 lines
+
+Work around LLVM PR30879, which is about a bad interaction between X86
+Call Frame Optimization on i386 and libunwind, by disallowing the
+optimization for i386-freebsd12.
+
+This should fix some instances of broken exception handling when frame
+pointers are omitted, in particular some unittests run during the build
+of editors/libreoffice.
+
+This hack will be removed as soon as upstream has implemented a more
+permanent fix for this problem.
+
+Upstream PR: https://llvm.org/bugs/show_bug.cgi?id=30879
+Reviewed by: emaste
+PR: 212343
+
+Index: lib/Target/X86/X86CallFrameOptimization.cpp
+===================================================================
+--- lib/Target/X86/X86CallFrameOptimization.cpp (revision 308866)
++++ lib/Target/X86/X86CallFrameOptimization.cpp (revision 308867)
+@@ -125,6 +125,11 @@ bool X86CallFrameOptimization::isLegal(MachineFunc
+ if (NoX86CFOpt.getValue())
+ return false;
+
++ // Work around LLVM PR30879 (bad interaction between CFO and libunwind)
++ if (STI->isTargetFreeBSD() && STI->is32Bit() &&
++ STI->getTargetTriple().getOSMajorVersion() >= 12)
++ return false;
++
+ // We can't encode multiple DW_CFA_GNU_args_size or DW_CFA_def_cfa_offset
+ // in the compact unwind encoding that Darwin uses. So, bail if there
+ // is a danger of that being generated.
diff --git a/devel/llvm60/files/patch-head-r330686.diff b/devel/llvm60/files/patch-head-r330686.diff
new file mode 100644
index 000000000000..5a5f04e3b0ef
--- /dev/null
+++ b/devel/llvm60/files/patch-head-r330686.diff
@@ -0,0 +1,80 @@
+r330686 | dim | 2018-03-09 10:21:22 +0100 (Fri, 09 Mar 2018) | 20 lines
+
+Pull in r326882 from upstream llvm trunk (by Sjoerd Meijer):
+
+ [ARM] Fix for PR36577
+
+ Don't PerformSHLSimplify if the given node is used by a node that
+ also uses a constant because we may get stuck in an infinite combine
+ loop.
+
+ bugzilla: https://bugs.llvm.org/show_bug.cgi?id=36577
+
+ Patch by Sam Parker.
+
+ Differential Revision: https://reviews.llvm.org/D44097
+
+This fixes a hang when compiling one particular file in java/openjdk8
+for armv6 and armv7.
+
+Reported by: swills
+PR: 226388
+
+Index: lib/Target/ARM/ARMISelLowering.cpp
+===================================================================
+--- lib/Target/ARM/ARMISelLowering.cpp (revision 330685)
++++ lib/Target/ARM/ARMISelLowering.cpp (revision 330686)
+@@ -10201,7 +10201,14 @@ static SDValue PerformSHLSimplify(SDNode *N,
+ case ISD::XOR:
+ case ISD::SETCC:
+ case ARMISD::CMP:
+- // Check that its not already using a shl.
++ // Check that the user isn't already using a constant because there
++ // aren't any instructions that support an immediate operand and a
++ // shifted operand.
++ if (isa<ConstantSDNode>(U->getOperand(0)) ||
++ isa<ConstantSDNode>(U->getOperand(1)))
++ return SDValue();
++
++ // Check that it's not already using a shift.
+ if (U->getOperand(0).getOpcode() == ISD::SHL ||
+ U->getOperand(1).getOpcode() == ISD::SHL)
+ return SDValue();
+@@ -10223,8 +10230,6 @@ static SDValue PerformSHLSimplify(SDNode *N,
+ if (!C1ShlC2 || !C2)
+ return SDValue();
+
+- DEBUG(dbgs() << "Trying to simplify shl: "; N->dump());
+-
+ APInt C2Int = C2->getAPIntValue();
+ APInt C1Int = C1ShlC2->getAPIntValue();
+
+@@ -10238,12 +10243,12 @@ static SDValue PerformSHLSimplify(SDNode *N,
+ C1Int.lshrInPlace(C2Int);
+
+ // The immediates are encoded as an 8-bit value that can be rotated.
+- unsigned Zeros = C1Int.countLeadingZeros() + C1Int.countTrailingZeros();
+- if (C1Int.getBitWidth() - Zeros > 8)
+- return SDValue();
++ auto LargeImm = [](const APInt &Imm) {
++ unsigned Zeros = Imm.countLeadingZeros() + Imm.countTrailingZeros();
++ return Imm.getBitWidth() - Zeros > 8;
++ };
+
+- Zeros = C2Int.countLeadingZeros() + C2Int.countTrailingZeros();
+- if (C2Int.getBitWidth() - Zeros > 8)
++ if (LargeImm(C1Int) || LargeImm(C2Int))
+ return SDValue();
+
+ SelectionDAG &DAG = DCI.DAG;
+@@ -10254,6 +10259,10 @@ static SDValue PerformSHLSimplify(SDNode *N,
+ // Shift left to compensate for the lshr of C1Int.
+ SDValue Res = DAG.getNode(ISD::SHL, dl, MVT::i32, BinOp, SHL.getOperand(1));
+
++ DEBUG(dbgs() << "Simplify shl use:\n"; SHL.getOperand(0).dump(); SHL.dump();
++ N->dump());
++ DEBUG(dbgs() << "Into:\n"; X.dump(); BinOp.dump(); Res.dump());
++
+ DAG.ReplaceAllUsesWith(SDValue(N, 0), Res);
+ return SDValue(N, 0);
+ }
diff --git a/devel/llvm60/files/patch-head-r331065.diff b/devel/llvm60/files/patch-head-r331065.diff
new file mode 100644
index 000000000000..6976ee83460f
--- /dev/null
+++ b/devel/llvm60/files/patch-head-r331065.diff
@@ -0,0 +1,88 @@
+r331065 | dim | 2018-03-16 18:50:44 +0100 (Fri, 16 Mar 2018) | 17 lines
+
+Pull in r327638 from upstream llvm trunk (by Matthew Simpson):
+
+ [ConstantFolding, InstSimplify] Handle more vector GEPs
+
+ This patch addresses some additional cases where the compiler crashes
+ upon encountering vector GEPs. This should fix PR36116.
+
+ Differential Revision: https://reviews.llvm.org/D44219
+ Reference: https://bugs.llvm.org/show_bug.cgi?id=36116
+
+This fixes an assertion when building the emulators/snes9x port.
+
+Reported by: jbeich
+PR: 225471
+MFC after: 3 months
+X-MFC-With: r327952
+
+Index: lib/Analysis/InstructionSimplify.cpp
+===================================================================
+--- lib/Analysis/InstructionSimplify.cpp (revision 331064)
++++ lib/Analysis/InstructionSimplify.cpp (revision 331065)
+@@ -3697,7 +3697,7 @@ static Value *SimplifyGEPInst(Type *SrcTy, ArrayRe
+
+ if (Ops.size() == 2) {
+ // getelementptr P, 0 -> P.
+- if (match(Ops[1], m_Zero()))
++ if (match(Ops[1], m_Zero()) && Ops[0]->getType() == GEPTy)
+ return Ops[0];
+
+ Type *Ty = SrcTy;
+@@ -3706,7 +3706,7 @@ static Value *SimplifyGEPInst(Type *SrcTy, ArrayRe
+ uint64_t C;
+ uint64_t TyAllocSize = Q.DL.getTypeAllocSize(Ty);
+ // getelementptr P, N -> P if P points to a type of zero size.
+- if (TyAllocSize == 0)
++ if (TyAllocSize == 0 && Ops[0]->getType() == GEPTy)
+ return Ops[0];
+
+ // The following transforms are only safe if the ptrtoint cast
+Index: lib/IR/ConstantFold.cpp
+===================================================================
+--- lib/IR/ConstantFold.cpp (revision 331064)
++++ lib/IR/ConstantFold.cpp (revision 331065)
+@@ -2018,8 +2018,16 @@ static bool isInBoundsIndices(ArrayRef<IndexTy> Id
+
+ // If the first index is one and all the rest are zero, it's in bounds,
+ // by the one-past-the-end rule.
+- if (!cast<ConstantInt>(Idxs[0])->isOne())
+- return false;
++ if (auto *CI = dyn_cast<ConstantInt>(Idxs[0])) {
++ if (!CI->isOne())
++ return false;
++ } else {
++ auto *CV = cast<ConstantDataVector>(Idxs[0]);
++ CI = dyn_cast_or_null<ConstantInt>(CV->getSplatValue());
++ if (!CI || !CI->isOne())
++ return false;
++ }
++
+ for (unsigned i = 1, e = Idxs.size(); i != e; ++i)
+ if (!cast<Constant>(Idxs[i])->isNullValue())
+ return false;
+@@ -2049,15 +2057,18 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *Po
+ ArrayRef<Value *> Idxs) {
+ if (Idxs.empty()) return C;
+
+- if (isa<UndefValue>(C)) {
+- Type *GEPTy = GetElementPtrInst::getGEPReturnType(
+- C, makeArrayRef((Value * const *)Idxs.data(), Idxs.size()));
++ Type *GEPTy = GetElementPtrInst::getGEPReturnType(
++ C, makeArrayRef((Value *const *)Idxs.data(), Idxs.size()));
++
++ if (isa<UndefValue>(C))
+ return UndefValue::get(GEPTy);
+- }
+
+ Constant *Idx0 = cast<Constant>(Idxs[0]);
+ if (Idxs.size() == 1 && (Idx0->isNullValue() || isa<UndefValue>(Idx0)))
+- return C;
++ return GEPTy->isVectorTy() && !C->getType()->isVectorTy()
++ ? ConstantVector::getSplat(
++ cast<VectorType>(GEPTy)->getNumElements(), C)
++ : C;
+
+ if (C->isNullValue()) {
+ bool isNull = true;
diff --git a/devel/llvm60/files/patch-head-r331366.diff b/devel/llvm60/files/patch-head-r331366.diff
new file mode 100644
index 000000000000..dccde7fb6bd6
--- /dev/null
+++ b/devel/llvm60/files/patch-head-r331366.diff
@@ -0,0 +1,609 @@
+r331366 | dim | 2018-03-22 19:58:34 +0100 (Thu, 22 Mar 2018) | 61 lines
+
+Pull in r327101 from upstream llvm trunk (by Rafael Espindola):
+
+ Don't treat .symver as a regular alias definition.
+
+ This patch starts simplifying the handling of .symver.
+
+ For now it just moves the responsibility for creating an alias down to
+ the streamer. With that the asm streamer can pass a .symver unchanged,
+ which is nice since gas cannot parse "foo@bar = zed".
+
+ In a followup I hope to move the handling down to the writer so that
+ we don't need special hacks for avoiding breaking names with @@@ on
+ windows.
+
+Pull in r327160 from upstream llvm trunk (by Rafael Espindola):
+
+ Delay creating an alias for @@@.
+
+ With this we only create an alias for @@@ once we know if it should
+ use @ or @@. This avoids last minutes renames and hacks to handle MS
+ names.
+
+ This only handles the ELF writer. LTO still has issues with @@@
+ aliases.
+
+Pull in r327928 from upstream llvm trunk (by Vitaly Buka):
+
+ Object: Move attribute calculation into RecordStreamer. NFC
+
+ Summary: Preparation for D44274
+
+ Reviewers: pcc, espindola
+
+ Subscribers: hiraditya
+
+ Differential Revision: https://reviews.llvm.org/D44276
+
+Pull in r327930 from upstream llvm trunk (by Vitaly Buka):
+
+ Object: Fix handling of @@@ in .symver directive
+
+ Summary:
+ name@@@nodename is going to be replaced with name@@nodename if symbols is
+ defined in the assembled file, or name@nodename if undefined.
+ https://sourceware.org/binutils/docs/as/Symver.html
+
+ Fixes PR36623
+
+ Reviewers: pcc, espindola
+
+ Subscribers: mehdi_amini, hiraditya
+
+ Differential Revision: https://reviews.llvm.org/D44274
+
+Together, these changes fix handling of @@@ in .symver directives when
+doing Link Time Optimization.
+
+Reported by: Shawn Webb <shawn.webb@hardenedbsd.org>
+MFC after: 3 months
+X-MFC-With: r327952
+
+Index: include/llvm/MC/MCAssembler.h
+===================================================================
+--- include/llvm/MC/MCAssembler.h (revision 331365)
++++ include/llvm/MC/MCAssembler.h (revision 331366)
+@@ -206,6 +206,8 @@ class MCAssembler {
+ handleFixup(const MCAsmLayout &Layout, MCFragment &F, const MCFixup &Fixup);
+
+ public:
++ std::vector<std::pair<StringRef, const MCSymbol *>> Symvers;
++
+ /// Construct a new assembler instance.
+ //
+ // FIXME: How are we going to parameterize this? Two obvious options are stay
+Index: include/llvm/MC/MCELFStreamer.h
+===================================================================
+--- include/llvm/MC/MCELFStreamer.h (revision 331365)
++++ include/llvm/MC/MCELFStreamer.h (revision 331366)
+@@ -51,6 +51,8 @@ class MCELFStreamer : public MCObjectStreamer {
+ unsigned ByteAlignment) override;
+
+ void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
++ void emitELFSymverDirective(StringRef AliasName,
++ const MCSymbol *Aliasee) override;
+
+ void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) override;
+Index: include/llvm/MC/MCStreamer.h
+===================================================================
+--- include/llvm/MC/MCStreamer.h (revision 331365)
++++ include/llvm/MC/MCStreamer.h (revision 331366)
+@@ -519,9 +519,10 @@ class MCStreamer {
+ ///
+ /// This corresponds to an assembler statement such as:
+ /// .symver _start, foo@@SOME_VERSION
+- /// \param Alias - The versioned alias (i.e. "foo@@SOME_VERSION")
++ /// \param AliasName - The versioned alias (i.e. "foo@@SOME_VERSION")
+ /// \param Aliasee - The aliased symbol (i.e. "_start")
+- virtual void emitELFSymverDirective(MCSymbol *Alias, const MCSymbol *Aliasee);
++ virtual void emitELFSymverDirective(StringRef AliasName,
++ const MCSymbol *Aliasee);
+
+ /// \brief Emit a Linker Optimization Hint (LOH) directive.
+ /// \param Args - Arguments of the LOH.
+Index: lib/MC/ELFObjectWriter.cpp
+===================================================================
+--- lib/MC/ELFObjectWriter.cpp (revision 331365)
++++ lib/MC/ELFObjectWriter.cpp (revision 331366)
+@@ -128,8 +128,6 @@ class ELFObjectWriter : public MCObjectWriter {
+ /// @name Symbol Table Data
+ /// @{
+
+- BumpPtrAllocator Alloc;
+- StringSaver VersionSymSaver{Alloc};
+ StringTableBuilder StrTabBuilder{StringTableBuilder::ELF};
+
+ /// @}
+@@ -391,27 +389,29 @@ void ELFObjectWriter::executePostLayoutBinding(MCA
+ const MCAsmLayout &Layout) {
+ // The presence of symbol versions causes undefined symbols and
+ // versions declared with @@@ to be renamed.
+- for (const MCSymbol &A : Asm.symbols()) {
+- const auto &Alias = cast<MCSymbolELF>(A);
+- // Not an alias.
+- if (!Alias.isVariable())
+- continue;
+- auto *Ref = dyn_cast<MCSymbolRefExpr>(Alias.getVariableValue());
+- if (!Ref)
+- continue;
+- const auto &Symbol = cast<MCSymbolELF>(Ref->getSymbol());
+-
+- StringRef AliasName = Alias.getName();
++ for (const std::pair<StringRef, const MCSymbol *> &P : Asm.Symvers) {
++ StringRef AliasName = P.first;
++ const auto &Symbol = cast<MCSymbolELF>(*P.second);
+ size_t Pos = AliasName.find('@');
+- if (Pos == StringRef::npos)
+- continue;
++ assert(Pos != StringRef::npos);
+
++ StringRef Prefix = AliasName.substr(0, Pos);
++ StringRef Rest = AliasName.substr(Pos);
++ StringRef Tail = Rest;
++ if (Rest.startswith("@@@"))
++ Tail = Rest.substr(Symbol.isUndefined() ? 2 : 1);
++
++ auto *Alias =
++ cast<MCSymbolELF>(Asm.getContext().getOrCreateSymbol(Prefix + Tail));
++ Asm.registerSymbol(*Alias);
++ const MCExpr *Value = MCSymbolRefExpr::create(&Symbol, Asm.getContext());
++ Alias->setVariableValue(Value);
++
+ // Aliases defined with .symvar copy the binding from the symbol they alias.
+ // This is the first place we are able to copy this information.
+- Alias.setExternal(Symbol.isExternal());
+- Alias.setBinding(Symbol.getBinding());
++ Alias->setExternal(Symbol.isExternal());
++ Alias->setBinding(Symbol.getBinding());
+
+- StringRef Rest = AliasName.substr(Pos);
+ if (!Symbol.isUndefined() && !Rest.startswith("@@@"))
+ continue;
+
+@@ -420,7 +420,7 @@ void ELFObjectWriter::executePostLayoutBinding(MCA
+ !Rest.startswith("@@@"))
+ report_fatal_error("A @@ version cannot be undefined");
+
+- Renames.insert(std::make_pair(&Symbol, &Alias));
++ Renames.insert(std::make_pair(&Symbol, Alias));
+ }
+ }
+
+@@ -836,44 +836,7 @@ void ELFObjectWriter::computeSymbolTable(
+ HasLargeSectionIndex = true;
+ }
+
+- // The @@@ in symbol version is replaced with @ in undefined symbols and @@
+- // in defined ones.
+- //
+- // FIXME: All name handling should be done before we get to the writer,
+- // including dealing with GNU-style version suffixes. Fixing this isn't
+- // trivial.
+- //
+- // We thus have to be careful to not perform the symbol version replacement
+- // blindly:
+- //
+- // The ELF format is used on Windows by the MCJIT engine. Thus, on
+- // Windows, the ELFObjectWriter can encounter symbols mangled using the MS
+- // Visual Studio C++ name mangling scheme. Symbols mangled using the MSVC
+- // C++ name mangling can legally have "@@@" as a sub-string. In that case,
+- // the EFLObjectWriter should not interpret the "@@@" sub-string as
+- // specifying GNU-style symbol versioning. The ELFObjectWriter therefore
+- // checks for the MSVC C++ name mangling prefix which is either "?", "@?",
+- // "__imp_?" or "__imp_@?".
+- //
+- // It would have been interesting to perform the MS mangling prefix check
+- // only when the target triple is of the form *-pc-windows-elf. But, it
+- // seems that this information is not easily accessible from the
+- // ELFObjectWriter.
+ StringRef Name = Symbol.getName();
+- SmallString<32> Buf;
+- if (!Name.startswith("?") && !Name.startswith("@?") &&
+- !Name.startswith("__imp_?") && !Name.startswith("__imp_@?")) {
+- // This symbol isn't following the MSVC C++ name mangling convention. We
+- // can thus safely interpret the @@@ in symbol names as specifying symbol
+- // versioning.
+- size_t Pos = Name.find("@@@");
+- if (Pos != StringRef::npos) {
+- Buf += Name.substr(0, Pos);
+- unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1;
+- Buf += Name.substr(Pos + Skip);
+- Name = VersionSymSaver.save(Buf.c_str());
+- }
+- }
+
+ // Sections have their own string table
+ if (Symbol.getType() != ELF::STT_SECTION) {
+Index: lib/MC/MCAsmStreamer.cpp
+===================================================================
+--- lib/MC/MCAsmStreamer.cpp (revision 331365)
++++ lib/MC/MCAsmStreamer.cpp (revision 331366)
+@@ -129,6 +129,9 @@ class MCAsmStreamer final : public MCStreamer {
+
+ void ChangeSection(MCSection *Section, const MCExpr *Subsection) override;
+
++ void emitELFSymverDirective(StringRef AliasName,
++ const MCSymbol *Aliasee) override;
++
+ void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override;
+ void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
+
+@@ -411,6 +414,14 @@ void MCAsmStreamer::ChangeSection(MCSection *Secti
+ }
+ }
+
++void MCAsmStreamer::emitELFSymverDirective(StringRef AliasName,
++ const MCSymbol *Aliasee) {
++ OS << ".symver ";
++ Aliasee->print(OS, MAI);
++ OS << ", " << AliasName;
++ EmitEOL();
++}
++
+ void MCAsmStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
+ MCStreamer::EmitLabel(Symbol, Loc);
+
+Index: lib/MC/MCELFStreamer.cpp
+===================================================================
+--- lib/MC/MCELFStreamer.cpp (revision 331365)
++++ lib/MC/MCELFStreamer.cpp (revision 331366)
+@@ -337,6 +337,11 @@ void MCELFStreamer::emitELFSize(MCSymbol *Symbol,
+ cast<MCSymbolELF>(Symbol)->setSize(Value);
+ }
+
++void MCELFStreamer::emitELFSymverDirective(StringRef AliasName,
++ const MCSymbol *Aliasee) {
++ getAssembler().Symvers.push_back({AliasName, Aliasee});
++}
++
+ void MCELFStreamer::EmitLocalCommonSymbol(MCSymbol *S, uint64_t Size,
+ unsigned ByteAlignment) {
+ auto *Symbol = cast<MCSymbolELF>(S);
+Index: lib/MC/MCParser/ELFAsmParser.cpp
+===================================================================
+--- lib/MC/MCParser/ELFAsmParser.cpp (revision 331365)
++++ lib/MC/MCParser/ELFAsmParser.cpp (revision 331366)
+@@ -767,12 +767,8 @@ bool ELFAsmParser::ParseDirectiveSymver(StringRef,
+ if (AliasName.find('@') == StringRef::npos)
+ return TokError("expected a '@' in the name");
+
+- MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName);
+ MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
+- const MCExpr *Value = MCSymbolRefExpr::create(Sym, getContext());
+-
+- getStreamer().EmitAssignment(Alias, Value);
+- getStreamer().emitELFSymverDirective(Alias, Sym);
++ getStreamer().emitELFSymverDirective(AliasName, Sym);
+ return false;
+ }
+
+Index: lib/MC/MCStreamer.cpp
+===================================================================
+--- lib/MC/MCStreamer.cpp (revision 331365)
++++ lib/MC/MCStreamer.cpp (revision 331366)
+@@ -925,7 +925,7 @@ void MCStreamer::EmitCOFFSymbolType(int Type) {
+ llvm_unreachable("this directive only supported on COFF targets");
+ }
+ void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
+-void MCStreamer::emitELFSymverDirective(MCSymbol *Alias,
++void MCStreamer::emitELFSymverDirective(StringRef AliasName,
+ const MCSymbol *Aliasee) {}
+ void MCStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) {}
+Index: lib/Object/ModuleSymbolTable.cpp
+===================================================================
+--- lib/Object/ModuleSymbolTable.cpp (revision 331365)
++++ lib/Object/ModuleSymbolTable.cpp (revision 331366)
+@@ -24,7 +24,6 @@
+ #include "llvm/IR/GlobalAlias.h"
+ #include "llvm/IR/GlobalValue.h"
+ #include "llvm/IR/GlobalVariable.h"
+-#include "llvm/IR/Mangler.h"
+ #include "llvm/IR/Module.h"
+ #include "llvm/MC/MCAsmInfo.h"
+ #include "llvm/MC/MCContext.h"
+@@ -69,81 +68,6 @@ void ModuleSymbolTable::addModule(Module *M) {
+ });
+ }
+
+-// Ensure ELF .symver aliases get the same binding as the defined symbol
+-// they alias with.
+-static void handleSymverAliases(const Module &M, RecordStreamer &Streamer) {
+- if (Streamer.symverAliases().empty())
+- return;
+-
+- // The name in the assembler will be mangled, but the name in the IR
+- // might not, so we first compute a mapping from mangled name to GV.
+- Mangler Mang;
+- SmallString<64> MangledName;
+- StringMap<const GlobalValue *> MangledNameMap;
+- auto GetMangledName = [&](const GlobalValue &GV) {
+- if (!GV.hasName())
+- return;
+-
+- MangledName.clear();
+- MangledName.reserve(GV.getName().size() + 1);
+- Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false);
+- MangledNameMap[MangledName] = &GV;
+- };
+- for (const Function &F : M)
+- GetMangledName(F);
+- for (const GlobalVariable &GV : M.globals())
+- GetMangledName(GV);
+- for (const GlobalAlias &GA : M.aliases())
+- GetMangledName(GA);
+-
+- // Walk all the recorded .symver aliases, and set up the binding
+- // for each alias.
+- for (auto &Symver : Streamer.symverAliases()) {
+- const MCSymbol *Aliasee = Symver.first;
+- MCSymbolAttr Attr = MCSA_Invalid;
+-
+- // First check if the aliasee binding was recorded in the asm.
+- RecordStreamer::State state = Streamer.getSymbolState(Aliasee);
+- switch (state) {
+- case RecordStreamer::Global:
+- case RecordStreamer::DefinedGlobal:
+- Attr = MCSA_Global;
+- break;
+- case RecordStreamer::UndefinedWeak:
+- case RecordStreamer::DefinedWeak:
+- Attr = MCSA_Weak;
+- break;
+- default:
+- break;
+- }
+-
+- // If we don't have a symbol attribute from assembly, then check if
+- // the aliasee was defined in the IR.
+- if (Attr == MCSA_Invalid) {
+- const auto *GV = M.getNamedValue(Aliasee->getName());
+- if (!GV) {
+- auto MI = MangledNameMap.find(Aliasee->getName());
+- if (MI != MangledNameMap.end())
+- GV = MI->second;
+- else
+- continue;
+- }
+- if (GV->hasExternalLinkage())
+- Attr = MCSA_Global;
+- else if (GV->hasLocalLinkage())
+- Attr = MCSA_Local;
+- else if (GV->isWeakForLinker())
+- Attr = MCSA_Weak;
+- }
+- if (Attr == MCSA_Invalid)
+- continue;
+-
+- // Set the detected binding on each alias with this aliasee.
+- for (auto &Alias : Symver.second)
+- Streamer.EmitSymbolAttribute(Alias, Attr);
+- }
+-}
+-
+ void ModuleSymbolTable::CollectAsmSymbols(
+ const Module &M,
+ function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmSymbol) {
+@@ -176,7 +100,7 @@ void ModuleSymbolTable::CollectAsmSymbols(
+ MCObjectFileInfo MOFI;
+ MCContext MCCtx(MAI.get(), MRI.get(), &MOFI);
+ MOFI.InitMCObjectFileInfo(TT, /*PIC*/ false, MCCtx);
+- RecordStreamer Streamer(MCCtx);
++ RecordStreamer Streamer(MCCtx, M);
+ T->createNullTargetStreamer(Streamer);
+
+ std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm));
+@@ -195,7 +119,7 @@ void ModuleSymbolTable::CollectAsmSymbols(
+ if (Parser->Run(false))
+ return;
+
+- handleSymverAliases(M, Streamer);
++ Streamer.flushSymverDirectives();
+
+ for (auto &KV : Streamer) {
+ StringRef Key = KV.first();
+Index: lib/Object/RecordStreamer.cpp
+===================================================================
+--- lib/Object/RecordStreamer.cpp (revision 331365)
++++ lib/Object/RecordStreamer.cpp (revision 331366)
+@@ -8,6 +8,9 @@
+ //===----------------------------------------------------------------------===//
+
+ #include "RecordStreamer.h"
++#include "llvm/IR/Mangler.h"
++#include "llvm/IR/Module.h"
++#include "llvm/MC/MCContext.h"
+ #include "llvm/MC/MCSymbol.h"
+
+ using namespace llvm;
+@@ -70,7 +73,8 @@ void RecordStreamer::markUsed(const MCSymbol &Symb
+
+ void RecordStreamer::visitUsedSymbol(const MCSymbol &Sym) { markUsed(Sym); }
+
+-RecordStreamer::RecordStreamer(MCContext &Context) : MCStreamer(Context) {}
++RecordStreamer::RecordStreamer(MCContext &Context, const Module &M)
++ : MCStreamer(Context), M(M) {}
+
+ RecordStreamer::const_iterator RecordStreamer::begin() {
+ return Symbols.begin();
+@@ -112,7 +116,109 @@ void RecordStreamer::EmitCommonSymbol(MCSymbol *Sy
+ markDefined(*Symbol);
+ }
+
+-void RecordStreamer::emitELFSymverDirective(MCSymbol *Alias,
++RecordStreamer::State RecordStreamer::getSymbolState(const MCSymbol *Sym) {
++ auto SI = Symbols.find(Sym->getName());
++ if (SI == Symbols.end())
++ return NeverSeen;
++ return SI->second;
++}
++
++void RecordStreamer::emitELFSymverDirective(StringRef AliasName,
+ const MCSymbol *Aliasee) {
+- SymverAliasMap[Aliasee].push_back(Alias);
++ SymverAliasMap[Aliasee].push_back(AliasName);
+ }
++
++void RecordStreamer::flushSymverDirectives() {
++ // Mapping from mangled name to GV.
++ StringMap<const GlobalValue *> MangledNameMap;
++ // The name in the assembler will be mangled, but the name in the IR
++ // might not, so we first compute a mapping from mangled name to GV.
++ Mangler Mang;
++ SmallString<64> MangledName;
++ for (const GlobalValue &GV : M.global_values()) {
++ if (!GV.hasName())
++ continue;
++ MangledName.clear();
++ MangledName.reserve(GV.getName().size() + 1);
++ Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false);
++ MangledNameMap[MangledName] = &GV;
++ }
++
++ // Walk all the recorded .symver aliases, and set up the binding
++ // for each alias.
++ for (auto &Symver : SymverAliasMap) {
++ const MCSymbol *Aliasee = Symver.first;
++ MCSymbolAttr Attr = MCSA_Invalid;
++ bool IsDefined = false;
++
++ // First check if the aliasee binding was recorded in the asm.
++ RecordStreamer::State state = getSymbolState(Aliasee);
++ switch (state) {
++ case RecordStreamer::Global:
++ case RecordStreamer::DefinedGlobal:
++ Attr = MCSA_Global;
++ break;
++ case RecordStreamer::UndefinedWeak:
++ case RecordStreamer::DefinedWeak:
++ Attr = MCSA_Weak;
++ break;
++ default:
++ break;
++ }
++
++ switch (state) {
++ case RecordStreamer::Defined:
++ case RecordStreamer::DefinedGlobal:
++ case RecordStreamer::DefinedWeak:
++ IsDefined = true;
++ break;
++ case RecordStreamer::NeverSeen:
++ case RecordStreamer::Global:
++ case RecordStreamer::Used:
++ case RecordStreamer::UndefinedWeak:
++ break;
++ }
++
++ if (Attr == MCSA_Invalid || !IsDefined) {
++ const GlobalValue *GV = M.getNamedValue(Aliasee->getName());
++ if (!GV) {
++ auto MI = MangledNameMap.find(Aliasee->getName());
++ if (MI != MangledNameMap.end())
++ GV = MI->second;
++ }
++ if (GV) {
++ // If we don't have a symbol attribute from assembly, then check if
++ // the aliasee was defined in the IR.
++ if (Attr == MCSA_Invalid) {
++ if (GV->hasExternalLinkage())
++ Attr = MCSA_Global;
++ else if (GV->hasLocalLinkage())
++ Attr = MCSA_Local;
++ else if (GV->isWeakForLinker())
++ Attr = MCSA_Weak;
++ }
++ IsDefined = IsDefined || !GV->isDeclarationForLinker();
++ }
++ }
++
++ // Set the detected binding on each alias with this aliasee.
++ for (auto AliasName : Symver.second) {
++ std::pair<StringRef, StringRef> Split = AliasName.split("@@@");
++ SmallString<128> NewName;
++ if (!Split.second.empty() && !Split.second.startswith("@")) {
++ // Special processing for "@@@" according
++ // https://sourceware.org/binutils/docs/as/Symver.html
++ const char *Separator = IsDefined ? "@@" : "@";
++ AliasName =
++ (Split.first + Separator + Split.second).toStringRef(NewName);
++ }
++ MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName);
++ // TODO: Handle "@@@". Depending on SymbolAttribute value it needs to be
++ // converted into @ or @@.
++ const MCExpr *Value = MCSymbolRefExpr::create(Aliasee, getContext());
++ EmitAssignment(Alias, Value);
++ if (Attr != MCSA_Invalid)
++ EmitSymbolAttribute(Alias, Attr);
++ }
++ }
++}
+Index: lib/Object/RecordStreamer.h
+===================================================================
+--- lib/Object/RecordStreamer.h (revision 331365)
++++ lib/Object/RecordStreamer.h (revision 331366)
+@@ -20,6 +20,9 @@
+
+ namespace llvm {
+
++class GlobalValue;
++class Module;
++
+ class RecordStreamer : public MCStreamer {
+ public:
+ enum State { NeverSeen, Global, Defined, DefinedGlobal, DefinedWeak, Used,
+@@ -26,12 +29,16 @@ class RecordStreamer : public MCStreamer {
+ UndefinedWeak};
+
+ private:
++ const Module &M;
+ StringMap<State> Symbols;
+ // Map of aliases created by .symver directives, saved so we can update
+ // their symbol binding after parsing complete. This maps from each
+ // aliasee to its list of aliases.
+- DenseMap<const MCSymbol *, std::vector<MCSymbol *>> SymverAliasMap;
++ DenseMap<const MCSymbol *, std::vector<StringRef>> SymverAliasMap;
+
++ /// Get the state recorded for the given symbol.
++ State getSymbolState(const MCSymbol *Sym);
++
+ void markDefined(const MCSymbol &Symbol);
+ void markGlobal(const MCSymbol &Symbol, MCSymbolAttr Attribute);
+ void markUsed(const MCSymbol &Symbol);
+@@ -38,7 +45,7 @@ class RecordStreamer : public MCStreamer {
+ void visitUsedSymbol(const MCSymbol &Sym) override;
+
+ public:
+- RecordStreamer(MCContext &Context);
++ RecordStreamer(MCContext &Context, const Module &M);
+
+ using const_iterator = StringMap<State>::const_iterator;
+
+@@ -54,20 +61,11 @@ class RecordStreamer : public MCStreamer {
+ void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) override;
+ /// Record .symver aliases for later processing.
+- void emitELFSymverDirective(MCSymbol *Alias,
++ void emitELFSymverDirective(StringRef AliasName,
+ const MCSymbol *Aliasee) override;
+- /// Return the map of .symver aliasee to associated aliases.
+- DenseMap<const MCSymbol *, std::vector<MCSymbol *>> &symverAliases() {
+- return SymverAliasMap;
+- }
+-
+- /// Get the state recorded for the given symbol.
+- State getSymbolState(const MCSymbol *Sym) {
+- auto SI = Symbols.find(Sym->getName());
+- if (SI == Symbols.end())
+- return NeverSeen;
+- return SI->second;
+- }
++ // Emit ELF .symver aliases and ensure they have the same binding as the
++ // defined symbol they alias with.
++ void flushSymverDirectives();
+ };
+
+ } // end namespace llvm
diff --git a/devel/llvm60/files/patch-head-r336969.diff b/devel/llvm60/files/patch-head-r336969.diff
new file mode 100644
index 000000000000..640b0d146c6c
--- /dev/null
+++ b/devel/llvm60/files/patch-head-r336969.diff
@@ -0,0 +1,32 @@
+r336969 | emaste | 2018-07-31 16:12:09 +0200 (Tue, 31 Jul 2018) | 13 lines
+
+llvm: [ELF][ARM] Add Arm ABI names for float ABI ELF Header flags
+
+The ELF for the Arm architecture document defines, for EF_ARM_EABI_VER5
+and above, the flags EF_ARM_ABI_FLOAT_HARD and EF_ARM_ABI_FLOAT_SOFT.
+These have been defined to be compatible with the existing
+EF_ARM_VFP_FLOAT and EF_ARM_SOFT_FLOAT used by gcc for
+EF_ARM_EABI_UNKNOWN.
+
+This patch adds the flags in addition to the existing ones so that any
+code depending on the old names will still work.
+
+Obtained from: llvm r338370 by Peter Smith
+
+Index: include/llvm/BinaryFormat/ELF.h
+===================================================================
+--- include/llvm/BinaryFormat/ELF.h (revision 336968)
++++ include/llvm/BinaryFormat/ELF.h (revision 336969)
+@@ -418,8 +418,10 @@ enum {
+
+ // ARM Specific e_flags
+ enum : unsigned {
+- EF_ARM_SOFT_FLOAT = 0x00000200U,
+- EF_ARM_VFP_FLOAT = 0x00000400U,
++ EF_ARM_SOFT_FLOAT = 0x00000200U, // Legacy pre EABI_VER5
++ EF_ARM_ABI_FLOAT_SOFT = 0x00000200U, // EABI_VER5
++ EF_ARM_VFP_FLOAT = 0x00000400U, // Legacy pre EABI_VER5
++ EF_ARM_ABI_FLOAT_HARD = 0x00000400U, // EABI_VER5
+ EF_ARM_EABI_UNKNOWN = 0x00000000U,
+ EF_ARM_EABI_VER1 = 0x01000000U,
+ EF_ARM_EABI_VER2 = 0x02000000U,
diff --git a/devel/llvm60/files/patch-head-r336970.diff b/devel/llvm60/files/patch-head-r336970.diff
new file mode 100644
index 000000000000..d788914eb445
--- /dev/null
+++ b/devel/llvm60/files/patch-head-r336970.diff
@@ -0,0 +1,24 @@
+r336970 | emaste | 2018-07-31 16:14:41 +0200 (Tue, 31 Jul 2018) | 9 lines
+
+llvm: [ARM] Complete enumeration values for Tag_ABI_VFP_args
+
+The LLD implementation of Tag_ABI_VFP_args needs to check the rarely
+seen values of 3 (toolchain specific) and 4 compatible with both Base
+and VFP. Add the missing enumeration values so that LLD can refer to
+them without having to use the raw numbers.
+
+Obtained from: llvm r338373 by Peter Smith
+
+Index: include/llvm/Support/ARMBuildAttributes.h
+===================================================================
+--- include/llvm/Support/ARMBuildAttributes.h (revision 336969)
++++ include/llvm/Support/ARMBuildAttributes.h (revision 336970)
+@@ -213,6 +213,8 @@ enum {
+ // Tag_ABI_VFP_args, (=28), uleb128
+ BaseAAPCS = 0,
+ HardFPAAPCS = 1,
++ ToolChainFPPCS = 2,
++ CompatibleFPAAPCS = 3,
+
+ // Tag_FP_HP_extension, (=36), uleb128
+ AllowHPFP = 1, // Allow use of Half Precision FP
diff --git a/devel/llvm60/files/patch-head-r337615.diff b/devel/llvm60/files/patch-head-r337615.diff
new file mode 100644
index 000000000000..645240b71cf3
--- /dev/null
+++ b/devel/llvm60/files/patch-head-r337615.diff
@@ -0,0 +1,64 @@
+r337615 | dim | 2018-08-11 12:42:12 +0200 (Sat, 11 Aug 2018) | 43 lines
+
+Pull in r338481 from upstream llvm trunk (by Chandler Carruth):
+
+ [x86] Fix a really subtle miscompile due to a somewhat glaring bug in
+ EFLAGS copy lowering.
+
+ If you have a branch of LLVM, you may want to cherrypick this. It is
+ extremely unlikely to hit this case empirically, but it will likely
+ manifest as an "impossible" branch being taken somewhere, and will be
+ ... very hard to debug.
+
+ Hitting this requires complex conditions living across complex
+ control flow combined with some interesting memory (non-stack)
+ initialized with the results of a comparison. Also, because you have
+ to arrange for an EFLAGS copy to be in *just* the right place, almost
+ anything you do to the code will hide the bug. I was unable to reduce
+ anything remotely resembling a "good" test case from the place where
+ I hit it, and so instead I have constructed synthetic MIR testing
+ that directly exercises the bug in question (as well as the good
+ behavior for completeness).
+
+ The issue is that we would mistakenly assume any SETcc with a valid
+ condition and an initial operand that was a register and a virtual
+ register at that to be a register *defining* SETcc...
+
+ It isn't though....
+
+ This would in turn cause us to test some other bizarre register,
+ typically the base pointer of some memory. Now, testing this register
+ and using that to branch on doesn't make any sense. It even fails the
+ machine verifier (if you are running it) due to the wrong register
+ class. But it will make it through LLVM, assemble, and it *looks*
+ fine... But wow do you get a very unsual and surprising branch taken
+ in your actual code.
+
+ The fix is to actually check what kind of SETcc instruction we're
+ dealing with. Because there are a bunch of them, I just test the
+ may-store bit in the instruction. I've also added an assert for
+ sanity that ensure we are, in fact, *defining* the register operand.
+ =D
+
+Noticed by: kib
+MFC after: 1 week
+
+Index: lib/Target/X86/X86FlagsCopyLowering.cpp
+===================================================================
+--- lib/Target/X86/X86FlagsCopyLowering.cpp (revision 337614)
++++ lib/Target/X86/X86FlagsCopyLowering.cpp (revision 337615)
+@@ -608,9 +608,12 @@ X86FlagsCopyLoweringPass::collectCondsInRegs(Machi
+ for (MachineInstr &MI : llvm::reverse(
+ llvm::make_range(MBB.instr_begin(), CopyDefI.getIterator()))) {
+ X86::CondCode Cond = X86::getCondFromSETOpc(MI.getOpcode());
+- if (Cond != X86::COND_INVALID && MI.getOperand(0).isReg() &&
+- TRI->isVirtualRegister(MI.getOperand(0).getReg()))
++ if (Cond != X86::COND_INVALID && !MI.mayStore() && MI.getOperand(0).isReg() &&
++ TRI->isVirtualRegister(MI.getOperand(0).getReg())) {
++ assert(MI.getOperand(0).isDef() &&
++ "A non-storing SETcc should always define a register!");
+ CondRegs[Cond] = MI.getOperand(0).getReg();
++ }
+
+ // Stop scanning when we see the first definition of the EFLAGS as prior to
+ // this we would potentially capture the wrong flag state.
diff --git a/devel/llvm60/files/patch-head-r338689.diff b/devel/llvm60/files/patch-head-r338689.diff
new file mode 100644
index 000000000000..c0a785e779ee
--- /dev/null
+++ b/devel/llvm60/files/patch-head-r338689.diff
@@ -0,0 +1,32 @@
+r338689 | dim | 2018-09-14 21:25:23 +0200 (Fri, 14 Sep 2018) | 12 lines
+
+Pull in r335365 from upstream llvm trunk (by Krzysztof Parzyszek):
+
+ Initialize LiveRegs once in BranchFolder::mergeCommonTails
+
+This should fix '(TRI && "LivePhysRegs is not initialized."' assertions
+when building the lang/qt5-qml port in certain configurations.
+
+Approved by: re (kib)
+Reported by: Piotr Kubaj <pkubaj@anongoth.pl>
+PR: 231355
+MFC after: 3 days
+
+Index: lib/CodeGen/BranchFolding.cpp
+===================================================================
+--- lib/CodeGen/BranchFolding.cpp (revision 338688)
++++ lib/CodeGen/BranchFolding.cpp (revision 338689)
+@@ -884,11 +884,12 @@ void BranchFolder::mergeCommonTails(unsigned commo
+ if (UpdateLiveIns) {
+ LivePhysRegs NewLiveIns(*TRI);
+ computeLiveIns(NewLiveIns, *MBB);
++ LiveRegs.init(*TRI);
+
+ // The flag merging may lead to some register uses no longer using the
+ // <undef> flag, add IMPLICIT_DEFs in the predecessors as necessary.
+ for (MachineBasicBlock *Pred : MBB->predecessors()) {
+- LiveRegs.init(*TRI);
++ LiveRegs.clear();
+ LiveRegs.addLiveOuts(*Pred);
+ MachineBasicBlock::iterator InsertBefore = Pred->getFirstTerminator();
+ for (unsigned Reg : NewLiveIns) {
diff --git a/devel/llvm60/files/patch-svn-r322325 b/devel/llvm60/files/patch-svn-r322325
new file mode 100644
index 000000000000..3b0501e37022
--- /dev/null
+++ b/devel/llvm60/files/patch-svn-r322325
@@ -0,0 +1,1589 @@
+r322325:
+
+PeepholeOpt cleanup/refactor; NFC
+
+- Less unnecessary use of `auto`
+- Add early `using RegSubRegPair(AndIdx) =` to avoid countless
+ `TargetInstrInfo::` qualifications.
+- Use references instead of pointers where possible.
+- Remove unused parameters.
+- Rewrite the CopyRewriter class hierarchy:
+ - Pull out uncoalescable copy rewriting functionality into
+ PeepholeOptimizer class.
+ - Use an abstract base class to make it clear that rewriters are
+ independent.
+- Remove unnecessary \brief in doxygen comments.
+- Remove unused constructor and method from ValueTracker.
+- Replace UseAdvancedTracking of ValueTracker with DisableAdvCopyOpt use.
+
+--- lib/CodeGen/PeepholeOptimizer.cpp.orig
++++ lib/CodeGen/PeepholeOptimizer.cpp
+@@ -98,6 +98,8 @@
+ #include <utility>
+
+ using namespace llvm;
++using RegSubRegPair = TargetInstrInfo::RegSubRegPair;
++using RegSubRegPairAndIdx = TargetInstrInfo::RegSubRegPairAndIdx;
+
+ #define DEBUG_TYPE "peephole-opt"
+
+@@ -110,6 +112,9 @@
+ DisablePeephole("disable-peephole", cl::Hidden, cl::init(false),
+ cl::desc("Disable the peephole optimizer"));
+
++/// Specifiy whether or not the value tracking looks through
++/// complex instructions. When this is true, the value tracker
++/// bails on everything that is not a copy or a bitcast.
+ static cl::opt<bool>
+ DisableAdvCopyOpt("disable-adv-copy-opt", cl::Hidden, cl::init(false),
+ cl::desc("Disable advanced copy optimization"));
+@@ -132,11 +137,11 @@
+ "of commuting operands"));
+
+
+-STATISTIC(NumReuse, "Number of extension results reused");
+-STATISTIC(NumCmps, "Number of compares eliminated");
+-STATISTIC(NumImmFold, "Number of move immediate folded");
+-STATISTIC(NumLoadFold, "Number of loads folded");
+-STATISTIC(NumSelects, "Number of selects optimized");
++STATISTIC(NumReuse, "Number of extension results reused");
++STATISTIC(NumCmps, "Number of compares eliminated");
++STATISTIC(NumImmFold, "Number of move immediate folded");
++STATISTIC(NumLoadFold, "Number of loads folded");
++STATISTIC(NumSelects, "Number of selects optimized");
+ STATISTIC(NumUncoalescableCopies, "Number of uncoalescable copies optimized");
+ STATISTIC(NumRewrittenCopies, "Number of copies rewritten");
+ STATISTIC(NumNAPhysCopies, "Number of non-allocatable physical copies removed");
+@@ -149,9 +154,9 @@
+ class PeepholeOptimizer : public MachineFunctionPass {
+ const TargetInstrInfo *TII;
+ const TargetRegisterInfo *TRI;
+- MachineRegisterInfo *MRI;
+- MachineDominatorTree *DT; // Machine dominator tree
+- MachineLoopInfo *MLI;
++ MachineRegisterInfo *MRI;
++ MachineDominatorTree *DT; // Machine dominator tree
++ MachineLoopInfo *MLI;
+
+ public:
+ static char ID; // Pass identification
+@@ -173,31 +178,28 @@
+ }
+ }
+
+- /// \brief Track Def -> Use info used for rewriting copies.
+- using RewriteMapTy =
+- SmallDenseMap<TargetInstrInfo::RegSubRegPair, ValueTrackerResult>;
++ /// Track Def -> Use info used for rewriting copies.
++ using RewriteMapTy = SmallDenseMap<RegSubRegPair, ValueTrackerResult>;
+
+- /// \brief Sequence of instructions that formulate recurrence cycle.
++ /// Sequence of instructions that formulate recurrence cycle.
+ using RecurrenceCycle = SmallVector<RecurrenceInstr, 4>;
+
+ private:
+- bool optimizeCmpInstr(MachineInstr *MI, MachineBasicBlock *MBB);
+- bool optimizeExtInstr(MachineInstr *MI, MachineBasicBlock *MBB,
++ bool optimizeCmpInstr(MachineInstr &MI);
++ bool optimizeExtInstr(MachineInstr &MI, MachineBasicBlock &MBB,
+ SmallPtrSetImpl<MachineInstr*> &LocalMIs);
+- bool optimizeSelect(MachineInstr *MI,
++ bool optimizeSelect(MachineInstr &MI,
+ SmallPtrSetImpl<MachineInstr *> &LocalMIs);
+- bool optimizeCondBranch(MachineInstr *MI);
+- bool optimizeCoalescableCopy(MachineInstr *MI);
+- bool optimizeUncoalescableCopy(MachineInstr *MI,
++ bool optimizeCondBranch(MachineInstr &MI);
++ bool optimizeCoalescableCopy(MachineInstr &MI);
++ bool optimizeUncoalescableCopy(MachineInstr &MI,
+ SmallPtrSetImpl<MachineInstr *> &LocalMIs);
+ bool optimizeRecurrence(MachineInstr &PHI);
+- bool findNextSource(unsigned Reg, unsigned SubReg,
+- RewriteMapTy &RewriteMap);
+- bool isMoveImmediate(MachineInstr *MI,
++ bool findNextSource(RegSubRegPair RegSubReg, RewriteMapTy &RewriteMap);
++ bool isMoveImmediate(MachineInstr &MI,
+ SmallSet<unsigned, 4> &ImmDefRegs,
+ DenseMap<unsigned, MachineInstr*> &ImmDefMIs);
+- bool foldImmediate(MachineInstr *MI, MachineBasicBlock *MBB,
+- SmallSet<unsigned, 4> &ImmDefRegs,
++ bool foldImmediate(MachineInstr &MI, SmallSet<unsigned, 4> &ImmDefRegs,
+ DenseMap<unsigned, MachineInstr*> &ImmDefMIs);
+
+ /// \brief Finds recurrence cycles, but only ones that formulated around
+@@ -212,11 +214,11 @@
+ /// the set \p CopySrcRegs and \p CopyMIs. If this virtual register was
+ /// previously seen as a copy, replace the uses of this copy with the
+ /// previously seen copy's destination register.
+- bool foldRedundantCopy(MachineInstr *MI,
++ bool foldRedundantCopy(MachineInstr &MI,
+ SmallSet<unsigned, 4> &CopySrcRegs,
+ DenseMap<unsigned, MachineInstr *> &CopyMIs);
+
+- /// \brief Is the register \p Reg a non-allocatable physical register?
++ /// Is the register \p Reg a non-allocatable physical register?
+ bool isNAPhysCopy(unsigned Reg);
+
+ /// \brief If copy instruction \p MI is a non-allocatable virtual<->physical
+@@ -224,11 +226,10 @@
+ /// non-allocatable physical register was previously copied to a virtual
+ /// registered and hasn't been clobbered, the virt->phys copy can be
+ /// deleted.
+- bool foldRedundantNAPhysCopy(
+- MachineInstr *MI,
++ bool foldRedundantNAPhysCopy(MachineInstr &MI,
+ DenseMap<unsigned, MachineInstr *> &NAPhysToVirtMIs);
+
+- bool isLoadFoldable(MachineInstr *MI,
++ bool isLoadFoldable(MachineInstr &MI,
+ SmallSet<unsigned, 16> &FoldAsLoadDefCandidates);
+
+ /// \brief Check whether \p MI is understood by the register coalescer
+@@ -249,10 +250,13 @@
+ (MI.isRegSequenceLike() || MI.isInsertSubregLike() ||
+ MI.isExtractSubregLike()));
+ }
++
++ MachineInstr &rewriteSource(MachineInstr &CopyLike,
++ RegSubRegPair Def, RewriteMapTy &RewriteMap);
+ };
+
+- /// \brief Helper class to hold instructions that are inside recurrence
+- /// cycles. The recurrence cycle is formulated around 1) a def operand and its
++ /// Helper class to hold instructions that are inside recurrence cycles.
++ /// The recurrence cycle is formulated around 1) a def operand and its
+ /// tied use operand, or 2) a def operand and a use operand that is commutable
+ /// with another use operand which is tied to the def operand. In the latter
+ /// case, index of the tied use operand and the commutable use operand are
+@@ -273,13 +277,13 @@
+ Optional<IndexPair> CommutePair;
+ };
+
+- /// \brief Helper class to hold a reply for ValueTracker queries. Contains the
+- /// returned sources for a given search and the instructions where the sources
+- /// were tracked from.
++ /// Helper class to hold a reply for ValueTracker queries.
++ /// Contains the returned sources for a given search and the instructions
++ /// where the sources were tracked from.
+ class ValueTrackerResult {
+ private:
+ /// Track all sources found by one ValueTracker query.
+- SmallVector<TargetInstrInfo::RegSubRegPair, 2> RegSrcs;
++ SmallVector<RegSubRegPair, 2> RegSrcs;
+
+ /// Instruction using the sources in 'RegSrcs'.
+ const MachineInstr *Inst = nullptr;
+@@ -302,16 +306,20 @@
+ }
+
+ void addSource(unsigned SrcReg, unsigned SrcSubReg) {
+- RegSrcs.push_back(TargetInstrInfo::RegSubRegPair(SrcReg, SrcSubReg));
++ RegSrcs.push_back(RegSubRegPair(SrcReg, SrcSubReg));
+ }
+
+ void setSource(int Idx, unsigned SrcReg, unsigned SrcSubReg) {
+ assert(Idx < getNumSources() && "Reg pair source out of index");
+- RegSrcs[Idx] = TargetInstrInfo::RegSubRegPair(SrcReg, SrcSubReg);
++ RegSrcs[Idx] = RegSubRegPair(SrcReg, SrcSubReg);
+ }
+
+ int getNumSources() const { return RegSrcs.size(); }
+
++ RegSubRegPair getSrc(int Idx) const {
++ return RegSrcs[Idx];
++ }
++
+ unsigned getSrcReg(int Idx) const {
+ assert(Idx < getNumSources() && "Reg source out of index");
+ return RegSrcs[Idx].Reg;
+@@ -367,59 +375,41 @@
+ /// The register where the value can be found.
+ unsigned Reg;
+
+- /// Specifiy whether or not the value tracking looks through
+- /// complex instructions. When this is false, the value tracker
+- /// bails on everything that is not a copy or a bitcast.
+- ///
+- /// Note: This could have been implemented as a specialized version of
+- /// the ValueTracker class but that would have complicated the code of
+- /// the users of this class.
+- bool UseAdvancedTracking;
+-
+ /// MachineRegisterInfo used to perform tracking.
+ const MachineRegisterInfo &MRI;
+
+- /// Optional TargetInstrInfo used to perform some complex
+- /// tracking.
++ /// Optional TargetInstrInfo used to perform some complex tracking.
+ const TargetInstrInfo *TII;
+
+- /// \brief Dispatcher to the right underlying implementation of
+- /// getNextSource.
++ /// Dispatcher to the right underlying implementation of getNextSource.
+ ValueTrackerResult getNextSourceImpl();
+
+- /// \brief Specialized version of getNextSource for Copy instructions.
++ /// Specialized version of getNextSource for Copy instructions.
+ ValueTrackerResult getNextSourceFromCopy();
+
+- /// \brief Specialized version of getNextSource for Bitcast instructions.
++ /// Specialized version of getNextSource for Bitcast instructions.
+ ValueTrackerResult getNextSourceFromBitcast();
+
+- /// \brief Specialized version of getNextSource for RegSequence
+- /// instructions.
++ /// Specialized version of getNextSource for RegSequence instructions.
+ ValueTrackerResult getNextSourceFromRegSequence();
+
+- /// \brief Specialized version of getNextSource for InsertSubreg
+- /// instructions.
++ /// Specialized version of getNextSource for InsertSubreg instructions.
+ ValueTrackerResult getNextSourceFromInsertSubreg();
+
+- /// \brief Specialized version of getNextSource for ExtractSubreg
+- /// instructions.
++ /// Specialized version of getNextSource for ExtractSubreg instructions.
+ ValueTrackerResult getNextSourceFromExtractSubreg();
+
+- /// \brief Specialized version of getNextSource for SubregToReg
+- /// instructions.
++ /// Specialized version of getNextSource for SubregToReg instructions.
+ ValueTrackerResult getNextSourceFromSubregToReg();
+
+- /// \brief Specialized version of getNextSource for PHI instructions.
++ /// Specialized version of getNextSource for PHI instructions.
+ ValueTrackerResult getNextSourceFromPHI();
+
+ public:
+- /// \brief Create a ValueTracker instance for the value defined by \p Reg.
++ /// Create a ValueTracker instance for the value defined by \p Reg.
+ /// \p DefSubReg represents the sub register index the value tracker will
+ /// track. It does not need to match the sub register index used in the
+ /// definition of \p Reg.
+- /// \p UseAdvancedTracking specifies whether or not the value tracker looks
+- /// through complex instructions. By default (false), it handles only copy
+- /// and bitcast instructions.
+ /// If \p Reg is a physical register, a value tracker constructed with
+ /// this constructor will not find any alternative source.
+ /// Indeed, when \p Reg is a physical register that constructor does not
+@@ -427,46 +417,20 @@
+ /// Use the next constructor to track a physical register.
+ ValueTracker(unsigned Reg, unsigned DefSubReg,
+ const MachineRegisterInfo &MRI,
+- bool UseAdvancedTracking = false,
+ const TargetInstrInfo *TII = nullptr)
+- : DefSubReg(DefSubReg), Reg(Reg),
+- UseAdvancedTracking(UseAdvancedTracking), MRI(MRI), TII(TII) {
++ : DefSubReg(DefSubReg), Reg(Reg), MRI(MRI), TII(TII) {
+ if (!TargetRegisterInfo::isPhysicalRegister(Reg)) {
+ Def = MRI.getVRegDef(Reg);
+ DefIdx = MRI.def_begin(Reg).getOperandNo();
+ }
+ }
+
+- /// \brief Create a ValueTracker instance for the value defined by
+- /// the pair \p MI, \p DefIdx.
+- /// Unlike the other constructor, the value tracker produced by this one
+- /// may be able to find a new source when the definition is a physical
+- /// register.
+- /// This could be useful to rewrite target specific instructions into
+- /// generic copy instructions.
+- ValueTracker(const MachineInstr &MI, unsigned DefIdx, unsigned DefSubReg,
+- const MachineRegisterInfo &MRI,
+- bool UseAdvancedTracking = false,
+- const TargetInstrInfo *TII = nullptr)
+- : Def(&MI), DefIdx(DefIdx), DefSubReg(DefSubReg),
+- UseAdvancedTracking(UseAdvancedTracking), MRI(MRI), TII(TII) {
+- assert(DefIdx < Def->getDesc().getNumDefs() &&
+- Def->getOperand(DefIdx).isReg() && "Invalid definition");
+- Reg = Def->getOperand(DefIdx).getReg();
+- }
+-
+ /// \brief Following the use-def chain, get the next available source
+ /// for the tracked value.
+ /// \return A ValueTrackerResult containing a set of registers
+ /// and sub registers with tracked values. A ValueTrackerResult with
+ /// an empty set of registers means no source was found.
+ ValueTrackerResult getNextSource();
+-
+- /// \brief Get the last register where the initial value can be found.
+- /// Initially this is the register of the definition.
+- /// Then, after each successful call to getNextSource, this is the
+- /// register of the last source.
+- unsigned getReg() const { return Reg; }
+ };
+
+ } // end anonymous namespace
+@@ -476,11 +440,11 @@
+ char &llvm::PeepholeOptimizerID = PeepholeOptimizer::ID;
+
+ INITIALIZE_PASS_BEGIN(PeepholeOptimizer, DEBUG_TYPE,
+- "Peephole Optimizations", false, false)
++ "Peephole Optimizations", false, false)
+ INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
+ INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
+ INITIALIZE_PASS_END(PeepholeOptimizer, DEBUG_TYPE,
+- "Peephole Optimizations", false, false)
++ "Peephole Optimizations", false, false)
+
+ /// If instruction is a copy-like instruction, i.e. it reads a single register
+ /// and writes a single register and it does not modify the source, and if the
+@@ -491,10 +455,10 @@
+ /// the code. Since this code does not currently share EXTRACTs, just ignore all
+ /// debug uses.
+ bool PeepholeOptimizer::
+-optimizeExtInstr(MachineInstr *MI, MachineBasicBlock *MBB,
++optimizeExtInstr(MachineInstr &MI, MachineBasicBlock &MBB,
+ SmallPtrSetImpl<MachineInstr*> &LocalMIs) {
+ unsigned SrcReg, DstReg, SubIdx;
+- if (!TII->isCoalescableExtInstr(*MI, SrcReg, DstReg, SubIdx))
++ if (!TII->isCoalescableExtInstr(MI, SrcReg, DstReg, SubIdx))
+ return false;
+
+ if (TargetRegisterInfo::isPhysicalRegister(DstReg) ||
+@@ -535,7 +499,7 @@
+ bool ExtendLife = true;
+ for (MachineOperand &UseMO : MRI->use_nodbg_operands(SrcReg)) {
+ MachineInstr *UseMI = UseMO.getParent();
+- if (UseMI == MI)
++ if (UseMI == &MI)
+ continue;
+
+ if (UseMI->isPHI()) {
+@@ -568,7 +532,7 @@
+ continue;
+
+ MachineBasicBlock *UseMBB = UseMI->getParent();
+- if (UseMBB == MBB) {
++ if (UseMBB == &MBB) {
+ // Local uses that come after the extension.
+ if (!LocalMIs.count(UseMI))
+ Uses.push_back(&UseMO);
+@@ -576,7 +540,7 @@
+ // Non-local uses where the result of the extension is used. Always
+ // replace these unless it's a PHI.
+ Uses.push_back(&UseMO);
+- } else if (Aggressive && DT->dominates(MBB, UseMBB)) {
++ } else if (Aggressive && DT->dominates(&MBB, UseMBB)) {
+ // We may want to extend the live range of the extension result in order
+ // to replace these uses.
+ ExtendedUses.push_back(&UseMO);
+@@ -640,19 +604,18 @@
+ /// against already sets (or could be modified to set) the same flag as the
+ /// compare, then we can remove the comparison and use the flag from the
+ /// previous instruction.
+-bool PeepholeOptimizer::optimizeCmpInstr(MachineInstr *MI,
+- MachineBasicBlock *MBB) {
++bool PeepholeOptimizer::optimizeCmpInstr(MachineInstr &MI) {
+ // If this instruction is a comparison against zero and isn't comparing a
+ // physical register, we can try to optimize it.
+ unsigned SrcReg, SrcReg2;
+ int CmpMask, CmpValue;
+- if (!TII->analyzeCompare(*MI, SrcReg, SrcReg2, CmpMask, CmpValue) ||
++ if (!TII->analyzeCompare(MI, SrcReg, SrcReg2, CmpMask, CmpValue) ||
+ TargetRegisterInfo::isPhysicalRegister(SrcReg) ||
+ (SrcReg2 != 0 && TargetRegisterInfo::isPhysicalRegister(SrcReg2)))
+ return false;
+
+ // Attempt to optimize the comparison instruction.
+- if (TII->optimizeCompareInstr(*MI, SrcReg, SrcReg2, CmpMask, CmpValue, MRI)) {
++ if (TII->optimizeCompareInstr(MI, SrcReg, SrcReg2, CmpMask, CmpValue, MRI)) {
+ ++NumCmps;
+ return true;
+ }
+@@ -661,27 +624,26 @@
+ }
+
+ /// Optimize a select instruction.
+-bool PeepholeOptimizer::optimizeSelect(MachineInstr *MI,
++bool PeepholeOptimizer::optimizeSelect(MachineInstr &MI,
+ SmallPtrSetImpl<MachineInstr *> &LocalMIs) {
+ unsigned TrueOp = 0;
+ unsigned FalseOp = 0;
+ bool Optimizable = false;
+ SmallVector<MachineOperand, 4> Cond;
+- if (TII->analyzeSelect(*MI, Cond, TrueOp, FalseOp, Optimizable))
++ if (TII->analyzeSelect(MI, Cond, TrueOp, FalseOp, Optimizable))
+ return false;
+ if (!Optimizable)
+ return false;
+- if (!TII->optimizeSelect(*MI, LocalMIs))
++ if (!TII->optimizeSelect(MI, LocalMIs))
+ return false;
+- MI->eraseFromParent();
++ MI.eraseFromParent();
+ ++NumSelects;
+ return true;
+ }
+
+-/// \brief Check if a simpler conditional branch can be
+-/// generated
+-bool PeepholeOptimizer::optimizeCondBranch(MachineInstr *MI) {
+- return TII->optimizeCondBranch(*MI);
++/// Check if a simpler conditional branch can be generated.
++bool PeepholeOptimizer::optimizeCondBranch(MachineInstr &MI) {
++ return TII->optimizeCondBranch(MI);
+ }
+
+ /// \brief Try to find the next source that share the same register file
+@@ -695,30 +657,29 @@
+ /// share the same register file as \p Reg and \p SubReg. The client should
+ /// then be capable to rewrite all intermediate PHIs to get the next source.
+ /// \return False if no alternative sources are available. True otherwise.
+-bool PeepholeOptimizer::findNextSource(unsigned Reg, unsigned SubReg,
++bool PeepholeOptimizer::findNextSource(RegSubRegPair RegSubReg,
+ RewriteMapTy &RewriteMap) {
+ // Do not try to find a new source for a physical register.
+ // So far we do not have any motivating example for doing that.
+ // Thus, instead of maintaining untested code, we will revisit that if
+ // that changes at some point.
++ unsigned Reg = RegSubReg.Reg;
+ if (TargetRegisterInfo::isPhysicalRegister(Reg))
+ return false;
+ const TargetRegisterClass *DefRC = MRI->getRegClass(Reg);
+
+- SmallVector<TargetInstrInfo::RegSubRegPair, 4> SrcToLook;
+- TargetInstrInfo::RegSubRegPair CurSrcPair(Reg, SubReg);
++ SmallVector<RegSubRegPair, 4> SrcToLook;
++ RegSubRegPair CurSrcPair = RegSubReg;
+ SrcToLook.push_back(CurSrcPair);
+
+ unsigned PHICount = 0;
+- while (!SrcToLook.empty() && PHICount < RewritePHILimit) {
+- TargetInstrInfo::RegSubRegPair Pair = SrcToLook.pop_back_val();
++ do {
++ CurSrcPair = SrcToLook.pop_back_val();
+ // As explained above, do not handle physical registers
+- if (TargetRegisterInfo::isPhysicalRegister(Pair.Reg))
++ if (TargetRegisterInfo::isPhysicalRegister(CurSrcPair.Reg))
+ return false;
+
+- CurSrcPair = Pair;
+- ValueTracker ValTracker(CurSrcPair.Reg, CurSrcPair.SubReg, *MRI,
+- !DisableAdvCopyOpt, TII);
++ ValueTracker ValTracker(CurSrcPair.Reg, CurSrcPair.SubReg, *MRI, TII);
+
+ // Follow the chain of copies until we find a more suitable source, a phi
+ // or have to abort.
+@@ -747,14 +708,17 @@
+ unsigned NumSrcs = Res.getNumSources();
+ if (NumSrcs > 1) {
+ PHICount++;
++ if (PHICount >= RewritePHILimit) {
++ DEBUG(dbgs() << "findNextSource: PHI limit reached\n");
++ return false;
++ }
++
+ for (unsigned i = 0; i < NumSrcs; ++i)
+- SrcToLook.push_back(TargetInstrInfo::RegSubRegPair(
+- Res.getSrcReg(i), Res.getSrcSubReg(i)));
++ SrcToLook.push_back(Res.getSrc(i));
+ break;
+ }
+
+- CurSrcPair.Reg = Res.getSrcReg(0);
+- CurSrcPair.SubReg = Res.getSrcSubReg(0);
++ CurSrcPair = Res.getSrc(0);
+ // Do not extend the live-ranges of physical registers as they add
+ // constraints to the register allocator. Moreover, if we want to extend
+ // the live-range of a physical register, unlike SSA virtual register,
+@@ -764,7 +728,8 @@
+
+ // Keep following the chain if the value isn't any better yet.
+ const TargetRegisterClass *SrcRC = MRI->getRegClass(CurSrcPair.Reg);
+- if (!TRI->shouldRewriteCopySrc(DefRC, SubReg, SrcRC, CurSrcPair.SubReg))
++ if (!TRI->shouldRewriteCopySrc(DefRC, RegSubReg.SubReg, SrcRC,
++ CurSrcPair.SubReg))
+ continue;
+
+ // We currently cannot deal with subreg operands on PHI instructions
+@@ -775,7 +740,7 @@
+ // We found a suitable source, and are done with this chain.
+ break;
+ }
+- }
++ } while (!SrcToLook.empty());
+
+ // If we did not find a more suitable source, there is nothing to optimize.
+ return CurSrcPair.Reg != Reg;
+@@ -786,54 +751,50 @@
+ /// successfully traverse a PHI instruction and find suitable sources coming
+ /// from its edges. By inserting a new PHI, we provide a rewritten PHI def
+ /// suitable to be used in a new COPY instruction.
+-static MachineInstr *
+-insertPHI(MachineRegisterInfo *MRI, const TargetInstrInfo *TII,
+- const SmallVectorImpl<TargetInstrInfo::RegSubRegPair> &SrcRegs,
+- MachineInstr *OrigPHI) {
++static MachineInstr &
++insertPHI(MachineRegisterInfo &MRI, const TargetInstrInfo &TII,
++ const SmallVectorImpl<RegSubRegPair> &SrcRegs,
++ MachineInstr &OrigPHI) {
+ assert(!SrcRegs.empty() && "No sources to create a PHI instruction?");
+
+- const TargetRegisterClass *NewRC = MRI->getRegClass(SrcRegs[0].Reg);
++ const TargetRegisterClass *NewRC = MRI.getRegClass(SrcRegs[0].Reg);
+ // NewRC is only correct if no subregisters are involved. findNextSource()
+ // should have rejected those cases already.
+ assert(SrcRegs[0].SubReg == 0 && "should not have subreg operand");
+- unsigned NewVR = MRI->createVirtualRegister(NewRC);
+- MachineBasicBlock *MBB = OrigPHI->getParent();
+- MachineInstrBuilder MIB = BuildMI(*MBB, OrigPHI, OrigPHI->getDebugLoc(),
+- TII->get(TargetOpcode::PHI), NewVR);
++ unsigned NewVR = MRI.createVirtualRegister(NewRC);
++ MachineBasicBlock *MBB = OrigPHI.getParent();
++ MachineInstrBuilder MIB = BuildMI(*MBB, &OrigPHI, OrigPHI.getDebugLoc(),
++ TII.get(TargetOpcode::PHI), NewVR);
+
+ unsigned MBBOpIdx = 2;
+- for (auto RegPair : SrcRegs) {
++ for (const RegSubRegPair &RegPair : SrcRegs) {
+ MIB.addReg(RegPair.Reg, 0, RegPair.SubReg);
+- MIB.addMBB(OrigPHI->getOperand(MBBOpIdx).getMBB());
++ MIB.addMBB(OrigPHI.getOperand(MBBOpIdx).getMBB());
+ // Since we're extended the lifetime of RegPair.Reg, clear the
+ // kill flags to account for that and make RegPair.Reg reaches
+ // the new PHI.
+- MRI->clearKillFlags(RegPair.Reg);
++ MRI.clearKillFlags(RegPair.Reg);
+ MBBOpIdx += 2;
+ }
+
+- return MIB;
++ return *MIB;
+ }
+
+ namespace {
+
+-/// \brief Helper class to rewrite the arguments of a copy-like instruction.
+-class CopyRewriter {
++/// Interface to query instructions amenable to copy rewriting.
++class Rewriter {
+ protected:
+- /// The copy-like instruction.
+ MachineInstr &CopyLike;
+-
+- /// The index of the source being rewritten.
+- unsigned CurrentSrcIdx = 0;
+-
++ unsigned CurrentSrcIdx = 0; ///< The index of the source being rewritten.
+ public:
+- CopyRewriter(MachineInstr &MI) : CopyLike(MI) {}
+- virtual ~CopyRewriter() = default;
++ Rewriter(MachineInstr &CopyLike) : CopyLike(CopyLike) {}
++ virtual ~Rewriter() {}
+
+ /// \brief Get the next rewritable source (SrcReg, SrcSubReg) and
+- /// the related value that it affects (TrackReg, TrackSubReg).
++ /// the related value that it affects (DstReg, DstSubReg).
+ /// A source is considered rewritable if its register class and the
+- /// register class of the related TrackReg may not be register
++ /// register class of the related DstReg may not be register
+ /// coalescer friendly. In other words, given a copy-like instruction
+ /// not all the arguments may be returned at rewritable source, since
+ /// some arguments are none to be register coalescer friendly.
+@@ -848,137 +809,72 @@
+ /// the only source this instruction has:
+ /// (SrcReg, SrcSubReg) = (src, srcSubIdx).
+ /// This source defines the whole definition, i.e.,
+- /// (TrackReg, TrackSubReg) = (dst, dstSubIdx).
++ /// (DstReg, DstSubReg) = (dst, dstSubIdx).
+ ///
+ /// The second and subsequent calls will return false, as there is only one
+ /// rewritable source.
+ ///
+ /// \return True if a rewritable source has been found, false otherwise.
+ /// The output arguments are valid if and only if true is returned.
+- virtual bool getNextRewritableSource(unsigned &SrcReg, unsigned &SrcSubReg,
+- unsigned &TrackReg,
+- unsigned &TrackSubReg) {
+- // If CurrentSrcIdx == 1, this means this function has already been called
+- // once. CopyLike has one definition and one argument, thus, there is
+- // nothing else to rewrite.
+- if (!CopyLike.isCopy() || CurrentSrcIdx == 1)
++ virtual bool getNextRewritableSource(RegSubRegPair &Src,
++ RegSubRegPair &Dst) = 0;
++
++ /// Rewrite the current source with \p NewReg and \p NewSubReg if possible.
++ /// \return True if the rewriting was possible, false otherwise.
++ virtual bool RewriteCurrentSource(unsigned NewReg, unsigned NewSubReg) = 0;
++};
++
++/// Rewriter for COPY instructions.
++class CopyRewriter : public Rewriter {
++public:
++ CopyRewriter(MachineInstr &MI) : Rewriter(MI) {
++ assert(MI.isCopy() && "Expected copy instruction");
++ }
++ virtual ~CopyRewriter() = default;
++
++ bool getNextRewritableSource(RegSubRegPair &Src,
++ RegSubRegPair &Dst) override {
++ // CurrentSrcIdx > 0 means this function has already been called.
++ if (CurrentSrcIdx > 0)
+ return false;
+ // This is the first call to getNextRewritableSource.
+ // Move the CurrentSrcIdx to remember that we made that call.
+ CurrentSrcIdx = 1;
+ // The rewritable source is the argument.
+ const MachineOperand &MOSrc = CopyLike.getOperand(1);
+- SrcReg = MOSrc.getReg();
+- SrcSubReg = MOSrc.getSubReg();
++ Src = RegSubRegPair(MOSrc.getReg(), MOSrc.getSubReg());
+ // What we track are the alternative sources of the definition.
+ const MachineOperand &MODef = CopyLike.getOperand(0);
+- TrackReg = MODef.getReg();
+- TrackSubReg = MODef.getSubReg();
++ Dst = RegSubRegPair(MODef.getReg(), MODef.getSubReg());
+ return true;
+ }
+
+- /// \brief Rewrite the current source with \p NewReg and \p NewSubReg
+- /// if possible.
+- /// \return True if the rewriting was possible, false otherwise.
+- virtual bool RewriteCurrentSource(unsigned NewReg, unsigned NewSubReg) {
+- if (!CopyLike.isCopy() || CurrentSrcIdx != 1)
++ bool RewriteCurrentSource(unsigned NewReg, unsigned NewSubReg) override {
++ if (CurrentSrcIdx != 1)
+ return false;
+ MachineOperand &MOSrc = CopyLike.getOperand(CurrentSrcIdx);
+ MOSrc.setReg(NewReg);
+ MOSrc.setSubReg(NewSubReg);
+ return true;
+ }
+-
+- /// \brief Given a \p Def.Reg and Def.SubReg pair, use \p RewriteMap to find
+- /// the new source to use for rewrite. If \p HandleMultipleSources is true and
+- /// multiple sources for a given \p Def are found along the way, we found a
+- /// PHI instructions that needs to be rewritten.
+- /// TODO: HandleMultipleSources should be removed once we test PHI handling
+- /// with coalescable copies.
+- TargetInstrInfo::RegSubRegPair
+- getNewSource(MachineRegisterInfo *MRI, const TargetInstrInfo *TII,
+- TargetInstrInfo::RegSubRegPair Def,
+- PeepholeOptimizer::RewriteMapTy &RewriteMap,
+- bool HandleMultipleSources = true) {
+- TargetInstrInfo::RegSubRegPair LookupSrc(Def.Reg, Def.SubReg);
+- do {
+- ValueTrackerResult Res = RewriteMap.lookup(LookupSrc);
+- // If there are no entries on the map, LookupSrc is the new source.
+- if (!Res.isValid())
+- return LookupSrc;
+-
+- // There's only one source for this definition, keep searching...
+- unsigned NumSrcs = Res.getNumSources();
+- if (NumSrcs == 1) {
+- LookupSrc.Reg = Res.getSrcReg(0);
+- LookupSrc.SubReg = Res.getSrcSubReg(0);
+- continue;
+- }
+-
+- // TODO: Remove once multiple srcs w/ coalescable copies are supported.
+- if (!HandleMultipleSources)
+- break;
+-
+- // Multiple sources, recurse into each source to find a new source
+- // for it. Then, rewrite the PHI accordingly to its new edges.
+- SmallVector<TargetInstrInfo::RegSubRegPair, 4> NewPHISrcs;
+- for (unsigned i = 0; i < NumSrcs; ++i) {
+- TargetInstrInfo::RegSubRegPair PHISrc(Res.getSrcReg(i),
+- Res.getSrcSubReg(i));
+- NewPHISrcs.push_back(
+- getNewSource(MRI, TII, PHISrc, RewriteMap, HandleMultipleSources));
+- }
+-
+- // Build the new PHI node and return its def register as the new source.
+- MachineInstr *OrigPHI = const_cast<MachineInstr *>(Res.getInst());
+- MachineInstr *NewPHI = insertPHI(MRI, TII, NewPHISrcs, OrigPHI);
+- DEBUG(dbgs() << "-- getNewSource\n");
+- DEBUG(dbgs() << " Replacing: " << *OrigPHI);
+- DEBUG(dbgs() << " With: " << *NewPHI);
+- const MachineOperand &MODef = NewPHI->getOperand(0);
+- return TargetInstrInfo::RegSubRegPair(MODef.getReg(), MODef.getSubReg());
+-
+- } while (true);
+-
+- return TargetInstrInfo::RegSubRegPair(0, 0);
+- }
+-
+- /// \brief Rewrite the source found through \p Def, by using the \p RewriteMap
+- /// and create a new COPY instruction. More info about RewriteMap in
+- /// PeepholeOptimizer::findNextSource. Right now this is only used to handle
+- /// Uncoalescable copies, since they are copy like instructions that aren't
+- /// recognized by the register allocator.
+- virtual MachineInstr *
+- RewriteSource(TargetInstrInfo::RegSubRegPair Def,
+- PeepholeOptimizer::RewriteMapTy &RewriteMap) {
+- return nullptr;
+- }
+ };
+
+ /// \brief Helper class to rewrite uncoalescable copy like instructions
+ /// into new COPY (coalescable friendly) instructions.
+-class UncoalescableRewriter : public CopyRewriter {
+-protected:
+- const TargetInstrInfo &TII;
+- MachineRegisterInfo &MRI;
+-
+- /// The number of defs in the bitcast
+- unsigned NumDefs;
++class UncoalescableRewriter : public Rewriter {
++ unsigned NumDefs; ///< Number of defs in the bitcast.
+
+ public:
+- UncoalescableRewriter(MachineInstr &MI, const TargetInstrInfo &TII,
+- MachineRegisterInfo &MRI)
+- : CopyRewriter(MI), TII(TII), MRI(MRI) {
++ UncoalescableRewriter(MachineInstr &MI) : Rewriter(MI) {
+ NumDefs = MI.getDesc().getNumDefs();
+ }
+
+- /// \brief Get the next rewritable def source (TrackReg, TrackSubReg)
++ /// \see See Rewriter::getNextRewritableSource()
+ /// All such sources need to be considered rewritable in order to
+ /// rewrite a uncoalescable copy-like instruction. This method return
+ /// each definition that must be checked if rewritable.
+- bool getNextRewritableSource(unsigned &SrcReg, unsigned &SrcSubReg,
+- unsigned &TrackReg,
+- unsigned &TrackSubReg) override {
++ bool getNextRewritableSource(RegSubRegPair &Src,
++ RegSubRegPair &Dst) override {
+ // Find the next non-dead definition and continue from there.
+ if (CurrentSrcIdx == NumDefs)
+ return false;
+@@ -990,64 +886,27 @@
+ }
+
+ // What we track are the alternative sources of the definition.
++ Src = RegSubRegPair(0, 0);
+ const MachineOperand &MODef = CopyLike.getOperand(CurrentSrcIdx);
+- TrackReg = MODef.getReg();
+- TrackSubReg = MODef.getSubReg();
++ Dst = RegSubRegPair(MODef.getReg(), MODef.getSubReg());
+
+ CurrentSrcIdx++;
+ return true;
+ }
+
+- /// \brief Rewrite the source found through \p Def, by using the \p RewriteMap
+- /// and create a new COPY instruction. More info about RewriteMap in
+- /// PeepholeOptimizer::findNextSource. Right now this is only used to handle
+- /// Uncoalescable copies, since they are copy like instructions that aren't
+- /// recognized by the register allocator.
+- MachineInstr *
+- RewriteSource(TargetInstrInfo::RegSubRegPair Def,
+- PeepholeOptimizer::RewriteMapTy &RewriteMap) override {
+- assert(!TargetRegisterInfo::isPhysicalRegister(Def.Reg) &&
+- "We do not rewrite physical registers");
+-
+- // Find the new source to use in the COPY rewrite.
+- TargetInstrInfo::RegSubRegPair NewSrc =
+- getNewSource(&MRI, &TII, Def, RewriteMap);
+-
+- // Insert the COPY.
+- const TargetRegisterClass *DefRC = MRI.getRegClass(Def.Reg);
+- unsigned NewVR = MRI.createVirtualRegister(DefRC);
+-
+- MachineInstr *NewCopy =
+- BuildMI(*CopyLike.getParent(), &CopyLike, CopyLike.getDebugLoc(),
+- TII.get(TargetOpcode::COPY), NewVR)
+- .addReg(NewSrc.Reg, 0, NewSrc.SubReg);
+-
+- NewCopy->getOperand(0).setSubReg(Def.SubReg);
+- if (Def.SubReg)
+- NewCopy->getOperand(0).setIsUndef();
+-
+- DEBUG(dbgs() << "-- RewriteSource\n");
+- DEBUG(dbgs() << " Replacing: " << CopyLike);
+- DEBUG(dbgs() << " With: " << *NewCopy);
+- MRI.replaceRegWith(Def.Reg, NewVR);
+- MRI.clearKillFlags(NewVR);
+-
+- // We extended the lifetime of NewSrc.Reg, clear the kill flags to
+- // account for that.
+- MRI.clearKillFlags(NewSrc.Reg);
+-
+- return NewCopy;
++ bool RewriteCurrentSource(unsigned NewReg, unsigned NewSubReg) override {
++ return false;
+ }
+ };
+
+-/// \brief Specialized rewriter for INSERT_SUBREG instruction.
+-class InsertSubregRewriter : public CopyRewriter {
++/// Specialized rewriter for INSERT_SUBREG instruction.
++class InsertSubregRewriter : public Rewriter {
+ public:
+- InsertSubregRewriter(MachineInstr &MI) : CopyRewriter(MI) {
++ InsertSubregRewriter(MachineInstr &MI) : Rewriter(MI) {
+ assert(MI.isInsertSubreg() && "Invalid instruction");
+ }
+
+- /// \brief See CopyRewriter::getNextRewritableSource.
++ /// \see See Rewriter::getNextRewritableSource()
+ /// Here CopyLike has the following form:
+ /// dst = INSERT_SUBREG Src1, Src2.src2SubIdx, subIdx.
+ /// Src1 has the same register class has dst, hence, there is
+@@ -1055,29 +914,27 @@
+ /// Src2.src2SubIdx, may not be register coalescer friendly.
+ /// Therefore, the first call to this method returns:
+ /// (SrcReg, SrcSubReg) = (Src2, src2SubIdx).
+- /// (TrackReg, TrackSubReg) = (dst, subIdx).
++ /// (DstReg, DstSubReg) = (dst, subIdx).
+ ///
+ /// Subsequence calls will return false.
+- bool getNextRewritableSource(unsigned &SrcReg, unsigned &SrcSubReg,
+- unsigned &TrackReg,
+- unsigned &TrackSubReg) override {
++ bool getNextRewritableSource(RegSubRegPair &Src,
++ RegSubRegPair &Dst) override {
+ // If we already get the only source we can rewrite, return false.
+ if (CurrentSrcIdx == 2)
+ return false;
+ // We are looking at v2 = INSERT_SUBREG v0, v1, sub0.
+ CurrentSrcIdx = 2;
+ const MachineOperand &MOInsertedReg = CopyLike.getOperand(2);
+- SrcReg = MOInsertedReg.getReg();
+- SrcSubReg = MOInsertedReg.getSubReg();
++ Src = RegSubRegPair(MOInsertedReg.getReg(), MOInsertedReg.getSubReg());
+ const MachineOperand &MODef = CopyLike.getOperand(0);
+
+ // We want to track something that is compatible with the
+ // partial definition.
+- TrackReg = MODef.getReg();
+ if (MODef.getSubReg())
+ // Bail if we have to compose sub-register indices.
+ return false;
+- TrackSubReg = (unsigned)CopyLike.getOperand(3).getImm();
++ Dst = RegSubRegPair(MODef.getReg(),
++ (unsigned)CopyLike.getOperand(3).getImm());
+ return true;
+ }
+
+@@ -1092,41 +949,39 @@
+ }
+ };
+
+-/// \brief Specialized rewriter for EXTRACT_SUBREG instruction.
+-class ExtractSubregRewriter : public CopyRewriter {
++/// Specialized rewriter for EXTRACT_SUBREG instruction.
++class ExtractSubregRewriter : public Rewriter {
+ const TargetInstrInfo &TII;
+
+ public:
+ ExtractSubregRewriter(MachineInstr &MI, const TargetInstrInfo &TII)
+- : CopyRewriter(MI), TII(TII) {
++ : Rewriter(MI), TII(TII) {
+ assert(MI.isExtractSubreg() && "Invalid instruction");
+ }
+
+- /// \brief See CopyRewriter::getNextRewritableSource.
++ /// \see Rewriter::getNextRewritableSource()
+ /// Here CopyLike has the following form:
+ /// dst.dstSubIdx = EXTRACT_SUBREG Src, subIdx.
+ /// There is only one rewritable source: Src.subIdx,
+ /// which defines dst.dstSubIdx.
+- bool getNextRewritableSource(unsigned &SrcReg, unsigned &SrcSubReg,
+- unsigned &TrackReg,
+- unsigned &TrackSubReg) override {
++ bool getNextRewritableSource(RegSubRegPair &Src,
++ RegSubRegPair &Dst) override {
+ // If we already get the only source we can rewrite, return false.
+ if (CurrentSrcIdx == 1)
+ return false;
+ // We are looking at v1 = EXTRACT_SUBREG v0, sub0.
+ CurrentSrcIdx = 1;
+ const MachineOperand &MOExtractedReg = CopyLike.getOperand(1);
+- SrcReg = MOExtractedReg.getReg();
+ // If we have to compose sub-register indices, bail out.
+ if (MOExtractedReg.getSubReg())
+ return false;
+
+- SrcSubReg = CopyLike.getOperand(2).getImm();
++ Src = RegSubRegPair(MOExtractedReg.getReg(),
++ CopyLike.getOperand(2).getImm());
+
+ // We want to track something that is compatible with the definition.
+ const MachineOperand &MODef = CopyLike.getOperand(0);
+- TrackReg = MODef.getReg();
+- TrackSubReg = MODef.getSubReg();
++ Dst = RegSubRegPair(MODef.getReg(), MODef.getSubReg());
+ return true;
+ }
+
+@@ -1156,14 +1011,14 @@
+ }
+ };
+
+-/// \brief Specialized rewriter for REG_SEQUENCE instruction.
+-class RegSequenceRewriter : public CopyRewriter {
++/// Specialized rewriter for REG_SEQUENCE instruction.
++class RegSequenceRewriter : public Rewriter {
+ public:
+- RegSequenceRewriter(MachineInstr &MI) : CopyRewriter(MI) {
++ RegSequenceRewriter(MachineInstr &MI) : Rewriter(MI) {
+ assert(MI.isRegSequence() && "Invalid instruction");
+ }
+
+- /// \brief See CopyRewriter::getNextRewritableSource.
++ /// \see Rewriter::getNextRewritableSource()
+ /// Here CopyLike has the following form:
+ /// dst = REG_SEQUENCE Src1.src1SubIdx, subIdx1, Src2.src2SubIdx, subIdx2.
+ /// Each call will return a different source, walking all the available
+@@ -1171,17 +1026,16 @@
+ ///
+ /// The first call returns:
+ /// (SrcReg, SrcSubReg) = (Src1, src1SubIdx).
+- /// (TrackReg, TrackSubReg) = (dst, subIdx1).
++ /// (DstReg, DstSubReg) = (dst, subIdx1).
+ ///
+ /// The second call returns:
+ /// (SrcReg, SrcSubReg) = (Src2, src2SubIdx).
+- /// (TrackReg, TrackSubReg) = (dst, subIdx2).
++ /// (DstReg, DstSubReg) = (dst, subIdx2).
+ ///
+ /// And so on, until all the sources have been traversed, then
+ /// it returns false.
+- bool getNextRewritableSource(unsigned &SrcReg, unsigned &SrcSubReg,
+- unsigned &TrackReg,
+- unsigned &TrackSubReg) override {
++ bool getNextRewritableSource(RegSubRegPair &Src,
++ RegSubRegPair &Dst) override {
+ // We are looking at v0 = REG_SEQUENCE v1, sub1, v2, sub2, etc.
+
+ // If this is the first call, move to the first argument.
+@@ -1194,17 +1048,17 @@
+ return false;
+ }
+ const MachineOperand &MOInsertedReg = CopyLike.getOperand(CurrentSrcIdx);
+- SrcReg = MOInsertedReg.getReg();
++ Src.Reg = MOInsertedReg.getReg();
+ // If we have to compose sub-register indices, bail out.
+- if ((SrcSubReg = MOInsertedReg.getSubReg()))
++ if ((Src.SubReg = MOInsertedReg.getSubReg()))
+ return false;
+
+ // We want to track something that is compatible with the related
+ // partial definition.
+- TrackSubReg = CopyLike.getOperand(CurrentSrcIdx + 1).getImm();
++ Dst.SubReg = CopyLike.getOperand(CurrentSrcIdx + 1).getImm();
+
+ const MachineOperand &MODef = CopyLike.getOperand(0);
+- TrackReg = MODef.getReg();
++ Dst.Reg = MODef.getReg();
+ // If we have to compose sub-registers, bail.
+ return MODef.getSubReg() == 0;
+ }
+@@ -1224,16 +1078,14 @@
+
+ } // end anonymous namespace
+
+-/// \brief Get the appropriated CopyRewriter for \p MI.
+-/// \return A pointer to a dynamically allocated CopyRewriter or nullptr
+-/// if no rewriter works for \p MI.
+-static CopyRewriter *getCopyRewriter(MachineInstr &MI,
+- const TargetInstrInfo &TII,
+- MachineRegisterInfo &MRI) {
++/// Get the appropriated Rewriter for \p MI.
++/// \return A pointer to a dynamically allocated Rewriter or nullptr if no
++/// rewriter works for \p MI.
++static Rewriter *getCopyRewriter(MachineInstr &MI, const TargetInstrInfo &TII) {
+ // Handle uncoalescable copy-like instructions.
+- if (MI.isBitcast() || (MI.isRegSequenceLike() || MI.isInsertSubregLike() ||
+- MI.isExtractSubregLike()))
+- return new UncoalescableRewriter(MI, TII, MRI);
++ if (MI.isBitcast() || MI.isRegSequenceLike() || MI.isInsertSubregLike() ||
++ MI.isExtractSubregLike())
++ return new UncoalescableRewriter(MI);
+
+ switch (MI.getOpcode()) {
+ default:
+@@ -1247,53 +1099,102 @@
+ case TargetOpcode::REG_SEQUENCE:
+ return new RegSequenceRewriter(MI);
+ }
+- llvm_unreachable(nullptr);
+ }
+
+-/// \brief Optimize generic copy instructions to avoid cross
+-/// register bank copy. The optimization looks through a chain of
+-/// copies and tries to find a source that has a compatible register
+-/// class.
+-/// Two register classes are considered to be compatible if they share
+-/// the same register bank.
++/// \brief Given a \p Def.Reg and Def.SubReg pair, use \p RewriteMap to find
++/// the new source to use for rewrite. If \p HandleMultipleSources is true and
++/// multiple sources for a given \p Def are found along the way, we found a
++/// PHI instructions that needs to be rewritten.
++/// TODO: HandleMultipleSources should be removed once we test PHI handling
++/// with coalescable copies.
++static RegSubRegPair
++getNewSource(MachineRegisterInfo *MRI, const TargetInstrInfo *TII,
++ RegSubRegPair Def,
++ const PeepholeOptimizer::RewriteMapTy &RewriteMap,
++ bool HandleMultipleSources = true) {
++ RegSubRegPair LookupSrc(Def.Reg, Def.SubReg);
++ while (true) {
++ ValueTrackerResult Res = RewriteMap.lookup(LookupSrc);
++ // If there are no entries on the map, LookupSrc is the new source.
++ if (!Res.isValid())
++ return LookupSrc;
++
++ // There's only one source for this definition, keep searching...
++ unsigned NumSrcs = Res.getNumSources();
++ if (NumSrcs == 1) {
++ LookupSrc.Reg = Res.getSrcReg(0);
++ LookupSrc.SubReg = Res.getSrcSubReg(0);
++ continue;
++ }
++
++ // TODO: Remove once multiple srcs w/ coalescable copies are supported.
++ if (!HandleMultipleSources)
++ break;
++
++ // Multiple sources, recurse into each source to find a new source
++ // for it. Then, rewrite the PHI accordingly to its new edges.
++ SmallVector<RegSubRegPair, 4> NewPHISrcs;
++ for (unsigned i = 0; i < NumSrcs; ++i) {
++ RegSubRegPair PHISrc(Res.getSrcReg(i), Res.getSrcSubReg(i));
++ NewPHISrcs.push_back(
++ getNewSource(MRI, TII, PHISrc, RewriteMap, HandleMultipleSources));
++ }
++
++ // Build the new PHI node and return its def register as the new source.
++ MachineInstr &OrigPHI = const_cast<MachineInstr &>(*Res.getInst());
++ MachineInstr &NewPHI = insertPHI(*MRI, *TII, NewPHISrcs, OrigPHI);
++ DEBUG(dbgs() << "-- getNewSource\n");
++ DEBUG(dbgs() << " Replacing: " << OrigPHI);
++ DEBUG(dbgs() << " With: " << NewPHI);
++ const MachineOperand &MODef = NewPHI.getOperand(0);
++ return RegSubRegPair(MODef.getReg(), MODef.getSubReg());
++ }
++
++ return RegSubRegPair(0, 0);
++}
++
++/// Optimize generic copy instructions to avoid cross register bank copy.
++/// The optimization looks through a chain of copies and tries to find a source
++/// that has a compatible register class.
++/// Two register classes are considered to be compatible if they share the same
++/// register bank.
+ /// New copies issued by this optimization are register allocator
+ /// friendly. This optimization does not remove any copy as it may
+ /// overconstrain the register allocator, but replaces some operands
+ /// when possible.
+ /// \pre isCoalescableCopy(*MI) is true.
+ /// \return True, when \p MI has been rewritten. False otherwise.
+-bool PeepholeOptimizer::optimizeCoalescableCopy(MachineInstr *MI) {
+- assert(MI && isCoalescableCopy(*MI) && "Invalid argument");
+- assert(MI->getDesc().getNumDefs() == 1 &&
++bool PeepholeOptimizer::optimizeCoalescableCopy(MachineInstr &MI) {
++ assert(isCoalescableCopy(MI) && "Invalid argument");
++ assert(MI.getDesc().getNumDefs() == 1 &&
+ "Coalescer can understand multiple defs?!");
+- const MachineOperand &MODef = MI->getOperand(0);
++ const MachineOperand &MODef = MI.getOperand(0);
+ // Do not rewrite physical definitions.
+ if (TargetRegisterInfo::isPhysicalRegister(MODef.getReg()))
+ return false;
+
+ bool Changed = false;
+ // Get the right rewriter for the current copy.
+- std::unique_ptr<CopyRewriter> CpyRewriter(getCopyRewriter(*MI, *TII, *MRI));
++ std::unique_ptr<Rewriter> CpyRewriter(getCopyRewriter(MI, *TII));
+ // If none exists, bail out.
+ if (!CpyRewriter)
+ return false;
+ // Rewrite each rewritable source.
+- unsigned SrcReg, SrcSubReg, TrackReg, TrackSubReg;
+- while (CpyRewriter->getNextRewritableSource(SrcReg, SrcSubReg, TrackReg,
+- TrackSubReg)) {
++ RegSubRegPair Src;
++ RegSubRegPair TrackPair;
++ while (CpyRewriter->getNextRewritableSource(Src, TrackPair)) {
+ // Keep track of PHI nodes and its incoming edges when looking for sources.
+ RewriteMapTy RewriteMap;
+ // Try to find a more suitable source. If we failed to do so, or get the
+ // actual source, move to the next source.
+- if (!findNextSource(TrackReg, TrackSubReg, RewriteMap))
++ if (!findNextSource(TrackPair, RewriteMap))
+ continue;
+
+ // Get the new source to rewrite. TODO: Only enable handling of multiple
+ // sources (PHIs) once we have a motivating example and testcases for it.
+- TargetInstrInfo::RegSubRegPair TrackPair(TrackReg, TrackSubReg);
+- TargetInstrInfo::RegSubRegPair NewSrc = CpyRewriter->getNewSource(
+- MRI, TII, TrackPair, RewriteMap, false /* multiple sources */);
+- if (SrcReg == NewSrc.Reg || NewSrc.Reg == 0)
++ RegSubRegPair NewSrc = getNewSource(MRI, TII, TrackPair, RewriteMap,
++ /*HandleMultipleSources=*/false);
++ if (Src.Reg == NewSrc.Reg || NewSrc.Reg == 0)
+ continue;
+
+ // Rewrite source.
+@@ -1312,6 +1213,47 @@
+ return Changed;
+ }
+
++/// \brief Rewrite the source found through \p Def, by using the \p RewriteMap
++/// and create a new COPY instruction. More info about RewriteMap in
++/// PeepholeOptimizer::findNextSource. Right now this is only used to handle
++/// Uncoalescable copies, since they are copy like instructions that aren't
++/// recognized by the register allocator.
++MachineInstr &
++PeepholeOptimizer::rewriteSource(MachineInstr &CopyLike,
++ RegSubRegPair Def, RewriteMapTy &RewriteMap) {
++ assert(!TargetRegisterInfo::isPhysicalRegister(Def.Reg) &&
++ "We do not rewrite physical registers");
++
++ // Find the new source to use in the COPY rewrite.
++ RegSubRegPair NewSrc = getNewSource(MRI, TII, Def, RewriteMap);
++
++ // Insert the COPY.
++ const TargetRegisterClass *DefRC = MRI->getRegClass(Def.Reg);
++ unsigned NewVReg = MRI->createVirtualRegister(DefRC);
++
++ MachineInstr *NewCopy =
++ BuildMI(*CopyLike.getParent(), &CopyLike, CopyLike.getDebugLoc(),
++ TII->get(TargetOpcode::COPY), NewVReg)
++ .addReg(NewSrc.Reg, 0, NewSrc.SubReg);
++
++ if (Def.SubReg) {
++ NewCopy->getOperand(0).setSubReg(Def.SubReg);
++ NewCopy->getOperand(0).setIsUndef();
++ }
++
++ DEBUG(dbgs() << "-- RewriteSource\n");
++ DEBUG(dbgs() << " Replacing: " << CopyLike);
++ DEBUG(dbgs() << " With: " << *NewCopy);
++ MRI->replaceRegWith(Def.Reg, NewVReg);
++ MRI->clearKillFlags(NewVReg);
++
++ // We extended the lifetime of NewSrc.Reg, clear the kill flags to
++ // account for that.
++ MRI->clearKillFlags(NewSrc.Reg);
++
++ return *NewCopy;
++}
++
+ /// \brief Optimize copy-like instructions to create
+ /// register coalescer friendly instruction.
+ /// The optimization tries to kill-off the \p MI by looking
+@@ -1324,48 +1266,40 @@
+ /// been removed from its parent.
+ /// All COPY instructions created, are inserted in \p LocalMIs.
+ bool PeepholeOptimizer::optimizeUncoalescableCopy(
+- MachineInstr *MI, SmallPtrSetImpl<MachineInstr *> &LocalMIs) {
+- assert(MI && isUncoalescableCopy(*MI) && "Invalid argument");
+-
+- // Check if we can rewrite all the values defined by this instruction.
+- SmallVector<TargetInstrInfo::RegSubRegPair, 4> RewritePairs;
+- // Get the right rewriter for the current copy.
+- std::unique_ptr<CopyRewriter> CpyRewriter(getCopyRewriter(*MI, *TII, *MRI));
+- // If none exists, bail out.
+- if (!CpyRewriter)
+- return false;
++ MachineInstr &MI, SmallPtrSetImpl<MachineInstr *> &LocalMIs) {
++ assert(isUncoalescableCopy(MI) && "Invalid argument");
++ UncoalescableRewriter CpyRewriter(MI);
+
+ // Rewrite each rewritable source by generating new COPYs. This works
+ // differently from optimizeCoalescableCopy since it first makes sure that all
+ // definitions can be rewritten.
+ RewriteMapTy RewriteMap;
+- unsigned Reg, SubReg, CopyDefReg, CopyDefSubReg;
+- while (CpyRewriter->getNextRewritableSource(Reg, SubReg, CopyDefReg,
+- CopyDefSubReg)) {
++ RegSubRegPair Src;
++ RegSubRegPair Def;
++ SmallVector<RegSubRegPair, 4> RewritePairs;
++ while (CpyRewriter.getNextRewritableSource(Src, Def)) {
+ // If a physical register is here, this is probably for a good reason.
+ // Do not rewrite that.
+- if (TargetRegisterInfo::isPhysicalRegister(CopyDefReg))
++ if (TargetRegisterInfo::isPhysicalRegister(Def.Reg))
+ return false;
+
+ // If we do not know how to rewrite this definition, there is no point
+ // in trying to kill this instruction.
+- TargetInstrInfo::RegSubRegPair Def(CopyDefReg, CopyDefSubReg);
+- if (!findNextSource(Def.Reg, Def.SubReg, RewriteMap))
++ if (!findNextSource(Def, RewriteMap))
+ return false;
+
+ RewritePairs.push_back(Def);
+ }
+
+ // The change is possible for all defs, do it.
+- for (const auto &Def : RewritePairs) {
++ for (const RegSubRegPair &Def : RewritePairs) {
+ // Rewrite the "copy" in a way the register coalescer understands.
+- MachineInstr *NewCopy = CpyRewriter->RewriteSource(Def, RewriteMap);
+- assert(NewCopy && "Should be able to always generate a new copy");
+- LocalMIs.insert(NewCopy);
++ MachineInstr &NewCopy = rewriteSource(MI, Def, RewriteMap);
++ LocalMIs.insert(&NewCopy);
+ }
+
+ // MI is now dead.
+- MI->eraseFromParent();
++ MI.eraseFromParent();
+ ++NumUncoalescableCopies;
+ return true;
+ }
+@@ -1374,18 +1308,18 @@
+ /// We only fold loads to virtual registers and the virtual register defined
+ /// has a single use.
+ bool PeepholeOptimizer::isLoadFoldable(
+- MachineInstr *MI, SmallSet<unsigned, 16> &FoldAsLoadDefCandidates) {
+- if (!MI->canFoldAsLoad() || !MI->mayLoad())
++ MachineInstr &MI, SmallSet<unsigned, 16> &FoldAsLoadDefCandidates) {
++ if (!MI.canFoldAsLoad() || !MI.mayLoad())
+ return false;
+- const MCInstrDesc &MCID = MI->getDesc();
++ const MCInstrDesc &MCID = MI.getDesc();
+ if (MCID.getNumDefs() != 1)
+ return false;
+
+- unsigned Reg = MI->getOperand(0).getReg();
++ unsigned Reg = MI.getOperand(0).getReg();
+ // To reduce compilation time, we check MRI->hasOneNonDBGUse when inserting
+ // loads. It should be checked when processing uses of the load, since
+ // uses can be removed during peephole.
+- if (!MI->getOperand(0).getSubReg() &&
++ if (!MI.getOperand(0).getSubReg() &&
+ TargetRegisterInfo::isVirtualRegister(Reg) &&
+ MRI->hasOneNonDBGUse(Reg)) {
+ FoldAsLoadDefCandidates.insert(Reg);
+@@ -1395,16 +1329,16 @@
+ }
+
+ bool PeepholeOptimizer::isMoveImmediate(
+- MachineInstr *MI, SmallSet<unsigned, 4> &ImmDefRegs,
++ MachineInstr &MI, SmallSet<unsigned, 4> &ImmDefRegs,
+ DenseMap<unsigned, MachineInstr *> &ImmDefMIs) {
+- const MCInstrDesc &MCID = MI->getDesc();
+- if (!MI->isMoveImmediate())
++ const MCInstrDesc &MCID = MI.getDesc();
++ if (!MI.isMoveImmediate())
+ return false;
+ if (MCID.getNumDefs() != 1)
+ return false;
+- unsigned Reg = MI->getOperand(0).getReg();
++ unsigned Reg = MI.getOperand(0).getReg();
+ if (TargetRegisterInfo::isVirtualRegister(Reg)) {
+- ImmDefMIs.insert(std::make_pair(Reg, MI));
++ ImmDefMIs.insert(std::make_pair(Reg, &MI));
+ ImmDefRegs.insert(Reg);
+ return true;
+ }
+@@ -1415,11 +1349,11 @@
+ /// Try folding register operands that are defined by move immediate
+ /// instructions, i.e. a trivial constant folding optimization, if
+ /// and only if the def and use are in the same BB.
+-bool PeepholeOptimizer::foldImmediate(
+- MachineInstr *MI, MachineBasicBlock *MBB, SmallSet<unsigned, 4> &ImmDefRegs,
++bool PeepholeOptimizer::foldImmediate(MachineInstr &MI,
++ SmallSet<unsigned, 4> &ImmDefRegs,
+ DenseMap<unsigned, MachineInstr *> &ImmDefMIs) {
+- for (unsigned i = 0, e = MI->getDesc().getNumOperands(); i != e; ++i) {
+- MachineOperand &MO = MI->getOperand(i);
++ for (unsigned i = 0, e = MI.getDesc().getNumOperands(); i != e; ++i) {
++ MachineOperand &MO = MI.getOperand(i);
+ if (!MO.isReg() || MO.isDef())
+ continue;
+ // Ignore dead implicit defs.
+@@ -1432,7 +1366,7 @@
+ continue;
+ DenseMap<unsigned, MachineInstr*>::iterator II = ImmDefMIs.find(Reg);
+ assert(II != ImmDefMIs.end() && "couldn't find immediate definition");
+- if (TII->FoldImmediate(*MI, *II->second, Reg, MRI)) {
++ if (TII->FoldImmediate(MI, *II->second, Reg, MRI)) {
+ ++NumImmFold;
+ return true;
+ }
+@@ -1454,28 +1388,28 @@
+ // %2 = COPY %0:sub1
+ //
+ // Should replace %2 uses with %1:sub1
+-bool PeepholeOptimizer::foldRedundantCopy(
+- MachineInstr *MI, SmallSet<unsigned, 4> &CopySrcRegs,
++bool PeepholeOptimizer::foldRedundantCopy(MachineInstr &MI,
++ SmallSet<unsigned, 4> &CopySrcRegs,
+ DenseMap<unsigned, MachineInstr *> &CopyMIs) {
+- assert(MI->isCopy() && "expected a COPY machine instruction");
++ assert(MI.isCopy() && "expected a COPY machine instruction");
+
+- unsigned SrcReg = MI->getOperand(1).getReg();
++ unsigned SrcReg = MI.getOperand(1).getReg();
+ if (!TargetRegisterInfo::isVirtualRegister(SrcReg))
+ return false;
+
+- unsigned DstReg = MI->getOperand(0).getReg();
++ unsigned DstReg = MI.getOperand(0).getReg();
+ if (!TargetRegisterInfo::isVirtualRegister(DstReg))
+ return false;
+
+ if (CopySrcRegs.insert(SrcReg).second) {
+ // First copy of this reg seen.
+- CopyMIs.insert(std::make_pair(SrcReg, MI));
++ CopyMIs.insert(std::make_pair(SrcReg, &MI));
+ return false;
+ }
+
+ MachineInstr *PrevCopy = CopyMIs.find(SrcReg)->second;
+
+- unsigned SrcSubReg = MI->getOperand(1).getSubReg();
++ unsigned SrcSubReg = MI.getOperand(1).getSubReg();
+ unsigned PrevSrcSubReg = PrevCopy->getOperand(1).getSubReg();
+
+ // Can't replace different subregister extracts.
+@@ -1504,19 +1438,19 @@
+ }
+
+ bool PeepholeOptimizer::foldRedundantNAPhysCopy(
+- MachineInstr *MI, DenseMap<unsigned, MachineInstr *> &NAPhysToVirtMIs) {
+- assert(MI->isCopy() && "expected a COPY machine instruction");
++ MachineInstr &MI, DenseMap<unsigned, MachineInstr *> &NAPhysToVirtMIs) {
++ assert(MI.isCopy() && "expected a COPY machine instruction");
+
+ if (DisableNAPhysCopyOpt)
+ return false;
+
+- unsigned DstReg = MI->getOperand(0).getReg();
+- unsigned SrcReg = MI->getOperand(1).getReg();
++ unsigned DstReg = MI.getOperand(0).getReg();
++ unsigned SrcReg = MI.getOperand(1).getReg();
+ if (isNAPhysCopy(SrcReg) && TargetRegisterInfo::isVirtualRegister(DstReg)) {
+ // %vreg = COPY %physreg
+ // Avoid using a datastructure which can track multiple live non-allocatable
+ // phys->virt copies since LLVM doesn't seem to do this.
+- NAPhysToVirtMIs.insert({SrcReg, MI});
++ NAPhysToVirtMIs.insert({SrcReg, &MI});
+ return false;
+ }
+
+@@ -1528,8 +1462,7 @@
+ if (PrevCopy == NAPhysToVirtMIs.end()) {
+ // We can't remove the copy: there was an intervening clobber of the
+ // non-allocatable physical register after the copy to virtual.
+- DEBUG(dbgs() << "NAPhysCopy: intervening clobber forbids erasing " << *MI
+- << '\n');
++ DEBUG(dbgs() << "NAPhysCopy: intervening clobber forbids erasing " << MI);
+ return false;
+ }
+
+@@ -1537,7 +1470,7 @@
+ if (PrevDstReg == SrcReg) {
+ // Remove the virt->phys copy: we saw the virtual register definition, and
+ // the non-allocatable physical register's state hasn't changed since then.
+- DEBUG(dbgs() << "NAPhysCopy: erasing " << *MI << '\n');
++ DEBUG(dbgs() << "NAPhysCopy: erasing " << MI);
+ ++NumNAPhysCopies;
+ return true;
+ }
+@@ -1546,7 +1479,7 @@
+ // register get a copy of the non-allocatable physical register, and we only
+ // track one such copy. Avoid getting confused by this new non-allocatable
+ // physical register definition, and remove it from the tracked copies.
+- DEBUG(dbgs() << "NAPhysCopy: missed opportunity " << *MI << '\n');
++ DEBUG(dbgs() << "NAPhysCopy: missed opportunity " << MI);
+ NAPhysToVirtMIs.erase(PrevCopy);
+ return false;
+ }
+@@ -1611,11 +1544,11 @@
+ return false;
+ }
+
+-/// \brief Phi instructions will eventually be lowered to copy instructions. If
+-/// phi is in a loop header, a recurrence may formulated around the source and
+-/// destination of the phi. For such case commuting operands of the instructions
+-/// in the recurrence may enable coalescing of the copy instruction generated
+-/// from the phi. For example, if there is a recurrence of
++/// Phi instructions will eventually be lowered to copy instructions.
++/// If phi is in a loop header, a recurrence may formulated around the source
++/// and destination of the phi. For such case commuting operands of the
++/// instructions in the recurrence may enable coalescing of the copy instruction
++/// generated from the phi. For example, if there is a recurrence of
+ ///
+ /// LoopHeader:
+ /// %1 = phi(%0, %100)
+@@ -1725,27 +1658,25 @@
+ }
+
+ if (!MI->isCopy()) {
+- for (const auto &Op : MI->operands()) {
++ for (const MachineOperand &MO : MI->operands()) {
+ // Visit all operands: definitions can be implicit or explicit.
+- if (Op.isReg()) {
+- unsigned Reg = Op.getReg();
+- if (Op.isDef() && isNAPhysCopy(Reg)) {
++ if (MO.isReg()) {
++ unsigned Reg = MO.getReg();
++ if (MO.isDef() && isNAPhysCopy(Reg)) {
+ const auto &Def = NAPhysToVirtMIs.find(Reg);
+ if (Def != NAPhysToVirtMIs.end()) {
+ // A new definition of the non-allocatable physical register
+ // invalidates previous copies.
+- DEBUG(dbgs() << "NAPhysCopy: invalidating because of " << *MI
+- << '\n');
++ DEBUG(dbgs() << "NAPhysCopy: invalidating because of " << *MI);
+ NAPhysToVirtMIs.erase(Def);
+ }
+ }
+- } else if (Op.isRegMask()) {
+- const uint32_t *RegMask = Op.getRegMask();
++ } else if (MO.isRegMask()) {
++ const uint32_t *RegMask = MO.getRegMask();
+ for (auto &RegMI : NAPhysToVirtMIs) {
+ unsigned Def = RegMI.first;
+ if (MachineOperand::clobbersPhysReg(RegMask, Def)) {
+- DEBUG(dbgs() << "NAPhysCopy: invalidating because of " << *MI
+- << '\n');
++ DEBUG(dbgs() << "NAPhysCopy: invalidating because of " << *MI);
+ NAPhysToVirtMIs.erase(Def);
+ }
+ }
+@@ -1761,58 +1692,57 @@
+ // don't know what's correct anymore.
+ //
+ // FIXME: handle explicit asm clobbers.
+- DEBUG(dbgs() << "NAPhysCopy: blowing away all info due to " << *MI
+- << '\n');
++ DEBUG(dbgs() << "NAPhysCopy: blowing away all info due to " << *MI);
+ NAPhysToVirtMIs.clear();
+ }
+
+ if ((isUncoalescableCopy(*MI) &&
+- optimizeUncoalescableCopy(MI, LocalMIs)) ||
+- (MI->isCompare() && optimizeCmpInstr(MI, &MBB)) ||
+- (MI->isSelect() && optimizeSelect(MI, LocalMIs))) {
++ optimizeUncoalescableCopy(*MI, LocalMIs)) ||
++ (MI->isCompare() && optimizeCmpInstr(*MI)) ||
++ (MI->isSelect() && optimizeSelect(*MI, LocalMIs))) {
+ // MI is deleted.
+ LocalMIs.erase(MI);
+ Changed = true;
+ continue;
+ }
+
+- if (MI->isConditionalBranch() && optimizeCondBranch(MI)) {
++ if (MI->isConditionalBranch() && optimizeCondBranch(*MI)) {
+ Changed = true;
+ continue;
+ }
+
+- if (isCoalescableCopy(*MI) && optimizeCoalescableCopy(MI)) {
++ if (isCoalescableCopy(*MI) && optimizeCoalescableCopy(*MI)) {
+ // MI is just rewritten.
+ Changed = true;
+ continue;
+ }
+
+ if (MI->isCopy() &&
+- (foldRedundantCopy(MI, CopySrcRegs, CopySrcMIs) ||
+- foldRedundantNAPhysCopy(MI, NAPhysToVirtMIs))) {
++ (foldRedundantCopy(*MI, CopySrcRegs, CopySrcMIs) ||
++ foldRedundantNAPhysCopy(*MI, NAPhysToVirtMIs))) {
+ LocalMIs.erase(MI);
+ MI->eraseFromParent();
+ Changed = true;
+ continue;
+ }
+
+- if (isMoveImmediate(MI, ImmDefRegs, ImmDefMIs)) {
++ if (isMoveImmediate(*MI, ImmDefRegs, ImmDefMIs)) {
+ SeenMoveImm = true;
+ } else {
+- Changed |= optimizeExtInstr(MI, &MBB, LocalMIs);
++ Changed |= optimizeExtInstr(*MI, MBB, LocalMIs);
+ // optimizeExtInstr might have created new instructions after MI
+ // and before the already incremented MII. Adjust MII so that the
+ // next iteration sees the new instructions.
+ MII = MI;
+ ++MII;
+ if (SeenMoveImm)
+- Changed |= foldImmediate(MI, &MBB, ImmDefRegs, ImmDefMIs);
++ Changed |= foldImmediate(*MI, ImmDefRegs, ImmDefMIs);
+ }
+
+ // Check whether MI is a load candidate for folding into a later
+ // instruction. If MI is not a candidate, check whether we can fold an
+ // earlier load into MI.
+- if (!isLoadFoldable(MI, FoldAsLoadDefCandidates) &&
++ if (!isLoadFoldable(*MI, FoldAsLoadDefCandidates) &&
+ !FoldAsLoadDefCandidates.empty()) {
+
+ // We visit each operand even after successfully folding a previous
+@@ -1861,7 +1791,7 @@
+ // the load candidates. Note: We might be able to fold *into* this
+ // instruction, so this needs to be after the folding logic.
+ if (MI->isLoadFoldBarrier()) {
+- DEBUG(dbgs() << "Encountered load fold barrier on " << *MI << "\n");
++ DEBUG(dbgs() << "Encountered load fold barrier on " << *MI);
+ FoldAsLoadDefCandidates.clear();
+ }
+ }
+@@ -1958,14 +1888,14 @@
+ // duplicate the code from the generic TII.
+ return ValueTrackerResult();
+
+- SmallVector<TargetInstrInfo::RegSubRegPairAndIdx, 8> RegSeqInputRegs;
++ SmallVector<RegSubRegPairAndIdx, 8> RegSeqInputRegs;
+ if (!TII->getRegSequenceInputs(*Def, DefIdx, RegSeqInputRegs))
+ return ValueTrackerResult();
+
+ // We are looking at:
+ // Def = REG_SEQUENCE v0, sub0, v1, sub1, ...
+ // Check if one of the operand defines the subreg we are interested in.
+- for (auto &RegSeqInput : RegSeqInputRegs) {
++ for (const RegSubRegPairAndIdx &RegSeqInput : RegSeqInputRegs) {
+ if (RegSeqInput.SubIdx == DefSubReg) {
+ if (RegSeqInput.SubReg)
+ // Bail if we have to compose sub registers.
+@@ -1996,8 +1926,8 @@
+ // duplicate the code from the generic TII.
+ return ValueTrackerResult();
+
+- TargetInstrInfo::RegSubRegPair BaseReg;
+- TargetInstrInfo::RegSubRegPairAndIdx InsertedReg;
++ RegSubRegPair BaseReg;
++ RegSubRegPairAndIdx InsertedReg;
+ if (!TII->getInsertSubregInputs(*Def, DefIdx, BaseReg, InsertedReg))
+ return ValueTrackerResult();
+
+@@ -2050,7 +1980,7 @@
+ // duplicate the code from the generic TII.
+ return ValueTrackerResult();
+
+- TargetInstrInfo::RegSubRegPairAndIdx ExtractSubregInputReg;
++ RegSubRegPairAndIdx ExtractSubregInputReg;
+ if (!TII->getExtractSubregInputs(*Def, DefIdx, ExtractSubregInputReg))
+ return ValueTrackerResult();
+
+@@ -2083,7 +2013,7 @@
+ Def->getOperand(3).getImm());
+ }
+
+-/// \brief Explore each PHI incoming operand and return its sources
++/// Explore each PHI incoming operand and return its sources.
+ ValueTrackerResult ValueTracker::getNextSourceFromPHI() {
+ assert(Def->isPHI() && "Invalid definition");
+ ValueTrackerResult Res;
+@@ -2095,7 +2025,7 @@
+
+ // Return all register sources for PHI instructions.
+ for (unsigned i = 1, e = Def->getNumOperands(); i < e; i += 2) {
+- auto &MO = Def->getOperand(i);
++ const MachineOperand &MO = Def->getOperand(i);
+ assert(MO.isReg() && "Invalid PHI instruction");
+ // We have no code to deal with undef operands. They shouldn't happen in
+ // normal programs anyway.
+@@ -2121,7 +2051,7 @@
+ return getNextSourceFromBitcast();
+ // All the remaining cases involve "complex" instructions.
+ // Bail if we did not ask for the advanced tracking.
+- if (!UseAdvancedTracking)
++ if (DisableAdvCopyOpt)
+ return ValueTrackerResult();
+ if (Def->isRegSequence() || Def->isRegSequenceLike())
+ return getNextSourceFromRegSequence();