github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/cmd/compile/internal/ir/func.go (about)

     1  // Copyright 2020 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 ir
     6  
     7  import (
     8  	"github.com/shogo82148/std/cmd/compile/internal/types"
     9  	"github.com/shogo82148/std/cmd/internal/obj"
    10  	"github.com/shogo82148/std/cmd/internal/src"
    11  )
    12  
    13  // A Func corresponds to a single function in a Go program
    14  // (and vice versa: each function is denoted by exactly one *Func).
    15  //
    16  // There are multiple nodes that represent a Func in the IR.
    17  //
    18  // The ONAME node (Func.Nname) is used for plain references to it.
    19  // The ODCLFUNC node (the Func itself) is used for its declaration code.
    20  // The OCLOSURE node (Func.OClosure) is used for a reference to a
    21  // function literal.
    22  //
    23  // An imported function will have an ONAME node which points to a Func
    24  // with an empty body.
    25  // A declared function or method has an ODCLFUNC (the Func itself) and an ONAME.
    26  // A function literal is represented directly by an OCLOSURE, but it also
    27  // has an ODCLFUNC (and a matching ONAME) representing the compiled
    28  // underlying form of the closure, which accesses the captured variables
    29  // using a special data structure passed in a register.
    30  //
    31  // A method declaration is represented like functions, except f.Sym
    32  // will be the qualified method name (e.g., "T.m").
    33  //
    34  // A method expression (T.M) is represented as an OMETHEXPR node,
    35  // in which n.Left and n.Right point to the type and method, respectively.
    36  // Each distinct mention of a method expression in the source code
    37  // constructs a fresh node.
    38  //
    39  // A method value (t.M) is represented by ODOTMETH/ODOTINTER
    40  // when it is called directly and by OMETHVALUE otherwise.
    41  // These are like method expressions, except that for ODOTMETH/ODOTINTER,
    42  // the method name is stored in Sym instead of Right.
    43  // Each OMETHVALUE ends up being implemented as a new
    44  // function, a bit like a closure, with its own ODCLFUNC.
    45  // The OMETHVALUE uses n.Func to record the linkage to
    46  // the generated ODCLFUNC, but there is no
    47  // pointer from the Func back to the OMETHVALUE.
    48  type Func struct {
    49  	miniNode
    50  	Body Nodes
    51  
    52  	Nname    *Name
    53  	OClosure *ClosureExpr
    54  
    55  	// ONAME nodes for all params/locals for this func/closure, does NOT
    56  	// include closurevars until transforming closures during walk.
    57  	// Names must be listed PPARAMs, PPARAMOUTs, then PAUTOs,
    58  	// with PPARAMs and PPARAMOUTs in order corresponding to the function signature.
    59  	// Anonymous and blank params are declared as ~pNN (for PPARAMs) and ~rNN (for PPARAMOUTs).
    60  	Dcl []*Name
    61  
    62  	// ClosureVars lists the free variables that are used within a
    63  	// function literal, but formally declared in an enclosing
    64  	// function. The variables in this slice are the closure function's
    65  	// own copy of the variables, which are used within its function
    66  	// body. They will also each have IsClosureVar set, and will have
    67  	// Byval set if they're captured by value.
    68  	ClosureVars []*Name
    69  
    70  	// Enclosed functions that need to be compiled.
    71  	// Populated during walk.
    72  	Closures []*Func
    73  
    74  	// Parents records the parent scope of each scope within a
    75  	// function. The root scope (0) has no parent, so the i'th
    76  	// scope's parent is stored at Parents[i-1].
    77  	Parents []ScopeID
    78  
    79  	// Marks records scope boundary changes.
    80  	Marks []Mark
    81  
    82  	FieldTrack map[*obj.LSym]struct{}
    83  	DebugInfo  interface{}
    84  	LSym       *obj.LSym
    85  
    86  	Inl *Inline
    87  
    88  	// funcLitGen and goDeferGen track how many closures have been
    89  	// created in this function for function literals and go/defer
    90  	// wrappers, respectively. Used by closureName for creating unique
    91  	// function names.
    92  	//
    93  	// Tracking goDeferGen separately avoids wrappers throwing off
    94  	// function literal numbering (e.g., runtime/trace_test.TestTraceSymbolize.func11).
    95  	funcLitGen int32
    96  	goDeferGen int32
    97  
    98  	Label int32
    99  
   100  	Endlineno src.XPos
   101  	WBPos     src.XPos
   102  
   103  	Pragma PragmaFlag
   104  
   105  	flags bitset16
   106  
   107  	// ABI is a function's "definition" ABI. This is the ABI that
   108  	// this function's generated code is expecting to be called by.
   109  	//
   110  	// For most functions, this will be obj.ABIInternal. It may be
   111  	// a different ABI for functions defined in assembly or ABI wrappers.
   112  	//
   113  	// This is included in the export data and tracked across packages.
   114  	ABI obj.ABI
   115  	// ABIRefs is the set of ABIs by which this function is referenced.
   116  	// For ABIs other than this function's definition ABI, the
   117  	// compiler generates ABI wrapper functions. This is only tracked
   118  	// within a package.
   119  	ABIRefs obj.ABISet
   120  
   121  	NumDefers  int32
   122  	NumReturns int32
   123  
   124  	// NWBRCalls records the LSyms of functions called by this
   125  	// function for go:nowritebarrierrec analysis. Only filled in
   126  	// if nowritebarrierrecCheck != nil.
   127  	NWBRCalls *[]SymAndPos
   128  
   129  	// For wrapper functions, WrappedFunc point to the original Func.
   130  	// Currently only used for go/defer wrappers.
   131  	WrappedFunc *Func
   132  
   133  	// WasmImport is used by the //go:wasmimport directive to store info about
   134  	// a WebAssembly function import.
   135  	WasmImport *WasmImport
   136  }
   137  
   138  // WasmImport stores metadata associated with the //go:wasmimport pragma.
   139  type WasmImport struct {
   140  	Module string
   141  	Name   string
   142  }
   143  
   144  // NewFunc returns a new Func with the given name and type.
   145  //
   146  // fpos is the position of the "func" token, and npos is the position
   147  // of the name identifier.
   148  //
   149  // TODO(mdempsky): I suspect there's no need for separate fpos and
   150  // npos.
   151  func NewFunc(fpos, npos src.XPos, sym *types.Sym, typ *types.Type) *Func
   152  
   153  func (f *Func) Type() *types.Type
   154  func (f *Func) Sym() *types.Sym
   155  func (f *Func) Linksym() *obj.LSym
   156  func (f *Func) LinksymABI(abi obj.ABI) *obj.LSym
   157  
   158  // An Inline holds fields used for function bodies that can be inlined.
   159  type Inline struct {
   160  	Cost int32
   161  
   162  	// Copy of Func.Dcl for use during inlining. This copy is needed
   163  	// because the function's Dcl may change from later compiler
   164  	// transformations. This field is also populated when a function
   165  	// from another package is imported and inlined.
   166  	Dcl     []*Name
   167  	HaveDcl bool
   168  
   169  	// Function properties, encoded as a string (these are used for
   170  	// making inlining decisions). See cmd/compile/internal/inline/inlheur.
   171  	Properties string
   172  
   173  	// CanDelayResults reports whether it's safe for the inliner to delay
   174  	// initializing the result parameters until immediately before the
   175  	// "return" statement.
   176  	CanDelayResults bool
   177  }
   178  
   179  // A Mark represents a scope boundary.
   180  type Mark struct {
   181  	// Pos is the position of the token that marks the scope
   182  	// change.
   183  	Pos src.XPos
   184  
   185  	// Scope identifies the innermost scope to the right of Pos.
   186  	Scope ScopeID
   187  }
   188  
   189  // A ScopeID represents a lexical scope within a function.
   190  type ScopeID int32
   191  
   192  type SymAndPos struct {
   193  	Sym *obj.LSym
   194  	Pos src.XPos
   195  }
   196  
   197  func (f *Func) Dupok() bool
   198  func (f *Func) Wrapper() bool
   199  func (f *Func) ABIWrapper() bool
   200  func (f *Func) Needctxt() bool
   201  func (f *Func) IsHiddenClosure() bool
   202  func (f *Func) IsDeadcodeClosure() bool
   203  func (f *Func) HasDefer() bool
   204  func (f *Func) NilCheckDisabled() bool
   205  func (f *Func) InlinabilityChecked() bool
   206  func (f *Func) NeverReturns() bool
   207  func (f *Func) OpenCodedDeferDisallowed() bool
   208  func (f *Func) ClosureResultsLost() bool
   209  func (f *Func) IsPackageInit() bool
   210  
   211  func (f *Func) SetDupok(b bool)
   212  func (f *Func) SetWrapper(b bool)
   213  func (f *Func) SetABIWrapper(b bool)
   214  func (f *Func) SetNeedctxt(b bool)
   215  func (f *Func) SetIsHiddenClosure(b bool)
   216  func (f *Func) SetIsDeadcodeClosure(b bool)
   217  func (f *Func) SetHasDefer(b bool)
   218  func (f *Func) SetNilCheckDisabled(b bool)
   219  func (f *Func) SetInlinabilityChecked(b bool)
   220  func (f *Func) SetNeverReturns(b bool)
   221  func (f *Func) SetOpenCodedDeferDisallowed(b bool)
   222  func (f *Func) SetClosureResultsLost(b bool)
   223  func (f *Func) SetIsPackageInit(b bool)
   224  
   225  func (f *Func) SetWBPos(pos src.XPos)
   226  
   227  // FuncName returns the name (without the package) of the function f.
   228  func FuncName(f *Func) string
   229  
   230  // PkgFuncName returns the name of the function referenced by f, with package
   231  // prepended.
   232  //
   233  // This differs from the compiler's internal convention where local functions
   234  // lack a package. This is primarily useful when the ultimate consumer of this
   235  // is a human looking at message.
   236  func PkgFuncName(f *Func) string
   237  
   238  // LinkFuncName returns the name of the function f, as it will appear in the
   239  // symbol table of the final linked binary.
   240  func LinkFuncName(f *Func) string
   241  
   242  // ParseLinkFuncName parsers a symbol name (as returned from LinkFuncName) back
   243  // to the package path and local symbol name.
   244  func ParseLinkFuncName(name string) (pkg, sym string, err error)
   245  
   246  var CurFunc *Func
   247  
   248  // WithFunc invokes do with CurFunc and base.Pos set to curfn and
   249  // curfn.Pos(), respectively, and then restores their previous values
   250  // before returning.
   251  func WithFunc(curfn *Func, do func())
   252  
   253  func FuncSymName(s *types.Sym) string
   254  
   255  // ClosureDebugRuntimeCheck applies boilerplate checks for debug flags
   256  // and compiling runtime.
   257  func ClosureDebugRuntimeCheck(clo *ClosureExpr)
   258  
   259  // IsTrivialClosure reports whether closure clo has an
   260  // empty list of captured vars.
   261  func IsTrivialClosure(clo *ClosureExpr) bool
   262  
   263  // NewClosureFunc creates a new Func to represent a function literal
   264  // with the given type.
   265  //
   266  // fpos the position used for the underlying ODCLFUNC and ONAME,
   267  // whereas cpos is the position used for the OCLOSURE. They're
   268  // separate because in the presence of inlining, the OCLOSURE node
   269  // should have an inline-adjusted position, whereas the ODCLFUNC and
   270  // ONAME must not.
   271  //
   272  // outerfn is the enclosing function, if any. The returned function is
   273  // appending to pkg.Funcs.
   274  //
   275  // why is the reason we're generating this Func. It can be OCLOSURE
   276  // (for a normal function literal) or OGO or ODEFER (for wrapping a
   277  // call expression that has parameters or results).
   278  func NewClosureFunc(fpos, cpos src.XPos, why Op, typ *types.Type, outerfn *Func, pkg *Package) *Func
   279  
   280  // IsFuncPCIntrinsic returns whether n is a direct call of internal/abi.FuncPCABIxxx functions.
   281  func IsFuncPCIntrinsic(n *CallExpr) bool
   282  
   283  // IsIfaceOfFunc inspects whether n is an interface conversion from a direct
   284  // reference of a func. If so, it returns referenced Func; otherwise nil.
   285  //
   286  // This is only usable before walk.walkConvertInterface, which converts to an
   287  // OMAKEFACE.
   288  func IsIfaceOfFunc(n Node) *Func
   289  
   290  // FuncPC returns a uintptr-typed expression that evaluates to the PC of a
   291  // function as uintptr, as returned by internal/abi.FuncPC{ABI0,ABIInternal}.
   292  //
   293  // n should be a Node of an interface type, as is passed to
   294  // internal/abi.FuncPC{ABI0,ABIInternal}.
   295  //
   296  // TODO(prattmic): Since n is simply an interface{} there is no assertion that
   297  // it is actually a function at all. Perhaps we should emit a runtime type
   298  // assertion?
   299  func FuncPC(pos src.XPos, n Node, wantABI obj.ABI) Node
   300  
   301  // DeclareParams creates Names for all of the parameters in fn's
   302  // signature and adds them to fn.Dcl.
   303  //
   304  // If setNname is true, then it also sets types.Field.Nname for each
   305  // parameter.
   306  func (fn *Func) DeclareParams(setNname bool)