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)