This is an open-ended performance idea to explore.
We have per-function compiler-specific export data (see method funcExt in iexport.go). We could do some analysis in package ssa of return values, add that to the export data, and use it on import. This might help with function calls that cannot be inlined.
For example, we could record whether a return value is known to be non-nil. Or a known limited range for a return value. Or a concrete type for a function that returns an interface.
Related: #25862. If we pursue this idea, the mechanism for using info about the return values could be re-used with some annotation for #25862. And possibly also to generalize and simplify the ssa rule "don't nilcheck the return value of newobject".
We could also return things like the ratio of Nodes to instructions, which we might want to use to improve downstream inlining decisions.
One weird thing about doing this is that calling functions from imported packages might optimize further than calling functions from within the same packages. (A similar problem arises for some of the ideas mooted in #17566.) Still probably worth exploring.
Would it be possible to also propagate stack usage (if known/constant), so that the caller can call morestack once (to ensure there's enough for both itself and the callees) and the callees can omit the morestack check/call?
@CAFxX That becomes possible when goroutine preemption can be done with signals. This is in the pipeline, and with luck will emerge in 1.12. This has some interaction with how the runtime/GC handles stack resizing -- if F calls G calls H, F is responsible for all their frames, if the GC ran during G and reduced the stack to what was adequate for G, a subsequent call to H might overrun the stack. So we'd need to work on some sort of a handshake or marker to prevent this.