-
Notifications
You must be signed in to change notification settings - Fork 17.5k
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
proposal: cmd/compile: go:readonly
comment directive for body-less functions
#67364
Comments
AFAIK go directives are not part of the language spec (https://go.dev/ref/spec), it is an internal detail of the go compiler. Go directives are generally made available for use inside internal Go packages and not user facing code, although they ended up leaking out and lurking into many codebases causing some trouble (looking at you go:linkname). This proposal seems to aim in providing a general mechanism to optimize Go code, I'm not sure if a directive is the proper way to achieve that. |
@mauri870 |
This would be useful for functions with a body as well, and for those the compiler can check the read-only property. Although this is starting to feel like const in C.. |
@bjorndm this would be a different proposal, the compiler can already read body-full functions and recover the readonlyness of arguments passed in. |
Proposal Details
Add
go:readonly
comment directive for body-less functions indicating the following arguments and any pointers exclusively accessed through a readonly argument wont be modified:The point of this is to hook up with 925d2fb this would allow
[]byte(str)
conversions to be elided when the byte string is passed as a readonly argument to an assembly optimized subroutine.github.com/cespare/xxhash
implementsSum64String(string) uint64
and(*Digest).WriteString(string)
usingunsafe
which allows to skip the allocation either by using(*strings.Reader).WriteTo
orio.WriteString
.Other hashing libraries such as
crypto
do not implement this optimization, this could allow to implement this using compiler optimizations rather than duplicating APIs for[]byte
andstring
. (*note: this assume you are using a devirtualizedhash.Hash
or a concrete hasher implementation, which is now possible and not unrealistic, particularly forh := sha256.New(); h.Write([]byte(str))
patterns)In the future this could improve register allocation in some rare edge cases so I don't expect this to be implemented.
Other stronger compilers like GCC and LLVM might already implement such logic in their register allocators, then work in gofrontend could be much easier (as I assume this would amount to setting up metadata flags on the function call nodes passed to gcc or llvm) so who knows.
The body-less function is allowed to read from memory, which is arguably a side effect when using
-race
altho I don't think very many body-less functions implement any kind of race tracking.For slices the body-less function would assume to not be allowed to write past capacity.
If some memory is accessible through an unknown and a readonly pointer the function is allowed to write to it:
Here the compiler would be allowed to assume only the last 32 bytes of the
x
array are readonly (I expect compilers to not implement this or to assumex
maybe completely overwritten).If a pointer to a pointer is readonly then both memory are readonly:
Note: this apply transitively to any amount of level.
Combining the two edge cases above, if a pointer to a pointer is accessible both through unknown and readonly paths, the body-less function may modify it:
The body-less function is assumed to maybe write to anything part of the global scope:
The text was updated successfully, but these errors were encountered: