]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/compile/internal/test/testdata/pgo/devirtualize/devirt.go
4748e19e10036716066bbdf27fbc8e12f3d67db2
[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 // Devirtualization of callees from transitive dependencies should work even if
15 // they aren't directly referenced in the package. See #61577.
16 //
17 // Dots in the last package path component are escaped in symbol names. Use one
18 // to ensure the escaping doesn't break lookup.
19 import "example.com/pgo/devirtualize/mult.pkg"
20
21 var sink int
22
23 type Adder interface {
24         Add(a, b int) int
25 }
26
27 type Add struct{}
28
29 func (Add) Add(a, b int) int {
30         for i := 0; i < 1000; i++ {
31                 sink++
32         }
33         return a + b
34 }
35
36 type Sub struct{}
37
38 func (Sub) Add(a, b int) int {
39         for i := 0; i < 1000; i++ {
40                 sink++
41         }
42         return a - b
43 }
44
45 // Exercise calls mostly a1 and m1.
46 //
47 //go:noinline
48 func Exercise(iter int, a1, a2 Adder, m1, m2 mult.Multiplier) {
49         for i := 0; i < iter; i++ {
50                 a := a1
51                 m := m1
52                 if i%10 == 0 {
53                         a = a2
54                         m = m2
55                 }
56
57                 // N.B. Profiles only distinguish calls on a per-line level,
58                 // making the two calls ambiguous. However because the
59                 // interfaces and implementations are mutually exclusive,
60                 // devirtualization can still select the correct callee for
61                 // each.
62                 //
63                 // If they were not mutually exclusive (for example, two Add
64                 // calls), then we could not definitively select the correct
65                 // callee.
66                 sink += m.Multiply(42, a.Add(1, 2))
67         }
68 }