go/src/cmd/compile/internal/gc/abiutilsaux_test.go
Matthew Dempsky f24e40c14a [dev.regabi] cmd/compile: remove Name.Class_ accessors
These aren't part of the Node interface anymore, so no need to keep
them around.

Passes toolstash -cmp.

[git-generate]
cd src/cmd/compile/internal/ir

: Fix one off case that causes trouble for rf.
sed -i -e 's/n.SetClass(ir.PAUTO)/n.Class_ = ir.PAUTO/' ../ssa/export_test.go

pkgs=$(go list . ../...)
rf '
	ex '"$(echo $pkgs)"' {
		var n *Name
		var c Class
		n.Class() -> n.Class_
		n.SetClass(c) -> n.Class_ = c
	}

	rm Name.Class
	rm Name.SetClass
	mv Name.Class_ Name.Class
'

Change-Id: Ifb304bf4691a8c455456aabd8aa77178d4a49500
Reviewed-on: https://go-review.googlesource.com/c/go/+/281294
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2021-01-04 10:30:09 +00:00

155 lines
3.9 KiB
Go

// Copyright 2020 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 gc
// This file contains utility routines and harness infrastructure used
// by the ABI tests in "abiutils_test.go".
import (
"cmd/compile/internal/ir"
"cmd/compile/internal/typecheck"
"cmd/compile/internal/types"
"cmd/internal/src"
"fmt"
"strings"
"testing"
"text/scanner"
)
func mkParamResultField(t *types.Type, s *types.Sym, which ir.Class) *types.Field {
field := types.NewField(src.NoXPos, s, t)
n := typecheck.NewName(s)
n.Class = which
field.Nname = n
n.SetType(t)
return field
}
// mkstruct is a helper routine to create a struct type with fields
// of the types specified in 'fieldtypes'.
func mkstruct(fieldtypes []*types.Type) *types.Type {
fields := make([]*types.Field, len(fieldtypes))
for k, t := range fieldtypes {
if t == nil {
panic("bad -- field has no type")
}
f := types.NewField(src.NoXPos, nil, t)
fields[k] = f
}
s := types.NewStruct(types.LocalPkg, fields)
return s
}
func mkFuncType(rcvr *types.Type, ins []*types.Type, outs []*types.Type) *types.Type {
q := typecheck.Lookup("?")
inf := []*types.Field{}
for _, it := range ins {
inf = append(inf, mkParamResultField(it, q, ir.PPARAM))
}
outf := []*types.Field{}
for _, ot := range outs {
outf = append(outf, mkParamResultField(ot, q, ir.PPARAMOUT))
}
var rf *types.Field
if rcvr != nil {
rf = mkParamResultField(rcvr, q, ir.PPARAM)
}
return types.NewSignature(types.LocalPkg, rf, inf, outf)
}
type expectedDump struct {
dump string
file string
line int
}
func tokenize(src string) []string {
var s scanner.Scanner
s.Init(strings.NewReader(src))
res := []string{}
for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() {
res = append(res, s.TokenText())
}
return res
}
func verifyParamResultOffset(t *testing.T, f *types.Field, r ABIParamAssignment, which string, idx int) int {
n := ir.AsNode(f.Nname).(*ir.Name)
if n.FrameOffset() != int64(r.Offset) {
t.Errorf("%s %d: got offset %d wanted %d t=%v",
which, idx, r.Offset, n.Offset_, f.Type)
return 1
}
return 0
}
func makeExpectedDump(e string) expectedDump {
return expectedDump{dump: e}
}
func difftokens(atoks []string, etoks []string) string {
if len(atoks) != len(etoks) {
return fmt.Sprintf("expected %d tokens got %d",
len(etoks), len(atoks))
}
for i := 0; i < len(etoks); i++ {
if etoks[i] == atoks[i] {
continue
}
return fmt.Sprintf("diff at token %d: expected %q got %q",
i, etoks[i], atoks[i])
}
return ""
}
func abitest(t *testing.T, ft *types.Type, exp expectedDump) {
types.CalcSize(ft)
// Analyze with full set of registers.
regRes := ABIAnalyze(ft, configAMD64)
regResString := strings.TrimSpace(regRes.String())
// Check results.
reason := difftokens(tokenize(regResString), tokenize(exp.dump))
if reason != "" {
t.Errorf("\nexpected:\n%s\ngot:\n%s\nreason: %s",
strings.TrimSpace(exp.dump), regResString, reason)
}
// Analyze again with empty register set.
empty := ABIConfig{}
emptyRes := ABIAnalyze(ft, empty)
emptyResString := emptyRes.String()
// Walk the results and make sure the offsets assigned match
// up with those assiged by dowidth. This checks to make sure that
// when we have no available registers the ABI assignment degenerates
// back to the original ABI0.
// receiver
failed := 0
rfsl := ft.Recvs().Fields().Slice()
poff := 0
if len(rfsl) != 0 {
failed |= verifyParamResultOffset(t, rfsl[0], emptyRes.inparams[0], "receiver", 0)
poff = 1
}
// params
pfsl := ft.Params().Fields().Slice()
for k, f := range pfsl {
verifyParamResultOffset(t, f, emptyRes.inparams[k+poff], "param", k)
}
// results
ofsl := ft.Results().Fields().Slice()
for k, f := range ofsl {
failed |= verifyParamResultOffset(t, f, emptyRes.outparams[k], "result", k)
}
if failed != 0 {
t.Logf("emptyres:\n%s\n", emptyResString)
}
}