]> granicus.if.org Git - llvm/commitdiff
Debug Info: Move the sorting and uniqueing of pieces from emitLocPieces()
authorAdrian Prantl <aprantl@apple.com>
Mon, 11 Aug 2014 21:05:55 +0000 (21:05 +0000)
committerAdrian Prantl <aprantl@apple.com>
Mon, 11 Aug 2014 21:05:55 +0000 (21:05 +0000)
into buildLocationList(). By keeping the list of Values sorted,
DebugLocEntry::Merge can also merge multi-piece entries.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@215384 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/AsmPrinter/DebugLocEntry.h
lib/CodeGen/AsmPrinter/DwarfDebug.cpp

index 97f48aac3bb487616290af6b9336aa1eb438087b..41735fca3765cd0df29f48885b4ce52f9cd69182 100644 (file)
@@ -76,6 +76,13 @@ public:
       llvm_unreachable("unhandled EntryKind");
     }
 
+    // Compare two pieces based on their offset.
+    bool operator<(const Value &other) const {
+      DIVariable Var(Variable);
+      DIVariable OtherVar(other.Variable);
+      return Var.getPieceOffset() < OtherVar.getPieceOffset();
+    }
+
     bool isLocation() const { return EntryKind == E_Location; }
     bool isInt() const { return EntryKind == E_Integer; }
     bool isConstantFP() const { return EntryKind == E_ConstantFP; }
@@ -87,7 +94,7 @@ public:
     const MDNode *getVariable() const { return Variable; }
   };
 private:
-  /// A list of locations/constants belonging to this entry.
+  /// A list of locations/constants belonging to this entry, sorted by offset.
   SmallVector<Value, 1> Values;
 
 public:
@@ -108,6 +115,7 @@ public:
       if (Var.getName() == NextVar.getName() &&
           Var.isVariablePiece() && NextVar.isVariablePiece()) {
         Values.append(Next.Values.begin(), Next.Values.end());
+        sortUniqueValues();
         End = Next.End;
         return true;
       }
@@ -135,6 +143,14 @@ public:
     assert(DIVariable(Val.Variable).isVariablePiece() &&
            "multi-value DebugLocEntries must be pieces");
     Values.push_back(Val);
+    sortUniqueValues();
+  }
+
+  // Sort the pieces by offset.
+  // Remove any duplicate entries by dropping all but the first.
+  void sortUniqueValues() {
+    std::sort(Values.begin(), Values.end());
+    Values.erase(std::unique(Values.begin(), Values.end()), Values.end());
   }
 };
 
index 3dc03d9fb19697ae6d8c74f791dd79c447f41ee6..b0ed22a5f4c6fc7c998d5a640d08374cfc6ee167 100644 (file)
@@ -2065,30 +2065,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) {
+  assert(std::all_of(Values.begin(), Values.end(), [](DebugLocEntry::Value P) {
         return DIVariable(P.getVariable()).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) {
+  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);