cmd/dist: don't compile unneeded GOARCH SSA rewrite rules during bootstrap
Speeds up build (the bootstrap phase) by ~6 seconds.
Bootstrap goes from ~18 seconds to ~12 seconds.
Change-Id: I7e2ec8f5fc668bf6168d90098eaf70390b16e479
Reviewed-on: https://go-review.googlesource.com/40503
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
diff --git a/src/cmd/dist/buildtool.go b/src/cmd/dist/buildtool.go
index 015ee91..cedd414 100644
--- a/src/cmd/dist/buildtool.go
+++ b/src/cmd/dist/buildtool.go
@@ -12,7 +12,10 @@
package main
import (
+ "fmt"
"os"
+ "path/filepath"
+ "runtime"
"strings"
)
@@ -123,9 +126,10 @@
}
}
srcFile := pathf("%s/%s", src, name)
+ dstFile := pathf("%s/%s", dst, name)
text := readfile(srcFile)
- text = bootstrapFixImports(text, srcFile)
- writefile(text, pathf("%s/%s", dst, name), 0)
+ text = bootstrapRewriteFile(text, srcFile)
+ writefile(text, dstFile, 0)
}
}
@@ -158,7 +162,18 @@
// https://groups.google.com/d/msg/golang-dev/Ss7mCKsvk8w/Gsq7VYI0AwAJ
// Use the math_big_pure_go build tag to disable the assembly in math/big
// which may contain unsupported instructions.
- run(workspace, ShowOutput|CheckExit, pathf("%s/bin/go", goroot_bootstrap), "install", "-gcflags=-l", "-tags=math_big_pure_go", "-v", "bootstrap/cmd/...")
+ cmd := []string{
+ pathf("%s/bin/go", goroot_bootstrap),
+ "install",
+ "-gcflags=-l",
+ "-tags=math_big_pure_go",
+ "-v",
+ }
+ if tool := os.Getenv("GOBOOTSTRAP_TOOLEXEC"); tool != "" {
+ cmd = append(cmd, "-toolexec="+tool)
+ }
+ cmd = append(cmd, "bootstrap/cmd/...")
+ run(workspace, ShowOutput|CheckExit, cmd...)
// Copy binaries into tool binary directory.
for _, name := range bootstrapDirs {
@@ -174,6 +189,53 @@
xprintf("\n")
}
+var ssaRewriteFileSubstring = filepath.ToSlash("src/cmd/compile/internal/ssa/rewrite")
+
+// isUnneededSSARewriteFile reports whether srcFile is a
+// src/cmd/compile/internal/ssa/rewriteARCHNAME.go file for an
+// architecture that isn't for the current runtime.GOARCH.
+//
+// When unneeded is true archCaps is the rewrite base filename without
+// the "rewrite" prefix or ".go" suffix: AMD64, 386, ARM, ARM64, etc.
+func isUnneededSSARewriteFile(srcFile string) (archCaps string, unneeded bool) {
+ if !strings.Contains(srcFile, ssaRewriteFileSubstring) {
+ return "", false
+ }
+ fileArch := strings.TrimSuffix(strings.TrimPrefix(filepath.Base(srcFile), "rewrite"), ".go")
+ if fileArch == "" {
+ return "", false
+ }
+ b := fileArch[0]
+ if b == '_' || ('a' <= b && b <= 'z') {
+ return "", false
+ }
+ archCaps = fileArch
+ fileArch = strings.ToLower(fileArch)
+ if fileArch == strings.TrimSuffix(runtime.GOARCH, "le") {
+ return "", false
+ }
+ if fileArch == strings.TrimSuffix(os.Getenv("GOARCH"), "le") {
+ return "", false
+ }
+ return archCaps, true
+}
+
+func bootstrapRewriteFile(text, srcFile string) string {
+ // During bootstrap, generate dummy rewrite files for
+ // irrelevant architectures. We only need to build a bootstrap
+ // binary that works for the current runtime.GOARCH.
+ // This saves 6+ seconds of bootstrap.
+ if archCaps, ok := isUnneededSSARewriteFile(srcFile); ok {
+ return fmt.Sprintf(`package ssa
+
+func rewriteValue%s(v *Value) bool { panic("unused during bootstrap") }
+func rewriteBlock%s(b *Block) bool { panic("unused during bootstrap") }
+`, archCaps, archCaps)
+ }
+
+ return bootstrapFixImports(text, srcFile)
+}
+
func bootstrapFixImports(text, srcFile string) string {
lines := strings.SplitAfter(text, "\n")
inBlock := false