Based on Minimizing Register Usage Penalty at Procedure Calls - Fred C. Chow, this is an implementation of a shrink-wrapping algorithm supporting multiple save / restore blocks.
The algorithm is meant to provide a shrink-wrapping interface to any kind of input. We can think of callee-saved registers, stack usage, life_range markers, etc. as input data, and run the shrink-wrapper in order to find the most efficient save / restore points.
The ShrinkWrapInfo class is meant to be subclassed by the users of this algorithm, in order to provide more details.
- Loops are handled using scc_iterators in order to handle irreducible loops and avoid placing any save / restore instruction inside a loop.
- Uses on no-return paths will be ignored and won't affect the final save / restore points.
- A "shrink-wrapping cost" is used to determine if the final placement is better than the default one (entry block, return blocks). This cost is nothing more than NumberOfSavesAndRestores * BlockFrequency * 100.
- There is a verifier running only when EXPENSIVE_CHECKS is on, checking that all the paths are correctly handled, that there are no saves without restores, no restores without saves, and no nested saves of the same element.
This is a high-level algorithm, without any target-specific implementation.
Since the MarkAsUsed lambda is always called with 3 parameters, there is no need to specify a default value for this lambda parameter.