Subzero: Use CFG-local arena allocation for relevant containers.

In particular, node lists for in and out edges of a CfgNode, and the live range segment list in a Variable.  This is done by making the Cfg allocator globally available through TLS, and providing the STL containers with an allocator struct that uses this.

This also cleans up some other allocation-related issues:

* The allocator is now hung off the Cfg via a pointer, rather than being embedded into the Cfg.  This allows a const Cfg pointer to be stored in TLS while still allowing its allocator to be mutated.

* Cfg is now created via a static create() method.

* The redundant Cfg::allocateInst<> methods are removed.

* The Variable::asType() method allocates a whole new Variable from the Cfg arena, rather than allocating it on the stack, removing the need for the move constructor in Variable and Operand.  This is OK since asType() is only used for textual asm emission.

* The same 1MB arena allocator is now used by the assembler as well.  The fact that it wasn't changed over to be the same as Cfg and GlobalContext was an oversight.  (It turns out this adds ~3MB to the translator memory footprint, so that could be tuned later.)

BUG= none
R=jfb@chromium.org, jvoung@chromium.org

Review URL: https://codereview.chromium.org/802183004
diff --git a/src/IceCfg.cpp b/src/IceCfg.cpp
index a328d21..59723ec 100644
--- a/src/IceCfg.cpp
+++ b/src/IceCfg.cpp
@@ -23,11 +23,17 @@
 
 namespace Ice {
 
+thread_local const Cfg *Cfg::CurrentCfg = NULL;
+
+ArenaAllocator *getCurrentCfgAllocator() {
+  return Cfg::getCurrentCfgAllocator();
+}
+
 Cfg::Cfg(GlobalContext *Ctx)
     : Ctx(Ctx), FunctionName(""), ReturnType(IceType_void),
       IsInternalLinkage(false), HasError(false), FocusedTiming(false),
       ErrorMessage(""), Entry(NULL), NextInstNumber(Inst::NumberInitial),
-      Live(nullptr),
+      Allocator(new ArenaAllocator()), Live(nullptr),
       Target(TargetLowering::createLowering(Ctx->getTargetArch(), this)),
       VMetadata(new VariablesMetadata(this)),
       TargetAssembler(
@@ -37,7 +43,13 @@
          "Attempt to build cfg when IR generation disabled");
 }
 
