]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] merge dev.regabi 41f3af9d04 into dev.typeparams
authorRuss Cox <rsc@golang.org>
Wed, 25 Nov 2020 17:44:11 +0000 (12:44 -0500)
committerRuss Cox <rsc@golang.org>
Wed, 25 Nov 2020 18:15:41 +0000 (13:15 -0500)
This brings in the new ir.Node interface, replacing *gc.Node.

Change-Id: I82c623655eee08d77d623babf22ec4d91f9aa3cd

1  2 
src/cmd/compile/fmtmap_test.go
src/cmd/compile/internal/base/flag.go
src/cmd/compile/internal/gc/dep_test.go
src/cmd/compile/internal/gc/go.go
src/cmd/compile/internal/gc/main.go
src/cmd/compile/internal/gc/noder.go
src/cmd/compile/internal/syntax/nodes.go
src/cmd/compile/internal/syntax/printer_test.go
src/cmd/dist/buildtool.go

index a7c1eca9dbe10734f38222320b119684a6860fce,7a375604fd9f2ff9f2402d260a0b6628b2a5db72..3b94b05bfbb1bff176cb0ecd5a4e9428a4e02bd0
@@@ -110,27 -71,27 +98,28 @@@ var knownFormats = map[string]string
        "byte %q":                                         "",
        "byte %v":                                         "",
        "cmd/compile/internal/arm.shift %d":               "",
-       "cmd/compile/internal/gc.Class %d":                "",
-       "cmd/compile/internal/gc.Class %s":                "",
-       "cmd/compile/internal/gc.Class %v":                "",
-       "cmd/compile/internal/gc.Ctype %d":                "",
-       "cmd/compile/internal/gc.Ctype %v":                "",
-       "cmd/compile/internal/gc.Nodes %#v":               "",
-       "cmd/compile/internal/gc.Nodes %+v":               "",
-       "cmd/compile/internal/gc.Nodes %.v":               "",
-       "cmd/compile/internal/gc.Nodes %v":                "",
-       "cmd/compile/internal/gc.Op %#v":                  "",
-       "cmd/compile/internal/gc.Op %v":                   "",
-       "cmd/compile/internal/gc.Val %#v":                 "",
-       "cmd/compile/internal/gc.Val %T":                  "",
-       "cmd/compile/internal/gc.Val %v":                  "",
-       "cmd/compile/internal/gc.fmtMode %d":              "",
        "cmd/compile/internal/gc.initKind %d":             "",
        "cmd/compile/internal/gc.itag %v":                 "",
 +      "cmd/compile/internal/importer.itag %v":           "",
+       "cmd/compile/internal/ir.Class %d":                "",
+       "cmd/compile/internal/ir.Class %v":                "",
+       "cmd/compile/internal/ir.FmtMode %d":              "",
+       "cmd/compile/internal/ir.Node %#v":                "",
+       "cmd/compile/internal/ir.Node %+S":                "",
+       "cmd/compile/internal/ir.Node %+v":                "",
+       "cmd/compile/internal/ir.Node %L":                 "",
+       "cmd/compile/internal/ir.Node %S":                 "",
+       "cmd/compile/internal/ir.Node %j":                 "",
+       "cmd/compile/internal/ir.Node %p":                 "",
+       "cmd/compile/internal/ir.Node %v":                 "",
+       "cmd/compile/internal/ir.Nodes %#v":               "",
+       "cmd/compile/internal/ir.Nodes %+v":               "",
+       "cmd/compile/internal/ir.Nodes %.v":               "",
+       "cmd/compile/internal/ir.Nodes %v":                "",
+       "cmd/compile/internal/ir.Op %#v":                  "",
+       "cmd/compile/internal/ir.Op %v":                   "",
        "cmd/compile/internal/ssa.BranchPrediction %d":    "",
        "cmd/compile/internal/ssa.Edge %v":                "",
-       "cmd/compile/internal/ssa.GCNode %v":              "",
        "cmd/compile/internal/ssa.ID %d":                  "",
        "cmd/compile/internal/ssa.ID %v":                  "",
        "cmd/compile/internal/ssa.LocalSlot %s":           "",
        "error %v":                                        "",
        "float64 %.2f":                                    "",
        "float64 %.3f":                                    "",
