Skip to content

Conversation

@dexonsmith
Copy link

This is built on top of #3555; I split that out since I think it can/should land whatever happens here.

  • 75946ec CAS.o/FlatV1: Adopt data::TargetInfoList in CompileUnit
  • 05ac2f5 CAS.o/FlatV1: Inline TargetInfoLists that have no addends

The first commit lifts addends out of the block and puts them in the compile unit, and the second one recovers from regressions caused by the former. They're split for ease of review.

My motivation is to make the content of flatv1::BlockRef encapsulate (exactly) data::BlockData (which maybe could be renamed to data::Block...). The other option is to add addends to data::BlockData. I think it's important to do one of those two things. The casobjectformats::data namespace has easily unit-testable code for the encodings; this also makes them reusable in different schemas, or in different parts of the same schema (e.g., inlined vs. outlined data). A pre-requisite for experimenting with outlining subgraphs in flatv1 is to make the encodings easy to reason about. If the "right" encoding for block data has the addends in it, then we should augment data::BlockData (and nestedv1). If it doesn't, then we should take this patch.

Honestly, I'm not sure this patch is the right approach vs. adding Addends to data::BlockData. The stats for Mach-O don't support this direction; it's almost neutral when adding the second commit, but the other direction (changing data::BlockData) is simpler. I'd like to see stats for ELF -- both -ffunction-sections and -fno-function-sections (although we care a lot more about the former, the latter would be good to understand) -- before landing this.

Pull addends out of blocks and use data::TargetInfoList to combine with
the TargetIndex. This makes "block" encode exactly what is in
data::BlockData and stops encoding "target"-related data there, fixing a
data layering issue.

Unfortunately this bloats the compile-unit a bit, since the data has
nowhere else to go. Eventually we can/should outline data and references
in logical chunks.

This commit uniques by TargetInfoList, but there's 5-10% bloat in the
size of a CU which makes this hard to justify on its own. A follow-up
will optimize this down; this is not squashed so that it's easy to
review in isolation.
As a follow-up to storing addends outside of blocks, inline the target
lists into the block's list of indexes (rather than creating a
TargetInfoList) if there are no non-zero addends. This avoids fixes the
regression for the workloads I tested.
@dexonsmith
Copy link
Author

@cachemeifyoucan , is it easy to collect stats yet on ELF? I'm interested in what you've seen so far.

@cachemeifyoucan
Copy link

@cachemeifyoucan , is it easy to collect stats yet on ELF? I'm interested in what you've seen so far.

I am fixing LinkGraphBuilder so it can consume all llvm-project objects. I can definitely collect early stats for swift-nio or part of llvm-project.

@cachemeifyoucan
Copy link

So the reason why EdgeList used to exist is to benchmark what is the gain to have exactly the BlockData you have in your mind. The answer for llvm-project and swift-nio is that by having edges store out of the block, it has almost no effect on block dedup (maybe 200 dedup out of 60000+, forgot the data).

So these two are basically trading a small dedup with growth rate. It is hard to tell but I can surely collect some data for all the combo.

@dexonsmith
Copy link
Author

So the reason why EdgeList used to exist is to benchmark what is the gain to have exactly the BlockData you have in your mind. The answer for llvm-project and swift-nio is that by having edges store out of the block, it has almost no effect on block dedup (maybe 200 dedup out of 60000+, forgot the data).

So these two are basically trading a small dedup with growth rate. It is hard to tell but I can surely collect some data for all the combo.

@cachemeifyoucan, now that ELF is mostly working, can you confirm stats for both debug and release builds with -fno-function-sections and -ffunction-sections?

I'd like to clean this up one way or the other, making flatv1::BlockRef a simple wrapper around data::BlockData and better aligning the data in nestedv1 and flatv1. The two approaches:

  • Remove addends from blocks and adopt data::TargetInfoList in flatv1 (this patch)
  • Change data::BlockData to include addends and remove from them data::TargetInfoList

I'd like data to confirm that the addends in ELF are as inconsequential as they seem to be in Mach-O.

@cachemeifyoucan
Copy link

I am not sure what information you need from ELF data to guide this patch. Currently, there is still one bug in ELF LinkGraph builder that should have minimal or no impact on size for one build but make size across multiple build invalid. I just run the current implementation on llvm-project for 1 build with -ffunction-sections:

Release:
Kind                        Count            Parents           Children           Data (B)           Cost (B)
====                        =====            =======           ========           ========           ========
builtin:blob                    1   0.00%          7   0.00%          0   0.00%         21   0.00%         21   0.00%
builtin:node                    7   0.00%       2550   0.30%         13   0.00%        100   0.00%        360   0.00%
builtin:tree                  789   0.18%        789   0.09%       3348   0.40%     112820   0.09%     179780   0.13%
cas.o:block                121174  27.53%     237554  28.27%          0   0.00%   93944329  74.67%   93944329  65.87%
cas.o:compile-unit           2544   0.58%       2559   0.30%     837065  99.60%    8185166   6.51%   24926466  17.48%
cas.o:section              112734  25.61%     179630  21.37%          0   0.00%   10816602   8.60%   10816602   7.58%
cas.o:symbol               202970  46.11%     417337  49.66%          0   0.00%   12747999  10.13%   12747999   8.94%
TOTAL                      440219 100.00%     840426 100.00%     840426 100.00%  125807037 100.00%  142615557 100.00%

Debug:
Kind                        Count            Parents           Children           Data (B)           Cost (B)
====                        =====            =======           ========           ========           ========
builtin:blob                    1   0.00%          7   0.00%          0   0.00%         21   0.00%         21   0.00%
builtin:node                    7   0.00%       2428   0.04%         13   0.00%        100   0.00%        360   0.00%
builtin:tree                  696   0.04%        695   0.01%       3129   0.06%     106152   0.03%     168732   0.03%
cas.o:block                207053  11.79%    1257516  22.18%          0   0.00%  152728297  39.58%  152728297  30.59%
cas.o:compile-unit           2422   0.14%       2434   0.04%    5666779  99.94%   77916660  20.19%  191252240  38.30%
cas.o:section              487438  27.76%    1838330  32.42%          0   0.00%   56810704  14.72%   56810704  11.38%
cas.o:symbol              1058200  60.27%    2568511  45.30%          0   0.00%   98344826  25.48%   98344826  19.70%
TOTAL                     1755817 100.00%    5669921 100.00%    5669921 100.00%  385906760 100.00%  499305180 100.00%

I currently have no artifacts generated to benchmark -fno-function-sections.

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.

2 participants