-
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
cmd/link: there should be a way to determine why deadcode elimination was not performed #60221
Comments
As an end user with little knowledge of how the linker works, I think it would be useful to only get basic high-level information, like:
Essentially, allowing me to look at a 20MiB Go binary, and see how much effort it would be to re-enable dead code elimination, perhaps shaving off two or three megabytes. Debug outputs like call graphs can always be helpful, but they're quite verbose and require knowledge of linker internals to understand them. For example, is it only |
@mvdan: Serious answer: if there was a linker flag we could use that did something like my patch (or to print a reachability graph with all the necessary information) the rest of the gap could be filled by blog posts/conference talks/community supported tools/etc. Joke answer: deadcode elimination is disabled because you are using cobra. |
Just for the record, the reachability of My recollection of the meeting we talked about the linker's With that said, it does seem like it would be nice to have a more user-friendly option that would give reliable info in this realm. |
cc @golang/compiler |
Yes,
If there is anything useful but missing from |
I think what's missing is a way to print which symobls have the ReflectMethod flag set. |
Change https://go.dev/cl/495715 mentions this issue: |
@aarzilli just gave a talk at https://golab.io on this topic, and mentioned this new tool of his: https://github.com/aarzilli/whydeadcode |
In the compiler/runtime office hours of January the problem of determining why deadcode elimination is not performed by the linker was brought up (by Daniel Martí @mvdan) and the
-c
option of the linker was offered as a solution, however it does not work for two reason: (1) it prints a call graph, not a reachability graph and (2) a reachability graph wouldn't be enough to determine why deadcode elimination was disabled anyway.To put it in more practical terms:
In this example deadcode elimination is disabled but you won't find any path to reflect.Value.MethodByName in the call graph
The call graph is printed after deadcode elimination does (not) run. When it contains a call path starting in a public method and ending on reflect.Value.MethodByName it's impossible to tell whether the public method at the start of the path would be reachable (were it not for deadcode elimination being disabled) or not. Example where it is reachable and example where it isn't.
If deadcode elimination is disabled by reflect.Type.Method it won't show up in the call graph, and deadcode elimination seems to use a symbol attribute to determine this (IsReflectMethod call in deadcodePass.flood), example of this.
There are several possible ways to do this, I patched the linker to hijack the
-k
option, which I do not advocate for but it shows that 90% of the work for this feature already exists in the linker.Related #6853
The text was updated successfully, but these errors were encountered: