Code Size: Pass large loadable types by address instead of by value - Updated Version #9142
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
radar rdar://problem/28680453
This is an updated version of #8909
It addresses the code review comments and splits the PR into multiple commits
Reduce the size of the text area (code size of the compiled output) by changing the way we generate LLVM IR for loadable types:
We do a SIL level transformation, during IRGen, that, from a bird's eye view, does the following:
For every every function that takes as an input a big type, re-write it to take a pointer to a big type instead.
: $@convention(method) (BigStruct)
turns into$@convention(method) (@in_constant BigStruct)
There are a few new SIL pieces to support this:
@in_constant
calling conventionretain_value_addr
andrelease_value_addr
SIL instructions that take as an input an address, load the value inside it and callretain_value
andrelease_value
respectivelyPlease note:
alloc_stack
instructions and, in some cases,load
of the function arguments to make this work. The current implementation, while it has some peephole optimizations for the most painful cases, is still very conservative: we can update this in the future, further reducing the code size$BigType
, and now takes$*BigType
, there are cases wherein we create newalloc_stack
andstore
instructions in order to call said function. Just like the point made above - the current implementation is very conservative / can be further optimized. this will be done in phasesThe radar mentioned in this PR contains a test program called BigTypeProg: This program contains a big struct with some loadable types + a class / need for retain and release. Passes it around to different functions that access the struct.
Under -Onone we have 3X binary size reduction, under -O a 2X binary size reduction. The text area is reduced by around 84% and 65% respectively.