Investigate if it would be worthwhile to change ghc's calling convention for architectures with higher register counts.
Currently across various backends the most integer/float arguments we will pass in registers is 6 as far as I know. The rest of the arguments will be passed on the stack.
The Problem
As I see it at this point:
- Since tail calls require all live values to be saved to the stack anyway there is little benefit to having callee saved registers.
- For some backends the vast majority of registers are currently unused during tail calls, but could be used for more efficient calls when calling functions with high arity.
However perhaps the bang isn't worth the bag when it comes to making this change:
- Functions of high arity are generally also large. This means the call overhead is a negligible fraction of the runtime for such functions in general.
- The called function might perform another tail call before using the passed argument, resulting in the value being spilled to the stack anyway.
- It's likely surprisingly tricky to actually change this, last but not least as it will likely require upstream llvm support. So the gains would need to be decent to make this worthwhile.
Proposed Change
Measure the potention impact of such a change, and estimate potential impact before making any change.
One relatively simple way to measure potential impact is:
- Use ticky-ticky to create a profile of a application, this comes with a list of functions, how often they were called and their arity.
- Estimate the best-case benefits of passing arguments in registers for function with arity of 6+
- Run the application under perf, measure the runtime and estimate a best-case improvement from this change.
It used to be the case that high-arity functions were pretty rare (See the push/enter vs eval/apply paper). But as time went on GHC became far more aggressive about W/W which likely increased average arity.
I'm not convinced the potential benefit from this will be worth the effort to implement this change. But it's something that's hard to estimate and it would be quite good to have concrete data on this.