This is an archive of the discontinued LLVM Phabricator instance.

Emit DW_LLE_base_address + DW_LLE_offset_pairs instead of DW_LLE_start_length in debug_loclists section
ClosedPublic

Authored by rastogishubham on Jun 15 2023, 3:28 PM.

Details

Summary

This patch tries to reduce the size of the debug_loclist section by replacing the DW_LLE_start_length opcodes currently emitted by dsymutil in favor of using DW_LLE_base_address + DW_LLE_offset_pair instead.

The DW_LLE_start_length is one AddressSize followed by a ULEB per entry, whereas, the DW_LLE_base_address + DW_LLE_offset_pair will use one AddressSize for the base address, and then the DW_LLE_offset_pair is a pair of ULEBs. This will be more efficient where a loclist fragment has many entries.

I tried to see the size of the clang.dSYM and it went from 12.23 MB to 10.46 MB in size.

Diff Detail

Event Timeline

rastogishubham created this revision.Jun 15 2023, 3:28 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 15 2023, 3:28 PM
rastogishubham requested review of this revision.Jun 15 2023, 3:28 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 15 2023, 3:28 PM

Nice!

I tried to see the size of the clang.dSYM and it went from 12.23 MB to 10.46 MB in size.

Is that the size of the loclists section inside clang.dSYM?

llvm/lib/DWARFLinker/DWARFStreamer.cpp
642

Don't we need to subtract the base address here?

aprantl added inline comments.Jun 15 2023, 4:11 PM
llvm/include/llvm/DebugInfo/DWARF/DWARFLocationExpression.h
48 ↗(On Diff #531918)

Maybe add an initializer here?

uint64_t BaseAddress = 0;
llvm/lib/DWARFLinker/DWARFLinker.cpp
1975 ↗(On Diff #531918)

and then convert this to an if (Unit.getOrigUnit().getVersion() >= 5 && FirstLocation.Range)

rastogishubham marked 3 inline comments as done.

Addressed Adrians comments:

  1. Added a default initializer for the BaseAddress in DWARFLocationExpressionsFragment
  1. Changed the ternery to an if statement when calculating the BaseAddress for a loclist fragment
llvm/lib/DWARFLinker/DWARFStreamer.cpp
642

No, we already adjusted the address on line 1984 - line 1989, in DWARFLinker.cpp

uint64_t LowPCVal = CurExpression.Range->LowPC +
                    CurLocAttr.RelocAdjustment -
                    LinkedLocationExpressionsFrag.BaseAddress;
assert(LowPCVal >= 0 && "Low PC value should not be negative!");
LinkedExpression.Range = {
    LowPCVal, CurExpression.Range->HighPC + CurLocAttr.RelocAdjustment -
                  LinkedLocationExpressionsFrag.BaseAddress};
JDevlieghere added inline comments.Jun 15 2023, 8:28 PM
llvm/lib/DWARFLinker/DWARFLinker.cpp
1974 ↗(On Diff #531946)

Is OriginalLocations guaranteed to be non empty? Also I would use OriginalLocations->front() here.

1988 ↗(On Diff #531946)

nit: Let's drop the exclamation mark: other asserts in this file either use a period or no punctuation at all.

avl added inline comments.Jun 16 2023, 1:32 AM
llvm/include/llvm/DebugInfo/DWARF/DWARFLocationExpression.h
47 ↗(On Diff #531946)

probably not name it "LinkedLocationExpression" as linked is dsymutil term. DebugInfo/DWARF does not name addresses linked or relocated. maybe LinkedLocationExpression -> LocationExpressions or LinkedLocationExpression -> LocationExpressionsVector.

llvm/lib/DWARFLinker/DWARFLinker.cpp
1988 ↗(On Diff #531946)

uint64_t could not be negative. probably:

uint64_t LowPCVal = CurExpression.Range->LowPC + CurLocAttr.RelocAdjustment - LinkedLocationExpressionsFrag.BaseAddress;
assert(LowPCVal <= CurExpression.Range->LowPC + CurLocAttr.RelocAdjustment && "Address overflow");
llvm/lib/DWARFLinker/DWARFStreamer.cpp
612

may be we can do all calculations inside DwarfStreamer::emitDwarfDebugLocListsTableFragment ? i.e. do not create new structure DWARFLocationExpressionsFragment, do not change DWARFLinker::generateUnitLocations, calculate and apply BaseAddress inside DwarfStreamer::emitDwarfDebugLocListsTableFragment ? Such approach allows to change output format not changing high level structures and makes overall patch smaller.

646

it looks like it should be emit_U_LEB128IntValue.

DW_LLE_offset_pair
This is a form of bounded location description entry that has two unsigned
LEB128 operands.

I think SLEB came from my original patch.

rastogishubham marked 6 inline comments as done.

Moved code to DWARFStreamer.cpp, makes the patch a lot smaller as calculated values do not have to be passed through

llvm/include/llvm/DebugInfo/DWARF/DWARFLocationExpression.h
47 ↗(On Diff #531946)

We don't need this anymore, because your other comment about moving the calculations to DWARFStreamer makes sense

llvm/lib/DWARFLinker/DWARFStreamer.cpp
612

Yes, this is a fantastic observation, and I don't know why I didn't think of it!

avl accepted this revision.EditedJun 17 2023, 12:36 AM

LGTM. Though, wait a couple of days for other reviewers, please.

llvm/lib/DWARFLinker/DWARFStreamer.cpp
620

not necessary to do that way, but if you found this useful: It might be a bit simpler if BaseAddress would be std::optional<uint64_t>. Then we do not need BaseAddressEmitted flag. A bit shorter and no connected variables.

std::optional<uint64_t> BaseAddress;

if (!BaseAddress) {
  BaseAddress = LocExpression.Range->LowPC;
  ...
  MS->emitIntValue(*BaseAddress, AddressSize);
  ...
}
This revision is now accepted and ready to land.Jun 17 2023, 12:36 AM

Changed from using a bool flag to a std::optional

rastogishubham marked an inline comment as done.Jun 20 2023, 9:34 AM
avl accepted this revision.Jun 21 2023, 2:26 AM
This revision was landed with ongoing or failed builds.Jun 21 2023, 12:49 PM
This revision was automatically updated to reflect the committed changes.