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)