-       "float64 %.6g":                                    "",
        "float64 %g":                                      "",
+       "go/constant.Kind %v":                             "",
+       "go/constant.Value %#v":                           "",
 +      "go/constant.Value %s":                            "",
+       "go/constant.Value %v":                            "",
        "int %#x":                                         "",
        "int %-12d":                                       "",
        "int %-6d":                                        "",
        "interface{} %q":                                  "",
        "interface{} %s":                                  "",
        "interface{} %v":                                  "",
-       "map[*cmd/compile/internal/gc.Node]*cmd/compile/internal/ssa.Value %v":           "",
-       "map[*cmd/compile/internal/gc.Node][]*cmd/compile/internal/gc.Node %v":           "",
 -      "map[cmd/compile/internal/ir.Node]*cmd/compile/internal/ssa.Value %v": "",
 -      "map[cmd/compile/internal/ir.Node][]cmd/compile/internal/ir.Node %v":  "",
 -      "map[cmd/compile/internal/ssa.ID]uint32 %v":                           "",
 +      "map[*cmd/compile/internal/types2.TypeParam]cmd/compile/internal/types2.Type %s": "",
++      "map[cmd/compile/internal/ir.Node]*cmd/compile/internal/ssa.Value %v":            "",
++      "map[cmd/compile/internal/ir.Node][]cmd/compile/internal/ir.Node %v":             "",
 +      "map[cmd/compile/internal/ssa.ID]uint32 %v":                                      "",
        "map[int64]uint32 %v":  "",
        "math/big.Accuracy %s": "",
        "reflect.Type %s":      "",
