You want function inlining, and most (optimizing) compilers are doing that.
I am a bit focusing on functional programming style, since you tagged your qestion as such.
Notice that you don't need to have any call stack (at least in the machine sense of the "call stack" expression). You could use only the heap (then you need an efficient garbage collector).
So, take a look at continuations and read more about continuation passing style (CPS) and CPS transformation. (intuitively, you could use continuation closures as reified "call frames" allocated in the heap, and they are sort-of mimicking a call stack). Then you need an efficient garbage collector.
Andrew Appel wrote a book Compiling with Continuations and an old paper garbage collection can be faster than stack allocation. See also A.Kennedy's paper (ICFP2007) Compiling with Continuations, Continued
I also recommend reading Queinnec's Lisp In Small Pieces book, which has several chapters related to continuation & compilation.
Notice also that some languages (e.g. Brainfuck) or abstract machines (e.g. OISC, RAM) don't have any calling facilities but are still Turing-complete, so you don't (in theory) even need any function call mechanism, even if it is extremely convenient. BTW, some old instruction set architectures (e.g. IBM/370) don't even have a hardware call stack, or a pushing call machine instruction (the IBM/370 had only a Branch and Link machine instruction)
At last, if your entire program (including all the needed libraries) does not have any recursion you could store the return address (and the "local" variables, which are actually static) of each function in static locations. Old Fortran77 compilers did that.