-Cfg::~Cfg() {}
+Cfg::~Cfg() {
+  // TODO(stichnot,kschimpf): Set CurrentCfg=NULL in the dtor for
+  // safety.  This can't be done currently because the translator
+  // manages the Cfg by creating a new Cfg (which sets CurrentCfg to
+  // the new value), then deleting the old Cfg (which would then reset
+  // CurrentCfg to NULL).
+}
 
 void Cfg::setError(const IceString &Message) {
   HasError = true;
diff --git a/src/IceCfg.h b/src/IceCfg.h
index 1768761..f037709 100644
--- a/src/IceCfg.h
+++ b/src/IceCfg.h
@@ -17,8 +17,6 @@
 
 #include <memory>
 
-#include "llvm/Support/Allocator.h"
-
 #include "assembler.h"
 #include "IceClFlags.h"
 #include "IceDefs.h"
@@ -32,9 +30,24 @@
   Cfg &operator=(const Cfg &) = delete;
 
 public:
-  Cfg(GlobalContext *Ctx);
   ~Cfg();
 
+  // TODO(stichnot): Change this to return unique_ptr<Cfg>, and plumb
+  // it through the callers, to make ownership and lifetime and
+  // destruction requirements more explicit.
+  static Cfg *create(GlobalContext *Ctx) {
+    Cfg *Func = new Cfg(Ctx);
+    CurrentCfg = Func;
+    return Func;
+  }
+  // Gets a pointer to the current thread's Cfg.
+  static const Cfg *getCurrentCfg() { return CurrentCfg; }
+  // Gets a pointer to the current thread's Cfg's allocator.
+  static ArenaAllocator *getCurrentCfgAllocator() {
+    assert(CurrentCfg);
+    return CurrentCfg->Allocator.get();
+  }
+
   GlobalContext *getContext() const { return Ctx; }
 
   // Manage the name and return type of the function being translated.
@@ -150,38 +163,25 @@
   void dump(const IceString &Message = "");
 
   // Allocate data of type T using the per-Cfg allocator.
-  template <typename T> T *allocate() { return Allocator.Allocate<T>(); }
-
-  // Allocate an instruction of type T using the per-Cfg instruction allocator.
-  template <typename T> T *allocateInst() { return Allocator.Allocate<T>(); }
+  template <typename T> T *allocate() { return Allocator->Allocate<T>(); }
 
   // Allocate an array of data of type T using the per-Cfg allocator.
   template <typename T> T *allocateArrayOf(size_t NumElems) {
-    return Allocator.Allocate<T>(NumElems);
+    return Allocator->Allocate<T>(NumElems);
   }
 
   // Deallocate data that was allocated via allocate<T>().
   template <typename T> void deallocate(T *Object) {
-    Allocator.Deallocate(Object);
-  }
-
-  // Deallocate data that was allocated via allocateInst<T>().
-  template <typename T> void deallocateInst(T *Instr) {
-    Allocator.Deallocate(Instr);
+    Allocator->Deallocate(Object);
   }
 
   // Deallocate data that was allocated via allocateArrayOf<T>().
   template <typename T> void deallocateArrayOf(T *Array) {
-    Allocator.Deallocate(Array);
+    Allocator->Deallocate(Array);
   }
 
 private:
-  // TODO: for now, everything is allocated from the same allocator. In the
-  // future we may want to split this to several allocators, for example in
-  // order to use a "Recycler" to preserve memory. If we keep all allocation
-  // requests from the Cfg exposed via methods, we can always switch the
-  // implementation over at a later point.
-  llvm::BumpPtrAllocatorImpl<llvm::MallocAllocator, 1024 * 1024> Allocator;
+  Cfg(GlobalContext *Ctx);
 
   GlobalContext *Ctx;
   IceString FunctionName;
@@ -197,6 +197,7 @@
   VarList Variables;
   VarList Args; // subset of Variables, in argument order
   VarList ImplicitArgs; // subset of Variables
+  std::unique_ptr<ArenaAllocator> Allocator;
   std::unique_ptr<Liveness> Live;
   std::unique_ptr<TargetLowering> Target;
   std::unique_ptr<VariablesMetadata> VMetadata;
@@ -208,6 +209,11 @@
   // register allocation, resetCurrentNode() should be called to avoid
   // spurious validation failures.
   const CfgNode *CurrentNode;
+
+  // Maintain a pointer in TLS to the current Cfg being translated.
+  // This is primarily for accessing its allocator statelessly, but
+  // other uses are possible.
+  thread_local static const Cfg *CurrentCfg;
 };
 
 } // end of namespace Ice
