components/llvm/patches/001-solaris-LLVM-libLLVMCodegen.patch
author Stefan Teleman <stefan.teleman@oracle.com>
Thu, 28 Jul 2016 16:25:34 -0700
changeset 6512 92717ce71105
permissions -rw-r--r--
24326140 upgrade LLVM to 3.8.1 24326159 upgrade clang to 3.8.1 22902339 memory corruption caused by undefined behavior in LLVM IR Module 22777179 implement [ -mtune= -march= -mcpu= ] in clang SPARC 22778085 LLVM is using %icc when it should be using %xcc 22778089 the SPARCV9 IS implementation is incomplete 22778098 LLVM should emit proc identifiers in SPARC assembler (capabilities) 22778650 clang should support OpenMP because it can 22859423 llvm CodeGen on Intel emits a bogus .ctors section 22902355 clang CodeGen is affected by 22902339 23701635 clang produces amd64 opcodes, but calls 32-bit assembler by default 23593143 lli JIT bitcode parsing creates a main function with wrong argc/argv 21759660 clang packages should include the scan-view and scan-build utilities 23854357 clang should check for GNU ld 17867434 clang crashed in LEXER 24306550 clang crashes in llvm::Twine::toStringRef 24311726 clang's Perl and Python utilities should not use #!/usr/bin/env 24312028 llvm::Twine needs copy constructors and assignment operators 24312221 classes must be CopyConstructible, CopyAssignable, MoveConstructible ... 24314621 LLVM should build using the new CMake based build system 24314638 LLVM CommandLine subsystem is busted 24314687 static initialization of optimization passes doesn't work as intended 21870069 clang makes incorrect assumptions about anonymous namespace instantiation order 22643565 llvm's Google test harness needs some attention 24314745 clang should support PIE executables in Solaris

# 22859423 llvm CodeGen on Intel emits a bogus .ctors section
# 22902339 memory corruption caused by undefined behavior in LLVM IR Module
--- include/llvm/CodeGen/CommandFlags.h	2015-12-16 14:58:30.000000000 -0500
+++ include/llvm/CodeGen/CommandFlags.h	2016-05-08 23:19:20.514430315 -0400
@@ -38,7 +38,7 @@
 MCPU("mcpu",
      cl::desc("Target a specific cpu type (-mcpu=help for details)"),
      cl::value_desc("cpu-name"),
-     cl::init(""));
+     cl::init(std::string("")));
 
 cl::list<std::string>
 MAttrs("mattr",
@@ -190,7 +190,7 @@
 cl::opt<std::string>
 TrapFuncName("trap-func", cl::Hidden,
         cl::desc("Emit a call to trap function rather than a trap instruction"),
-        cl::init(""));
+        cl::init(std::string("")));
 
 cl::opt<bool>
 EnablePIE("enable-pie",
@@ -202,35 +202,42 @@
              cl::desc("Use .ctors instead of .init_array."),
              cl::init(false));
 
-cl::opt<std::string> StopAfter("stop-after",
-                            cl::desc("Stop compilation after a specific pass"),
-                            cl::value_desc("pass-name"),
-                                      cl::init(""));
-cl::opt<std::string> StartAfter("start-after",
-                          cl::desc("Resume compilation after a specific pass"),
-                          cl::value_desc("pass-name"),
-                          cl::init(""));
+cl::opt<std::string>
+StopAfter("stop-after",
+          cl::desc("Stop compilation after a specific pass"),
+          cl::value_desc("pass-name"),
+          cl::init(std::string("")));
+
+cl::opt<std::string>
+StartAfter("start-after",
+           cl::desc("Resume compilation after a specific pass"),
+           cl::value_desc("pass-name"),
+           cl::init(std::string("")));
 
 cl::opt<std::string>
-    RunPass("run-pass", cl::desc("Run compiler only for one specific pass"),
-            cl::value_desc("pass-name"), cl::init(""));
+RunPass("run-pass", cl::desc("Run compiler only for one specific pass"),
+        cl::value_desc("pass-name"),
+        cl::init(std::string("")));
 
-cl::opt<bool> DataSections("data-sections",
-                           cl::desc("Emit data into separate sections"),
-                           cl::init(false));
+cl::opt<bool>
+DataSections("data-sections",
+             cl::desc("Emit data into separate sections"),
+             cl::init(false));
 
 cl::opt<bool>
 FunctionSections("function-sections",
                  cl::desc("Emit functions into separate sections"),
                  cl::init(false));
 
-cl::opt<bool> EmulatedTLS("emulated-tls",
-                          cl::desc("Use emulated TLS model"),
-                          cl::init(false));
-
-cl::opt<bool> UniqueSectionNames("unique-section-names",
-                                 cl::desc("Give unique names to every section"),
-                                 cl::init(true));
+cl::opt<bool>
+EmulatedTLS("emulated-tls",
+            cl::desc("Use emulated TLS model"),
+            cl::init(false));
+
+cl::opt<bool>
+UniqueSectionNames("unique-section-names",
+                   cl::desc("Give unique names to every section"),
+                   cl::init(true));
 
 cl::opt<llvm::JumpTable::JumpTableType>
 JTableType("jump-table-type",
@@ -269,7 +276,9 @@
 
 // Common utility function tightly tied to the options listed here. Initializes
 // a TargetOptions object with CodeGen flags and returns it.
-static inline TargetOptions InitTargetOptionsFromCodeGenFlags() {
+static inline
+__attribute__((used))
+TargetOptions InitTargetOptionsFromCodeGenFlags() {
   TargetOptions Options;
   Options.LessPreciseFPMADOption = EnableFPMAD;
   Options.AllowFPOpFusion = FuseFPOps;
###
--- include/llvm/CodeGen/LiveInterval.h	2016-02-17 10:41:44.000000000 -0800
+++ include/llvm/CodeGen/LiveInterval.h	2016-07-08 16:53:26.422739200 -0700
@@ -43,7 +43,7 @@
   /// This class holds information about a machine level values, including
   /// definition and use points.
   ///
-  class VNInfo {
+  class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) VNInfo {
   public:
     typedef BumpPtrAllocator Allocator;
 
@@ -55,13 +55,11 @@
 
     /// VNInfo constructor.
     VNInfo(unsigned i, SlotIndex d)
-      : id(i), def(d)
-    { }
+    : id(i), def(d) { }
 
     /// VNInfo construtor, copies values from orig, except for the value number.
     VNInfo(unsigned i, const VNInfo &orig)
-      : id(i), def(orig.def)
-    { }
+    : id(i), def(orig.def) { }
 
     /// Copy from the parameter into this VNInfo.
     void copyFrom(VNInfo &src) {
@@ -85,16 +83,15 @@
   /// of live ranges, and it should be used as the primary interface for
   /// examining live ranges around instructions.
   class LiveQueryResult {
+  private:
     VNInfo *const EarlyVal;
     VNInfo *const LateVal;
     const SlotIndex EndPoint;
     const bool Kill;
 
   public:
-    LiveQueryResult(VNInfo *EarlyVal, VNInfo *LateVal, SlotIndex EndPoint,
-                    bool Kill)
-      : EarlyVal(EarlyVal), LateVal(LateVal), EndPoint(EndPoint), Kill(Kill)
-    {}
+    LiveQueryResult(VNInfo *EV, VNInfo *LV, SlotIndex EP, bool K)
+    : EarlyVal(EV), LateVal(LV), EndPoint(EP), Kill(K) { }
 
     /// Return the value that is live-in to the instruction. This is the value
     /// that will be read by the instruction's use operands. Return NULL if no
@@ -157,12 +154,13 @@
     /// This represents a simple continuous liveness interval for a value.
     /// The start point is inclusive, the end point exclusive. These intervals
     /// are rendered as [start,end).
-    struct Segment {
+    class Segment {
+    public:
       SlotIndex start;  // Start point of the interval (inclusive)
       SlotIndex end;    // End point of the interval (exclusive)
       VNInfo *valno;    // identifier for the value contained in this segment.
 
-      Segment() : valno(nullptr) {}
+      Segment() : start(), end(), valno(nullptr) { }
 
       Segment(SlotIndex S, SlotIndex E, VNInfo *V)
         : start(S), end(E), valno(V) {
@@ -190,8 +188,9 @@
       void dump() const;
     };
 
-    typedef SmallVector<Segment,4> Segments;
-    typedef SmallVector<VNInfo*,4> VNInfoList;
+    typedef std::vector<Segment> Segments;
+    typedef std::vector<VNInfo*> VNInfoList;
+    typedef std::set<Segment> SegmentSet;
 
     Segments segments;   // the liveness segments
     VNInfoList valnos;   // value#'s
@@ -199,7 +198,6 @@
     // The segment set is used temporarily to accelerate initial computation
     // of live ranges of physical registers in computeRegUnitRange.
     // After that the set is flushed to the segment vector and deleted.
-    typedef std::set<Segment> SegmentSet;
     std::unique_ptr<SegmentSet> segmentSet;
 
     typedef Segments::iterator iterator;
@@ -219,13 +217,14 @@
     const_vni_iterator vni_end() const   { return valnos.end(); }
 
     /// Constructs a new LiveRange object.
-    LiveRange(bool UseSegmentSet = false)
-        : segmentSet(UseSegmentSet ? llvm::make_unique<SegmentSet>()
-                                   : nullptr) {}
+    explicit LiveRange(bool UseSegmentSet = false)
+    : segments(), valnos(),
+    segmentSet(UseSegmentSet ? llvm::make_unique<SegmentSet>() : nullptr) { }
 
     /// Constructs a new LiveRange object by copying segments and valnos from
     /// another LiveRange.
-    LiveRange(const LiveRange &Other, BumpPtrAllocator &Allocator) {
+    LiveRange(const LiveRange &Other, BumpPtrAllocator &Allocator)
+    : segments(), valnos(), segmentSet() {
       assert(Other.segmentSet == nullptr &&
              "Copying of LiveRanges with active SegmentSets is not supported");
 
@@ -305,8 +304,15 @@
     /// getNextValue - Create a new value number and return it.  MIIdx specifies
     /// the instruction that defines the value number.
     VNInfo *getNextValue(SlotIndex def, VNInfo::Allocator &VNInfoAllocator) {
-      VNInfo *VNI =
-        new (VNInfoAllocator) VNInfo((unsigned)valnos.size(), def);
+      size_t Size = sizeof(VNInfo) + valnos.size();
+      size_t Alignment = llvm::AlignOf<llvm::VNInfo>::Alignment;
+      void *Mem = VNInfoAllocator.Allocate(Size, Alignment);
+      assert(Mem && "VNInfoAllocator memory allocation failed!");
+
+      VNInfo *VNI = new (reinterpret_cast<VNInfo*>(Mem))
+        VNInfo(static_cast<unsigned>(valnos.size()), def);
+      assert(VNI && "VNInfo placement construction failed!");
+
       valnos.push_back(VNI);
       return VNI;
     }
@@ -320,8 +326,15 @@
     /// for the Value number.
     VNInfo *createValueCopy(const VNInfo *orig,
                             VNInfo::Allocator &VNInfoAllocator) {
-      VNInfo *VNI =
-        new (VNInfoAllocator) VNInfo((unsigned)valnos.size(), *orig);
+      size_t Size = sizeof(VNInfo) + valnos.size();
+      size_t Alignment = llvm::AlignOf<llvm::VNInfo>::Alignment;
+      void *Mem = VNInfoAllocator.Allocate(Size, Alignment);
+      assert(Mem && "VNInfoAllocator memory allocation failed!");
+
+      VNInfo *VNI = new (reinterpret_cast<VNInfo*>(Mem))
+        VNInfo(static_cast<unsigned>(valnos.size()), *orig);
+      assert(VNI && "VNInfo placement construction failed!");
+
       valnos.push_back(VNI);
       return VNI;
     }
@@ -591,28 +604,26 @@
 
   /// LiveInterval - This class represents the liveness of a register,
   /// or stack slot.
-  class LiveInterval : public LiveRange {
+  class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) LiveInterval : public LiveRange {
   public:
     typedef LiveRange super;
 
     /// A live range for subregisters. The LaneMask specifies which parts of the
     /// super register are covered by the interval.
     /// (@sa TargetRegisterInfo::getSubRegIndexLaneMask()).
-    class SubRange : public LiveRange {
+    class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) SubRange : public LiveRange {
     public:
       SubRange *Next;
       LaneBitmask LaneMask;
 
       /// Constructs a new SubRange object.
-      SubRange(LaneBitmask LaneMask)
-        : Next(nullptr), LaneMask(LaneMask) {
-      }
+      explicit SubRange(LaneBitmask Mask = 0U)
+      : LiveRange(), Next(nullptr), LaneMask(Mask) { }
 
       /// Constructs a new SubRange object by copying liveness from @p Other.
-      SubRange(LaneBitmask LaneMask, const LiveRange &Other,
+      SubRange(LaneBitmask Mask, const LiveRange &Other,
                BumpPtrAllocator &Allocator)
-        : LiveRange(Other, Allocator), Next(nullptr), LaneMask(LaneMask) {
-      }
+      : LiveRange(Other, Allocator), Next(nullptr), LaneMask(Mask) { }
     };
 
   private:
@@ -623,7 +634,7 @@
     float weight;        // weight of this interval
 
     LiveInterval(unsigned Reg, float Weight)
-      : SubRanges(nullptr), reg(Reg), weight(Weight) {}
+    : LiveRange(), SubRanges(nullptr), reg(Reg), weight(Weight) { }
 
     ~LiveInterval() {
       clearSubRanges();
@@ -787,13 +798,14 @@
     SlotIndex LastStart;
     LiveRange::iterator WriteI;
     LiveRange::iterator ReadI;
-    SmallVector<LiveRange::Segment, 16> Spills;
+    std::vector<LiveRange::Segment> Spills;
     void mergeSpills();
 
   public:
     /// Create a LiveRangeUpdater for adding segments to LR.
     /// LR will temporarily be in an invalid state until flush() is called.
-    LiveRangeUpdater(LiveRange *lr = nullptr) : LR(lr) {}
+    explicit LiveRangeUpdater(LiveRange *lr = nullptr)
+    : LR(lr), LastStart(), WriteI(), ReadI(), Spills() { }
 
     ~LiveRangeUpdater() { flush(); }
 
###
--- lib/CodeGen/LiveInterval.cpp	2016-02-17 10:41:44.000000000 -0800
+++ lib/CodeGen/LiveInterval.cpp	2016-05-25 10:21:23.432898762 -0700
@@ -320,10 +320,16 @@
 VNInfo *LiveRange::createDeadDef(SlotIndex Def,
                                   VNInfo::Allocator &VNInfoAllocator) {
   // Use the segment set, if it is available.
-  if (segmentSet != nullptr)
-    return CalcLiveRangeUtilSet(this).createDeadDef(Def, VNInfoAllocator);
+  if (segmentSet != nullptr) {
+    CalcLiveRangeUtilSet CLR(this);
+    VNInfo *VNI = CLR.createDeadDef(Def, VNInfoAllocator);
+    return VNI;
+  }
+
   // Otherwise use the segment vector.
-  return CalcLiveRangeUtilVector(this).createDeadDef(Def, VNInfoAllocator);
+  CalcLiveRangeUtilVector CLR(this);
+  VNInfo *VNI = CLR.createDeadDef(Def, VNInfoAllocator);
+  return VNI;
 }
 
 // overlaps - Return true if the intersection of the two live ranges is
@@ -740,10 +746,12 @@
 
 void LiveRange::flushSegmentSet() {
   assert(segmentSet != nullptr && "segment set must have been created");
-  assert(
-      segments.empty() &&
-      "segment set can be used only initially before switching to the array");
-  segments.append(segmentSet->begin(), segmentSet->end());
+  assert(segments.empty() &&
+         "segment set can be used only initially before "
+         "switching to the array");
+
+  segments.insert(segments.end(),
+                  segmentSet->begin(), segmentSet->end());
   segmentSet = nullptr;
   verify();
 }
###
--- lib/CodeGen/LiveIntervalAnalysis.cpp	2016-01-07 17:16:35.000000000 -0800
+++ lib/CodeGen/LiveIntervalAnalysis.cpp	2016-05-25 08:48:39.699849409 -0700
@@ -185,12 +185,19 @@
 }
 #endif
 
-LiveInterval* LiveIntervals::createInterval(unsigned reg) {
-  float Weight = TargetRegisterInfo::isPhysicalRegister(reg) ?
+LiveInterval* LiveIntervals::createInterval(unsigned Reg) {
+  float Weight = TargetRegisterInfo::isPhysicalRegister(Reg) ?
                   llvm::huge_valf : 0.0F;
-  return new LiveInterval(reg, Weight);
-}
+  void *Mem;
+  size_t Alignment = llvm::AlignOf<uint64_t>::Alignment;
+  if (posix_memalign(&Mem, Alignment, sizeof(LiveInterval)) != 0)
+    return nullptr;
+
+  (void) std::memset(Mem, 0, sizeof(LiveInterval));
 
+  LiveInterval *LI = new (Mem) LiveInterval(Reg, Weight);
+  return LI;
+}
 
 /// computeVirtRegInterval - Compute the live interval of a virtual register,
 /// based on defs and uses.
###
--- lib/CodeGen/MachineBasicBlock.cpp	2016-01-07 01:26:32.000000000 -0900
+++ lib/CodeGen/MachineBasicBlock.cpp	2016-07-07 10:45:17.893185995 -0800
@@ -40,12 +40,16 @@
 #define DEBUG_TYPE "codegen"
 
 MachineBasicBlock::MachineBasicBlock(MachineFunction &MF, const BasicBlock *B)
-    : BB(B), Number(-1), xParent(&MF) {
-  Insts.Parent = this;
+  : ilist_node_with_parent<MachineBasicBlock, MachineFunction>(),
+  BB(B), Number(-1), xParent(&MF),
+  Predecessors(), Successors(), Probs(), LiveIns(),
+  Alignment(0U), IsEHPad(false), AddressTaken(false),
+  IsEHFuncletEntry(false), IsCleanupFuncletEntry(false),
+  CachedMCSymbol(nullptr) {
+    Insts.Parent = this;
 }
 
-MachineBasicBlock::~MachineBasicBlock() {
-}
+MachineBasicBlock::~MachineBasicBlock() { }
 
 /// Return the MCSymbol for this basic block.
 MCSymbol *MachineBasicBlock::getSymbol() const {
@@ -525,8 +529,9 @@
                                      BranchProbability Prob) {
   // Probability list is either empty (if successor list isn't empty, this means
   // disabled optimization) or has the same size as successor list.
-  if (!(Probs.empty() && !Successors.empty()))
+  if (Probs.empty() || (Probs.size() == Successors.size()))
     Probs.push_back(Prob);
+
   Successors.push_back(Succ);
   Succ->addPredecessor(this);
 }
###.
--- include/llvm/CodeGen/MachineBasicBlock.h	2015-12-13 00:26:17.000000000 -0900
+++ include/llvm/CodeGen/MachineBasicBlock.h	2016-07-07 10:24:28.207403130 -0800
@@ -125,7 +125,15 @@
   mutable MCSymbol *CachedMCSymbol = nullptr;
 
   // Intrusive list support
-  MachineBasicBlock() {}
+  MachineBasicBlock()
+  : ilist_node_with_parent<MachineBasicBlock, MachineFunction>(),
+  Insts(), BB(nullptr), Number(-1), xParent(nullptr),
+  Predecessors(), Successors(), Probs(), LiveIns(),
+  Alignment(0U), IsEHPad(false), AddressTaken(false),
+  IsEHFuncletEntry(false), IsCleanupFuncletEntry(false),
+  CachedMCSymbol(nullptr) {
+    Insts.Parent = this;
+  }
 
   explicit MachineBasicBlock(MachineFunction &MF, const BasicBlock *BB);
 
###
--- lib/CodeGen/AsmPrinter/AsmPrinter.cpp	2016-01-12 17:18:13.000000000 -0800
+++ lib/CodeGen/AsmPrinter/AsmPrinter.cpp	2016-05-25 14:27:34.764865039 -0700
@@ -1614,6 +1614,7 @@
 };
 } // end namespace
 
+
 /// EmitXXStructorList - Emit the ctor or dtor list taking into account the init
 /// priority.
 void AsmPrinter::EmitXXStructorList(const DataLayout &DL, const Constant *List,
@@ -1667,13 +1668,14 @@
 
       KeySym = getSymbol(GV);
     }
-    MCSection *OutputSection =
-        (isCtor ? Obj.getStaticCtorSection(S.Priority, KeySym)
-                : Obj.getStaticDtorSection(S.Priority, KeySym));
-    OutStreamer->SwitchSection(OutputSection);
-    if (OutStreamer->getCurrentSection() != OutStreamer->getPreviousSection())
-      EmitAlignment(Align);
-    EmitXXStructor(DL, S.Func);
+
+    // Why is this even necessary?
+    // Constructors for global statics are emitted in
+    // clang/lib/CodeGen/DeclCXX.cpp
+    // Destructors for global statics register themselves with __cxa_atexit.
+    // I.e. they do not need any kind of additional special handling.
+    // The only thing this does is duplicate constructor calls for
+    // global static initializations.
   }
 }
 
###
--- lib/CodeGen/CodeGenPrepare.cpp	2016-01-22 13:26:38.000000000 -0500
+++ lib/CodeGen/CodeGenPrepare.cpp	2016-05-28 13:01:43.647551022 -0400
@@ -2445,59 +2445,67 @@
 
 private:
   /// The ordered list of actions made so far.
-  SmallVector<std::unique_ptr<TypePromotionAction>, 16> Actions;
-  typedef SmallVectorImpl<std::unique_ptr<TypePromotionAction>>::iterator CommitPt;
+  /// You cannot use a SmallVector here because of copy vs. move
+  /// semantics. You can't use a std::unique_ptr eiter, for the
+  /// same exact reasons.
+  std::vector<std::shared_ptr<TypePromotionAction> > Actions;
+  typedef std::vector<std::shared_ptr<TypePromotionAction>>::iterator CommitPt;
 };
 
 void TypePromotionTransaction::setOperand(Instruction *Inst, unsigned Idx,
                                           Value *NewVal) {
   Actions.push_back(
-      make_unique<TypePromotionTransaction::OperandSetter>(Inst, Idx, NewVal));
+      std::make_shared<TypePromotionTransaction::OperandSetter>(Inst,
+                                                                Idx, NewVal));
 }
 
 void TypePromotionTransaction::eraseInstruction(Instruction *Inst,
                                                 Value *NewVal) {
   Actions.push_back(
-      make_unique<TypePromotionTransaction::InstructionRemover>(Inst, NewVal));
+      std::make_shared<TypePromotionTransaction::InstructionRemover>(Inst,
+                                                                     NewVal));
 }
 
 void TypePromotionTransaction::replaceAllUsesWith(Instruction *Inst,
                                                   Value *New) {
-  Actions.push_back(make_unique<TypePromotionTransaction::UsesReplacer>(Inst, New));
+  Actions.push_back(
+    std::make_shared<TypePromotionTransaction::UsesReplacer>(Inst, New));
 }
 
 void TypePromotionTransaction::mutateType(Instruction *Inst, Type *NewTy) {
-  Actions.push_back(make_unique<TypePromotionTransaction::TypeMutator>(Inst, NewTy));
+  Actions.push_back(
+    std::make_shared<TypePromotionTransaction::TypeMutator>(Inst, NewTy));
 }
 
 Value *TypePromotionTransaction::createTrunc(Instruction *Opnd,
                                              Type *Ty) {
-  std::unique_ptr<TruncBuilder> Ptr(new TruncBuilder(Opnd, Ty));
+  std::shared_ptr<TruncBuilder> Ptr(new TruncBuilder(Opnd, Ty));
   Value *Val = Ptr->getBuiltValue();
-  Actions.push_back(std::move(Ptr));
+  Actions.push_back(Ptr);
   return Val;
 }
 
 Value *TypePromotionTransaction::createSExt(Instruction *Inst,
                                             Value *Opnd, Type *Ty) {
-  std::unique_ptr<SExtBuilder> Ptr(new SExtBuilder(Inst, Opnd, Ty));
+  std::shared_ptr<SExtBuilder> Ptr(new SExtBuilder(Inst, Opnd, Ty));
   Value *Val = Ptr->getBuiltValue();
-  Actions.push_back(std::move(Ptr));
+  Actions.push_back(Ptr);
   return Val;
 }
 
 Value *TypePromotionTransaction::createZExt(Instruction *Inst,
                                             Value *Opnd, Type *Ty) {
-  std::unique_ptr<ZExtBuilder> Ptr(new ZExtBuilder(Inst, Opnd, Ty));
+  std::shared_ptr<ZExtBuilder> Ptr(new ZExtBuilder(Inst, Opnd, Ty));
   Value *Val = Ptr->getBuiltValue();
-  Actions.push_back(std::move(Ptr));
+  Actions.push_back(Ptr);
   return Val;
 }
 
 void TypePromotionTransaction::moveBefore(Instruction *Inst,
                                           Instruction *Before) {
   Actions.push_back(
-      make_unique<TypePromotionTransaction::InstructionMoveBefore>(Inst, Before));
+      std::make_shared<TypePromotionTransaction::InstructionMoveBefore>(Inst,
+                                                                        Before));
 }
 
 TypePromotionTransaction::ConstRestorationPt
@@ -2515,8 +2523,9 @@
 void TypePromotionTransaction::rollback(
     TypePromotionTransaction::ConstRestorationPt Point) {
   while (!Actions.empty() && Point != Actions.back().get()) {
-    std::unique_ptr<TypePromotionAction> Curr = Actions.pop_back_val();
+    std::shared_ptr<TypePromotionAction> Curr = Actions.back();
     Curr->undo();
+    Actions.pop_back();
   }
 }
 
###
--- lib/CodeGen/Passes.cpp	2015-12-16 03:09:48.000000000 -0800
+++ lib/CodeGen/Passes.cpp	2016-05-13 17:38:47.747582295 -0700
@@ -31,9 +31,17 @@
 #include "llvm/Transforms/Instrumentation.h"
 #include "llvm/Transforms/Scalar.h"
 #include "llvm/Transforms/Utils/SymbolRewriter.h"
-
+#include "llvm/LinkAllPasses.h"
 using namespace llvm;
 
+//===----------------------------------------------------------------------===//
+/// See the file ${top_srcdir}/include/llvm/LinkAllPasses.h for the
+/// explanation of this hack.
+namespace llvm {
+    ForcePassLinking* ForcePassLinking::FPL = new llvm::ForcePassLinking();
+} // namespace llvm
+//===----------------------------------------------------------------------===//
+
 static cl::opt<bool> DisablePostRA("disable-post-ra", cl::Hidden,
     cl::desc("Disable Post Regalloc"));
 static cl::opt<bool> DisableBranchFold("disable-branch-fold", cl::Hidden,
###
--- lib/CodeGen/TargetLoweringObjectFileImpl.cpp	2015-11-17 22:02:15.000000000 -0800
+++ lib/CodeGen/TargetLoweringObjectFileImpl.cpp	2016-05-25 14:26:17.415867207 -0700
@@ -360,8 +360,10 @@
   return DataRelROSection;
 }
 
-static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray,
-                                              bool IsCtor, unsigned Priority,
+static MCSectionELF *getStaticStructorSection(MCContext &Ctx,
+                                              bool UseInitArray,
+                                              bool IsCtor,
+                                              unsigned Priority,
                                               const MCSymbol *KeySym) {
   std::string Name;
   unsigned Type;
@@ -379,21 +381,34 @@
       Type = ELF::SHT_FINI_ARRAY;
       Name = ".fini_array";
     }
+
     if (Priority != 65535) {
       Name += '.';
-      Name += utostr(Priority);
+      Name += std::to_string(Priority);
     }
   } else {
-    // The default scheme is .ctor / .dtor, so we have to invert the priority
-    // numbering.
-    if (IsCtor)
-      Name = ".ctors";
-    else
-      Name = ".dtors";
+    if (Ctx.getObjectFileInfo()->getTargetTriple().getOS() ==
+        llvm::Triple::Solaris) {
+      // on Solaris we use .inift/.fini because the Solaris linker
+      // can't handle .ctors/.dtors.
+      if (IsCtor)
+        Name = ".init";
+      else
+        Name = ".fini";
+    } else {
+      // The default scheme is .ctor / .dtor, so we have to invert the priority
+      // numbering.
+      if (IsCtor)
+        Name = ".ctors";
+      else
+        Name = ".dtors";
+    }
+
     if (Priority != 65535) {
       Name += '.';
-      Name += utostr(65535 - Priority);
+      Name += std::to_string(65535 - Priority);
     }
+
     Type = ELF::SHT_PROGBITS;
   }
 
###