diff options
author | Adrian Prantl <aprantl@apple.com> | 2016-12-05 18:04:47 +0000 |
---|---|---|
committer | Adrian Prantl <aprantl@apple.com> | 2016-12-05 18:04:47 +0000 |
commit | 941fa7588bbee856a8d3f634c5b88f101089d30f (patch) | |
tree | a27a566046fe17ba1ab5691911b2468395a91e52 /llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp | |
parent | fc78d7cb8e5c0c849950fca7d69d81485f3513e1 (diff) | |
download | llvm-941fa7588bbee856a8d3f634c5b88f101089d30f.zip llvm-941fa7588bbee856a8d3f634c5b88f101089d30f.tar.gz llvm-941fa7588bbee856a8d3f634c5b88f101089d30f.tar.bz2 |
[DIExpression] Introduce a dedicated DW_OP_LLVM_fragment operation
so we can stop using DW_OP_bit_piece with the wrong semantics.
The entire back story can be found here:
http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20161114/405934.html
The gist is that in LLVM we've been misinterpreting DW_OP_bit_piece's
offset field to mean the offset into the source variable rather than
the offset into the location at the top the DWARF expression stack. In
order to be able to fix this in a subsequent patch, this patch
introduces a dedicated DW_OP_LLVM_fragment operation with the
semantics that we used to apply to DW_OP_bit_piece, which is what we
actually need while inside of LLVM. This patch is complete with a
bitcode upgrade for expressions using the old format. It does not yet
fix the DWARF backend to use DW_OP_bit_piece correctly.
Implementation note: We discussed several options for implementing
this, including reserving a dedicated field in DIExpression for the
fragment size and offset, but using an custom operator at the end of
the expression works just fine and is more efficient because we then
only pay for it when we need it.
Differential Revision: https://reviews.llvm.org/D27361
rdar://problem/29335809
llvm-svn: 288683
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp | 33 |
1 files changed, 16 insertions, 17 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp index d30f106..ce57f17 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp @@ -63,14 +63,12 @@ MCSymbol *DebugHandlerBase::getLabelAfterInsn(const MachineInstr *MI) { return LabelsAfterInsn.lookup(MI); } -// Determine the relative position of the pieces described by P1 and P2. -// Returns -1 if P1 is entirely before P2, 0 if P1 and P2 overlap, -// 1 if P1 is entirely after P2. -int DebugHandlerBase::pieceCmp(const DIExpression *P1, const DIExpression *P2) { - unsigned l1 = P1->getBitPieceOffset(); - unsigned l2 = P2->getBitPieceOffset(); - unsigned r1 = l1 + P1->getBitPieceSize(); - unsigned r2 = l2 + P2->getBitPieceSize(); +int DebugHandlerBase::fragmentCmp(const DIExpression *P1, + const DIExpression *P2) { + unsigned l1 = P1->getFragmentOffsetInBits(); + unsigned l2 = P2->getFragmentOffsetInBits(); + unsigned r1 = l1 + P1->getFragmentSizeInBits(); + unsigned r2 = l2 + P2->getFragmentSizeInBits(); if (r1 <= l2) return -1; else if (r2 <= l1) @@ -79,11 +77,11 @@ int DebugHandlerBase::pieceCmp(const DIExpression *P1, const DIExpression *P2) { return 0; } -/// Determine whether two variable pieces overlap. -bool DebugHandlerBase::piecesOverlap(const DIExpression *P1, const DIExpression *P2) { - if (!P1->isBitPiece() || !P2->isBitPiece()) +bool DebugHandlerBase::fragmentsOverlap(const DIExpression *P1, + const DIExpression *P2) { + if (!P1->isFragment() || !P2->isFragment()) return true; - return pieceCmp(P1, P2) == 0; + return fragmentCmp(P1, P2) == 0; } /// If this type is derived from a base type then return base type size. @@ -142,14 +140,15 @@ void DebugHandlerBase::beginFunction(const MachineFunction *MF) { if (DIVar->isParameter() && getDISubprogram(DIVar->getScope())->describes(MF->getFunction())) { LabelsBeforeInsn[Ranges.front().first] = Asm->getFunctionBegin(); - if (Ranges.front().first->getDebugExpression()->isBitPiece()) { - // Mark all non-overlapping initial pieces. + if (Ranges.front().first->getDebugExpression()->isFragment()) { + // Mark all non-overlapping initial fragments. for (auto I = Ranges.begin(); I != Ranges.end(); ++I) { - const DIExpression *Piece = I->first->getDebugExpression(); + const DIExpression *Fragment = I->first->getDebugExpression(); if (std::all_of(Ranges.begin(), I, [&](DbgValueHistoryMap::InstrRange Pred) { - return !piecesOverlap(Piece, Pred.first->getDebugExpression()); - })) + return !fragmentsOverlap( + Fragment, Pred.first->getDebugExpression()); + })) LabelsBeforeInsn[I->first] = Asm->getFunctionBegin(); else break; |