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