components/llvm/patches/001-solaris-LLVM-libLLVMCodegen.patch
changeset 6512 92717ce71105
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/llvm/patches/001-solaris-LLVM-libLLVMCodegen.patch	Thu Jul 28 16:25:34 2016 -0700
@@ -0,0 +1,629 @@
+# 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;
+   }
+ 
+###
+