diff --git a/src/IceConverter.cpp b/src/IceConverter.cpp
index 2e6021b..cdfdc43 100644
--- a/src/IceConverter.cpp
+++ b/src/IceConverter.cpp
@@ -83,7 +83,7 @@
   Ice::Cfg *convertFunction(const Function *F) {
     VarMap.clear();
     NodeMap.clear();
-    Func = new Ice::Cfg(Ctx);
+    Func = Ice::Cfg::create(Ctx);
     Func->setFunctionName(F->getName());
     Func->setReturnType(convertToIceType(F->getReturnType()));
     Func->setInternal(F->hasInternalLinkage());
diff --git a/src/IceDefs.h b/src/IceDefs.h
index 6434077..867a2dd 100644
--- a/src/IceDefs.h
+++ b/src/IceDefs.h
@@ -32,6 +32,7 @@
 #include "llvm/ADT/SmallBitVector.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Allocator.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/ELF.h"
 #include "llvm/Support/raw_ostream.h"
@@ -56,16 +57,40 @@
 class VariableDeclaration;
 class VariablesMetadata;
 
-// TODO: Switch over to LLVM's ADT container classes.
-// http://llvm.org/docs/ProgrammersManual.html#picking-the-right-data-structure-for-a-task
+typedef llvm::BumpPtrAllocatorImpl<llvm::MallocAllocator, 1024 * 1024>
+ArenaAllocator;
+
+ArenaAllocator *getCurrentCfgAllocator();
+
+template <typename T> struct CfgLocalAllocator {
+  using value_type = T;
+  CfgLocalAllocator() = default;
+  template <class U> CfgLocalAllocator(const CfgLocalAllocator<U> &) {}
+  T *allocate(std::size_t Num) {
+    return getCurrentCfgAllocator()->Allocate<T>(Num);
+  }
+  void deallocate(T *, std::size_t) {}
+};
+template <typename T, typename U>
+inline bool operator==(const CfgLocalAllocator<T> &,
+                       const CfgLocalAllocator<U> &) {
+  return true;
+}
+template <typename T, typename U>
+inline bool operator!=(const CfgLocalAllocator<T> &,
+                       const CfgLocalAllocator<U> &) {
+  return false;
+}
+
 typedef std::string IceString;
 typedef llvm::ilist<Inst> InstList;
 // Ideally PhiList would be llvm::ilist<InstPhi>, and similar for
 // AssignList, but this runs into issues with SFINAE.
 typedef InstList PhiList;
 typedef InstList AssignList;
-typedef std::vector<Variable *> VarList;
-typedef std::vector<CfgNode *> NodeList;
+// VarList and NodeList are arena-allocated from the Cfg's allocator.
+typedef std::vector<Variable *, CfgLocalAllocator<Variable *>> VarList;
+typedef std::vector<CfgNode *, CfgLocalAllocator<CfgNode *>> NodeList;
 typedef std::vector<Constant *> ConstantList;
 
 // SizeT is for holding small-ish limits like number of source
diff --git a/src/IceGlobalContext.h b/src/IceGlobalContext.h
index fe50b53..0a0ed75 100644
--- a/src/IceGlobalContext.h
+++ b/src/IceGlobalContext.h
@@ -17,8 +17,6 @@
 
 #include <memory>
 
-#include "llvm/Support/Allocator.h"
-
 #include "IceDefs.h"
 #include "IceClFlags.h"
 #include "IceELFObjectWriter.h"
@@ -208,7 +206,7 @@
   Ostream *StrDump; // Stream for dumping / diagnostics
   Ostream *StrEmit; // Stream for code emission
 
-  llvm::BumpPtrAllocatorImpl<llvm::MallocAllocator, 1024 * 1024> Allocator;
+  ArenaAllocator Allocator;
   VerboseMask VMask;
   std::unique_ptr<class ConstantPool> ConstPool;
   Intrinsics IntrinsicsInfo;
diff --git a/src/IceInst.h b/src/IceInst.h
index 0b3b66c..0b7dc03 100644
--- a/src/IceInst.h
+++ b/src/IceInst.h
@@ -230,7 +230,7 @@
 public:
   static InstAlloca *create(Cfg *Func, Operand *ByteCount,
                             uint32_t AlignInBytes, Variable *Dest) {
-    return new (Func->allocateInst<InstAlloca>())
+    return new (Func->allocate<InstAlloca>())
         InstAlloca(Func, ByteCount, AlignInBytes, Dest);
   }
   uint32_t getAlignInBytes() const { return AlignInBytes; }
@@ -261,7 +261,7 @@
 
   static InstArithmetic *create(Cfg *Func, OpKind Op, Variable *Dest,
                                 Operand *Source1, Operand *Source2) {
-    return new (Func->allocateInst<InstArithmetic>())
+    return new (Func->allocate<InstArithmetic>())
         InstArithmetic(Func, Op, Dest, Source1, Source2);
   }
   OpKind getOp() const { return Op; }
@@ -292,8 +292,7 @@
 
 public:
   static InstAssign *create(Cfg *Func, Variable *Dest, Operand *Source) {
-    return new (Func->allocateInst<InstAssign>())
-        InstAssign(Func, Dest, Source);
+    return new (Func->allocate<InstAssign>()) InstAssign(Func, Dest, Source);
   }
   bool isSimpleAssign() const override { return true; }
   void dump(const Cfg *Func) const override;
@@ -315,12 +314,12 @@
   // optimized to an unconditional branch.
   static InstBr *create(Cfg *Func, Operand *Source, CfgNode *TargetTrue,
                         CfgNode *TargetFalse) {
-    return new (Func->allocateInst<InstBr>())
+    return new (Func->allocate<InstBr>())
         InstBr(Func, Source, TargetTrue, TargetFalse);
   }
   // Create an unconditional branch.
   static InstBr *create(Cfg *Func, CfgNode *Target) {
-    return new (Func->allocateInst<InstBr>()) InstBr(Func, Target);
+    return new (Func->allocate<InstBr>()) InstBr(Func, Target);
   }
   bool isUnconditional() const { return getTargetTrue() == NULL; }
   Operand *getCondition() const {
@@ -364,7 +363,7 @@
     // particular intrinsic is deletable and has no side-effects.
     const bool HasSideEffects = true;
     const InstKind Kind = Inst::Call;
-    return new (Func->allocateInst<InstCall>()) InstCall(
+    return new (Func->allocate<InstCall>()) InstCall(
         Func, NumArgs, Dest, CallTarget, HasTailCall, HasSideEffects, Kind);
   }
   void addArg(Operand *Arg) { addSource(Arg); }
@@ -406,7 +405,7 @@
 
   static InstCast *create(Cfg *Func, OpKind CastKind, Variable *Dest,
                           Operand *Source) {
-    return new (Func->allocateInst<InstCast>())
+    return new (Func->allocate<InstCast>())
         InstCast(Func, CastKind, Dest, Source);
   }
   OpKind getCastKind() const { return CastKind; }
@@ -427,7 +426,7 @@
 public:
   static InstExtractElement *create(Cfg *Func, Variable *Dest, Operand *Source1,
                                     Operand *Source2) {
-    return new (Func->allocateInst<InstExtractElement>())
+    return new (Func->allocate<InstExtractElement>())
         InstExtractElement(Func, Dest, Source1, Source2);
   }
 
@@ -458,7 +457,7 @@
 
   static InstFcmp *create(Cfg *Func, FCond Condition, Variable *Dest,
                           Operand *Source1, Operand *Source2) {
-    return new (Func->allocateInst<InstFcmp>())
+    return new (Func->allocate<InstFcmp>())
         InstFcmp(Func, Condition, Dest, Source1, Source2);
   }
   FCond getCondition() const { return Condition; }
@@ -488,7 +487,7 @@
 
   static InstIcmp *create(Cfg *Func, ICond Condition, Variable *Dest,
                           Operand *Source1, Operand *Source2) {
-    return new (Func->allocateInst<InstIcmp>())
+    return new (Func->allocate<InstIcmp>())
         InstIcmp(Func, Condition, Dest, Source1, Source2);
   }
   ICond getCondition() const { return Condition; }
@@ -510,7 +509,7 @@
 public:
   static InstInsertElement *create(Cfg *Func, Variable *Dest, Operand *Source1,
                                    Operand *Source2, Operand *Source3) {
-    return new (Func->allocateInst<InstInsertElement>())
+    return new (Func->allocate<InstInsertElement>())
         InstInsertElement(Func, Dest, Source1, Source2, Source3);
   }
 
@@ -535,7 +534,7 @@
   static InstIntrinsicCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest,
                                    Operand *CallTarget,
                                    const Intrinsics::IntrinsicInfo &Info) {
-    return new (Func->allocateInst<InstIntrinsicCall>())
+    return new (Func->allocate<InstIntrinsicCall>())
         InstIntrinsicCall(Func, NumArgs, Dest, CallTarget, Info);
   }
   static bool classof(const Inst *Inst) {
@@ -564,8 +563,7 @@
                           uint32_t Align = 1) {
     // TODO(kschimpf) Stop ignoring alignment specification.
     (void)Align;
-    return new (Func->allocateInst<InstLoad>())
-        InstLoad(Func, Dest, SourceAddr);
+    return new (Func->allocate<InstLoad>()) InstLoad(Func, Dest, SourceAddr);
   }
   Operand *getSourceAddress() const { return getSrc(0); }
   void dump(const Cfg *Func) const override;
@@ -584,7 +582,7 @@
 
 public:
   static InstPhi *create(Cfg *Func, SizeT MaxSrcs, Variable *Dest) {
-    return new (Func->allocateInst<InstPhi>()) InstPhi(Func, MaxSrcs, Dest);
+    return new (Func->allocate<InstPhi>()) InstPhi(Func, MaxSrcs, Dest);
   }
   void addArgument(Operand *Source, CfgNode *Label);
   Operand *getOperandForTarget(CfgNode *Target) const;
@@ -618,7 +616,7 @@
 
 public:
   static InstRet *create(Cfg *Func, Operand *RetValue = NULL) {
-    return new (Func->allocateInst<InstRet>()) InstRet(Func, RetValue);
+    return new (Func->allocate<InstRet>()) InstRet(Func, RetValue);
   }
   bool hasRetValue() const { return getSrcSize(); }
   Operand *getRetValue() const {
@@ -642,7 +640,7 @@
 public:
   static InstSelect *create(Cfg *Func, Variable *Dest, Operand *Condition,
                             Operand *SourceTrue, Operand *SourceFalse) {
-    return new (Func->allocateInst<InstSelect>())
+    return new (Func->allocate<InstSelect>())
         InstSelect(Func, Dest, Condition, SourceTrue, SourceFalse);
   }
   Operand *getCondition() const { return getSrc(0); }
@@ -668,7 +666,7 @@
                            uint32_t align = 1) {
     // TODO(kschimpf) Stop ignoring alignment specification.
     (void)align;
-    return new (Func->allocateInst<InstStore>()) InstStore(Func, Data, Addr);
+    return new (Func->allocate<InstStore>()) InstStore(Func, Data, Addr);
   }
   Operand *getAddr() const { return getSrc(1); }
   Operand *getData() const { return getSrc(0); }
@@ -689,7 +687,7 @@
 public:
   static InstSwitch *create(Cfg *Func, SizeT NumCases, Operand *Source,
                             CfgNode *LabelDefault) {
-    return new (Func->allocateInst<InstSwitch>())
+    return new (Func->allocate<InstSwitch>())
         InstSwitch(Func, NumCases, Source, LabelDefault);
   }
   Operand *getComparison() const { return getSrc(0); }
@@ -732,7 +730,7 @@
 
 public:
   static InstUnreachable *create(Cfg *Func) {
-    return new (Func->allocateInst<InstUnreachable>()) InstUnreachable(Func);
+    return new (Func->allocate<InstUnreachable>()) InstUnreachable(Func);
   }
   NodeList getTerminatorEdges() const override { return NodeList(); }
   void dump(const Cfg *Func) const override;
@@ -763,7 +761,7 @@
 
 public:
   static InstFakeDef *create(Cfg *Func, Variable *Dest, Variable *Src = NULL) {
-    return new (Func->allocateInst<InstFakeDef>()) InstFakeDef(Func, Dest, Src);
+    return new (Func->allocate<InstFakeDef>()) InstFakeDef(Func, Dest, Src);
   }
   void emit(const Cfg *Func) const override;
   void emitIAS(const Cfg * /* Func */) const override {}
@@ -786,7 +784,7 @@
 
 public:
   static InstFakeUse *create(Cfg *Func, Variable *Src) {
-    return new (Func->allocateInst<InstFakeUse>()) InstFakeUse(Func, Src);
+    return new (Func->allocate<InstFakeUse>()) InstFakeUse(Func, Src);
   }
   void emit(const Cfg *Func) const override;
   void emitIAS(const Cfg * /* Func */) const override {}
@@ -814,7 +812,7 @@
 
 public:
   static InstFakeKill *create(Cfg *Func, const Inst *Linked) {
-    return new (Func->allocateInst<InstFakeKill>()) InstFakeKill(Func, Linked);
+    return new (Func->allocate<InstFakeKill>()) InstFakeKill(Func, Linked);
   }
   const Inst *getLinked() const { return Linked; }
   void emit(const Cfg *Func) const override;
diff --git a/src/IceInstX8632.cpp b/src/IceInstX8632.cpp
index 3da2aa2..3f9250b 100644
--- a/src/IceInstX8632.cpp
+++ b/src/IceInstX8632.cpp
@@ -2023,7 +2023,7 @@
     Type Ty = Src0Var->getType();
     // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an
     // acceptable type.
-    Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty).emit(Func);
+    Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty)->emit(Func);
   } else {
     Src0->emit(Func);
   }
@@ -2056,7 +2056,7 @@
          Func->getTarget()->typeWidthInBytesOnStack(SrcTy));
   Src->emit(Func);
   Str << ", ";
-  getDest()->asType(SrcTy).emit(Func);
+  getDest()->asType(SrcTy)->emit(Func);
 }
 
 template <> void InstX8632Mov::emitIAS(const Cfg *Func) const {
@@ -2446,7 +2446,7 @@
   // a memory dest, but we aren't using it. For uniformity, just restrict
   // them all to have a register dest for now.
   assert(Dest->hasReg());
-  Dest->asType(IceType_i32).emit(Func);
+  Dest->asType(IceType_i32)->emit(Func);
 }
 
 template <> void InstX8632Pextr::emitIAS(const Cfg *Func) const {
@@ -2489,7 +2489,7 @@
   if (const auto Src1Var = llvm::dyn_cast<Variable>(Src1)) {
     // If src1 is a register, it should always be r32.
     if (Src1Var->hasReg()) {
-      Src1Var->asType(IceType_i32).emit(Func);
+      Src1Var->asType(IceType_i32)->emit(Func);
     } else {
       Src1Var->emit(Func);
     }
diff --git a/src/IceOperand.cpp b/src/IceOperand.cpp
index bf5546f..8d0ffed 100644
--- a/src/IceOperand.cpp
+++ b/src/IceOperand.cpp
@@ -126,13 +126,16 @@
   return "__" + std::to_string(getIndex());
 }
 
-Variable Variable::asType(Type Ty) {
+Variable *Variable::asType(Type Ty) {
   // Note: This returns a Variable, even if the "this" object is a
   // subclass of Variable.
-  Variable V(kVariable, Ty, Number);
-  V.NameIndex = NameIndex;
-  V.RegNum = RegNum;
-  V.StackOffset = StackOffset;
+  if (!ALLOW_DUMP || getType() == Ty)
+    return this;
+  Variable *V = new (getCurrentCfgAllocator()->Allocate<Variable>())
+      Variable(kVariable, Ty, Number);
+  V->NameIndex = NameIndex;
+  V->RegNum = RegNum;
+  V->StackOffset = StackOffset;
   return V;
 }
 
diff --git a/src/IceOperand.h b/src/IceOperand.h
index 3b92dfb..7562382 100644
--- a/src/IceOperand.h
+++ b/src/IceOperand.h
@@ -87,7 +87,6 @@
 protected:
   Operand(OperandKind Kind, Type Ty)
       : Ty(Ty), Kind(Kind), NumVars(0), Vars(NULL) {}
-  Operand(Operand &&O) = default;
 
   const Type Ty;
   const OperandKind Kind;
@@ -362,8 +361,9 @@
 
 private:
   typedef std::pair<InstNumberT, InstNumberT> RangeElementType;
-  // Assume a common case of 2 or fewer segments per live range.
-  typedef llvm::SmallVector<RangeElementType, 2> RangeType;
+  // RangeType is arena-allocated from the Cfg's allocator.
+  typedef std::vector<RangeElementType, CfgLocalAllocator<RangeElementType>>
+  RangeType;
   RangeType Range;
   RegWeight Weight;
   // TrimmedBegin is an optimization for the overlaps() computation.
@@ -385,7 +385,6 @@
 class Variable : public Operand {
   Variable(const Variable &) = delete;
   Variable &operator=(const Variable &) = delete;
-  Variable(Variable &&V) = default;
 
 public:
   static Variable *create(Cfg *Func, Type Ty, SizeT Index) {
@@ -466,9 +465,9 @@
   // Creates a temporary copy of the variable with a different type.
   // Used primarily for syntactic correctness of textual assembly
   // emission.  Note that only basic information is copied, in
-  // particular not DefInst, IsArgument, Weight, LoVar, HiVar,
-  // VarsReal.
-  Variable asType(Type Ty);
+  // particular not IsArgument, IsImplicitArgument, IgnoreLiveness,
+  // RegNumTmp, Weight, Live, LoVar, HiVar, VarsReal.
+  Variable *asType(Type Ty);
 
   void emit(const Cfg *Func) const override;
   using Operand::dump;
@@ -479,9 +478,6 @@
     return Kind >= kVariable && Kind <= kVariable_Num;
   }
 
-  // The destructor is public because of the asType() method.
-  ~Variable() override {}
-
 protected:
   Variable(OperandKind K, Type Ty, SizeT Index)
       : Operand(K, Ty), Number(Index), NameIndex(Cfg::IdentifierIndexInvalid),
@@ -492,6 +488,7 @@
     Vars[0] = this;
     NumVars = 1;
   }
+  ~Variable() override {}
   // Number is unique across all variables, and is used as a
   // (bit)vector index for liveness analysis.
   const SizeT Number;
diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp
index 71f860f..aeeb7c4 100644
--- a/src/IceTargetLoweringX8632.cpp
+++ b/src/IceTargetLoweringX8632.cpp
@@ -1026,8 +1026,8 @@
 
 void TargetX8632::emitConstants() const {
   // Note: Still used by emit IAS.
-  emitConstantPool<PoolTypeConverter<float> >();
-  emitConstantPool<PoolTypeConverter<double> >();
+  emitConstantPool<PoolTypeConverter<float>>();
+  emitConstantPool<PoolTypeConverter<double>>();
 
   // No need to emit constants from the int pool since (for x86) they
   // are embedded as immediates in the instructions.
diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp
index 0644582..ac4c697 100644
--- a/src/PNaClTranslator.cpp
+++ b/src/PNaClTranslator.cpp
@@ -1066,7 +1066,7 @@
         Timer(Ice::TimerStack::TT_parseFunctions, getTranslator().getContext()),
         Func(isIRGenerationDisabled()
                  ? nullptr
-                 : new Ice::Cfg(getTranslator().getContext())),
+                 : Ice::Cfg::create(getTranslator().getContext())),
         CurrentBbIndex(0), FcnId(Context->getNextFunctionBlockValueID()),
         FuncDecl(Context->getFunctionByID(FcnId)),
         CachedNumGlobalValueIDs(Context->getNumGlobalIDs()),
diff --git a/src/assembler.h b/src/assembler.h
index dc70668..cdbc505 100644
--- a/src/assembler.h
+++ b/src/assembler.h
@@ -24,9 +24,7 @@
 #define SUBZERO_SRC_ASSEMBLER_H
 
 #include "IceDefs.h"
-
 #include "IceFixups.h"
-#include "llvm/Support/Allocator.h"
 
 namespace Ice {
 
@@ -232,7 +230,7 @@
   void emitIASBytes(GlobalContext *Ctx) const;
 
 private:
-  llvm::BumpPtrAllocator Allocator;
+  ArenaAllocator Allocator;
 
 protected:
   AssemblerBuffer buffer_;