index 0000000000000000000000000000000000000000,aadc70f49645f40e8454b754d1b28b2f0ced5338..240258d6b8e23e79c71827b6ee5795f84cd39b66
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,453 +1,454 @@@
+ // Copyright 2009 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 base
+ import (
+       "encoding/json"
+       "flag"
+       "fmt"
+       "io/ioutil"
+       "log"
+       "os"
+       "reflect"
+       "runtime"
+       "strings"
+       "cmd/internal/objabi"
+       "cmd/internal/sys"
+ )
+ func usage() {
+       fmt.Fprintf(os.Stderr, "usage: compile [options] file.go...\n")
+       objabi.Flagprint(os.Stderr)
+       Exit(2)
+ }
+ // Flag holds the parsed command-line flags.
+ // See ParseFlag for non-zero defaults.
+ var Flag CmdFlags
+ // A CountFlag is a counting integer flag.
+ // It accepts -name=value to set the value directly,
+ // but it also accepts -name with no =value to increment the count.
+ type CountFlag int
+ // CmdFlags defines the command-line flags (see var Flag).
+ // Each struct field is a different flag, by default named for the lower-case of the field name.
+ // If the flag name is a single letter, the default flag name is left upper-case.
+ // If the flag name is "Lower" followed by a single letter, the default flag name is the lower-case of the last letter.
+ //
+ // If this default flag name can't be made right, the `flag` struct tag can be used to replace it,
+ // but this should be done only in exceptional circumstances: it helps everyone if the flag name
+ // is obvious from the field name when the flag is used elsewhere in the compiler sources.
+ // The `flag:"-"` struct tag makes a field invisible to the flag logic and should also be used sparingly.
+ //
+ // Each field must have a `help` struct tag giving the flag help message.
+ //
+ // The allowed field types are bool, int, string, pointers to those (for values stored elsewhere),
+ // CountFlag (for a counting flag), and func(string) (for a flag that uses special code for parsing).
+ type CmdFlags struct {
+       // Single letters
+       B CountFlag    "help:\"disable bounds checking\""
+       C CountFlag    "help:\"disable printing of columns in error messages\""
+       D string       "help:\"set relative `path` for local imports\""
+       E CountFlag    "help:\"debug symbol export\""
++      G CountFlag    "help:\"accept generic code\""
+       I func(string) "help:\"add `directory` to import search path\""
+       K CountFlag    "help:\"debug missing line numbers\""
+       L CountFlag    "help:\"show full file names in error messages\""
+       N CountFlag    "help:\"disable optimizations\""
+       S CountFlag    "help:\"print assembly listing\""
+       // V is added by objabi.AddVersionFlag
+       W CountFlag "help:\"debug parse tree after type checking\""
+       LowerC int          "help:\"concurrency during compilation (1 means no concurrency)\""
+       LowerD func(string) "help:\"enable debugging settings; try -d help\""
+       LowerE CountFlag    "help:\"no limit on number of errors reported\""
+       LowerH CountFlag    "help:\"halt on error\""
+       LowerJ CountFlag    "help:\"debug runtime-initialized variables\""
+       LowerL CountFlag    "help:\"disable inlining\""
+       LowerM CountFlag    "help:\"print optimization decisions\""
+       LowerO string       "help:\"write output to `file`\""
+       LowerP *string      "help:\"set expected package import `path`\"" // &Ctxt.Pkgpath, set below
+       LowerR CountFlag    "help:\"debug generated wrappers\""
+       LowerT bool         "help:\"enable tracing for debugging the compiler\""
+       LowerW CountFlag    "help:\"debug type checking\""
+       LowerV *bool        "help:\"increase debug verbosity\""
+       // Special characters
+       Percent          int  "flag:\"%\" help:\"debug non-static initializers\""
+       CompilingRuntime bool "flag:\"+\" help:\"compiling runtime\""
+       // Longer names
+       AsmHdr             string       "help:\"write assembly header to `file`\""
+       Bench              string       "help:\"append benchmark times to `file`\""
+       BlockProfile       string       "help:\"write block profile to `file`\""
+       BuildID            string       "help:\"record `id` as the build id in the export metadata\""
+       CPUProfile         string       "help:\"write cpu profile to `file`\""
+       Complete           bool         "help:\"compiling complete package (no C or assembly)\""
+       Dwarf              bool         "help:\"generate DWARF symbols\""
+       DwarfBASEntries    *bool        "help:\"use base address selection entries in DWARF\""                        // &Ctxt.UseBASEntries, set below
+       DwarfLocationLists *bool        "help:\"add location lists to DWARF in optimized mode\""                      // &Ctxt.Flag_locationlists, set below
+       Dynlink            *bool        "help:\"support references to Go symbols defined in other shared libraries\"" // &Ctxt.Flag_dynlink, set below
+       EmbedCfg           func(string) "help:\"read go:embed configuration from `file`\""
+       GenDwarfInl        int          "help:\"generate DWARF inline info records\"" // 0=disabled, 1=funcs, 2=funcs+formals/locals
+       GoVersion          string       "help:\"required version of the runtime\""
+       ImportCfg          func(string) "help:\"read import configuration from `file`\""
+       ImportMap          func(string) "help:\"add `definition` of the form source=actual to import map\""
+       InstallSuffix      string       "help:\"set pkg directory `suffix`\""
+       JSON               string       "help:\"version,file for JSON compiler/optimizer detail output\""
+       Lang               string       "help:\"Go language version source code expects\""
+       LinkObj            string       "help:\"write linker-specific object to `file`\""
+       LinkShared         *bool        "help:\"generate code that will be linked against Go shared libraries\"" // &Ctxt.Flag_linkshared, set below
+       Live               CountFlag    "help:\"debug liveness analysis\""
+       MSan               bool         "help:\"build code compatible with C/C++ memory sanitizer\""
+       MemProfile         string       "help:\"write memory profile to `file`\""
+       MemProfileRate     int64        "help:\"set runtime.MemProfileRate to `rate`\""
+       MutexProfile       string       "help:\"write mutex profile to `file`\""
+       NoLocalImports     bool         "help:\"reject local (relative) imports\""
+       Pack               bool         "help:\"write to file.a instead of file.o\""
+       Race               bool         "help:\"enable race detector\""
+       Shared             *bool        "help:\"generate code that can be linked into a shared library\"" // &Ctxt.Flag_shared, set below
+       SmallFrames        bool         "help:\"reduce the size limit for stack allocated objects\""      // small stacks, to diagnose GC latency; see golang.org/issue/27732
+       Spectre            string       "help:\"enable spectre mitigations in `list` (all, index, ret)\""
+       Std                bool         "help:\"compiling standard library\""
+       SymABIs            string       "help:\"read symbol ABIs from `file`\""
+       TraceProfile       string       "help:\"write an execution trace to `file`\""
+       TrimPath           string       "help:\"remove `prefix` from recorded source file paths\""
+       WB                 bool         "help:\"enable write barrier\"" // TODO: remove
+       // Configuration derived from flags; not a flag itself.
+       Cfg struct {
+               Embed struct { // set by -embedcfg
+                       Patterns map[string][]string
+                       Files    map[string]string
+               }
+               ImportDirs   []string          // appended to by -I
+               ImportMap    map[string]string // set by -importmap OR -importcfg
+               PackageFile  map[string]string // set by -importcfg; nil means not in use
+               SpectreIndex bool              // set by -spectre=index or -spectre=all
+       }
+ }
+ // ParseFlags parses the command-line flags into Flag.
+ func ParseFlags() {
+       Flag.I = addImportDir
+       Flag.LowerC = 1
+       Flag.LowerD = parseDebug
+       Flag.LowerP = &Ctxt.Pkgpath
+       Flag.LowerV = &Ctxt.Debugvlog
+       Flag.Dwarf = objabi.GOARCH != "wasm"
+       Flag.DwarfBASEntries = &Ctxt.UseBASEntries
+       Flag.DwarfLocationLists = &Ctxt.Flag_locationlists
+       *Flag.DwarfLocationLists = true
+       Flag.Dynlink = &Ctxt.Flag_dynlink
+       Flag.EmbedCfg = readEmbedCfg
+       Flag.GenDwarfInl = 2
+       Flag.ImportCfg = readImportCfg
+       Flag.ImportMap = addImportMap
+       Flag.LinkShared = &Ctxt.Flag_linkshared
+       Flag.Shared = &Ctxt.Flag_shared
+       Flag.WB = true
+       Flag.Cfg.ImportMap = make(map[string]string)
+       objabi.AddVersionFlag() // -V
+       registerFlags()
+       objabi.Flagparse(usage)
+       if Flag.MSan && !sys.MSanSupported(objabi.GOOS, objabi.GOARCH) {
+               log.Fatalf("%s/%s does not support -msan", objabi.GOOS, objabi.GOARCH)
+       }
+       if Flag.Race && !sys.RaceDetectorSupported(objabi.GOOS, objabi.GOARCH) {
+               log.Fatalf("%s/%s does not support -race", objabi.GOOS, objabi.GOARCH)
+       }
+       if (*Flag.Shared || *Flag.Dynlink || *Flag.LinkShared) && !Ctxt.Arch.InFamily(sys.AMD64, sys.ARM, sys.ARM64, sys.I386, sys.PPC64, sys.RISCV64, sys.S390X) {
+               log.Fatalf("%s/%s does not support -shared", objabi.GOOS, objabi.GOARCH)
+       }
+       parseSpectre(Flag.Spectre) // left as string for recordFlags
+       Ctxt.Flag_shared = Ctxt.Flag_dynlink || Ctxt.Flag_shared
+       Ctxt.Flag_optimize = Flag.N == 0
+       Ctxt.Debugasm = int(Flag.S)
+       if flag.NArg() < 1 {
+               usage()
+       }
+       if Flag.GoVersion != "" && Flag.GoVersion != runtime.Version() {
+               fmt.Printf("compile: version %q does not match go tool version %q\n", runtime.Version(), Flag.GoVersion)
+               Exit(2)
+       }
+       if Flag.LowerO == "" {
+               p := flag.Arg(0)
+               if i := strings.LastIndex(p, "/"); i >= 0 {
+                       p = p[i+1:]
+               }
+               if runtime.GOOS == "windows" {
+                       if i := strings.LastIndex(p, `\`); i >= 0 {
+                               p = p[i+1:]
+                       }
+               }
+               if i := strings.LastIndex(p, "."); i >= 0 {
+                       p = p[:i]
+               }
+               suffix := ".o"
+               if Flag.Pack {
+                       suffix = ".a"
+               }
+               Flag.LowerO = p + suffix
+       }
+       if Flag.Race && Flag.MSan {
+               log.Fatal("cannot use both -race and -msan")
+       }
+       if Flag.Race || Flag.MSan {
+               // -race and -msan imply -d=checkptr for now.
+               Debug.Checkptr = 1
+       }
+       if Flag.CompilingRuntime && Flag.N != 0 {
+               log.Fatal("cannot disable optimizations while compiling runtime")
+       }
+       if Flag.LowerC < 1 {
+               log.Fatalf("-c must be at least 1, got %d", Flag.LowerC)
+       }
+       if Flag.LowerC > 1 && !concurrentBackendAllowed() {
+               log.Fatalf("cannot use concurrent backend compilation with provided flags; invoked as %v", os.Args)
+       }
+       if Flag.CompilingRuntime {
+               // Runtime can't use -d=checkptr, at least not yet.
+               Debug.Checkptr = 0
+               // Fuzzing the runtime isn't interesting either.
+               Debug.Libfuzzer = 0
+       }
+       // set via a -d flag
+       Ctxt.Debugpcln = Debug.PCTab
+ }
+ // registerFlags adds flag registrations for all the fields in Flag.
+ // See the comment on type CmdFlags for the rules.
+ func registerFlags() {
+       var (
+               boolType      = reflect.TypeOf(bool(false))
+               intType       = reflect.TypeOf(int(0))
+               stringType    = reflect.TypeOf(string(""))
+               ptrBoolType   = reflect.TypeOf(new(bool))
+               ptrIntType    = reflect.TypeOf(new(int))
+               ptrStringType = reflect.TypeOf(new(string))
+               countType     = reflect.TypeOf(CountFlag(0))
+               funcType      = reflect.TypeOf((func(string))(nil))
+       )
+       v := reflect.ValueOf(&Flag).Elem()
+       t := v.Type()
+       for i := 0; i < t.NumField(); i++ {
+               f := t.Field(i)
+               if f.Name == "Cfg" {
+                       continue
+               }
+               var name string
+               if len(f.Name) == 1 {
+                       name = f.Name
+               } else if len(f.Name) == 6 && f.Name[:5] == "Lower" && 'A' <= f.Name[5] && f.Name[5] <= 'Z' {
+                       name = string(rune(f.Name[5] + 'a' - 'A'))
+               } else {
+                       name = strings.ToLower(f.Name)
+               }
+               if tag := f.Tag.Get("flag"); tag != "" {
+                       name = tag
+               }
+               help := f.Tag.Get("help")
+               if help == "" {
+                       panic(fmt.Sprintf("base.Flag.%s is missing help text", f.Name))
+               }
+               if k := f.Type.Kind(); (k == reflect.Ptr || k == reflect.Func) && v.Field(i).IsNil() {
+                       panic(fmt.Sprintf("base.Flag.%s is uninitialized %v", f.Name, f.Type))
+               }
+               switch f.Type {
+               case boolType:
+                       p := v.Field(i).Addr().Interface().(*bool)
+                       flag.BoolVar(p, name, *p, help)
+               case intType:
+                       p := v.Field(i).Addr().Interface().(*int)
+                       flag.IntVar(p, name, *p, help)
+               case stringType:
+                       p := v.Field(i).Addr().Interface().(*string)
+                       flag.StringVar(p, name, *p, help)
+               case ptrBoolType:
+                       p := v.Field(i).Interface().(*bool)
+                       flag.BoolVar(p, name, *p, help)
+               case ptrIntType:
+                       p := v.Field(i).Interface().(*int)
+                       flag.IntVar(p, name, *p, help)
+               case ptrStringType:
+                       p := v.Field(i).Interface().(*string)
+                       flag.StringVar(p, name, *p, help)
+               case countType:
+                       p := (*int)(v.Field(i).Addr().Interface().(*CountFlag))
+                       objabi.Flagcount(name, help, p)
+               case funcType:
+                       f := v.Field(i).Interface().(func(string))
+                       objabi.Flagfn1(name, help, f)
+               }
+       }
+ }
+ // concurrentFlagOk reports whether the current compiler flags
+ // are compatible with concurrent compilation.
+ func concurrentFlagOk() bool {
+       // TODO(rsc): Many of these are fine. Remove them.
+       return Flag.Percent == 0 &&
+               Flag.E == 0 &&
+               Flag.K == 0 &&
+               Flag.L == 0 &&
+               Flag.LowerH == 0 &&
+               Flag.LowerJ == 0 &&
+               Flag.LowerM == 0 &&
+               Flag.LowerR == 0
+ }
+ func concurrentBackendAllowed() bool {
+       if !concurrentFlagOk() {
+               return false
+       }
+       // Debug.S by itself is ok, because all printing occurs
+       // while writing the object file, and that is non-concurrent.
+       // Adding Debug_vlog, however, causes Debug.S to also print
+       // while flushing the plist, which happens concurrently.
+       if Ctxt.Debugvlog || Debug.Any() || Flag.Live > 0 {
+               return false
+       }
+       // TODO: Test and delete this condition.
+       if objabi.Fieldtrack_enabled != 0 {
+               return false
+       }
+       // TODO: fix races and enable the following flags
+       if Ctxt.Flag_shared || Ctxt.Flag_dynlink || Flag.Race {
+               return false
+       }
+       return true
+ }
+ func addImportDir(dir string) {
+       if dir != "" {
+               Flag.Cfg.ImportDirs = append(Flag.Cfg.ImportDirs, dir)
+       }
+ }
+ func addImportMap(s string) {
+       if Flag.Cfg.ImportMap == nil {
+               Flag.Cfg.ImportMap = make(map[string]string)
+       }
+       if strings.Count(s, "=") != 1 {
+               log.Fatal("-importmap argument must be of the form source=actual")
+       }
+       i := strings.Index(s, "=")
+       source, actual := s[:i], s[i+1:]
+       if source == "" || actual == "" {
+               log.Fatal("-importmap argument must be of the form source=actual; source and actual must be non-empty")
+       }
+       Flag.Cfg.ImportMap[source] = actual
+ }
+ func readImportCfg(file string) {
+       if Flag.Cfg.ImportMap == nil {
+               Flag.Cfg.ImportMap = make(map[string]string)
+       }
+       Flag.Cfg.PackageFile = map[string]string{}
+       data, err := ioutil.ReadFile(file)
+       if err != nil {
+               log.Fatalf("-importcfg: %v", err)
+       }
+       for lineNum, line := range strings.Split(string(data), "\n") {
+               lineNum++ // 1-based
+               line = strings.TrimSpace(line)
+               if line == "" || strings.HasPrefix(line, "#") {
+                       continue
+               }
+               var verb, args string
+               if i := strings.Index(line, " "); i < 0 {
+                       verb = line
+               } else {
+                       verb, args = line[:i], strings.TrimSpace(line[i+1:])
+               }
+               var before, after string
+               if i := strings.Index(args, "="); i >= 0 {
+                       before, after = args[:i], args[i+1:]
+               }
+               switch verb {
+               default:
+                       log.Fatalf("%s:%d: unknown directive %q", file, lineNum, verb)
+               case "importmap":
+                       if before == "" || after == "" {
+                               log.Fatalf(`%s:%d: invalid importmap: syntax is "importmap old=new"`, file, lineNum)
+                       }
+                       Flag.Cfg.ImportMap[before] = after
+               case "packagefile":
+                       if before == "" || after == "" {
+                               log.Fatalf(`%s:%d: invalid packagefile: syntax is "packagefile path=filename"`, file, lineNum)
+                       }
+                       Flag.Cfg.PackageFile[before] = after
+               }
+       }
+ }
+ func readEmbedCfg(file string) {
+       data, err := ioutil.ReadFile(file)
+       if err != nil {
+               log.Fatalf("-embedcfg: %v", err)
+       }
+       if err := json.Unmarshal(data, &Flag.Cfg.Embed); err != nil {
+               log.Fatalf("%s: %v", file, err)
+       }
+       if Flag.Cfg.Embed.Patterns == nil {
+               log.Fatalf("%s: invalid embedcfg: missing Patterns", file)
+       }
+       if Flag.Cfg.Embed.Files == nil {
+               log.Fatalf("%s: invalid embedcfg: missing Files", file)
+       }
+ }
+ // parseSpectre parses the spectre configuration from the string s.
+ func parseSpectre(s string) {
+       for _, f := range strings.Split(s, ",") {
+               f = strings.TrimSpace(f)
+               switch f {
+               default:
+                       log.Fatalf("unknown setting -spectre=%s", f)
+               case "":
+                       // nothing
+               case "all":
+                       Flag.Cfg.SpectreIndex = true
+                       Ctxt.Retpoline = true
+               case "index":
+                       Flag.Cfg.SpectreIndex = true
+               case "ret":
+                       Ctxt.Retpoline = true
+               }
+       }
+       if Flag.Cfg.SpectreIndex {
+               switch objabi.GOARCH {
+               case "amd64":
+                       // ok
+               default:
+                       log.Fatalf("GOARCH=%s does not support -spectre=index", objabi.GOARCH)
+               }
+       }
+ }
index ecc9a70ce4ab8e893898f1c96c286cc70ca272d3,a185bc9f547c5261b4c81b0abad34aea62570819..d03683a2808c39b2084c39fd35e087082a2414f3
@@@ -18,13 -18,8 +18,13 @@@ func TestDeps(t *testing.T) 
        }
        for _, dep := range strings.Fields(strings.Trim(string(out), "[]")) {
                switch dep {
-               case "go/build", "go/token":
+               case "go/build", "go/scanner":
 -                      t.Errorf("undesired dependency on %q", dep)
 +                      // cmd/compile/internal/importer introduces a dependency
 +                      // on go/build and go/token; cmd/compile/internal/ uses
 +                      // go/constant which uses go/token in its API. Once we
 +                      // got rid of those dependencies, enable this check again.
 +                      // TODO(gri) fix this
 +                      // t.Errorf("undesired dependency on %q", dep)
                }
        }
  }
index c7627bddcf2506b8413cc678fea1901972ea2f41,84e6bc5faf38809ff2bffd2c57194f718202e5bd..0c6b81ffb71dd260b6c33c7c0e772954ee92eeda
@@@ -99,40 -78,8 +78,10 @@@ var 
  
  var pragcgobuf [][]string
  
- var outfile string
- var linkobj string
- // nerrors is the number of compiler errors reported
- // since the last call to saveerrors.
- var nerrors int
- // nsavederrors is the total number of compiler errors
- // reported before the last call to saveerrors.
- var nsavederrors int
- var nsyntaxerrors int
  var decldepth int32
  
- // gc debug flags
- type DebugFlags struct {
-       P, B, C, E, G,
-       K, L, N, S,
-       W, e, h, j,
-       l, m, r, w int
- }
- var Debug DebugFlags
- var debugstr string
- var Debug_checknil int
- var Debug_typeassert int
- var localpkg *types.Pkg // package being compiled
 +var nolocalimports bool
 +
  var inimport bool // set during import
  
  var itabpkg *types.Pkg // fake pkg for itab entries
index 7015d9d6cd5319bfb464e4ef902ebe860fe94467,30ee57c02daa2145fbffca5bd4c2c29f3a34410b..6b7123dc7162bc7e2e646e8b5f06d0a9fb020e4c
@@@ -576,16 -229,9 +229,14 @@@ func Main(archInit func(*Arch)) 
        loadsys()
  
        timings.Start("fe", "parse")
-       lines := parseFiles(flag.Args(), Debug.G != 0)
 -      lines := parseFiles(flag.Args())
++      lines := parseFiles(flag.Args(), base.Flag.G != 0)
        timings.Stop()
        timings.AddEvent(int64(lines), "lines")
-       if Debug.G != 0 {
++      if base.Flag.G != 0 {
 +              // can only parse generic code for now
-               if nerrors+nsavederrors != 0 {
-                       errorexit()
-               }
++              base.ExitIfErrors()
 +              return
 +      }
  
        finishUniverse()
  
index 4ed91035a5ad13c204aae9d5c1a9a293ac06dada,950d50904795d05942cc15af5ca2579c8bb19dfa..0cbea2c461a659272f94e33b50f750b71afc36c4
@@@ -6,7 -6,8 +6,9 @@@ package g
  
  import (
        "fmt"
+       "go/constant"
+       "go/token"
 +      "io"
        "os"
        "path/filepath"
        "runtime"
        "unicode"
        "unicode/utf8"
  
+       "cmd/compile/internal/base"
 +      "cmd/compile/internal/importer"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/syntax"
        "cmd/compile/internal/types"
 +      "cmd/compile/internal/types2"
        "cmd/internal/obj"
        "cmd/internal/objabi"
        "cmd/internal/src"
@@@ -61,88 -58,26 +65,88 @@@ func parseFiles(filenames []string, all
                }(filename)
        }
  
 -      var lines uint
 +      if allowGenerics {
 +              nodersmap := make(map[string]*noder)
 +              var files []*syntax.File
 +              for _, p := range noders {
 +                      for e := range p.err {
-                               p.yyerrorpos(e.Pos, "%s", e.Msg)
++                              p.errorAt(e.Pos, "%s", e.Msg)
 +                      }
 +
 +                      nodersmap[p.file.Pos().RelFilename()] = p
 +                      files = append(files, p.file)
 +                      lines += p.file.EOF.Line()
 +
-                       if nsyntaxerrors != 0 {
-                               errorexit()
++                      if base.SyntaxErrors() != 0 {
++                              base.ErrorExit()
 +                      }
 +              }
 +
 +              conf := types2.Config{
 +                      InferFromConstraints: true,
 +                      Error: func(err error) {
 +                              terr := err.(types2.Error)
 +                              if len(terr.Msg) > 0 && terr.Msg[0] == '\t' {
 +                                      // types2 reports error clarifications via separate
 +                                      // error messages which are indented with a tab.
 +                                      // Ignore them to satisfy tools and tests that expect
 +                                      // only one error in such cases.
 +                                      // TODO(gri) Need to adjust error reporting in types2.
 +                                      return
 +                              }
 +                              p := nodersmap[terr.Pos.RelFilename()]
-                               yyerrorl(p.makeXPos(terr.Pos), "%s", terr.Msg)
++                              base.ErrorfAt(p.makeXPos(terr.Pos), "%s", terr.Msg)
 +                      },
 +                      Importer: &gcimports{
 +                              packages: make(map[string]*types2.Package),
 +                              lookup: func(path string) (io.ReadCloser, error) {
 +                                      file, ok := findpkg(path)
 +                                      if !ok {
 +                                              return nil, fmt.Errorf("can't find import: %q", path)
 +                                      }
 +                                      return os.Open(file)
 +                              },
 +                      },
 +              }
-               conf.Check(Ctxt.Pkgpath, files, nil)
++              conf.Check(base.Ctxt.Pkgpath, files, nil)
 +              return
 +      }
 +
        for _, p := range noders {
                for e := range p.err {
-                       p.yyerrorpos(e.Pos, "%s", e.Msg)
+                       p.errorAt(e.Pos, "%s", e.Msg)
                }
  
                p.node()
 -              lines += p.file.Lines
 +              lines += p.file.EOF.Line()
                p.file = nil // release memory
  
-               if nsyntaxerrors != 0 {
-                       errorexit()
+               if base.SyntaxErrors() != 0 {
+                       base.ErrorExit()
                }
                // Always run testdclstack here, even when debug_dclstack is not set, as a sanity measure.
                testdclstack()
        }
  
-       localpkg.Height = myheight
+       ir.LocalPkg.Height = myheight
 +      return
 +}
 +
 +// Temporary import helper to get type2-based type-checking going.
 +type gcimports struct {
 +      packages map[string]*types2.Package
 +      lookup   func(path string) (io.ReadCloser, error)
 +}
 +
 +func (m *gcimports) Import(path string) (*types2.Package, error) {
 +      return m.ImportFrom(path, "" /* no vendoring */, 0)
 +}
  
 -      return lines
 +func (m *gcimports) ImportFrom(path, srcDir string, mode types2.ImportMode) (*types2.Package, error) {
 +      if mode != 0 {
 +              panic("mode must be 0")
 +      }
 +      return importer.Import(m.packages, path, srcDir, m.lookup)
  }
  
  // makeSrcPosBase translates from a *syntax.PosBase to a *src.PosBase.
index f5dcd34cc1f8005d59ee7694acdf4a1b647d5ba5,839579349a28de43d17568ea9b89e10d1d41faed..5dfd5ee16e86b41e35e54580031d66fc2a3e766c
@@@ -41,7 -42,7 +42,8 @@@ var bootstrapDirs = []string
        "cmd/compile/internal/arm",
        "cmd/compile/internal/arm64",
        "cmd/compile/internal/gc",
 +      "cmd/compile/internal/importer",
+       "cmd/compile/internal/ir",
        "cmd/compile/internal/logopt",
        "cmd/compile/internal/mips",
        "cmd/compile/internal/mips64",