]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/compile/internal/test/testdata/pgo/devirtualize/devirt.go
cmd/compile/internal/devirtualize: devirtualize methods in other packages if current...
[gostls13.git] / src / cmd / compile / internal / test / testdata / pgo / devirtualize / devirt.go
1 // Copyright 2023 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 // WARNING: Please avoid updating this file. If this file needs to be updated,
6 // then a new devirt.pprof file should be generated:
7 //
8 //      $ cd $GOROOT/src/cmd/compile/internal/test/testdata/pgo/devirtualize/
9 //      $ go mod init example.com/pgo/devirtualize
10 //      $ go test -bench=. -cpuprofile ./devirt.pprof
11
12 package devirt
13
14 import "example.com/pgo/devirtualize/mult"
15
16 var sink int
17
18 type Adder interface {
19         Add(a, b int) int
20 }
21
22 type Add struct{}
23
24 func (Add) Add(a, b int) int {
25         for i := 0; i < 1000; i++ {
26                 sink++
27         }
28         return a + b
29 }
30
31 type Sub struct{}
32
33 func (Sub) Add(a, b int) int {
34         for i := 0; i < 1000; i++ {
35                 sink++
36         }
37         return a - b
38 }
39
40 // Exercise calls mostly a1 and m1.
41 //
42 //go:noinline
43 func Exercise(iter int, a1, a2 Adder, m1, m2 mult.Multiplier) {
44         for i := 0; i < iter; i++ {
45                 a := a1
46                 m := m1
47                 if i%10 == 0 {
48                         a = a2
49                         m = m2
50                 }
51
52                 // N.B. Profiles only distinguish calls on a per-line level,
53                 // making the two calls ambiguous. However because the
54                 // interfaces and implementations are mutually exclusive,
55                 // devirtualization can still select the correct callee for
56                 // each.
57                 //
58                 // If they were not mutually exclusive (for example, two Add
59                 // calls), then we could not definitively select the correct
60                 // callee.
61                 sink += m.Multiply(42, a.Add(1, 2))
62         }
63 }
64
65 func init() {
66         // TODO: until https://golang.org/cl/497175 or similar lands,
67         // we need to create an explicit reference to callees
68         // in another package for devirtualization to work.
69         m := mult.Mult{}
70         m.Multiply(42, 0)
71         n := mult.NegMult{}
72         n.Multiply(42, 0)
73 }