-
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
gccgo: cmd/internal/obj/x86 takes a long time to compile #46600
Comments
Compiling cmd/compile/internal/ssa also takes about 90 seconds. More understandable since ssa is a large package with a lot of code, but mentioning in case there's anything to do about it too. |
I can reproduce this on tip, more or less. On my machine the "bootstrap/cmd/internal/obj/x86" build takes about 257 seconds at "-O2" and 450 seconds at "-O1". The offending pass appears to be variable_tracking; looks like the time is being spent in alias analysis / memory disambiguation. Attaching a couple of profiles. |
As an experiment, I carved off the file avx_optabs.go from the package and put it into its own stand-alone module. The new package takes about 3 minutes to compile at -O1 and 1.5 minutes at -O2. I also did a bit of experimenting with GCC to see if this is a regression or whether the problem has been around for a while. Turns out that this behavior has been there for a good long while. I tested (using release branches) gcc-8, gcc-9, gcc-10, and gcc-11, and I'm seeing long compile times for all of them (gcc-11 is maybe 5 or 10 percent faster, but that's it). So I don't think this is a situation where we can bisect it to a specific GCC commit. |
I filed an upstream GCC bug for this: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101064 |
@thanm Thanks for investigating and filing the GCC issue. Do you see any non-invasive tweaks we could make to the cmd/internal/obj/x86 sources to mitigate this issue and get better compile times under gccgo? E.g., could we break up the variable initializers into explicit initialization functions or something? |
Change https://golang.org/cl/331513 mentions this issue: |
I was going to suggest breaking out avx_optabs into a separate package (I prototyped that to see if if would work), which would help reduce the critical path. Looks like Ian has sent a gofrontend change however. |
For a composite literal we only need to introduce a temporary variable if we may be converting to an interface type, so only do it then. This saves over 80% of compilation time when using gccgo to compile cmd/internal/obj/x86, as the GCC middle-end spends a lot of time pointlessly computing interactions between temporary variables. For golang/go#46600 Change-Id: I6f01a3c84762b9d06268c5304af6ffce14a0a031 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/331513 Trust: Ian Lance Taylor <iant@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: Than McIntosh <thanm@google.com>
For a composite literal we only need to introduce a temporary variable if we may be converting to an interface type, so only do it then. This saves over 80% of compilation time when using gccgo to compile cmd/internal/obj/x86, as the GCC middle-end spends a lot of time pointlessly computing interactions between temporary variables. For PR debug/101064 For golang/go#46600 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/331513
For a composite literal we only need to introduce a temporary variable if we may be converting to an interface type, so only do it then. This saves over 80% of compilation time when using gccgo to compile cmd/internal/obj/x86, as the GCC middle-end spends a lot of time pointlessly computing interactions between temporary variables. For PR debug/101064 For golang/go#46600 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/331513
I've committed GCC patches to make this significantly faster on GCC mainline and GCC 11 branch. However, it will of course take a while for these fixes to move through the GCC release process and the distro release process. I don't know that we really want to change the generated code merely to make gccgo builds faster. But if we do, I think that compile time would be shorter if we avoid a large composite literal and instead set each element separately, as in avxOptab[0] = Optab{as: AANDNL, ytab: _yandnl, prefix: Pavx, op: opBytes{
avxEscape | vex128 | vex0F38 | vexW0, 0xF2,
}}
avxOptab[1] = Optab{{as: AANDNQ, ytab: _yandnl, prefix: Pavx, op: opBytes{
avxEscape | vex128 | vex0F38 | vexW1, 0xF2,
}}
... (but I haven't actually tried it). |
Thanks!
Yeah, that seems too invasive to be worth the trouble. I assume the issue will go away in ~6 months when I upgrade to Fedora 35 and get the new GCC. I'm happy to consider this issue fixed, unless you have more gccgo changes in mind. |
Nothing else planned, so closing. |
Fedora on amd64 uses gccgo as the default Go implementation installed to /usr, and using this to bootstrap the gc implementation takes a very long time due to compiling cmd/internal/obj/x86:
/cc @ianlancetaylor
The text was updated successfully, but these errors were encountered: