github.com/go-asm/go@v1.21.1-0.20240213172139-40c5ead50c48/cmd/compile/ssa/passbm_test.go (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package ssa 6 7 import ( 8 "fmt" 9 "testing" 10 11 "github.com/go-asm/go/cmd/compile/types" 12 ) 13 14 const ( 15 blockCount = 1000 16 passCount = 15000 17 ) 18 19 type passFunc func(*Func) 20 21 func BenchmarkDSEPass(b *testing.B) { benchFnPass(b, dse, blockCount, genFunction) } 22 func BenchmarkDSEPassBlock(b *testing.B) { benchFnBlock(b, dse, genFunction) } 23 func BenchmarkCSEPass(b *testing.B) { benchFnPass(b, cse, blockCount, genFunction) } 24 func BenchmarkCSEPassBlock(b *testing.B) { benchFnBlock(b, cse, genFunction) } 25 func BenchmarkDeadcodePass(b *testing.B) { benchFnPass(b, deadcode, blockCount, genFunction) } 26 func BenchmarkDeadcodePassBlock(b *testing.B) { benchFnBlock(b, deadcode, genFunction) } 27 28 func multi(f *Func) { 29 cse(f) 30 dse(f) 31 deadcode(f) 32 } 33 func BenchmarkMultiPass(b *testing.B) { benchFnPass(b, multi, blockCount, genFunction) } 34 func BenchmarkMultiPassBlock(b *testing.B) { benchFnBlock(b, multi, genFunction) } 35 36 // benchFnPass runs passFunc b.N times across a single function. 37 func benchFnPass(b *testing.B, fn passFunc, size int, bg blockGen) { 38 b.ReportAllocs() 39 c := testConfig(b) 40 fun := c.Fun("entry", bg(size)...) 41 CheckFunc(fun.f) 42 b.ResetTimer() 43 for i := 0; i < b.N; i++ { 44 fn(fun.f) 45 b.StopTimer() 46 CheckFunc(fun.f) 47 b.StartTimer() 48 } 49 } 50 51 // benchFnPass runs passFunc across a function with b.N blocks. 52 func benchFnBlock(b *testing.B, fn passFunc, bg blockGen) { 53 b.ReportAllocs() 54 c := testConfig(b) 55 fun := c.Fun("entry", bg(b.N)...) 56 CheckFunc(fun.f) 57 b.ResetTimer() 58 for i := 0; i < passCount; i++ { 59 fn(fun.f) 60 } 61 b.StopTimer() 62 } 63 64 func genFunction(size int) []bloc { 65 var blocs []bloc 66 elemType := types.Types[types.TINT64] 67 ptrType := elemType.PtrTo() 68 69 valn := func(s string, m, n int) string { return fmt.Sprintf("%s%d-%d", s, m, n) } 70 blocs = append(blocs, 71 Bloc("entry", 72 Valu(valn("store", 0, 4), OpInitMem, types.TypeMem, 0, nil), 73 Valu("sb", OpSB, types.Types[types.TUINTPTR], 0, nil), 74 Goto(blockn(1)), 75 ), 76 ) 77 for i := 1; i < size+1; i++ { 78 blocs = append(blocs, Bloc(blockn(i), 79 Valu(valn("v", i, 0), OpConstBool, types.Types[types.TBOOL], 1, nil), 80 Valu(valn("addr", i, 1), OpAddr, ptrType, 0, nil, "sb"), 81 Valu(valn("addr", i, 2), OpAddr, ptrType, 0, nil, "sb"), 82 Valu(valn("addr", i, 3), OpAddr, ptrType, 0, nil, "sb"), 83 Valu(valn("zero", i, 1), OpZero, types.TypeMem, 8, elemType, valn("addr", i, 3), 84 valn("store", i-1, 4)), 85 Valu(valn("store", i, 1), OpStore, types.TypeMem, 0, elemType, valn("addr", i, 1), 86 valn("v", i, 0), valn("zero", i, 1)), 87 Valu(valn("store", i, 2), OpStore, types.TypeMem, 0, elemType, valn("addr", i, 2), 88 valn("v", i, 0), valn("store", i, 1)), 89 Valu(valn("store", i, 3), OpStore, types.TypeMem, 0, elemType, valn("addr", i, 1), 90 valn("v", i, 0), valn("store", i, 2)), 91 Valu(valn("store", i, 4), OpStore, types.TypeMem, 0, elemType, valn("addr", i, 3), 92 valn("v", i, 0), valn("store", i, 3)), 93 Goto(blockn(i+1)))) 94 } 95 96 blocs = append(blocs, 97 Bloc(blockn(size+1), Goto("exit")), 98 Bloc("exit", Exit("store0-4")), 99 ) 100 101 return blocs 102 }