-
Notifications
You must be signed in to change notification settings - Fork 18k
cmd/compile: weird double-jump in code generation #15090
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
Comments
/cc @randall77 |
Amateur response: The JMP at cd9 goes to cf8, which JMPs at cff to cdb. So all the jumps are used, and that's OK. Is this compiler output or final generated code, because I would have expected the linker to do some branch folding if this is the final output. I believe the TESTLs are nil checks introduced by the compiler as guarantees that indirections through nil pointers cannot be used to access random memory. The "register spill" is putting a value back on the stack. It may be unnecessary but it's hard to tell from this incomplete fragment. To me, this all looks pretty normal. |
(this is not a bug report, but a missing optimization issue, for future consideration) The code shown is the final, complete code of The jumps are all used but they are inefficient compared to the minimal possible output. The TESTL might be residual of removed nil-checks (as the flags set by those tests are not checked afterwards), but if so, they should removed as well. The register spill is in fact used later on at 0x4096cea, but there are a dozen of registers available so there's really no reason for spilling to the stack. |
I may be wrong but I'm pretty sure the TESTL remains there for the side effect of validating the struct's base address before indirecting through to the field. That is the nil check. I am surprised that the linker didn't fold the branches. |
-Correction-:
|
Sorry if I'm dense (I'm often confused by the ASM syntax you use, I'm used to a different syntax). TESTL just sets the flags; who's checking for those flags? Who's handling the result of such nilcheck? I don't see this happening in the above code. |
|
Thanks for clarifying, I didn't know nilchecks relied on page faults. Makes sense now. |
I stand corrected, again:
was not the cause of this. It's just the lack for merging consecutive if's on the same variable. This is probably a common case where we would benefit from merging consecutive if's. |
Loop hoisting, we could do. I got as far as writing the detector, measured hits, decided that there weren't enough to get that excited. But I could revive that, if people are interested. Algorithm was:
Only thing remaining is to move those into the predecessor of the loop header (assuming after critical edges eliminated). Note that this increases register pressure, so you might want a heuristic on loop size. |
On "merging consecutive ifs", see also #12628. |
CL https://golang.org/cl/28191 mentions this issue. |
@randall77 the CL has been forgotten. Do you plan to submit it? |
Yes, I just need to ping a reviewer. It will get in for 1.8. |
var x uint64 uint8(x >> 56) We don't need to generate any code for the uint8(). Update #15090 Change-Id: Ie1ca4e32022dccf7f7bc42d531a285521fb67872 Reviewed-on: https://go-review.googlesource.com/28191 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com>
Please answer these questions before submitting your issue. Thanks!
go version
)?go version devel +ac8d97b Sat Apr 2 12:38:00 2016 +0000 darwin/amd64
Final generated code for
(*radixTree).Search
, as dumped bygo tool objdump
:I see the following issues:
unused test at 0x4096ca9(it is a nilcheck)The text was updated successfully, but these errors were encountered: