Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cranelift: implement omitting frame pointers (where permissible). #2073

Open
peterhuene opened this issue Jul 27, 2020 · 8 comments
Open

Cranelift: implement omitting frame pointers (where permissible). #2073

peterhuene opened this issue Jul 27, 2020 · 8 comments
Labels
cranelift Issues related to the Cranelift code generator enhancement

Comments

@peterhuene
Copy link
Member

peterhuene commented Jul 27, 2020

Feature

When permitted by the ABI and optimization goals, implement omitting frame pointers in Cranelift and add an option for forcing the establishment of frame pointers.

Benefit

Some supported ABIs do not need a frame pointer for debugging or unwinding purposes. Moderns compilers that target such ABIs tend to omit the frame pointer by default or when doing so is permissible (e.g. based on an optimization goal).

Omitting the frame pointer might free up an additional general purpose register to use (e.g. RBP for x86-64). It may also lead to more compact and efficient code depending on the function.

See #1149 and #1105 for some other discussions around this issue.

Implementation

As frame pointers might be useful to some third-party tools, add a Cranelift compiler option for forcing the use of frame pointers in prologues/epilogues (an analogue to -fno-omit-frame-pointer). It should default to false. For ABIs where a frame pointer is required, this option will have no effect.

For ABIs where it is permissible to do so, respect the option not being present by omitting the establishment of the frame pointer in the prologue and also the restoring the previous frame pointer in the epilogue.

Note that, depending on the offsets used relative to a frame pointer vs. the stack pointer, omitting a frame pointer might impact code size by forcing encodings of larger offsets relative to the stack pointer. Ultimately whether or not a frame pointer is omitted should be based on the impact to the desired optimization goals. Currently in Cranelift, some ABIs, like Windows and SystemV for x86-64, always establish a frame pointer but are addressing the stack relative to the stack pointer, so omitting the frame pointer won't have any negative impact on code generation size.

Also note that for certain ABIs, dynamic stack allocations (e.g. alloca) may require a "frame pointer" register to denote the base address of the static part of the frame as if it were the stack pointer prior to the first dynamic stack pointer adjustment. Locals and arguments could be addressed as a positive relative offset from this frame pointer register. Windows x64, for example, calls this a frame pointer for the purposes of unwinding.

Alternatives

The alternative is to do what Cranelift does now which is to always establish a frame pointer, which may lead to less efficient code or otherwise unnecessary instructions for every compiled function.

@peterhuene peterhuene added the cranelift Issues related to the Cranelift code generator label Jul 27, 2020
@github-actions
Copy link

Subscribe to Label Action

cc @bnjbvr

This issue or pull request has been labeled: "cranelift"

Thus the following users have been cc'd because of the following labels:

  • bnjbvr: cranelift

To subscribe or unsubscribe from this label, edit the .github/subscribe-to-label.json configuration file.

Learn more.

@xmartinez
Copy link

As frame pointers might be useful to some third-party tools, add a Cranelift compiler option for forcing the use of frame pointers in prologues/epilogues (an analogue to -fno-omit-frame-pointer). It should default to false.

Could this default to true, instead? I.e., could the compiler use frame pointers unless explicitly asked not to? (At least in Linux targets that are not register-starved, e.g., x86-64).

As already mentioned by @bjorn3 (#1105 (comment)), some tools such as Linux perf and bpftrace rely or can benefit from frame pointers for efficient user-space stack walking. These tools can be used to profile unmodified binaries.

Omitting frame pointers by default will decrease the out-of-the-box usefulness of these tools (as getting proper stack traces might require a recompilation of the traced binaries and its dependencies).

@peterhuene
Copy link
Member Author

I'm fine with the default in Cranelift being true, but I think Wasmtime should set such an option to false by default, possibly turning it to true for debug code generation.

@yurydelendik
Copy link
Contributor

FWIW if stack unwinding implemented right it is possible to still support backtrace/unwinding type of scenarios.

@bjorn3
Copy link
Contributor

bjorn3 commented Nov 2, 2020

DWARF based unwinding results in much larger perf profiles as it needs to copy a big chunk of the stack for offline unwinding. The amount of stack copied is fixed with the max configurable soze being 50kb. If the stack is deeper, frames will be missing from the backtrace
In addition it takes much longer to process the profiles when using DWARF unwinding.

@jameysharp
Copy link
Contributor

I think this was addressed by #4469 so I'm going to close it. If I've missed something, feel free to re-open!

@bjorn3
Copy link
Contributor

bjorn3 commented May 25, 2023

On x86_64 we still unconditionally preserve the frame pointer even if the option is set to allow omitting them.

@fitzgen fitzgen reopened this May 30, 2023
@fitzgen
Copy link
Member

fitzgen commented May 30, 2023

Yeah this isn't fully implemented yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cranelift Issues related to the Cranelift code generator enhancement
Development

No branches or pull requests

7 participants