]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.simd] simd: make 'go generate' generate everything
authorAustin Clements <austin@google.com>
Tue, 18 Nov 2025 17:03:51 +0000 (12:03 -0500)
committerGopher Robot <gobot@golang.org>
Tue, 18 Nov 2025 23:13:48 +0000 (15:13 -0800)
The simd package involves quite a lot of code generation.
Currently, that's spread across a few different tools.
Bring the process together in simd/_gen/main.go and make
'go generate' in the simd package do the right thing.

Change-Id: Iba7e120987f13840a23ed32a528e2398fc7a6065
Reviewed-on: https://go-review.googlesource.com/c/go/+/721663
Reviewed-by: David Chase <drchase@google.com>
Auto-Submit: Austin Clements <austin@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/simd/_gen/main.go [new file with mode: 0644]
src/simd/generate.go [new file with mode: 0644]
src/simd/no_tag.go [deleted file]

diff --git a/src/simd/_gen/main.go b/src/simd/_gen/main.go
new file mode 100644 (file)
index 0000000..5061de7
--- /dev/null
@@ -0,0 +1,149 @@
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Run all SIMD-related code generators.
+package main
+
+import (
+       "flag"
+       "fmt"
+       "os"
+       "os/exec"
+       "path/filepath"
+       "strings"
+)
+
+const defaultXedPath = "$XEDPATH" + string(filepath.ListSeparator) + "./simdgen/xeddata" + string(filepath.ListSeparator) + "$HOME/xed/obj/dgen"
+
+var (
+       flagTmplgen = flag.Bool("tmplgen", true, "run tmplgen generator")
+       flagSimdgen = flag.Bool("simdgen", true, "run simdgen generator")
+
+       flagN       = flag.Bool("n", false, "dry run")
+       flagXedPath = flag.String("xedPath", defaultXedPath, "load XED datafile from `path`, which must be the XED obj/dgen directory")
+)
+
+var goRoot string
+
+func main() {
+       flag.Parse()
+       if flag.NArg() > 0 {
+               flag.Usage()
+               os.Exit(1)
+       }
+
+       if *flagXedPath == defaultXedPath {
+               // In general we want the shell to do variable expansion, but for the
+               // default value we don't get that, so do it ourselves.
+               *flagXedPath = os.ExpandEnv(defaultXedPath)
+       }
+
+       var err error
+       goRoot, err = resolveGOROOT()
+       if err != nil {
+               fmt.Fprintln(os.Stderr, err)
+               os.Exit(1)
+       }
+
+       if *flagTmplgen {
+               doTmplgen()
+       }
+       if *flagSimdgen {
+               doSimdgen()
+       }
+}
+
+func doTmplgen() {
+       goRun("-C", "tmplgen", ".")
+}
+
+func doSimdgen() {
+       xedPath, err := resolveXEDPath(*flagXedPath)
+       if err != nil {
+               fmt.Fprintln(os.Stderr, err)
+               os.Exit(1)
+       }
+
+       // Regenerate the XED-derived SIMD files
+       goRun("-C", "simdgen", ".", "-o", "godefs", "-goroot", goRoot, "-xedPath", prettyPath("./simdgen", xedPath), "go.yaml", "types.yaml", "categories.yaml")
+
+       // simdgen produces SSA rule files, so update the SSA files
+       goRun("-C", prettyPath(".", filepath.Join(goRoot, "src", "cmd", "compile", "internal", "ssa", "_gen")), ".")
+}
+
+func resolveXEDPath(pathList string) (xedPath string, err error) {
+       for _, path := range filepath.SplitList(pathList) {
+               if path == "" {
+                       // Probably an unknown shell variable. Ignore.
+                       continue
+               }
+               if _, err := os.Stat(filepath.Join(path, "all-dec-instructions.txt")); err == nil {
+                       return filepath.Abs(path)
+               }
+       }
+       return "", fmt.Errorf("set $XEDPATH or -xedPath to the XED obj/dgen directory")
+}
+
+func resolveGOROOT() (goRoot string, err error) {
+       cmd := exec.Command("go", "env", "GOROOT")
+       cmd.Stderr = os.Stderr
+       out, err := cmd.Output()
+       if err != nil {
+               return "", fmt.Errorf("%s: %s", cmd, err)
+       }
+       goRoot = strings.TrimSuffix(string(out), "\n")
+       return goRoot, nil
+}
+
+func goRun(args ...string) {
+       exe := filepath.Join(goRoot, "bin", "go")
+       cmd := exec.Command(exe, append([]string{"run"}, args...)...)
+       run(cmd)
+}
+
+func run(cmd *exec.Cmd) {
+       cmd.Stdout = os.Stdout
+       cmd.Stderr = os.Stderr
+       fmt.Fprintf(os.Stderr, "%s\n", cmdString(cmd))
+       if *flagN {
+               return
+       }
+       if err := cmd.Run(); err != nil {
+               fmt.Fprintf(os.Stderr, "%s failed: %s\n", cmd, err)
+       }
+}
+
+func prettyPath(base, path string) string {
+       base, err := filepath.Abs(base)
+       if err != nil {
+               return path
+       }
+       p, err := filepath.Rel(base, path)
+       if err != nil {
+               return path
+       }
+       return p
+}
+
+func cmdString(cmd *exec.Cmd) string {
+       // TODO: Shell quoting?
+       // TODO: Environment.
+
+       var buf strings.Builder
+
+       cmdPath, err := exec.LookPath(filepath.Base(cmd.Path))
+       if err == nil && cmdPath == cmd.Path {
+               cmdPath = filepath.Base(cmdPath)
+       } else {
+               cmdPath = prettyPath(".", cmd.Path)
+       }
+       buf.WriteString(cmdPath)
+
+       for _, arg := range cmd.Args[1:] {
+               buf.WriteByte(' ')
+               buf.WriteString(arg)
+       }
+
+       return buf.String()
+}
diff --git a/src/simd/generate.go b/src/simd/generate.go
new file mode 100644 (file)
index 0000000..95ae5d7
--- /dev/null
@@ -0,0 +1,12 @@
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package simd
+
+// Invoke code generators.
+//
+// This file intentionally has no goexperiment.simd build tag, so that go
+// generate can run without a GOEXPERIMENT set.
+
+//go:generate go run -C _gen . -tmplgen -simdgen
diff --git a/src/simd/no_tag.go b/src/simd/no_tag.go
deleted file mode 100644 (file)
index 65c1918..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2025 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package simd
-
-// This file has no build tag, so that go generate can run without a build tag.
-
-//go:generate go run -C _gen/tmplgen .