Add functionality to be able to inline recursive functions. Both direct and indirect (mutual) recursion are considered for inlining. The default behavior is still not to inline, but this can be changed by setting flag -max-recursion-inline to a value higher than 0.
This is intended as a previous step to optimized recursion inlining. Therefore, the heuristics are not tuned up for performance, and recursion inlining is not part of -Ox optimizations.
The patch slightly changes -O3 behavior. Inlining recursive functions into functions external to their SCC is allowed even if recursion inlining is not turned on (see regression test 2 below). Before, it was considered part of the recursion and therefore was marked as "never" inline. This change has been tested for correctness and performance with several benchmarks (LLVM test-suite included) and on two platforms, one aarch64 and one x86.
SUMMARY OF CHANGES:
"IsRecursiveCall" checks are removed in the inline cost calculator. The only inline recursion checks are now done in the Inliner with the help of function InlineHistoryIncludes(). That function now allows skipping part of the inline history (the recursion levels) to allow functions to be inlined into themselves or into members of their SCC.
Regression tests for recursion inlining:
- Add checks for a function that calls itself (direct recursion) and for a SCC of size 2 (indirect recursion).
- Removed a test checking that, if A is recursive and called by B, A is never inlined into B. Note that B is not necessarily part of A's SCC. Now, the calls to A from callers external to A's SCC are treated as any other function call.
- Removed triple from a previous unit test, and added comments.
The continuation line can now fit on one line.