-
Notifications
You must be signed in to change notification settings - Fork 91
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
all: avoid clobbering BP register #156
Comments
ref mmcloughlin/avo#156 which contains links to other relevant refs
If during code generation, avo needs to use BP then it must be saved, which in turn requires at least 8 bytes in the stack.
|
Just to test the simple solution, I tried marking Therefore, I think the more nuanced solution is worth pursuing, specifically de-prioritizing |
For reference, the relevant parts of the assembler are:
|
First of all, thanks for avo, it has been useful and helped me make what formerly was a gigantic collection of For what it's worth, the way I am working around this problem for now is to use a nasty kludge involving reflection and unsafe to mark BP as restricted, since I know that I do not need to use While this case should be addressed by the allocator gaining a notion of priority, it would be nice for me to continue to take this general approach (preferably without unsafe/reflection). My current thinking is that in the event that I write something that actually needs every single register in the future after avo starts applying the non-zero frame size hack, I would prefer to handle allocating/saving/restoring rbp myself. Some minor questions regarding the "non-zero frame size" hack:
|
Currently `avo` uses `BP` as a standard general-purpose register. However, `BP` is used for the frame pointer and should be callee-save. Under some circumstances, the Go assembler will do this automatically, but not always. At the moment `avo` can produce code that clobbers the `BP` register. Since Go 1.16 this code will also fail a new `go vet` check. This PR provides a (currently sub-optimal) fix for the issue. It introduces an `EnsureBasePointerCalleeSaved` pass which will check if the base pointer is written to by a function, and if so will artificially ensure that the function has a non-zero frame size. This will trigger the Go assembler to automatically save and restore the BP register. In addition, we update the `asmdecl` tool to `asmvet`, which includes the `framepointer` vet check. Updates #156
I have landed #174 and #184 which should de-prioritize BP in register allocation, and apply the "frame size hack" if it must be used. I believe this fixes the immediate problem at hand, so I will close this issue, but that doesn't mean there's no more work to be done related to this. @Yawning Thanks for your comments. I think the answer to your questions is configurable "compilation options", which could be applied globally or per function. In this case, I could imagine two options: one that controls whether BP is available for allocation at all, and another to control whether |
See discussion on Slack and
golang-dev
https://gophers.slack.com/archives/C6WDZJ70S/p1598210629000900
https://groups.google.com/g/golang-dev/c/aLn9t8tKg2o/m/Kw-N7lUuBAAJ
Summary:
BP
should be callee-save (poorly documented, even some standard library assembly didn't handle this correctly until recently)BP
"will be saved automatically if there is a nonzero frame size" https://golang.org/cl/248260avo
needs to handle this somehow. Suggestions:BP
has been usedBP
in the register allocatorBP
? People can still use it directly as a physical register. https://gophers.slack.com/archives/C6WDZJ70S/p15982907240323000
stack frame and to useBP
, and they'll save it themselves. "maybe avo.NoClobberBp() ? avo.SavingBPMyselfPromise() ?" https://gophers.slack.com/archives/C6WDZJ70S/p1598290549031600The text was updated successfully, but these errors were encountered: