Skip to content

Cache Abbreviation entries after materializing them to speedup MCCAS replay #7852

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 19, 2023

Conversation

rastogishubham
Copy link

When looking at a trace of MCCAS replay, we noticed that a large chunk of time is spent in the function visitDIEAttrs

The reason for that is because, we materialize abbreviations every time we see a new DIE, which leads to decoding the same ULEB128 values that represent the form and attribute of a DIE for every DIE in the debug info section. We can materialize them once and cache them, which would reduce the time spent and give us some speedup.

We see some speedup as well:

MCCAS With Abbrev Caching
ninja clang 150.46s user 48.35s system 536% cpu 37.071 total

ninja clang 150.43s user 47.33s system 561% cpu 35.240 total

ninja clang 150.78s user 47.23s system 565% cpu 34.987 total

MCCAS Without Abbrev Caching
ninja clang 193.36s user 48.17s system 557% cpu 43.320 total

ninja clang 190.28s user 46.98s system 595% cpu 39.867 total

ninja clang 191.55s user 46.95s system 602% cpu 39.602 total

@rastogishubham rastogishubham requested review from felipepiovezan and adrian-prantl and removed request for felipepiovezan December 6, 2023 22:49
@rastogishubham rastogishubham force-pushed the CachingMCCAS branch 4 times, most recently from c515933 to 53fe5f9 Compare December 7, 2023 03:34
Copy link

@felipepiovezan felipepiovezan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exciting!

@rastogishubham rastogishubham force-pushed the CachingMCCAS branch 2 times, most recently from 2158b92 to 53fe5f9 Compare December 9, 2023 21:41
}

Error DIEVisitor::materializeAbbrevDIE(unsigned AbbrevIdx) {
constexpr auto AddrSize = 8;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does this come from? Should it be hardcoded?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For all of our purposes the AddressSize is always 8 bytes on MachO, if you see DIEVisitor::visitDIEAttrs, the same is true there

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, if you see getAndSetDebugAbbrevOffsetAndSkip, we have a check to make sure that the address size is 8

if (AddressSize != 8)
      return createStringError(
          inconvertibleErrorCode(),
          "Address size is not 8 bytes, unsupported architecture for MCCAS!");

Error DIEVisitor::materializeAbbrevDIE(unsigned AbbrevIdx) {
constexpr auto AddrSize = 8;
constexpr auto FormParams =
dwarf::FormParams{4 /*Version*/, AddrSize, dwarf::DwarfFormat::DWARF32};

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that also the version for DWARF 5?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just realized, what happens if you use MCCAS with a dwarf 2 binary? Is there a graceful degradation path?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we never really addressed the dwarf version issue.
We need to do that asap but separately

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with Felipe, the DWARF version is a separate issue and I will put up a separate patch for that

}

auto AbbrevDIECacheVal =
AbbrevDIECache[decodeAbbrevIndexAsAbbrevSetIdx(AbbrevIdx)];

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we usually use the find() method because operator[] default-constructs the value and thus silently fails if there is no cache hit.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be more evident once we disable the default constructor for that struct

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am confused, AbbrevDIECache is a SmallVector, not a DenseMap

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah nevermind.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So how does this function work? It materializes all abbreviations (3299) every time an entry is needed? I must be missing something obvious...

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue has been fixed, that was an oversight which did work when this patch was on top of the patch that switched materialization to iterative from recursive, but now I have a constructor in DIEVisitor to do the AbbrevEntryCache creation instead

Copy link

@felipepiovezan felipepiovezan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, a bunch of things escaped me the first time I looked into this. Feel free to merge once you address these and Adrian's comments.
(I think the DWARF version issue should be handled separately, as it is a pre-existing problem)

Error DIEVisitor::materializeAbbrevDIE(unsigned AbbrevIdx) {
constexpr auto AddrSize = 8;
constexpr auto FormParams =
dwarf::FormParams{4 /*Version*/, AddrSize, dwarf::DwarfFormat::DWARF32};

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we never really addressed the dwarf version issue.
We need to do that asap but separately

}

auto AbbrevDIECacheVal =
AbbrevDIECache[decodeAbbrevIndexAsAbbrevSetIdx(AbbrevIdx)];

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be more evident once we disable the default constructor for that struct

Copy link

@felipepiovezan felipepiovezan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

AbbrevEntryCache.reserve(AbbrevEntries.size());
for (unsigned I = 0; I < AbbrevEntries.size(); I++) {
if (Error E = materializeAbbrevDIE(encodeAbbrevIndex(I)))
report_fatal_error(std::move(E));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that we are crashing the compiler on invalid input.
I don't remember how this used to be done in previous iterations of this PR, but we could (maybe in a separate PR) move this out of DIEVisitor entirely; the DIEVisitor could take the already-cached abbreviations

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, once we move to the flat patch, we can do this materialization in visitDIERef

@rastogishubham
Copy link
Author

@swift-ci please test llvm

This patch caches abbreviation entries after materializing them onces to
avoid rematerializing the same abbreviation entry for every DIE, thus
speeding up MCCAS replay
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants