In the case that there is only one call of a function with internal linkage,This patch concerns chains of calls like so:
Suppose foo has internal linkage. Also let's say that the call to foo within wibble is the only call to foo within the module.
Normally, the inlining cost model will apply a large bonus to ensure that foo is inlined into wibble because there's basically no cost in doing so. However, if wibble is unreachable-terminated, this won't happen. This is because the cost model currently does the following:
1. Check if the block containing the call is unreachable-terminated (allowSizeGrowth)
2. it can still be beneficial to inline functions that are unreachable-terminated (for exampleIf it is, the attached testcase)set the threshold to 0 and return
This happens before the bonus is applied. If we didn't have the check for allowSizeGrowthTherefore, this would be inlined as expectany "zero-cost" case relying on the bonus won't ever be inlined when we're dealing with unreachable-terminated blocks.
- Removes the early return when allowSizeGrowth is false
- Wraps the threshold tweaks in a conditional which is true only when size growth is allowed.
Since we want to only inline things if they have **at most 0 cost upon the call to allowSizeGrowth**, this commit wraps the tweaks to the threshold in a check for whether or not allowSizeGrowth is true.The tweaks are wrapped in a conditional to reflect that we only want to inline when the cost of inlining is truly 0 or better; Thus,any modifications to the threshold would break this assertion. we only end up inlining when the cost is 0 or better when allowSizeGrowth(CS) is trueThe early return is removed to facilitate inlining the example case.
This produced some minor code size improvements for ARM, AArch64, and x86-64 at Oz.
Output from compare.py here for Oz: https://hastebin.com/fojuquzoru.erl
//Edit: More clarity. The word salad from before wasn't that great.//