github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/cmd/compile/internal/devirtualize/pgo.go (about) 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 package devirtualize 6 7 import ( 8 "github.com/shogo82148/std/cmd/compile/internal/ir" 9 "github.com/shogo82148/std/cmd/compile/internal/pgo" 10 ) 11 12 // CallStat summarizes a single call site. 13 // 14 // This is used only for debug logging. 15 type CallStat struct { 16 Pkg string 17 Pos string 18 19 Caller string 20 21 // Direct or indirect call. 22 Direct bool 23 24 // For indirect calls, interface call or other indirect function call. 25 Interface bool 26 27 // Total edge weight from this call site. 28 Weight int64 29 30 // Hottest callee from this call site, regardless of type 31 // compatibility. 32 Hottest string 33 HottestWeight int64 34 35 // Devirtualized callee if != "". 36 // 37 // Note that this may be different than Hottest because we apply 38 // type-check restrictions, which helps distinguish multiple calls on 39 // the same line. 40 Devirtualized string 41 DevirtualizedWeight int64 42 } 43 44 // ProfileGuided performs call devirtualization of indirect calls based on 45 // profile information. 46 // 47 // Specifically, it performs conditional devirtualization of interface calls or 48 // function value calls for the hottest callee. 49 // 50 // That is, for interface calls it performs a transformation like: 51 // 52 // type Iface interface { 53 // Foo() 54 // } 55 // 56 // type Concrete struct{} 57 // 58 // func (Concrete) Foo() {} 59 // 60 // func foo(i Iface) { 61 // i.Foo() 62 // } 63 // 64 // to: 65 // 66 // func foo(i Iface) { 67 // if c, ok := i.(Concrete); ok { 68 // c.Foo() 69 // } else { 70 // i.Foo() 71 // } 72 // } 73 // 74 // For function value calls it performs a transformation like: 75 // 76 // func Concrete() {} 77 // 78 // func foo(fn func()) { 79 // fn() 80 // } 81 // 82 // to: 83 // 84 // func foo(fn func()) { 85 // if internal/abi.FuncPCABIInternal(fn) == internal/abi.FuncPCABIInternal(Concrete) { 86 // Concrete() 87 // } else { 88 // fn() 89 // } 90 // } 91 // 92 // The primary benefit of this transformation is enabling inlining of the 93 // direct call. 94 func ProfileGuided(fn *ir.Func, p *pgo.Profile)