Local variables get assigned global addresses based upon call tree
This sounds similar to register allocation.  Normally, register allocation is done at the scope of a single function, but it can also be done globally (interprocedurally).  If you ignore all recursive and mutually recursive calls, you might be able to apply standard algorithms for register allocation to your situation.