Fix Linux/x86 call alignment calculation and insertion (dotnet/coreclr#10266)
* Fix Linux/x86 call alignment calculation and insertion
The existing system of calculating per-call alignment adjustments
did not consider the possibility of nested calls. On x86, some
arguments for a call might be pushed on the stack before a
nested call's arguments start being pushed. Thus, a call can't
consider only its own arguments when determining the stack level.
Instead, use the existing genStackLevel variable, updated
dynamically during code generation, to determine the baseline
stack alignment when a call first needs to push something on
the stack, or if it has no stack arguments, whether it needs to
align the stack before a call.
One wrinkle here is that the fgAddCodeRef() function for adding
throw blocks for array bounds checks, and other similar helpers,
need to know the stack level on entry, and this stack level is
computed during argument morphing. There is a tough phase ordering
problem here. So, we bail out and force an EBP frame if there are
any such throw helpers in the function. When using an EBP frame,
the helper block doesn't need to know the stack level -- it is
only needed for ESP frames, needed for unwinding. Note that this
bail out already existed if the same helper needed multiple different
stack levels on entry. We could do slightly better without too much
work by not bailing out for top-level calls with no stack arguments.
* Track max alignment added for nested calls during codegen
This information is needed by Linux/x86 for an assert about
maximum emitter stack depth.
* Make max stack align tracking available in release as well
The assert these are used in is a noway_assert.
* Formatting
Commit migrated from https://github.com/dotnet/coreclr/commit/
68012bf209f37ab5b5b11a02b203f2949d1ef8dc