AsmPrinter: Use an intrusively linked list for DIE::Children
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>
Thu, 25 Jun 2015 23:52:10 +0000 (23:52 +0000)
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>
Thu, 25 Jun 2015 23:52:10 +0000 (23:52 +0000)
Replace the `std::vector<>` for `DIE::Children` with an intrusively
linked list.  This is a strict memory improvement: it requires no
auxiliary storage, and reduces `sizeof(DIE)` by one pointer.  It also
factors out the DIE-related malloc traffic.

This drops llc memory usage from 735 MB down to 718 MB, or ~2.3%.

(I'm looking at `llc` memory usage on `verify-uselistorder.lto.opt.bc`;
see r236629 for details.)

llvm-svn: 240736

llvm/include/llvm/CodeGen/DIE.h
llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
llvm/lib/CodeGen/AsmPrinter/DIE.cpp
llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp
llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp
llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h
llvm/tools/dsymutil/DwarfLinker.cpp
llvm/unittests/CodeGen/DIEHashTest.cpp

index 5d589f7..d7938ca 100644 (file)
@@ -609,7 +609,9 @@ public:
 //===--------------------------------------------------------------------===//
 /// DIE - A structured debug information entry.  Has an abbreviation which
 /// describes its organization.
-class DIE {
+class DIE : IntrusiveBackListNode {
+  friend class IntrusiveBackList<DIE>;
+
 protected:
   /// Offset - Offset in debug info section.
   ///
@@ -626,27 +628,24 @@ protected:
   dwarf::Tag Tag = (dwarf::Tag)0;
 
   /// Children DIEs.
-  ///
-  // This can't be a vector<DIE> because pointer validity is requirent for the
-  // Parent pointer and DIEEntry.
-  // It can't be a list<DIE> because some clients need pointer validity before
-  // the object has been added to any child list
-  // (eg: DwarfUnit::constructVariableDIE). These aren't insurmountable, but may
-  // be more convoluted than beneficial.
-  std::vector<std::unique_ptr<DIE>> Children;
+  IntrusiveBackList<DIE> Children;
 
-  DIE *Parent;
+  DIE *Parent = nullptr;
 
   /// Attribute values.
   ///
   DIEValueList Values;
 
 protected:
-  DIE() : Offset(0), Size(0), Parent(nullptr) {}
+  DIE() : Offset(0), Size(0) {}
+
+private:
+  explicit DIE(dwarf::Tag Tag) : Offset(0), Size(0), Tag(Tag) {}
 
 public:
-  explicit DIE(dwarf::Tag Tag)
-      : Offset(0), Size(0), Tag(Tag), Parent(nullptr) {}
+  static DIE *get(BumpPtrAllocator &Alloc, dwarf::Tag Tag) {
+    return new (Alloc) DIE(Tag);
+  }
 
   // Accessors.
   unsigned getAbbrevNumber() const { return AbbrevNumber; }
@@ -655,10 +654,15 @@ public:
   unsigned getSize() const { return Size; }
   bool hasChildren() const { return !Children.empty(); }
 
-  typedef std::vector<std::unique_ptr<DIE>>::const_iterator child_iterator;
+  typedef IntrusiveBackList<DIE>::iterator child_iterator;
+  typedef IntrusiveBackList<DIE>::const_iterator const_child_iterator;
   typedef iterator_range<child_iterator> child_range;
+  typedef iterator_range<const_child_iterator> const_child_range;
 
-  child_range children() const {
+  child_range children() {
+    return llvm::make_range(Children.begin(), Children.end());
+  }
+  const_child_range children() const {
     return llvm::make_range(Children.begin(), Children.end());
   }
 
@@ -707,13 +711,12 @@ public:
     return Values.emplace(Alloc, Attribute, Form, std::forward<T>(Value));
   }
 
-  /// addChild - Add a child to the DIE.
-  ///
-  DIE &addChild(std::unique_ptr<DIE> Child) {
-    assert(!Child->getParent());
+  /// Add a child to the DIE.
+  DIE &addChild(DIE *Child) {
+    assert(!Child->getParent() && "Child should be orphaned");
     Child->Parent = this;
-    Children.push_back(std::move(Child));
-    return *Children.back();
+    Children.push_back(*Child);
+    return Children.back();
   }
 
   /// Find a value in the DIE with the attribute given.
index de0ef33..ad180b6 100644 (file)
@@ -277,7 +277,7 @@ void AsmPrinter::emitDwarfDIE(const DIE &Die) const {
   // Emit the DIE children if any.
   if (Die.hasChildren()) {
     for (auto &Child : Die.children())
-      emitDwarfDIE(*Child);
+      emitDwarfDIE(Child);
 
     OutStreamer->AddComment("End Of Children Mark");
     EmitInt8(0);
index 30493c8..46dbc76 100644 (file)
@@ -180,9 +180,8 @@ void DIE::print(raw_ostream &O, unsigned IndentCount) const {
   }
   IndentCount -= 2;
 
-  for (unsigned j = 0, M = Children.size(); j < M; ++j) {
-    Children[j]->print(O, IndentCount+4);
-  }
+  for (const auto &Child : children())
+    Child.print(O, IndentCount + 4);
 
   if (!isBlock) O << "\n";
 }
index 56bd906..5e60156 100644 (file)
@@ -454,15 +454,15 @@ void DIEHash::computeHash(const DIE &Die) {
   for (auto &C : Die.children()) {
     // 7.27 Step 7
     // If C is a nested type entry or a member function entry, ...
-    if (isType(C->getTag()) || C->getTag() == dwarf::DW_TAG_subprogram) {
-      StringRef Name = getDIEStringAttr(*C, dwarf::DW_AT_name);
+    if (isType(C.getTag()) || C.getTag() == dwarf::DW_TAG_subprogram) {
+      StringRef Name = getDIEStringAttr(C, dwarf::DW_AT_name);
       // ... and has a DW_AT_name attribute
       if (!Name.empty()) {
-        hashNestedType(*C, Name);
+        hashNestedType(C, Name);
         continue;
       }
     }
-    computeHash(*C);
+    computeHash(C);
   }
 
   // Following the last (or if there are no children), append a zero byte.
index 46cde88..c4b945d 100644 (file)
@@ -301,7 +301,7 @@ DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP) {
 
 // Construct a DIE for this scope.
 void DwarfCompileUnit::constructScopeDIE(
-    LexicalScope *Scope, SmallVectorImpl<std::unique_ptr<DIE>> &FinalChildren) {
+    LexicalScope *Scope, SmallVectorImpl<DIE *> &FinalChildren) {
   if (!Scope || !Scope->getScopeNode())
     return;
 
@@ -312,12 +312,12 @@ void DwarfCompileUnit::constructScopeDIE(
          "constructSubprogramScopeDIE for non-inlined "
          "subprograms");
 
-  SmallVector<std::unique_ptr<DIE>, 8> Children;
+  SmallVector<DIE *, 8> Children;
 
   // We try to create the scope DIE first, then the children DIEs. This will
   // avoid creating un-used children then removing them later when we find out
   // the scope DIE is null.
-  std::unique_ptr<DIE> ScopeDIE;
+  DIE *ScopeDIE;
   if (Scope->getParent() && isa<DISubprogram>(DS)) {
     ScopeDIE = constructInlinedScopeDIE(Scope);
     if (!ScopeDIE)
@@ -416,8 +416,7 @@ void DwarfCompileUnit::attachRangesOrLowHighPC(
 
 // This scope represents inlined body of a function. Construct DIE to
 // represent this concrete inlined copy of the function.
-std::unique_ptr<DIE>
-DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope) {
+DIE *DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope) {
   assert(Scope->getScopeNode());
   auto *DS = Scope->getScopeNode();
   auto *InlinedSP = getDISubprogram(DS);
@@ -426,7 +425,7 @@ DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope) {
   DIE *OriginDIE = DU->getAbstractSPDies()[InlinedSP];
   assert(OriginDIE && "Unable to find original DIE for an inlined subprogram.");
 
-  auto ScopeDIE = make_unique<DIE>(dwarf::DW_TAG_inlined_subroutine);
+  auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_inlined_subroutine);
   addDIEEntry(*ScopeDIE, dwarf::DW_AT_abstract_origin, *OriginDIE);
 
   attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges());
@@ -446,12 +445,11 @@ DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope) {
 
 // Construct new DW_TAG_lexical_block for this scope and attach
 // DW_AT_low_pc/DW_AT_high_pc labels.
-std::unique_ptr<DIE>
-DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) {
+DIE *DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) {
   if (DD->isLexicalScopeDIENull(Scope))
     return nullptr;
 
-  auto ScopeDIE = make_unique<DIE>(dwarf::DW_TAG_lexical_block);
+  auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_lexical_block);
   if (Scope->isAbstractScope())
     return ScopeDIE;
 
@@ -461,18 +459,16 @@ DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) {
 }
 
 /// constructVariableDIE - Construct a DIE for the given DbgVariable.
-std::unique_ptr<DIE> DwarfCompileUnit::constructVariableDIE(DbgVariable &DV,
-                                                            bool Abstract) {
+DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, bool Abstract) {
   auto D = constructVariableDIEImpl(DV, Abstract);
   DV.setDIE(*D);
   return D;
 }
 
-std::unique_ptr<DIE>
-DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
-                                           bool Abstract) {
+DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
+                                                bool Abstract) {
   // Define variable debug information entry.
-  auto VariableDie = make_unique<DIE>(DV.getTag());
+  auto VariableDie = DIE::get(DIEValueAllocator, DV.getTag());
 
   if (Abstract) {
     applyVariableAttributes(DV, *VariableDie);
@@ -532,17 +528,18 @@ DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
   return VariableDie;
 }
 
-std::unique_ptr<DIE> DwarfCompileUnit::constructVariableDIE(
-    DbgVariable &DV, const LexicalScope &Scope, DIE *&ObjectPointer) {
+DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV,
+                                            const LexicalScope &Scope,
+                                            DIE *&ObjectPointer) {
   auto Var = constructVariableDIE(DV, Scope.isAbstractScope());
   if (DV.isObjectPointer())
-    ObjectPointer = Var.get();
+    ObjectPointer = Var;
   return Var;
 }
 
-DIE *DwarfCompileUnit::createScopeChildrenDIE(
-    LexicalScope *Scope, SmallVectorImpl<std::unique_ptr<DIE>> &Children,
-    unsigned *ChildScopeCount) {
+DIE *DwarfCompileUnit::createScopeChildrenDIE(LexicalScope *Scope,
+                                              SmallVectorImpl<DIE *> &Children,
+                                              unsigned *ChildScopeCount) {
   DIE *ObjectPointer = nullptr;
 
   for (DbgVariable *DV : DU->getScopeVariables().lookup(Scope))
@@ -583,13 +580,14 @@ void DwarfCompileUnit::constructSubprogramScopeDIE(LexicalScope *Scope) {
   // variadic function.
   if (FnArgs.size() > 1 && !FnArgs[FnArgs.size() - 1] &&
       !includeMinimalInlineScopes())
-    ScopeDIE.addChild(make_unique<DIE>(dwarf::DW_TAG_unspecified_parameters));
+    ScopeDIE.addChild(
+        DIE::get(DIEValueAllocator, dwarf::DW_TAG_unspecified_parameters));
 }
 
 DIE *DwarfCompileUnit::createAndAddScopeChildren(LexicalScope *Scope,
                                                  DIE &ScopeDIE) {
   // We create children when the scope DIE is not null.
-  SmallVector<std::unique_ptr<DIE>, 8> Children;
+  SmallVector<DIE *, 8> Children;
   DIE *ObjectPointer = createScopeChildrenDIE(Scope, Children);
 
   // Add children
@@ -632,10 +630,10 @@ DwarfCompileUnit::constructAbstractSubprogramScopeDIE(LexicalScope *Scope) {
     addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);
 }
 
-std::unique_ptr<DIE>
-DwarfCompileUnit::constructImportedEntityDIE(const DIImportedEntity *Module) {
-  std::unique_ptr<DIE> IMDie = make_unique<DIE>((dwarf::Tag)Module->getTag());
-  insertDIE(Module, IMDie.get());
+DIE *DwarfCompileUnit::constructImportedEntityDIE(
+    const DIImportedEntity *Module) {
+  DIE *IMDie = DIE::get(DIEValueAllocator, (dwarf::Tag)Module->getTag());
+  insertDIE(Module, IMDie);
   DIE *EntityDie;
   auto *Entity = resolve(Module->getEntity());
   if (auto *NS = dyn_cast<DINamespace>(Entity))
index 03721a2..509c943 100644 (file)
@@ -58,8 +58,7 @@ class DwarfCompileUnit : public DwarfUnit {
 
   /// \brief Construct a DIE for the given DbgVariable without initializing the
   /// DbgVariable's DIE reference.
-  std::unique_ptr<DIE> constructVariableDIEImpl(const DbgVariable &DV,
-                                                bool Abstract);
+  DIE *constructVariableDIEImpl(const DbgVariable &DV, bool Abstract);
 
   bool isDwoUnit() const override;
 
@@ -117,7 +116,7 @@ public:
   DIE &updateSubprogramScopeDIE(const DISubprogram *SP);
 
   void constructScopeDIE(LexicalScope *Scope,
-                         SmallVectorImpl<std::unique_ptr<DIE>> &FinalChildren);
+                         SmallVectorImpl<DIE *> &FinalChildren);
 
   /// \brief A helper function to construct a RangeSpanList for a given
   /// lexical scope.
@@ -129,23 +128,21 @@ public:
                                const SmallVectorImpl<InsnRange> &Ranges);
   /// \brief This scope represents inlined body of a function. Construct
   /// DIE to represent this concrete inlined copy of the function.
-  std::unique_ptr<DIE> constructInlinedScopeDIE(LexicalScope *Scope);
+  DIE *constructInlinedScopeDIE(LexicalScope *Scope);
 
   /// \brief Construct new DW_TAG_lexical_block for this scope and
   /// attach DW_AT_low_pc/DW_AT_high_pc labels.
-  std::unique_ptr<DIE> constructLexicalScopeDIE(LexicalScope *Scope);
+  DIE *constructLexicalScopeDIE(LexicalScope *Scope);
 
   /// constructVariableDIE - Construct a DIE for the given DbgVariable.
-  std::unique_ptr<DIE> constructVariableDIE(DbgVariable &DV,
-                                            bool Abstract = false);
+  DIE *constructVariableDIE(DbgVariable &DV, bool Abstract = false);
 
-  std::unique_ptr<DIE> constructVariableDIE(DbgVariable &DV,
-                                            const LexicalScope &Scope,
-                                            DIE *&ObjectPointer);
+  DIE *constructVariableDIE(DbgVariable &DV, const LexicalScope &Scope,
+                            DIE *&ObjectPointer);
 
   /// A helper function to create children of a Scope DIE.
   DIE *createScopeChildrenDIE(LexicalScope *Scope,
-                              SmallVectorImpl<std::unique_ptr<DIE>> &Children,
+                              SmallVectorImpl<DIE *> &Children,
                               unsigned *ChildScopeCount = nullptr);
 
   /// \brief Construct a DIE for this subprogram scope.
@@ -156,8 +153,7 @@ public:
   void constructAbstractSubprogramScopeDIE(LexicalScope *Scope);
 
   /// \brief Construct import_module DIE.
-  std::unique_ptr<DIE>
-  constructImportedEntityDIE(const DIImportedEntity *Module);
+  DIE *constructImportedEntityDIE(const DIImportedEntity *Module);
 
   void finishSubprogramDefinition(const DISubprogram *SP);
 
index 408d379..51b27b4 100644 (file)
@@ -111,7 +111,7 @@ unsigned DwarfFile::computeSizeAndOffset(DIE &Die, unsigned Offset) {
     assert(Abbrev.hasChildren() && "Children flag not set");
 
     for (auto &Child : Die.children())
-      Offset = computeSizeAndOffset(*Child, Offset);
+      Offset = computeSizeAndOffset(Child, Offset);
 
     // End of children marker.
     Offset += sizeof(int8_t);
index 6977e30..51a268a 100644 (file)
@@ -66,8 +66,9 @@ bool DIEDwarfExpression::isFrameRegister(unsigned MachineReg) {
 DwarfUnit::DwarfUnit(unsigned UID, dwarf::Tag UnitTag,
                      const DICompileUnit *Node, AsmPrinter *A, DwarfDebug *DW,
                      DwarfFile *DWU)
-    : UniqueID(UID), CUNode(Node), UnitDie(UnitTag), DebugInfoOffset(0), Asm(A),
-      DD(DW), DU(DWU), IndexTyDie(nullptr), Section(nullptr) {
+    : UniqueID(UID), CUNode(Node),
+      UnitDie(*DIE::get(DIEValueAllocator, UnitTag)), DebugInfoOffset(0),
+      Asm(A), DD(DW), DU(DWU), IndexTyDie(nullptr), Section(nullptr) {
   assert(UnitTag == dwarf::DW_TAG_compile_unit ||
          UnitTag == dwarf::DW_TAG_type_unit);
 }
@@ -293,7 +294,7 @@ void DwarfUnit::addDIEEntry(DIE &Die, dwarf::Attribute Attribute,
 DIE &DwarfUnit::createAndAddDIE(unsigned Tag, DIE &Parent, const DINode *N) {
   assert(Tag != dwarf::DW_TAG_auto_variable &&
          Tag != dwarf::DW_TAG_arg_variable);
-  DIE &Die = Parent.addChild(make_unique<DIE>((dwarf::Tag)Tag));
+  DIE &Die = Parent.addChild(DIE::get(DIEValueAllocator, (dwarf::Tag)Tag));
   if (N)
     insertDIE(N, &Die);
   return Die;
index bf2b872..405903a 100644 (file)
@@ -77,7 +77,7 @@ protected:
   BumpPtrAllocator DIEValueAllocator;
 
   /// Unit debug information entry.
-  DIE UnitDie;
+  DIE &UnitDie;
 
   /// Offset of the UnitDie from beginning of debug info section.
   unsigned DebugInfoOffset;
index a2cf7d3..7879e83 100644 (file)
@@ -113,8 +113,8 @@ public:
 
   unsigned getUniqueID() const { return ID; }
 
-  DIE *getOutputUnitDIE() const { return CUDie.get(); }
-  void setOutputUnitDIE(DIE *Die) { CUDie.reset(Die); }
+  DIE *getOutputUnitDIE() const { return CUDie; }
+  void setOutputUnitDIE(DIE *Die) { CUDie = Die; }
 
   DIEInfo &getInfo(unsigned Idx) { return Info[Idx]; }
   const DIEInfo &getInfo(unsigned Idx) const { return Info[Idx]; }
@@ -194,7 +194,7 @@ private:
   DWARFUnit &OrigUnit;
   unsigned ID;
   std::vector<DIEInfo> Info;  ///< DIE info indexed by DIE index.
-  std::unique_ptr<DIE> CUDie; ///< Root of the linked DIE tree.
+  DIE *CUDie;                 ///< Root of the linked DIE tree.
 
   uint64_t StartOffset;
   uint64_t NextUnitOffset;
@@ -1861,7 +1861,7 @@ unsigned DwarfLinker::cloneDieReferenceAttribute(
     assert(Ref > InputDIE.getOffset());
     // We haven't cloned this DIE yet. Just create an empty one and
     // store it. It'll get really cloned when we process it.
-    RefInfo.Clone = new DIE(dwarf::Tag(RefDie->getTag()));
+    RefInfo.Clone = DIE::get(DIEAlloc, dwarf::Tag(RefDie->getTag()));
   }
   NewRefDie = RefInfo.Clone;
 
@@ -2163,7 +2163,7 @@ DIE *DwarfLinker::cloneDIE(const DWARFDebugInfoEntryMinimal &InputDIE,
   // (see cloneDieReferenceAttribute()).
   DIE *Die = Info.Clone;
   if (!Die)
-    Die = Info.Clone = new DIE(dwarf::Tag(InputDIE.getTag()));
+    Die = Info.Clone = DIE::get(DIEAlloc, dwarf::Tag(InputDIE.getTag()));
   assert(Die->getTag() == InputDIE.getTag());
   Die->setOffset(OutOffset);
 
@@ -2255,7 +2255,7 @@ DIE *DwarfLinker::cloneDIE(const DWARFDebugInfoEntryMinimal &InputDIE,
   for (auto *Child = InputDIE.getFirstChild(); Child && !Child->isNULL();
        Child = Child->getSibling()) {
     if (DIE *Clone = cloneDIE(*Child, Unit, PCOffset, OutOffset)) {
-      Die->addChild(std::unique_ptr<DIE>(Clone));
+      Die->addChild(Clone);
       OutOffset = Clone->getOffset() + Clone->getSize();
     }
   }
index 5476463..e3a9e56 100644 (file)
@@ -38,7 +38,7 @@ public:
 
 TEST_F(DIEHashTest, Data1) {
   DIEHash Hash;
-  DIE Die(dwarf::DW_TAG_base_type);
+  DIE &Die = *DIE::get(Alloc, dwarf::DW_TAG_base_type);
   DIEInteger Size(4);
   Die.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Size);
   uint64_t MD5Res = Hash.computeTypeSignature(Die);
@@ -47,7 +47,7 @@ TEST_F(DIEHashTest, Data1) {
 
 // struct {};
 TEST_F(DIEHashTest, TrivialType) {
-  DIE Unnamed(dwarf::DW_TAG_structure_type);
+  DIE &Unnamed = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
   DIEInteger One(1);
   Unnamed.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
 
@@ -62,7 +62,7 @@ TEST_F(DIEHashTest, TrivialType) {
 
 // struct foo { };
 TEST_F(DIEHashTest, NamedType) {
-  DIE Foo(dwarf::DW_TAG_structure_type);
+  DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
   DIEInteger One(1);
   DIEString FooStr = getString("foo");
   Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
@@ -76,9 +76,9 @@ TEST_F(DIEHashTest, NamedType) {
 
 // namespace space { struct foo { }; }
 TEST_F(DIEHashTest, NamespacedType) {
-  DIE CU(dwarf::DW_TAG_compile_unit);
+  DIE &CU = *DIE::get(Alloc, dwarf::DW_TAG_compile_unit);
 
-  auto Space = make_unique<DIE>(dwarf::DW_TAG_namespace);
+  auto Space = DIE::get(Alloc, dwarf::DW_TAG_namespace);
   DIEInteger One(1);
   DIEString SpaceStr = getString("space");
   Space->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, SpaceStr);
@@ -87,7 +87,7 @@ TEST_F(DIEHashTest, NamespacedType) {
                   One);
   // sibling?
 
-  auto Foo = make_unique<DIE>(dwarf::DW_TAG_structure_type);
+  auto Foo = DIE::get(Alloc, dwarf::DW_TAG_structure_type);
   DIEString FooStr = getString("foo");
   Foo->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
   Foo->addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
@@ -104,11 +104,11 @@ TEST_F(DIEHashTest, NamespacedType) {
 
 // struct { int member; };
 TEST_F(DIEHashTest, TypeWithMember) {
-  DIE Unnamed(dwarf::DW_TAG_structure_type);
+  DIE &Unnamed = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
   DIEInteger Four(4);
   Unnamed.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Four);
 
-  DIE Int(dwarf::DW_TAG_base_type);
+  DIE &Int = *DIE::get(Alloc, dwarf::DW_TAG_base_type);
   DIEString IntStr = getString("int");
   Int.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, IntStr);
   Int.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Four);
@@ -117,7 +117,7 @@ TEST_F(DIEHashTest, TypeWithMember) {
 
   DIEEntry IntRef(Int);
 
-  auto Member = make_unique<DIE>(dwarf::DW_TAG_member);
+  auto Member = DIE::get(Alloc, dwarf::DW_TAG_member);
   DIEString MemberStr = getString("member");
   Member->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemberStr);
   DIEInteger Zero(0);
@@ -134,12 +134,12 @@ TEST_F(DIEHashTest, TypeWithMember) {
 
 // struct foo { int mem1, mem2; };
 TEST_F(DIEHashTest, ReusedType) {
-  DIE Unnamed(dwarf::DW_TAG_structure_type);
+  DIE &Unnamed = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
   DIEInteger Eight(8);
   Unnamed.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
 
   DIEInteger Four(4);
-  DIE Int(dwarf::DW_TAG_base_type);
+  DIE &Int = *DIE::get(Alloc, dwarf::DW_TAG_base_type);
   DIEString IntStr = getString("int");
   Int.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, IntStr);
   Int.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Four);
@@ -148,7 +148,7 @@ TEST_F(DIEHashTest, ReusedType) {
 
   DIEEntry IntRef(Int);
 
-  auto Mem1 = make_unique<DIE>(dwarf::DW_TAG_member);
+  auto Mem1 = DIE::get(Alloc, dwarf::DW_TAG_member);
   DIEString Mem1Str = getString("mem1");
   Mem1->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, Mem1Str);
   DIEInteger Zero(0);
@@ -158,7 +158,7 @@ TEST_F(DIEHashTest, ReusedType) {
 
   Unnamed.addChild(std::move(Mem1));
 
-  auto Mem2 = make_unique<DIE>(dwarf::DW_TAG_member);
+  auto Mem2 = DIE::get(Alloc, dwarf::DW_TAG_member);
   DIEString Mem2Str = getString("mem2");
   Mem2->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, Mem2Str);
   Mem2->addValue(Alloc, dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
@@ -174,13 +174,13 @@ TEST_F(DIEHashTest, ReusedType) {
 
 // struct foo { static foo f; };
 TEST_F(DIEHashTest, RecursiveType) {
-  DIE Foo(dwarf::DW_TAG_structure_type);
+  DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
   DIEInteger One(1);
   Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
   DIEString FooStr = getString("foo");
   Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
 
-  auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
+  auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
   DIEString MemStr = getString("mem");
   Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
   DIEEntry FooRef(Foo);
@@ -196,20 +196,20 @@ TEST_F(DIEHashTest, RecursiveType) {
 
 // struct foo { foo *mem; };
 TEST_F(DIEHashTest, Pointer) {
-  DIE Foo(dwarf::DW_TAG_structure_type);
+  DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
   DIEInteger Eight(8);
   Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
   DIEString FooStr = getString("foo");
   Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
 
-  auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
+  auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
   DIEString MemStr = getString("mem");
   Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
   DIEInteger Zero(0);
   Mem->addValue(Alloc, dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
                 Zero);
 
-  DIE FooPtr(dwarf::DW_TAG_pointer_type);
+  DIE &FooPtr = *DIE::get(Alloc, dwarf::DW_TAG_pointer_type);
   FooPtr.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
   DIEEntry FooRef(Foo);
   FooPtr.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooRef);
@@ -226,25 +226,25 @@ TEST_F(DIEHashTest, Pointer) {
 
 // struct foo { foo &mem; };
 TEST_F(DIEHashTest, Reference) {
-  DIE Foo(dwarf::DW_TAG_structure_type);
+  DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
   DIEInteger Eight(8);
   Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
   DIEString FooStr = getString("foo");
   Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
 
-  auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
+  auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
   DIEString MemStr = getString("mem");
   Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
   DIEInteger Zero(0);
   Mem->addValue(Alloc, dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
                 Zero);
 
-  DIE FooRef(dwarf::DW_TAG_reference_type);
+  DIE &FooRef = *DIE::get(Alloc, dwarf::DW_TAG_reference_type);
   FooRef.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
   DIEEntry FooEntry(Foo);
   FooRef.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooEntry);
 
-  DIE FooRefConst(dwarf::DW_TAG_const_type);
+  DIE &FooRefConst = *DIE::get(Alloc, dwarf::DW_TAG_const_type);
   DIEEntry FooRefRef(FooRef);
   FooRefConst.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
                        FooRefRef);
@@ -261,25 +261,25 @@ TEST_F(DIEHashTest, Reference) {
 
 // struct foo { foo &&mem; };
 TEST_F(DIEHashTest, RValueReference) {
-  DIE Foo(dwarf::DW_TAG_structure_type);
+  DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
   DIEInteger Eight(8);
   Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
   DIEString FooStr = getString("foo");
   Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
 
-  auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
+  auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
   DIEString MemStr = getString("mem");
   Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
   DIEInteger Zero(0);
   Mem->addValue(Alloc, dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
                 Zero);
 
-  DIE FooRef(dwarf::DW_TAG_rvalue_reference_type);
+  DIE &FooRef = *DIE::get(Alloc, dwarf::DW_TAG_rvalue_reference_type);
   FooRef.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
   DIEEntry FooEntry(Foo);
   FooRef.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooEntry);
 
-  DIE FooRefConst(dwarf::DW_TAG_const_type);
+  DIE &FooRefConst = *DIE::get(Alloc, dwarf::DW_TAG_const_type);
   DIEEntry FooRefRef(FooRef);
   FooRefConst.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
                        FooRefRef);
@@ -296,20 +296,20 @@ TEST_F(DIEHashTest, RValueReference) {
 
 // struct foo { foo foo::*mem; };
 TEST_F(DIEHashTest, PtrToMember) {
-  DIE Foo(dwarf::DW_TAG_structure_type);
+  DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
   DIEInteger Eight(8);
   Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
   DIEString FooStr = getString("foo");
   Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
 
-  auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
+  auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
   DIEString MemStr = getString("mem");
   Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
   DIEInteger Zero(0);
   Mem->addValue(Alloc, dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
                 Zero);
 
-  DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
+  DIE &PtrToFooMem = *DIE::get(Alloc, dwarf::DW_TAG_ptr_to_member_type);
   DIEEntry FooEntry(Foo);
   PtrToFooMem.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooEntry);
   PtrToFooMem.addValue(Alloc, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
@@ -339,21 +339,21 @@ TEST_F(DIEHashTest, PtrToMemberDeclDefMatch) {
   DIEString MemStr = getString("mem");
   uint64_t MD5ResDecl;
   {
-    DIE Bar(dwarf::DW_TAG_structure_type);
+    DIE &Bar = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
     Bar.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, BarStr);
     Bar.addValue(Alloc, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present,
                  One);
 
-    DIE Foo(dwarf::DW_TAG_structure_type);
+    DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
     Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
     Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
 
-    auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
+    auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
     Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
     Mem->addValue(Alloc, dwarf::DW_AT_data_member_location,
                   dwarf::DW_FORM_data1, Zero);
 
-    DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
+    DIE &PtrToFooMem = *DIE::get(Alloc, dwarf::DW_TAG_ptr_to_member_type);
     DIEEntry BarEntry(Bar);
     PtrToFooMem.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
                          BarEntry);
@@ -371,20 +371,20 @@ TEST_F(DIEHashTest, PtrToMemberDeclDefMatch) {
   }
   uint64_t MD5ResDef;
   {
-    DIE Bar(dwarf::DW_TAG_structure_type);
+    DIE &Bar = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
     Bar.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, BarStr);
     Bar.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
 
-    DIE Foo(dwarf::DW_TAG_structure_type);
+    DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
     Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
     Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
 
-    auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
+    auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
     Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
     Mem->addValue(Alloc, dwarf::DW_AT_data_member_location,
                   dwarf::DW_FORM_data1, Zero);
 
-    DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
+    DIE &PtrToFooMem = *DIE::get(Alloc, dwarf::DW_TAG_ptr_to_member_type);
     DIEEntry BarEntry(Bar);
     PtrToFooMem.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
                          BarEntry);
@@ -417,21 +417,21 @@ TEST_F(DIEHashTest, PtrToMemberDeclDefMisMatch) {
   DIEString MemStr = getString("mem");
   uint64_t MD5ResDecl;
   {
-    DIE Bar(dwarf::DW_TAG_structure_type);
+    DIE &Bar = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
     Bar.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, BarStr);
     Bar.addValue(Alloc, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present,
                  One);
 
-    DIE Foo(dwarf::DW_TAG_structure_type);
+    DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
     Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
     Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
 
-    auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
+    auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
     Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
     Mem->addValue(Alloc, dwarf::DW_AT_data_member_location,
                   dwarf::DW_FORM_data1, Zero);
 
-    DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
+    DIE &PtrToFooMem = *DIE::get(Alloc, dwarf::DW_TAG_ptr_to_member_type);
     DIEEntry BarEntry(Bar);
     PtrToFooMem.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
                          BarEntry);
@@ -448,20 +448,20 @@ TEST_F(DIEHashTest, PtrToMemberDeclDefMisMatch) {
   }
   uint64_t MD5ResDef;
   {
-    DIE Bar(dwarf::DW_TAG_structure_type);
+    DIE &Bar = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
     Bar.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, BarStr);
     Bar.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
 
-    DIE Foo(dwarf::DW_TAG_structure_type);
+    DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
     Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
     Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
 
-    auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
+    auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
     Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
     Mem->addValue(Alloc, dwarf::DW_AT_data_member_location,
                   dwarf::DW_FORM_data1, Zero);
 
-    DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
+    DIE &PtrToFooMem = *DIE::get(Alloc, dwarf::DW_TAG_ptr_to_member_type);
     DIEEntry BarEntry(Bar);
     PtrToFooMem.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
                          BarEntry);
@@ -493,19 +493,19 @@ TEST_F(DIEHashTest, RefUnnamedType) {
   DIEString FooStr = getString("foo");
   DIEString MemStr = getString("mem");
 
-  DIE Unnamed(dwarf::DW_TAG_structure_type);
+  DIE &Unnamed = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
   Unnamed.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
 
-  DIE Foo(dwarf::DW_TAG_structure_type);
+  DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
   Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
   Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
 
-  auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
+  auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
   Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
   Mem->addValue(Alloc, dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
                 Zero);
 
-  DIE UnnamedPtr(dwarf::DW_TAG_pointer_type);
+  DIE &UnnamedPtr = *DIE::get(Alloc, dwarf::DW_TAG_pointer_type);
   UnnamedPtr.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1,
                       Eight);
   DIEEntry UnnamedRef(Unnamed);
@@ -524,11 +524,11 @@ TEST_F(DIEHashTest, RefUnnamedType) {
 
 // struct { struct foo { }; };
 TEST_F(DIEHashTest, NestedType) {
-  DIE Unnamed(dwarf::DW_TAG_structure_type);
+  DIE &Unnamed = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
   DIEInteger One(1);
   Unnamed.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
 
-  auto Foo = make_unique<DIE>(dwarf::DW_TAG_structure_type);
+  auto Foo = DIE::get(Alloc, dwarf::DW_TAG_structure_type);
   DIEString FooStr = getString("foo");
   Foo->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
   Foo->addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
@@ -543,11 +543,11 @@ TEST_F(DIEHashTest, NestedType) {
 
 // struct { static void func(); };
 TEST_F(DIEHashTest, MemberFunc) {
-  DIE Unnamed(dwarf::DW_TAG_structure_type);
+  DIE &Unnamed = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
   DIEInteger One(1);
   Unnamed.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
 
-  auto Func = make_unique<DIE>(dwarf::DW_TAG_subprogram);
+  auto Func = DIE::get(Alloc, dwarf::DW_TAG_subprogram);
   DIEString FuncStr = getString("func");
   Func->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FuncStr);
 
@@ -563,7 +563,7 @@ TEST_F(DIEHashTest, MemberFunc) {
 //   static void func();
 // };
 TEST_F(DIEHashTest, MemberFuncFlag) {
-  DIE A(dwarf::DW_TAG_structure_type);
+  DIE &A = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
   DIEInteger One(1);
   DIEString AStr = getString("A");
   A.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, AStr);
@@ -571,7 +571,7 @@ TEST_F(DIEHashTest, MemberFuncFlag) {
   A.addValue(Alloc, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, One);
   A.addValue(Alloc, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, One);
 
-  auto Func = make_unique<DIE>(dwarf::DW_TAG_subprogram);
+  auto Func = DIE::get(Alloc, dwarf::DW_TAG_subprogram);
   DIEString FuncStr = getString("func");
   DIEString FuncLinkage = getString("_ZN1A4funcEv");
   DIEInteger Two(2);
@@ -599,7 +599,7 @@ TEST_F(DIEHashTest, MemberFuncFlag) {
 // };
 // A a;
 TEST_F(DIEHashTest, MemberSdata) {
-  DIE A(dwarf::DW_TAG_structure_type);
+  DIE &A = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
   DIEInteger One(1);
   DIEString AStr = getString("A");
   A.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, AStr);
@@ -610,17 +610,17 @@ TEST_F(DIEHashTest, MemberSdata) {
   DIEInteger Four(4);
   DIEInteger Five(5);
   DIEString FStr = getString("int");
-  DIE IntTyDIE(dwarf::DW_TAG_base_type);
+  DIE &IntTyDIE = *DIE::get(Alloc, dwarf::DW_TAG_base_type);
   IntTyDIE.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Four);
   IntTyDIE.addValue(Alloc, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Five);
   IntTyDIE.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FStr);
 
   DIEEntry IntTy(IntTyDIE);
-  auto PITyDIE = make_unique<DIE>(dwarf::DW_TAG_const_type);
+  auto PITyDIE = DIE::get(Alloc, dwarf::DW_TAG_const_type);
   PITyDIE->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IntTy);
 
   DIEEntry PITy(*PITyDIE);
-  auto PI = make_unique<DIE>(dwarf::DW_TAG_member);
+  auto PI = DIE::get(Alloc, dwarf::DW_TAG_member);
   DIEString PIStr = getString("PI");
   DIEInteger Two(2);
   DIEInteger NegThree(-3);
@@ -645,7 +645,7 @@ TEST_F(DIEHashTest, MemberSdata) {
 // };
 // A a;
 TEST_F(DIEHashTest, MemberBlock) {
-  DIE A(dwarf::DW_TAG_structure_type);
+  DIE &A = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
   DIEInteger One(1);
   DIEString AStr = getString("A");
   A.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, AStr);
@@ -655,19 +655,18 @@ TEST_F(DIEHashTest, MemberBlock) {
 
   DIEInteger Four(4);
   DIEString FStr = getString("float");
-  auto FloatTyDIE = make_unique<DIE>(dwarf::DW_TAG_base_type);
+  auto FloatTyDIE = DIE::get(Alloc, dwarf::DW_TAG_base_type);
   FloatTyDIE->addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1,
                        Four);
   FloatTyDIE->addValue(Alloc, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
                        Four);
   FloatTyDIE->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FStr);
-
   DIEEntry FloatTy(*FloatTyDIE);
-  auto PITyDIE = make_unique<DIE>(dwarf::DW_TAG_const_type);
+  auto PITyDIE = DIE::get(Alloc, dwarf::DW_TAG_const_type);
   PITyDIE->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FloatTy);
 
   DIEEntry PITy(*PITyDIE);
-  auto PI = make_unique<DIE>(dwarf::DW_TAG_member);
+  auto PI = DIE::get(Alloc, dwarf::DW_TAG_member);
   DIEString PIStr = getString("PI");
   DIEInteger Two(2);
   PI->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, PIStr);