Remove DwarfDebug::PrevSection, PrevCU is sufficient for handling address range holes.
[oota-llvm.git] / lib / CodeGen / AsmPrinter / DwarfDebug.cpp
index c94eeb943c9e6327f4ddccad80d028d7af31846c..663ebef250bfab5a7269d070f80b5991e4894f05 100644 (file)
@@ -346,9 +346,7 @@ bool DwarfDebug::isLexicalScopeDIENull(LexicalScope *Scope) {
 
   // We don't create a DIE if we have a single Range and the end label
   // is null.
-  SmallVectorImpl<InsnRange>::const_iterator RI = Ranges.begin();
-  MCSymbol *End = getLabelAfterInsn(RI->second);
-  return !End;
+  return !getLabelAfterInsn(Ranges.front().second);
 }
 
 static void addSectionLabel(AsmPrinter &Asm, DwarfUnit &U, DIE &D,
@@ -457,48 +455,35 @@ static std::unique_ptr<DIE> constructVariableDIE(DwarfCompileUnit &TheCU,
 
 DIE *DwarfDebug::createScopeChildrenDIE(
     DwarfCompileUnit &TheCU, LexicalScope *Scope,
-    SmallVectorImpl<std::unique_ptr<DIE>> &Children) {
+    SmallVectorImpl<std::unique_ptr<DIE>> &Children,
+    unsigned *ChildScopeCount) {
   DIE *ObjectPointer = nullptr;
 
-  // Collect arguments for current function.
-  if (LScopes.isCurrentFunctionScope(Scope)) {
-    for (DbgVariable *ArgDV : CurrentFnArguments)
-      if (ArgDV)
-        Children.push_back(
-            constructVariableDIE(TheCU, *ArgDV, *Scope, ObjectPointer));
-
-    // If this is a variadic function, add an unspecified parameter.
-    DISubprogram SP(Scope->getScopeNode());
-    DITypeArray FnArgs = SP.getType().getTypeArray();
-    // If we have a single element of null, it is a function that returns void.
-    // If we have more than one elements and the last one is null, it is a
-    // variadic function.
-    if (FnArgs.getNumElements() > 1 &&
-        !FnArgs.getElement(FnArgs.getNumElements() - 1))
-      Children.push_back(
-          make_unique<DIE>(dwarf::DW_TAG_unspecified_parameters));
-  }
-
-  // Collect lexical scope children first.
   for (DbgVariable *DV : ScopeVariables.lookup(Scope))
     Children.push_back(constructVariableDIE(TheCU, *DV, *Scope, ObjectPointer));
 
+  unsigned ChildCountWithoutScopes = Children.size();
+
   for (LexicalScope *LS : Scope->getChildren())
-    if (std::unique_ptr<DIE> Nested = constructScopeDIE(TheCU, LS))
-      Children.push_back(std::move(Nested));
+    constructScopeDIE(TheCU, LS, Children);
+
+  if (ChildScopeCount)
+    *ChildScopeCount = Children.size() - ChildCountWithoutScopes;
+
   return ObjectPointer;
 }
 
-void DwarfDebug::createAndAddScopeChildren(DwarfCompileUnit &TheCU,
+DIE *DwarfDebug::createAndAddScopeChildren(DwarfCompileUnit &TheCU,
                                            LexicalScope *Scope, DIE &ScopeDIE) {
   // We create children when the scope DIE is not null.
   SmallVector<std::unique_ptr<DIE>, 8> Children;
-  if (DIE *ObjectPointer = createScopeChildrenDIE(TheCU, Scope, Children))
-    TheCU.addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer);
+  DIE *ObjectPointer = createScopeChildrenDIE(TheCU, Scope, Children);
 
   // Add children
   for (auto &I : Children)
     ScopeDIE.addChild(std::move(I));
+
+  return ObjectPointer;
 }
 
 void DwarfDebug::constructAbstractSubprogramScopeDIE(DwarfCompileUnit &TheCU,
@@ -537,7 +522,8 @@ void DwarfDebug::constructAbstractSubprogramScopeDIE(DwarfCompileUnit &TheCU,
   SPCU.applySubprogramAttributesToDefinition(SP, *AbsDef);
 
   SPCU.addUInt(*AbsDef, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined);
-  createAndAddScopeChildren(SPCU, Scope, *AbsDef);
+  if (DIE *ObjectPointer = createAndAddScopeChildren(SPCU, Scope, *AbsDef))
+    SPCU.addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);
 }
 
 DIE &DwarfDebug::constructSubprogramScopeDIE(DwarfCompileUnit &TheCU,
@@ -553,16 +539,43 @@ DIE &DwarfDebug::constructSubprogramScopeDIE(DwarfCompileUnit &TheCU,
 
   DIE &ScopeDIE = updateSubprogramScopeDIE(TheCU, Sub);
 
-  createAndAddScopeChildren(TheCU, Scope, ScopeDIE);
+  // Collect arguments for current function.
+  assert(LScopes.isCurrentFunctionScope(Scope));
+  DIE *ObjectPointer = nullptr;
+  for (DbgVariable *ArgDV : CurrentFnArguments)
+    if (ArgDV)
+      ScopeDIE.addChild(
+          constructVariableDIE(TheCU, *ArgDV, *Scope, ObjectPointer));
+
+  // If this is a variadic function, add an unspecified parameter.
+  DITypeArray FnArgs = Sub.getType().getTypeArray();
+  // If we have a single element of null, it is a function that returns void.
+  // If we have more than one elements and the last one is null, it is a
+  // variadic function.
+  if (FnArgs.getNumElements() > 1 &&
+      !FnArgs.getElement(FnArgs.getNumElements() - 1))
+    ScopeDIE.addChild(make_unique<DIE>(dwarf::DW_TAG_unspecified_parameters));
+
+  // Collect lexical scope children first.
+  // ObjectPointer might be a local (non-argument) local variable if it's a
+  // block's synthetic this pointer.
+  if (DIE *BlockObjPtr = createAndAddScopeChildren(TheCU, Scope, ScopeDIE)) {
+    assert(!ObjectPointer && "multiple object pointers can't be described");
+    ObjectPointer = BlockObjPtr;
+  }
+
+  if (ObjectPointer)
+    TheCU.addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer);
 
   return ScopeDIE;
 }
 
 // Construct a DIE for this scope.
-std::unique_ptr<DIE> DwarfDebug::constructScopeDIE(DwarfCompileUnit &TheCU,
-                                                   LexicalScope *Scope) {
+void DwarfDebug::constructScopeDIE(
+    DwarfCompileUnit &TheCU, LexicalScope *Scope,
+    SmallVectorImpl<std::unique_ptr<DIE>> &FinalChildren) {
   if (!Scope || !Scope->getScopeNode())
-    return nullptr;
+    return;
 
   DIScope DS(Scope->getScopeNode());
 
@@ -580,17 +593,19 @@ std::unique_ptr<DIE> DwarfDebug::constructScopeDIE(DwarfCompileUnit &TheCU,
   if (Scope->getParent() && DS.isSubprogram()) {
     ScopeDIE = constructInlinedScopeDIE(TheCU, Scope);
     if (!ScopeDIE)
-      return nullptr;
+      return;
     // We create children when the scope DIE is not null.
     createScopeChildrenDIE(TheCU, Scope, Children);
   } else {
     // Early exit when we know the scope DIE is going to be null.
     if (isLexicalScopeDIENull(Scope))
-      return nullptr;
+      return;
+
+    unsigned ChildScopeCount;
 
     // We create children here when we know the scope DIE is not going to be
     // null and the children will be added to the scope DIE.
-    createScopeChildrenDIE(TheCU, Scope, Children);
+    createScopeChildrenDIE(TheCU, Scope, Children, &ChildScopeCount);
 
     // There is no need to emit empty lexical block DIE.
     std::pair<ImportedEntityMap::const_iterator,
@@ -599,20 +614,27 @@ std::unique_ptr<DIE> DwarfDebug::constructScopeDIE(DwarfCompileUnit &TheCU,
                          ScopesWithImportedEntities.end(),
                          std::pair<const MDNode *, const MDNode *>(DS, nullptr),
                          less_first());
-    if (Children.empty() && Range.first == Range.second)
-      return nullptr;
-    ScopeDIE = constructLexicalScopeDIE(TheCU, Scope);
-    assert(ScopeDIE && "Scope DIE should not be null.");
     for (ImportedEntityMap::const_iterator i = Range.first; i != Range.second;
          ++i)
-      constructImportedEntityDIE(TheCU, i->second, *ScopeDIE);
+      Children.push_back(
+          constructImportedEntityDIE(TheCU, DIImportedEntity(i->second)));
+    // If there are only other scopes as children, put them directly in the
+    // parent instead, as this scope would serve no purpose.
+    if (Children.size() == ChildScopeCount) {
+      FinalChildren.insert(FinalChildren.end(),
+                           std::make_move_iterator(Children.begin()),
+                           std::make_move_iterator(Children.end()));
+      return;
+    }
+    ScopeDIE = constructLexicalScopeDIE(TheCU, Scope);
+    assert(ScopeDIE && "Scope DIE should not be null.");
   }
 
   // Add children
   for (auto &I : Children)
     ScopeDIE->addChild(std::move(I));
 
-  return ScopeDIE;
+  FinalChildren.push_back(std::move(ScopeDIE));
 }
 
 void DwarfDebug::addGnuPubAttributes(DwarfUnit &U, DIE &D) const {
@@ -685,27 +707,21 @@ DwarfCompileUnit &DwarfDebug::constructDwarfCompileUnit(DICompileUnit DIUnit) {
   return NewCU;
 }
 
-void DwarfDebug::constructImportedEntityDIE(DwarfCompileUnit &TheCU,
-                                            const MDNode *N) {
+void DwarfDebug::constructAndAddImportedEntityDIE(DwarfCompileUnit &TheCU,
+                                                  const MDNode *N) {
   DIImportedEntity Module(N);
   assert(Module.Verify());
   if (DIE *D = TheCU.getOrCreateContextDIE(Module.getContext()))
-    constructImportedEntityDIE(TheCU, Module, *D);
+    D->addChild(constructImportedEntityDIE(TheCU, Module));
 }
 
-void DwarfDebug::constructImportedEntityDIE(DwarfCompileUnit &TheCU,
-                                            const MDNode *N, DIE &Context) {
-  DIImportedEntity Module(N);
-  assert(Module.Verify());
-  return constructImportedEntityDIE(TheCU, Module, Context);
-}
-
-void DwarfDebug::constructImportedEntityDIE(DwarfCompileUnit &TheCU,
-                                            const DIImportedEntity &Module,
-                                            DIE &Context) {
+std::unique_ptr<DIE>
+DwarfDebug::constructImportedEntityDIE(DwarfCompileUnit &TheCU,
+                                       const DIImportedEntity &Module) {
   assert(Module.Verify() &&
          "Use one of the MDNode * overloads to handle invalid metadata");
-  DIE &IMDie = TheCU.createAndAddDIE(Module.getTag(), Context, Module);
+  std::unique_ptr<DIE> IMDie = make_unique<DIE>((dwarf::Tag)Module.getTag());
+  TheCU.insertDIE(Module, IMDie.get());
   DIE *EntityDie;
   DIDescriptor Entity = resolve(Module.getEntity());
   if (Entity.isNameSpace())
@@ -716,13 +732,16 @@ void DwarfDebug::constructImportedEntityDIE(DwarfCompileUnit &TheCU,
     EntityDie = TheCU.getOrCreateTypeDIE(DIType(Entity));
   else
     EntityDie = TheCU.getDIE(Entity);
-  TheCU.addSourceLine(IMDie, Module.getLineNumber(),
+  assert(EntityDie);
+  TheCU.addSourceLine(*IMDie, Module.getLineNumber(),
                       Module.getContext().getFilename(),
                       Module.getContext().getDirectory());
-  TheCU.addDIEEntry(IMDie, dwarf::DW_AT_import, *EntityDie);
+  TheCU.addDIEEntry(*IMDie, dwarf::DW_AT_import, *EntityDie);
   StringRef Name = Module.getName();
   if (!Name.empty())
-    TheCU.addString(IMDie, dwarf::DW_AT_name, Name);
+    TheCU.addString(*IMDie, dwarf::DW_AT_name, Name);
+
+  return IMDie;
 }
 
 // Emit all Dwarf sections that should come prior to the content. Create
@@ -783,7 +802,7 @@ void DwarfDebug::beginModule() {
     // Emit imported_modules last so that the relevant context is already
     // available.
     for (unsigned i = 0, e = ImportedEntities.getNumElements(); i != e; ++i)
-      constructImportedEntityDIE(CU, ImportedEntities.getElement(i));
+      constructAndAddImportedEntityDIE(CU, ImportedEntities.getElement(i));
   }
 
   // Tell MMI that we have debug info.
@@ -796,9 +815,7 @@ void DwarfDebug::beginModule() {
 void DwarfDebug::finishVariableDefinitions() {
   for (const auto &Var : ConcreteVariables) {
     DIE *VariableDie = Var->getDIE();
-    // FIXME: There shouldn't be any variables without DIEs.
-    if (!VariableDie)
-      continue;
+    assert(VariableDie);
     // FIXME: Consider the time-space tradeoff of just storing the unit pointer
     // in the ConcreteVariables list, rather than looking it up again here.
     // DIE::getUnit isn't simple - it walks parent pointers, etc.
@@ -952,10 +969,7 @@ void DwarfDebug::finalizeModuleInfo() {
                     0);
         } else {
           RangeSpan &Range = TheU->getRanges().back();
-          U.addLocalLabelAddress(U.getUnitDie(), dwarf::DW_AT_low_pc,
-                                 Range.getStart());
-          U.addLabelDelta(U.getUnitDie(), dwarf::DW_AT_high_pc, Range.getEnd(),
-                          Range.getStart());
+          attachLowHighPC(U, U.getUnitDie(), Range.getStart(), Range.getEnd());
         }
       }
     }
@@ -1144,13 +1158,14 @@ bool DwarfDebug::addCurrentFnArgument(DbgVariable *Var, LexicalScope *Scope) {
   // arguments does the function have at source level.
   if (ArgNo > Size)
     CurrentFnArguments.resize(ArgNo * 2);
+  assert(!CurrentFnArguments[ArgNo - 1]);
   CurrentFnArguments[ArgNo - 1] = Var;
   return true;
 }
 
 // Collect variable information from side table maintained by MMI.
 void DwarfDebug::collectVariableInfoFromMMITable(
-    SmallPtrSet<const MDNode *, 16> &Processed) {
+    SmallPtrSetImpl<const MDNode *> &Processed) {
   for (const auto &VI : MMI->getVariableDbgInfo()) {
     if (!VI.Var)
       continue;
@@ -1229,12 +1244,10 @@ static bool piecesOverlap(DIVariable P1, DIVariable P2) {
 // [1-3]    [x, (reg0, piece  0, 32), (reg1, piece 32, 32)]
 // [3-4]    [x, (reg1, piece 32, 32)]
 // [4- ]    [x, (mem,  piece  0, 64)]
-void DwarfDebug::
-buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
-                  const DbgValueHistoryMap::InstrRanges &Ranges,
-                  DwarfCompileUnit *TheCU) {
-  typedef std::pair<DIVariable, DebugLocEntry::Value> Range;
-  SmallVector<Range, 4> OpenRanges;
+void
+DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
+                              const DbgValueHistoryMap::InstrRanges &Ranges) {
+  SmallVector<DebugLocEntry::Value, 4> OpenRanges;
 
   for (auto I = Ranges.begin(), E = Ranges.end(); I != E; ++I) {
     const MachineInstr *Begin = I->first;
@@ -1242,18 +1255,18 @@ buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
     assert(Begin->isDebugValue() && "Invalid History entry");
 
     // Check if a variable is inaccessible in this range.
-    if (!Begin->isDebugValue() ||
-        (Begin->getNumOperands() > 1 && Begin->getOperand(0).isReg() &&
-         !Begin->getOperand(0).getReg())) {
+    if (Begin->getNumOperands() > 1 &&
+        Begin->getOperand(0).isReg() && !Begin->getOperand(0).getReg()) {
       OpenRanges.clear();
       continue;
     }
 
     // If this piece overlaps with any open ranges, truncate them.
     DIVariable DIVar = Begin->getDebugVariable();
-    auto Last = std::remove_if(OpenRanges.begin(), OpenRanges.end(), [&](Range R){
-        return piecesOverlap(DIVar, R.first);
-      });
+    auto Last = std::remove_if(OpenRanges.begin(), OpenRanges.end(),
+                               [&](DebugLocEntry::Value R) {
+                                 return piecesOverlap(DIVar, R.getVariable());
+                               });
     OpenRanges.erase(Last, OpenRanges.end());
 
     const MCSymbol *StartLabel = getLabelBeforeInsn(Begin);
@@ -1271,19 +1284,38 @@ buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
     DEBUG(dbgs() << "DotDebugLoc: " << *Begin << "\n");
 
     auto Value = getDebugLocValue(Begin);
-    DebugLocEntry Loc(StartLabel, EndLabel, Value, TheCU);
-    if (DebugLoc.empty() || !DebugLoc.back().Merge(Loc)) {
-      // Add all values from still valid non-overlapping pieces.
-      for (auto Range : OpenRanges)
-        Loc.addValue(Range.second);
+    DebugLocEntry Loc(StartLabel, EndLabel, Value);
+    bool couldMerge = false;
+
+    // If this is a piece, it may belong to the current DebugLocEntry.
+    if (DIVar.isVariablePiece()) {
+      // Add this value to the list of open ranges.
+      OpenRanges.push_back(Value);
+
+      // Attempt to add the piece to the last entry.
+      if (!DebugLoc.empty())
+        if (DebugLoc.back().MergeValues(Loc))
+          couldMerge = true;
+    }
+
+    if (!couldMerge) {
+      // Need to add a new DebugLocEntry. Add all values from still
+      // valid non-overlapping pieces.
+      if (OpenRanges.size())
+        Loc.addValues(OpenRanges);
+
       DebugLoc.push_back(std::move(Loc));
     }
-    // Add this value to the list of open ranges.
-    if (DIVar.isVariablePiece())
-      OpenRanges.push_back(std::make_pair(DIVar, Value));
+
+    // Attempt to coalesce the ranges of two otherwise identical
+    // DebugLocEntries.
+    auto CurEntry = DebugLoc.rbegin();
+    auto PrevEntry = std::next(CurEntry);
+    if (PrevEntry != DebugLoc.rend() && PrevEntry->MergeRanges(*CurEntry))
+      DebugLoc.pop_back();
 
     DEBUG(dbgs() << "Values:\n";
-          for (auto Value : DebugLoc.back().getValues())
+          for (auto Value : CurEntry->getValues())
             Value.getVariable()->dump();
           dbgs() << "-----\n");
   }
@@ -1292,7 +1324,7 @@ buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
 
 // Find variables for each lexical scope.
 void
-DwarfDebug::collectVariableInfo(SmallPtrSet<const MDNode *, 16> &Processed) {
+DwarfDebug::collectVariableInfo(SmallPtrSetImpl<const MDNode *> &Processed) {
   LexicalScope *FnScope = LScopes.getCurrentFunctionScope();
   DwarfCompileUnit *TheCU = SPMap.lookup(FnScope->getScopeNode());
 
@@ -1310,10 +1342,7 @@ DwarfDebug::collectVariableInfo(SmallPtrSet<const MDNode *, 16> &Processed) {
       continue;
 
     LexicalScope *Scope = nullptr;
-    if (DV.getTag() == dwarf::DW_TAG_arg_variable &&
-        DISubprogram(DV.getContext()).describes(CurFn->getFunction()))
-      Scope = LScopes.getCurrentFunctionScope();
-    else if (MDNode *IA = DV.getInlinedAt()) {
+    if (MDNode *IA = DV.getInlinedAt()) {
       DebugLoc DL = DebugLoc::getFromDILocation(IA);
       Scope = LScopes.findInlinedScope(DebugLoc::get(
           DL.getLine(), DL.getCol(), DV.getContext(), IA));
@@ -1340,11 +1369,12 @@ DwarfDebug::collectVariableInfo(SmallPtrSet<const MDNode *, 16> &Processed) {
 
     DotDebugLocEntries.resize(DotDebugLocEntries.size() + 1);
     DebugLocList &LocList = DotDebugLocEntries.back();
+    LocList.CU = TheCU;
     LocList.Label =
         Asm->GetTempSymbol("debug_loc", DotDebugLocEntries.size() - 1);
 
     // Build the location list for this variable.
-    buildLocationList(LocList.List, Ranges, TheCU);
+    buildLocationList(LocList.List, Ranges);
   }
 
   // Collect info for variables that were optimized out.
@@ -1637,7 +1667,6 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
     // If we don't have a lexical scope for this function then there will
     // be a hole in the range information. Keep note of this by setting the
     // previously used section to nullptr.
-    PrevSection = nullptr;
     PrevCU = nullptr;
     CurFn = nullptr;
     return;
@@ -1680,7 +1709,6 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
   // Add the range of this function to the list of ranges for the CU.
   RangeSpan Span(FunctionBeginSym, FunctionEndSym);
   TheCU.addRange(std::move(Span));
-  PrevSection = Asm->getCurrentSection();
   PrevCU = &TheCU;
 
   // Clear debug info
@@ -1708,8 +1736,8 @@ void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S,
     assert(Scope.isScope());
     Fn = Scope.getFilename();
     Dir = Scope.getDirectory();
-    if (Scope.isLexicalBlock())
-      Discriminator = DILexicalBlock(S).getDiscriminator();
+    if (Scope.isLexicalBlockFile())
+      Discriminator = DILexicalBlockFile(S).getDiscriminator();
 
     unsigned CUID = Asm->OutStreamer.getContext().getDwarfCompileUnitID();
     Src = static_cast<DwarfCompileUnit &>(*InfoHolder.getUnits()[CUID])
@@ -2049,30 +2077,18 @@ void DwarfDebug::emitDebugStr() {
 void DwarfDebug::emitLocPieces(ByteStreamer &Streamer,
                                const DITypeIdentifierMap &Map,
                                ArrayRef<DebugLocEntry::Value> Values) {
-  typedef DebugLocEntry::Value Piece;
-  SmallVector<Piece, 4> Pieces(Values.begin(), Values.end());
-  assert(std::all_of(Pieces.begin(), Pieces.end(), [](Piece &P) {
-        return DIVariable(P.getVariable()).isVariablePiece();
+  assert(std::all_of(Values.begin(), Values.end(), [](DebugLocEntry::Value P) {
+        return P.isVariablePiece();
       }) && "all values are expected to be pieces");
-
-  // Sort the pieces so they can be emitted using DW_OP_piece.
-  std::sort(Pieces.begin(), Pieces.end(), [](const Piece &A, const Piece &B) {
-      DIVariable VarA(A.getVariable());
-      DIVariable VarB(B.getVariable());
-      return VarA.getPieceOffset() < VarB.getPieceOffset();
-    });
-  // Remove any duplicate entries by dropping all but the first.
-  Pieces.erase(std::unique(Pieces.begin(), Pieces.end(),
-                           [] (const Piece &A,const Piece &B){
-                             return A.getVariable() == B.getVariable();
-                           }), Pieces.end());
+  assert(std::is_sorted(Values.begin(), Values.end()) &&
+         "pieces are expected to be sorted");
 
   unsigned Offset = 0;
-  for (auto Piece : Pieces) {
-    DIVariable Var(Piece.getVariable());
+  for (auto Piece : Values) {
+    DIVariable Var = Piece.getVariable();
     unsigned PieceOffset = Var.getPieceOffset();
     unsigned PieceSize = Var.getPieceSize();
-    assert(Offset <= PieceOffset && "overlapping pieces in DebugLocEntry");
+    assert(Offset <= PieceOffset && "overlapping or duplicate pieces");
     if (Offset < PieceOffset) {
       // The DWARF spec seriously mandates pieces with no locations for gaps.
       Asm->EmitDwarfOpPiece(Streamer, (PieceOffset-Offset)*8);
@@ -2105,8 +2121,7 @@ void DwarfDebug::emitLocPieces(ByteStreamer &Streamer,
 void DwarfDebug::emitDebugLocEntry(ByteStreamer &Streamer,
                                    const DebugLocEntry &Entry) {
   const DebugLocEntry::Value Value = Entry.getValues()[0];
-  DIVariable DV(Value.getVariable());
-  if (DV.isVariablePiece())
+  if (Value.isVariablePiece())
     // Emit all pieces that belong to the same variable and range.
     return emitLocPieces(Streamer, TypeIdentifierMap, Entry.getValues());
 
@@ -2116,7 +2131,7 @@ void DwarfDebug::emitDebugLocEntry(ByteStreamer &Streamer,
 
 void DwarfDebug::emitDebugLocValue(ByteStreamer &Streamer,
                                    const DebugLocEntry::Value &Value) {
-  DIVariable DV(Value.getVariable());
+  DIVariable DV = Value.getVariable();
   // Regular entry.
   if (Value.isInt()) {
     DIBasicType BTy(resolve(DV.getType()));
@@ -2198,11 +2213,12 @@ void DwarfDebug::emitDebugLoc() {
   unsigned char Size = Asm->getDataLayout().getPointerSize();
   for (const auto &DebugLoc : DotDebugLocEntries) {
     Asm->OutStreamer.EmitLabel(DebugLoc.Label);
+    const DwarfCompileUnit *CU = DebugLoc.CU;
+    assert(!CU->getRanges().empty());
     for (const auto &Entry : DebugLoc.List) {
       // Set up the range. This range is relative to the entry point of the
       // compile unit. This is a hard coded 0 for low_pc when we're emitting
       // ranges, or the DW_AT_low_pc on the compile unit otherwise.
-      const DwarfCompileUnit *CU = Entry.getCU();
       if (CU->getRanges().size() == 1) {
         // Grab the begin symbol from the first range as our base.
         const MCSymbol *Base = CU->getRanges()[0].getStart();
@@ -2479,24 +2495,6 @@ DwarfCompileUnit &DwarfDebug::constructSkeletonCU(const DwarfCompileUnit &CU) {
   return NewCU;
 }
 
-// This DIE has the following attributes: DW_AT_comp_dir, DW_AT_dwo_name,
-// DW_AT_addr_base.
-DwarfTypeUnit &DwarfDebug::constructSkeletonTU(DwarfTypeUnit &TU) {
-  DwarfCompileUnit &CU = static_cast<DwarfCompileUnit &>(
-      *SkeletonHolder.getUnits()[TU.getCU().getUniqueID()]);
-
-  auto OwnedUnit = make_unique<DwarfTypeUnit>(TU.getUniqueID(), CU, Asm, this,
-                                              &SkeletonHolder);
-  DwarfTypeUnit &NewTU = *OwnedUnit;
-  NewTU.setTypeSignature(TU.getTypeSignature());
-  NewTU.setType(nullptr);
-  NewTU.initSection(
-      Asm->getObjFileLowering().getDwarfTypesSection(TU.getTypeSignature()));
-
-  initSkeletonUnit(TU, NewTU.getUnitDie(), std::move(OwnedUnit));
-  return NewTU;
-}
-
 // Emit the .debug_info.dwo section for separated dwarf. This contains the
 // compile units that would normally be in debug_info.
 void DwarfDebug::emitDebugInfoDWO() {
@@ -2619,17 +2617,14 @@ void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU,
 
     // If the type wasn't dependent on fission addresses, finish adding the type
     // and all its dependent types.
-    for (auto &TU : TypeUnitsToAdd) {
-      if (useSplitDwarf())
-        TU.first->setSkeleton(constructSkeletonTU(*TU.first));
+    for (auto &TU : TypeUnitsToAdd)
       InfoHolder.addUnit(std::move(TU.first));
-    }
   }
   CU.addDIETypeSignature(RefDie, NewTU);
 }
 
 void DwarfDebug::attachLowHighPC(DwarfCompileUnit &Unit, DIE &D,
-                                 MCSymbol *Begin, MCSymbol *End) {
+                                 const MCSymbol *Begin, const MCSymbol *End) {
   assert(Begin && "Begin label should not be null!");
   assert(End && "End label should not be null!");
   assert(Begin->isDefined() && "Invalid starting label");