Commit 4e95dfed authored by Todd Neal's avatar Todd Neal

[dev.ssa] cmd/compile: add max arg length to opcodes

Add the max arg length to opcodes and use it in zcse.  Doesn't affect
speed, but allows better checking in checkFunc and removes the need
to keep a list of zero arg opcodes up to date.

Change-Id: I157c6587154604119720ec6228b767b6e52bb5c7
Reviewed-on: https://go-review.googlesource.com/19994Reviewed-by: default avatarKeith Randall <khr@golang.org>
Run-TryBot: Todd Neal <todd@tneal.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 91f69c67
......@@ -148,6 +148,13 @@ func checkFunc(f *Func) {
}
for _, v := range b.Values {
// Check to make sure argument count makes sense (argLen of -1 indicates
// variable length args)
nArgs := opcodeTable[v.Op].argLen
if nArgs != -1 && int32(len(v.Args)) != nArgs {
f.Fatalf("value %v has %d args, expected %d", v.LongString(),
len(v.Args), nArgs)
}
// Check to make sure aux values make sense.
canHaveAux := false
......
......@@ -14,7 +14,7 @@ func TestFuseEliminatesOneBranch(t *testing.T) {
Goto("checkPtr")),
Bloc("checkPtr",
Valu("ptr1", OpLoad, ptrType, 0, nil, "sb", "mem"),
Valu("nilptr", OpConstNil, ptrType, 0, nil, "sb"),
Valu("nilptr", OpConstNil, ptrType, 0, nil),
Valu("bool1", OpNeqPtr, TypeBool, 0, nil, "ptr1", "nilptr"),
If("bool1", "then", "exit")),
Bloc("then",
......@@ -42,7 +42,7 @@ func TestFuseEliminatesBothBranches(t *testing.T) {
Goto("checkPtr")),
Bloc("checkPtr",
Valu("ptr1", OpLoad, ptrType, 0, nil, "sb", "mem"),
Valu("nilptr", OpConstNil, ptrType, 0, nil, "sb"),
Valu("nilptr", OpConstNil, ptrType, 0, nil),
Valu("bool1", OpNeqPtr, TypeBool, 0, nil, "ptr1", "nilptr"),
If("bool1", "then", "else")),
Bloc("then",
......@@ -75,7 +75,7 @@ func TestFuseHandlesPhis(t *testing.T) {
Goto("checkPtr")),
Bloc("checkPtr",
Valu("ptr1", OpLoad, ptrType, 0, nil, "sb", "mem"),
Valu("nilptr", OpConstNil, ptrType, 0, nil, "sb"),
Valu("nilptr", OpConstNil, ptrType, 0, nil),
Valu("bool1", OpNeqPtr, TypeBool, 0, nil, "ptr1", "nilptr"),
If("bool1", "then", "else")),
Bloc("then",
......
......@@ -32,7 +32,7 @@ type opData struct {
typ string // default result type
aux string
rematerializeable bool
variableLength bool // this operation has a variable number of arguments
argLength int32 // number of arguments, if -1, then this operation has a variable number of arguments
commutative bool // this operation is commutative (e.g. addition)
}
......@@ -126,6 +126,8 @@ func genOp() {
if v.aux != "" {
fmt.Fprintf(w, "auxType: aux%s,\n", v.aux)
}
fmt.Fprintf(w, "argLen: %d,\n", v.argLength)
if v.rematerializeable {
if v.reg.clobbers != 0 {
log.Fatalf("%s is rematerializeable and clobbers registers", v.name)
......@@ -191,6 +193,7 @@ func genOp() {
var err error
b, err = format.Source(b)
if err != nil {
fmt.Printf("%s\n", w.Bytes())
panic(err)
}
......
......@@ -398,14 +398,14 @@ func genMatch0(w io.Writer, arch arch, match, v string, m map[string]string, top
variableLength := false
for _, op := range genericOps {
if op.name == s[0] {
variableLength = op.variableLength
if op.name == s[0] && op.argLength == -1 {
variableLength = true
break
}
}
for _, op := range arch.ops {
if op.name == s[0] {
variableLength = op.variableLength
if op.name == s[0] && op.argLength == -1 {
variableLength = true
break
}
}
......
......@@ -177,7 +177,8 @@ func TestNilcheckAddPtr(t *testing.T) {
Valu("sb", OpSB, TypeInvalid, 0, nil),
Goto("checkPtr")),
Bloc("checkPtr",
Valu("ptr1", OpAddPtr, ptrType, 0, nil, "sb"),
Valu("off", OpConst64, TypeInt64, 20, nil),
Valu("ptr1", OpAddPtr, ptrType, 0, nil, "sb", "off"),
Valu("bool1", OpIsNonNil, TypeBool, 0, nil, "ptr1"),
If("bool1", "extra", "exit")),
Bloc("extra",
......@@ -355,7 +356,7 @@ func TestNilcheckUser(t *testing.T) {
Goto("checkPtr")),
Bloc("checkPtr",
Valu("ptr1", OpLoad, ptrType, 0, nil, "sb", "mem"),
Valu("nilptr", OpConstNil, ptrType, 0, nil, "sb"),
Valu("nilptr", OpConstNil, ptrType, 0, nil),
Valu("bool1", OpNeqPtr, TypeBool, 0, nil, "ptr1", "nilptr"),
If("bool1", "secondCheck", "exit")),
Bloc("secondCheck",
......@@ -394,7 +395,7 @@ func TestNilcheckBug(t *testing.T) {
Goto("checkPtr")),
Bloc("checkPtr",
Valu("ptr1", OpLoad, ptrType, 0, nil, "sb", "mem"),
Valu("nilptr", OpConstNil, ptrType, 0, nil, "sb"),
Valu("nilptr", OpConstNil, ptrType, 0, nil),
Valu("bool1", OpNeqPtr, TypeBool, 0, nil, "ptr1", "nilptr"),
If("bool1", "secondCheck", "couldBeNil")),
Bloc("couldBeNil",
......
......@@ -19,6 +19,7 @@ type opInfo struct {
asm int
reg regInfo
auxType auxType
argLen int32 // the number of arugments, -1 if variable length
generic bool // this is a generic (arch-independent) opcode
rematerializeable bool // this op is rematerializeable
commutative bool // this operation is commutative (e.g. addition)
......
This diff is collapsed.
......@@ -16,10 +16,8 @@ func zcse(f *Func) {
for i := 0; i < len(b.Values); {
v := b.Values[i]
next := true
switch v.Op {
case OpSB, OpConst64, OpConst32, OpConst16, OpConst8, OpConst64F,
OpConst32F, OpConstBool, OpConstNil, OpConstSlice, OpConstInterface:
key := vkey{v.Op, keyFor(v), typeStr(v)}
if opcodeTable[v.Op].argLen == 0 {
key := vkey{v.Op, keyFor(v), v.Aux, typeStr(v)}
if vals[key] == nil {
vals[key] = v
if b != f.Entry {
......@@ -47,11 +45,8 @@ func zcse(f *Func) {
for _, b := range f.Blocks {
for _, v := range b.Values {
for i, a := range v.Args {
// TODO: encode arglen in the opcode table, then do this switch with a table lookup?
switch a.Op {
case OpSB, OpConst64, OpConst32, OpConst16, OpConst8, OpConst64F,
OpConst32F, OpConstBool, OpConstNil, OpConstSlice, OpConstInterface:
key := vkey{a.Op, keyFor(a), typeStr(a)}
if opcodeTable[a.Op].argLen == 0 {
key := vkey{a.Op, keyFor(a), a.Aux, typeStr(a)}
if rv, ok := vals[key]; ok {
v.Args[i] = rv
}
......@@ -64,7 +59,8 @@ func zcse(f *Func) {
// vkey is a type used to uniquely identify a zero arg value.
type vkey struct {
op Op
a int64 // aux
ai int64 // aux int
ax interface{} // aux
t string // type
}
......@@ -89,7 +85,6 @@ func keyFor(v *Value) int64 {
case OpConst8, OpConstBool:
return int64(int8(v.AuxInt))
default:
// Also matches OpSB, OpConstNil, OpConstSlice, OpConstInterface:
return 0
return v.AuxInt
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment