Preprocess PGO profiles in a separate action
rules_go passes the pprof profile to the compiler as
-gcflags=all=-pgoprofile=<raw>, which bypasses the preprocessing the go
command does for its own -pgo flag. Every compiler invocation therefore
parses the profile and builds the PGO call graph from scratch: GoStdlib
runs one compiler per CPU within a single action, and every GoCompilePkg
action repeats the work. For a large profile this dominates peak memory,
with GoStdlib alone reaching tens of GB on a many-core machine.
Convert the profile once with "go tool preprofile" and hand the result to
every compile action instead. The action is created in go_config, the
single point where both the pgoprofile attribute and the
//go/config:pgoprofile flag are resolved, so GoStdlib and GoCompilePkg
pick it up through go.mode.pgoprofile unchanged.
A profile that the user converted ahead of time is passed through as is,
as "go tool preprofile" fails on its own output. Only the "GO PREPROFILE "
prefix of the header is matched so that a profile converted by a newer
toolchain is still recognized. "go tool preprofile" was added in Go 1.23;
older SDKs keep receiving the raw profile.
7 files changed