From: Keith Randall Date: Fri, 29 May 2015 23:20:33 +0000 (-0700) Subject: [dev.ssa] cmd/compile/internal/ssa: Add code to test generated opcode counts X-Git-Tag: go1.7beta1~1623^2^2~460 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=b0da62903d045f6d3e832ba1181387a1e9ad33f1;p=gostls13.git [dev.ssa] cmd/compile/internal/ssa: Add code to test generated opcode counts Add test handler to count and check generated opcodes. This will be useful for testing that certain optimizations don't regress. Also pass a *Config to the Fun constructor so that compile() works. Change-Id: Iee679e87cf0bc635ddcbe433fc1bd4c1d9c953cc Reviewed-on: https://go-review.googlesource.com/10502 Reviewed-by: Michael Matloob Reviewed-by: Keith Randall --- diff --git a/src/cmd/compile/internal/ssa/deadcode_test.go b/src/cmd/compile/internal/ssa/deadcode_test.go index ced46e524b..f3d5682355 100644 --- a/src/cmd/compile/internal/ssa/deadcode_test.go +++ b/src/cmd/compile/internal/ssa/deadcode_test.go @@ -9,7 +9,8 @@ import ( ) func TestDeadLoop(t *testing.T) { - fun := Fun("entry", + c := NewConfig("amd64") + fun := Fun(c, "entry", Bloc("entry", Valu("mem", OpArg, TypeMem, ".mem"), Goto("exit")), @@ -38,7 +39,8 @@ func TestDeadLoop(t *testing.T) { } func TestDeadValue(t *testing.T) { - fun := Fun("entry", + c := NewConfig("amd64") + fun := Fun(c, "entry", Bloc("entry", Valu("mem", OpArg, TypeMem, ".mem"), Valu("deadval", OpConst, TypeInt64, int64(37)), @@ -60,7 +62,8 @@ func TestDeadValue(t *testing.T) { } func TestNeverTaken(t *testing.T) { - fun := Fun("entry", + c := NewConfig("amd64") + fun := Fun(c, "entry", Bloc("entry", Valu("cond", OpConst, TypeBool, false), Valu("mem", OpArg, TypeMem, ".mem"), diff --git a/src/cmd/compile/internal/ssa/func_test.go b/src/cmd/compile/internal/ssa/func_test.go index e7619ca4f8..4839c1ee63 100644 --- a/src/cmd/compile/internal/ssa/func_test.go +++ b/src/cmd/compile/internal/ssa/func_test.go @@ -134,8 +134,9 @@ type fun struct { // returns a fun containing the composed Func. entry must be a name // supplied to one of the Bloc functions. Each of the bloc names and // valu names should be unique across the Fun. -func Fun(entry string, blocs ...bloc) fun { +func Fun(c *Config, entry string, blocs ...bloc) fun { f := new(Func) + f.Config = c blocks := make(map[string]*Block) values := make(map[string]*Value) // Create all the blocks and values. @@ -256,7 +257,8 @@ func addEdge(b, c *Block) { } func TestArgs(t *testing.T) { - fun := Fun("entry", + c := NewConfig("amd64") + fun := Fun(c, "entry", Bloc("entry", Valu("a", OpConst, TypeInt64, 14), Valu("b", OpConst, TypeInt64, 26), @@ -275,10 +277,11 @@ func TestArgs(t *testing.T) { } func TestEquiv(t *testing.T) { + c := NewConfig("amd64") equivalentCases := []struct{ f, g fun }{ // simple case { - Fun("entry", + Fun(c, "entry", Bloc("entry", Valu("a", OpConst, TypeInt64, 14), Valu("b", OpConst, TypeInt64, 26), @@ -287,7 +290,7 @@ func TestEquiv(t *testing.T) { Goto("exit")), Bloc("exit", Exit("mem"))), - Fun("entry", + Fun(c, "entry", Bloc("entry", Valu("a", OpConst, TypeInt64, 14), Valu("b", OpConst, TypeInt64, 26), @@ -299,7 +302,7 @@ func TestEquiv(t *testing.T) { }, // block order changed { - Fun("entry", + Fun(c, "entry", Bloc("entry", Valu("a", OpConst, TypeInt64, 14), Valu("b", OpConst, TypeInt64, 26), @@ -308,7 +311,7 @@ func TestEquiv(t *testing.T) { Goto("exit")), Bloc("exit", Exit("mem"))), - Fun("entry", + Fun(c, "entry", Bloc("exit", Exit("mem")), Bloc("entry", @@ -332,26 +335,26 @@ func TestEquiv(t *testing.T) { differentCases := []struct{ f, g fun }{ // different shape { - Fun("entry", + Fun(c, "entry", Bloc("entry", Valu("mem", OpArg, TypeMem, ".mem"), Goto("exit")), Bloc("exit", Exit("mem"))), - Fun("entry", + Fun(c, "entry", Bloc("entry", Valu("mem", OpArg, TypeMem, ".mem"), Exit("mem"))), }, // value order changed { - Fun("entry", + Fun(c, "entry", Bloc("entry", Valu("mem", OpArg, TypeMem, ".mem"), Valu("b", OpConst, TypeInt64, 26), Valu("a", OpConst, TypeInt64, 14), Exit("mem"))), - Fun("entry", + Fun(c, "entry", Bloc("entry", Valu("mem", OpArg, TypeMem, ".mem"), Valu("a", OpConst, TypeInt64, 14), @@ -360,12 +363,12 @@ func TestEquiv(t *testing.T) { }, // value aux different { - Fun("entry", + Fun(c, "entry", Bloc("entry", Valu("mem", OpArg, TypeMem, ".mem"), Valu("a", OpConst, TypeInt64, 14), Exit("mem"))), - Fun("entry", + Fun(c, "entry", Bloc("entry", Valu("mem", OpArg, TypeMem, ".mem"), Valu("a", OpConst, TypeInt64, 26), @@ -373,14 +376,14 @@ func TestEquiv(t *testing.T) { }, // value args different { - Fun("entry", + Fun(c, "entry", Bloc("entry", Valu("mem", OpArg, TypeMem, ".mem"), Valu("a", OpConst, TypeInt64, 14), Valu("b", OpConst, TypeInt64, 26), Valu("sum", OpAdd, TypeInt64, nil, "a", "b"), Exit("mem"))), - Fun("entry", + Fun(c, "entry", Bloc("entry", Valu("mem", OpArg, TypeMem, ".mem"), Valu("a", OpConst, TypeInt64, 0), @@ -399,3 +402,26 @@ func TestEquiv(t *testing.T) { } } } + +// opcodeMap returns a map from opcode to the number of times that opcode +// appears in the function. +func opcodeMap(f *Func) map[Op]int { + m := map[Op]int{} + for _, b := range f.Blocks { + for _, v := range b.Values { + m[v.Op]++ + } + } + return m +} + +// opcodeCounts checks that the number of opcodes listed in m agree with the +// number of opcodes that appear in the function. +func checkOpcodeCounts(t *testing.T, f *Func, m map[Op]int) { + n := opcodeMap(f) + for op, cnt := range m { + if n[op] != cnt { + t.Errorf("%s appears %d times, want %d times", op, n[op], cnt) + } + } +}