// Go command pragmas
GoBuildPragma
+
+ RegisterParams // TODO remove after register abi is working
+
)
func AsNode(n types.Object) Node {
ir.Nosplit |
ir.Noinline |
ir.NoCheckPtr |
+ ir.RegisterParams | // TODO remove after register abi is working
ir.CgoUnsafeArgs |
ir.UintptrEscapes |
ir.Systemstack |
// in the argument list.
// Used in syscall/dll_windows.go.
return ir.UintptrEscapes
+ case "go:registerparams": // TODO remove after register abi is working
+ return ir.RegisterParams
case "go:notinheap":
return ir.NotInHeap
}
if fn.Pragma&ir.Nosplit != 0 {
s.f.NoSplit = true
}
+ if fn.Pragma&ir.RegisterParams != 0 { // TODO remove after register abi is working
+ if strings.Contains(name, ".") {
+ base.ErrorfAt(fn.Pos(), "Calls to //go:registerparams method %s won't work, remove the pragma from the declaration.", name)
+ }
+ s.f.Warnl(fn.Pos(), "Declared function %s has register params", name)
+ }
+
s.panics = map[funcLine]*ssa.Block{}
s.softFloat = s.config.SoftFloat
}
testLateExpansion := false
+ inRegisters := false
switch n.Op() {
case ir.OCALLFUNC:
if k == callNormal && fn.Op() == ir.ONAME && fn.(*ir.Name).Class == ir.PFUNC {
fn := fn.(*ir.Name)
sym = fn.Sym()
+ // TODO remove after register abi is working
+ inRegistersImported := fn.Pragma()&ir.RegisterParams != 0
+ inRegistersSamePackage := fn.Func != nil && fn.Func.Pragma&ir.RegisterParams != 0
+ inRegisters = inRegistersImported || inRegistersSamePackage
+ if inRegisters {
+ s.f.Warnl(n.Pos(), "Called function %s has register params", sym.Linksym().Name)
+ }
break
}
closure = s.expr(fn)
w.linkname(n.Sym())
w.symIdx(n.Sym())
+ // TODO remove after register abi is working.
+ w.uint64(uint64(n.Func.Pragma))
+
// Escape analysis.
for _, fs := range &types.RecvsParams {
for _, f := range fs(n.Type()).FieldSlice() {
r.linkname(n.Sym())
r.symIdx(n.Sym())
+ // TODO remove after register abi is working
+ n.SetPragma(ir.PragmaFlag(r.uint64()))
+
// Escape analysis.
for _, fs := range &types.RecvsParams {
for _, f := range fs(n.Type()).FieldSlice() {
--- /dev/null
+// Copyright 2021 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 main
+
+import (
+ "fmt"
+ "regabipragma.dir/tmp"
+)
+
+type S string
+
+//go:noinline
+func (s S) ff(t string) string {
+ return string(s) + " " + t
+}
+
+//go:noinline
+//go:registerparams
+func f(s,t string) string { // ERROR "Declared function f has register params"
+ return s + " " + t
+}
+
+func check(s string) {
+ if s != "Hello world!" {
+ fmt.Printf("FAIL, wanted 'Hello world!' but got '%s'\n", s)
+ }
+}
+
+func main() {
+ check(f("Hello", "world!")) // ERROR "Called function ...f has register params"
+ check(tmp.F("Hello", "world!")) // ERROR "Called function regabipragma.dir/tmp.F has register params"
+ check(S("Hello").ff("world!"))
+ check(tmp.S("Hello").FF("world!"))
+}
--- /dev/null
+// Copyright 2021 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 tmp
+
+
+type S string
+
+//go:noinline
+func (s S) FF(t string) string {
+ return string(s) + " " + t
+}
+
+//go:noinline
+//go:registerparams
+func F(s,t string) string {
+ return s + " " + t
+}
--- /dev/null
+// runindir
+
+// Copyright 2021 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.
+
+// TODO May delete or adapt this test once regabi is the default
+
+package ignore
--- /dev/null
+# regabipragma.dir/tmp
+tmp/foo.go:17:6: Declared function F has register params
+# regabipragma.dir
+./main.go:21:6: Declared function f has register params
+./main.go:32:9: Called function "".f has register params
+./main.go:33:13: Called function regabipragma.dir/tmp.F has register params
// dirs are the directories to look for *.go files in.
// TODO(bradfitz): just use all directories?
- dirs = []string{".", "ken", "chan", "interface", "syntax", "dwarf", "fixedbugs", "codegen", "runtime"}
+ dirs = []string{".", "ken", "chan", "interface", "syntax", "dwarf", "fixedbugs", "codegen", "runtime", "abi"}
// ratec controls the max number of tests running at a time.
ratec chan bool