From: Michael Pratt Date: Thu, 29 Feb 2024 20:15:44 +0000 (-0500) Subject: cmd/go: preprocess PGO profiles X-Git-Tag: go1.23rc1~592 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=081dc9fd8c9cf824f5caac3a03a1c8dfd86894c0;p=gostls13.git cmd/go: preprocess PGO profiles Following the previous CL, now actually run the preprofile tool to create the preprocessed output. There is still no build cache integration, so the tool will run on every build even if nothing has changed. For #58102. Cq-Include-Trybots: luci.golang.try:gotip-linux-amd64-longtest Change-Id: I0414377a956889f457e50898737fcaa8a698658d Reviewed-on: https://go-review.googlesource.com/c/go/+/569424 Auto-Submit: Michael Pratt LUCI-TryBot-Result: Go LUCI Reviewed-by: Cherry Mui --- diff --git a/src/cmd/dist/build.go b/src/cmd/dist/build.go index 64f8f53054..99f517e758 100644 --- a/src/cmd/dist/build.go +++ b/src/cmd/dist/build.go @@ -1354,7 +1354,7 @@ func toolenv() []string { return env } -var toolchain = []string{"cmd/asm", "cmd/cgo", "cmd/compile", "cmd/link"} +var toolchain = []string{"cmd/asm", "cmd/cgo", "cmd/compile", "cmd/link", "cmd/preprofile"} // The bootstrap command runs a build from scratch, // stopping at having installed the go_bootstrap command. diff --git a/src/cmd/go/internal/work/action.go b/src/cmd/go/internal/work/action.go index c4cee8947c..249c802269 100644 --- a/src/cmd/go/internal/work/action.go +++ b/src/cmd/go/internal/work/action.go @@ -476,12 +476,7 @@ func (p *pgoActor) Act(b *Builder, ctx context.Context, a *Action) error { return err } - // TODO(prattmic): This should use go tool preprofile to actually - // preprocess the profile. For now, this is a dummy implementation that - // simply copies the input to the output. This is technically a valid - // implementation because go tool compile -pgofile accepts either a - // pprof file or preprocessed file. - if err := sh.CopyFile(a.Target, p.input, 0644, false); err != nil { + if err := sh.run(".", p.input, nil, cfg.BuildToolexec, base.Tool("preprofile"), "-o", a.Target, "-i", p.input); err != nil { return err } diff --git a/src/cmd/go/testdata/script/build_pgo.txt b/src/cmd/go/testdata/script/build_pgo.txt index 48bba683c1..0ca2105f56 100644 --- a/src/cmd/go/testdata/script/build_pgo.txt +++ b/src/cmd/go/testdata/script/build_pgo.txt @@ -9,7 +9,7 @@ go build triv.go # build with PGO, should trigger rebuild # starting with an empty profile (the compiler accepts it) go build -x -pgo=prof -o triv.exe triv.go -stderr 'cp.*prof' # preprocess PGO profile +stderr 'preprofile.*-i.*prof' stderr 'compile.*-pgoprofile=.*triv.go' # check that PGO appears in build info @@ -36,7 +36,7 @@ go run overwrite.go # build again, profile content changed, should trigger rebuild, including std go build -n -pgo=prof triv.go -stderr 'cp.*prof' # preprocess PGO profile +stderr 'preprofile.*-i.*prof' stderr 'compile.*-pgoprofile=.*triv.go' stderr 'compile.*-p runtime.*-pgoprofile=.*' @@ -61,6 +61,7 @@ package main import ( "os" "runtime/pprof" + "time" ) func main() { @@ -72,6 +73,10 @@ func main() { if err != nil { panic(err) } + // Spin to ensure we get some samples. If we get no samples, the result + // is equivalent to an empty profile. + start := time.Now() + for time.Since(start) < 100*time.Millisecond {} pprof.StopCPUProfile() f.Close() } diff --git a/src/cmd/go/testdata/script/build_pgo_auto.txt b/src/cmd/go/testdata/script/build_pgo_auto.txt index aebf83d224..1ae86d4e57 100644 --- a/src/cmd/go/testdata/script/build_pgo_auto.txt +++ b/src/cmd/go/testdata/script/build_pgo_auto.txt @@ -4,7 +4,7 @@ # use default.pgo for a single main package go build -n -pgo=auto -o a1.exe ./a/a1 -stderr 'cp.*default\.pgo' # preprocess PGO profile +stderr 'preprofile.*-i.*default\.pgo' stderr 'compile.*-pgoprofile=.*a1.go' # check that pgo applied to dependencies diff --git a/src/cmd/go/testdata/script/build_pgo_auto_multi.txt b/src/cmd/go/testdata/script/build_pgo_auto_multi.txt index 88cc49d421..509edb0230 100644 --- a/src/cmd/go/testdata/script/build_pgo_auto_multi.txt +++ b/src/cmd/go/testdata/script/build_pgo_auto_multi.txt @@ -3,8 +3,8 @@ go install -a -n -pgo=auto ./a ./b ./nopgo # a/default.pgo and b/default.pgo are both preprocessed -stderr 'cp.*a(/|\\)default\.pgo' -stderr 'cp.*b(/|\\)default\.pgo' +stderr 'preprofile.*-i.*a(/|\\\\)default\.pgo' +stderr 'preprofile.*-i.*b(/|\\\\)default\.pgo' # a and b built once each with PGO. # Ideally we would check that the passed profile is the expected profile (here