cmd/compile: use staticuint64s #37612
Comments
This may be a decent starter issue for someone wanting to work on the compiler. |
I'm not sure what this has to do with the compiler? It seems to be purely a runtime optimization - the linked CL doesn't touch cmd/compile at all. |
Look for |
Right. But now that we have For part one, grep the compiler for staticbytes and use staticuint64s instead. (The offset math will need to change a bit; see Keith's linked CL comment.) Then delete runtime.staticbytes. For part two, in places where we only optimize byte-sized things, we can probably now optimize constant larger-int-sized things. The sites will be the same sites encountered in part one. |
There are actually two more remaining uses of runtime.staticbytes, in |
Thanks! Those could also be converted, using similar arithmetic. |
Change https://golang.org/cl/221957 mentions this issue: |
I've sent a CL implementing the first part of the compiler change. I'll do the other two follow-ups later. |
There are still two places in src/runtime/string.go that use staticbytes, so we cannot delete it just yet. There is a new codegen test to verify that the index calculation is constant-folded, at least on amd64. ppc64, mips[64] and s390x cannot currently do that. There is also a new runtime benchmark to ensure that this does not slow down performance (tested against parent commit): name old time/op new time/op delta ConvT2EByteSized/bool-4 1.07ns ± 1% 1.07ns ± 1% ~ (p=0.060 n=14+15) ConvT2EByteSized/uint8-4 1.06ns ± 1% 1.07ns ± 1% ~ (p=0.095 n=14+15) Updates #37612 Change-Id: I5ec30738edaa48cda78dfab4a78e24a32fa7fd6a Reviewed-on: https://go-review.googlesource.com/c/go/+/221957 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Change https://golang.org/cl/221979 mentions this issue: |
This was the last remaining use of staticbytes, so we can now delete it. The new code appears slightly faster on amd64: name old time/op new time/op delta SliceByteToString/1-4 6.29ns ± 2% 5.89ns ± 1% -6.46% (p=0.000 n=14+14) This may not be the case on the big-endian architectures, since they have to do an extra addition. Updates #37612 Change-Id: Icb84c5911ba025f798de152849992a55be99e4f3 Reviewed-on: https://go-review.googlesource.com/c/go/+/221979 Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com> Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
I was trying to do the small int constant part, but by the time walkexpr runs, the OLITERAL has been replaced with an ONAME node for a temporary:
I can't figure out how to recover the value of the constant from that ONAME. |
You’ll probably need to make a companion change to order.go at the same time. I’m AFK for a little while. If that isn’t enough of a hint, let me know and I’ll expand on it when I am at a real keyboard. |
I tried narrowing the condition in the OCONVIFACE case of // Don't use a temporary for integer constants that fit in a byte; walk will replace
// them with pointers into runtime.staticuint64s.
if _, needsaddr := convFuncName(n.Left.Type, n.Type); (needsaddr || isStaticCompositeLiteral(n.Left)) && !(n.Left.CanInt64() && n.Left.Int64() >= 0 && n.Left.Int64() < 256) { That almost works, but I get a couple of test failures, which seem directly relevant to this code:
I've had a look at the code in order.go and sinit.go that handles composite literals, but I'm having a hard time following what's going on, so I'm stuck. |
Please post your changes in a CL so I can take a look. Thanks. I’m still AFK, and due to coronavirus school closures, it is unclear when I will next have meaningful laptop time. But I will look as best as I can, next opportunity I get. |
I wonder—have you checked what code we generate right now for this case? I wonder whether we have enough existing optimizations at tip (probably not 1.14) to already optimally handle the case of a small constant int. (There’s an entirely separate question of handling an int that is non-constant but whose unsigned equivalent provably fits in one byte. That we definitely don’t handle well now. But I don’t think that that is what you were looking at, either.) |
Change https://golang.org/cl/223358 mentions this issue: |
Currently (both 1.14 and tip) we generate a static global with the constant's value and use a pointer to that, like we do for string literals:
This is optimal in execution time, but not in binary size: pointing into staticuint64s would allow us to elide these globals, saving 8 bytes each in the common case of int constants on 64-bit architectures. |
CL 216401 introduced a new static array of uint64s running from 0 to 255.
Two follow-ups here:
We should use it in the compiler instead of staticbytes for byte-sized values (see https://go-review.googlesource.com/c/go/+/216401/2/src/runtime/iface.go#531).
We should use it in the compiler for larger-sized ints whose value is a constant between 0 and 255.
The text was updated successfully, but these errors were encountered: