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