• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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