1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-20 19:42:54 +02:00

Debug Info: Move the sorting and uniqueing of pieces from emitLocPieces()

into buildLocationList(). By keeping the list of Values sorted,
DebugLocEntry::Merge can also merge multi-piece entries.

llvm-svn: 215384
This commit is contained in:
Adrian Prantl 2014-08-11 21:05:55 +00:00
parent ac2ef47b2d
commit ef4cab1ac9
2 changed files with 22 additions and 18 deletions

View File

@ -76,6 +76,13 @@ public:
llvm_unreachable("unhandled EntryKind"); 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 isLocation() const { return EntryKind == E_Location; }
bool isInt() const { return EntryKind == E_Integer; } bool isInt() const { return EntryKind == E_Integer; }
bool isConstantFP() const { return EntryKind == E_ConstantFP; } bool isConstantFP() const { return EntryKind == E_ConstantFP; }
@ -87,7 +94,7 @@ public:
const MDNode *getVariable() const { return Variable; } const MDNode *getVariable() const { return Variable; }
}; };
private: 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; SmallVector<Value, 1> Values;
public: public:
@ -108,6 +115,7 @@ public:
if (Var.getName() == NextVar.getName() && if (Var.getName() == NextVar.getName() &&
Var.isVariablePiece() && NextVar.isVariablePiece()) { Var.isVariablePiece() && NextVar.isVariablePiece()) {
Values.append(Next.Values.begin(), Next.Values.end()); Values.append(Next.Values.begin(), Next.Values.end());
sortUniqueValues();
End = Next.End; End = Next.End;
return true; return true;
} }
@ -135,6 +143,14 @@ public:
assert(DIVariable(Val.Variable).isVariablePiece() && assert(DIVariable(Val.Variable).isVariablePiece() &&
"multi-value DebugLocEntries must be pieces"); "multi-value DebugLocEntries must be pieces");
Values.push_back(Val); 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());
} }
}; };

View File

@ -2065,30 +2065,18 @@ void DwarfDebug::emitDebugStr() {
void DwarfDebug::emitLocPieces(ByteStreamer &Streamer, void DwarfDebug::emitLocPieces(ByteStreamer &Streamer,
const DITypeIdentifierMap &Map, const DITypeIdentifierMap &Map,
ArrayRef<DebugLocEntry::Value> Values) { ArrayRef<DebugLocEntry::Value> Values) {
typedef DebugLocEntry::Value Piece; assert(std::all_of(Values.begin(), Values.end(), [](DebugLocEntry::Value P) {
SmallVector<Piece, 4> Pieces(Values.begin(), Values.end());
assert(std::all_of(Pieces.begin(), Pieces.end(), [](Piece &P) {
return DIVariable(P.getVariable()).isVariablePiece(); return DIVariable(P.getVariable()).isVariablePiece();
}) && "all values are expected to be pieces"); }) && "all values are expected to be pieces");
assert(std::is_sorted(Values.begin(), Values.end()) &&
// Sort the pieces so they can be emitted using DW_OP_piece. "pieces are expected to be sorted");
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());
unsigned Offset = 0; unsigned Offset = 0;
for (auto Piece : Pieces) { for (auto Piece : Values) {
DIVariable Var(Piece.getVariable()); DIVariable Var(Piece.getVariable());
unsigned PieceOffset = Var.getPieceOffset(); unsigned PieceOffset = Var.getPieceOffset();
unsigned PieceSize = Var.getPieceSize(); unsigned PieceSize = Var.getPieceSize();
assert(Offset <= PieceOffset && "overlapping pieces in DebugLocEntry"); assert(Offset <= PieceOffset && "overlapping or duplicate pieces");
if (Offset < PieceOffset) { if (Offset < PieceOffset) {
// The DWARF spec seriously mandates pieces with no locations for gaps. // The DWARF spec seriously mandates pieces with no locations for gaps.
Asm->EmitDwarfOpPiece(Streamer, (PieceOffset-Offset)*8); Asm->EmitDwarfOpPiece(Streamer, (PieceOffset-Offset)*8);