github.com/amarpal/go-tools@v0.0.0-20240422043104-40142f59f616/go/ir/ssa.go (about) 1 // Copyright 2013 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 // This package defines a high-level intermediate representation for 8 // Go programs using static single-information (SSI) form. 9 10 import ( 11 "fmt" 12 "go/ast" 13 "go/constant" 14 "go/token" 15 "go/types" 16 "math/big" 17 "sync" 18 19 "github.com/amarpal/go-tools/go/types/typeutil" 20 ) 21 22 const ( 23 // Replace CompositeValue with only constant values with AggregateConst. Currently disabled because it breaks field 24 // tracking in U1000. 25 doSimplifyConstantCompositeValues = false 26 ) 27 28 type ID int 29 30 // A Program is a partial or complete Go program converted to IR form. 31 type Program struct { 32 Fset *token.FileSet // position information for the files of this Program 33 PrintFunc string // create ir.html for function specified in PrintFunc 34 imported map[string]*Package // all importable Packages, keyed by import path 35 packages map[*types.Package]*Package // all loaded Packages, keyed by object 36 mode BuilderMode // set of mode bits for IR construction 37 MethodSets typeutil.MethodSetCache // cache of type-checker's method-sets 38 39 methodsMu sync.Mutex // guards the following maps: 40 methodSets typeutil.Map[*methodSet] // maps type to its concrete methodSet 41 runtimeTypes typeutil.Map[bool] // types for which rtypes are needed 42 canon typeutil.Map[types.Type] // type canonicalization map 43 bounds map[*types.Func]*Function // bounds for curried x.Method closures 44 thunks map[selectionKey]*Function // thunks for T.Method expressions 45 } 46 47 // A Package is a single analyzed Go package containing Members for 48 // all package-level functions, variables, constants and types it 49 // declares. These may be accessed directly via Members, or via the 50 // type-specific accessor methods Func, Type, Var and Const. 51 // 52 // Members also contains entries for "init" (the synthetic package 53 // initializer) and "init#%d", the nth declared init function, 54 // and unspecified other things too. 55 type Package struct { 56 Prog *Program // the owning program 57 Pkg *types.Package // the corresponding go/types.Package 58 Members map[string]Member // all package members keyed by name (incl. init and init#%d) 59 Functions []*Function // all functions, excluding anonymous ones 60 values map[types.Object]Value // package members (incl. types and methods), keyed by object 61 init *Function // Func("init"); the package's init function 62 debug bool // include full debug info in this package 63 printFunc string // which function to print in HTML form 64 65 // The following fields are set transiently, then cleared 66 // after building. 67 buildOnce sync.Once // ensures package building occurs once 68 ninit int32 // number of init functions 69 info *types.Info // package type information 70 files []*ast.File // package ASTs 71 } 72 73 // A Member is a member of a Go package, implemented by *NamedConst, 74 // *Global, *Function, or *Type; they are created by package-level 75 // const, var, func and type declarations respectively. 76 type Member interface { 77 Name() string // declared name of the package member 78 String() string // package-qualified name of the package member 79 RelString(*types.Package) string // like String, but relative refs are unqualified 80 Object() types.Object // typechecker's object for this member, if any 81 Type() types.Type // type of the package member 82 Token() token.Token // token.{VAR,FUNC,CONST,TYPE} 83 Package() *Package // the containing package 84 } 85 86 // A Type is a Member of a Package representing a package-level named type. 87 type Type struct { 88 object *types.TypeName 89 pkg *Package 90 } 91 92 // A NamedConst is a Member of a Package representing a package-level 93 // named constant. 94 // 95 // Pos() returns the position of the declaring ast.ValueSpec.Names[*] 96 // identifier. 97 // 98 // NB: a NamedConst is not a Value; it contains a constant Value, which 99 // it augments with the name and position of its 'const' declaration. 100 type NamedConst struct { 101 object *types.Const 102 Value *Const 103 pkg *Package 104 } 105 106 // A Value is an IR value that can be referenced by an instruction. 107 type Value interface { 108 setID(ID) 109 110 // Name returns the name of this value, and determines how 111 // this Value appears when used as an operand of an 112 // Instruction. 113 // 114 // This is the same as the source name for Parameters, 115 // Builtins, Functions, FreeVars, Globals. 116 // For constants, it is a representation of the constant's value 117 // and type. For all other Values this is the name of the 118 // virtual register defined by the instruction. 119 // 120 // The name of an IR Value is not semantically significant, 121 // and may not even be unique within a function. 122 Name() string 123 124 // ID returns the ID of this value. IDs are unique within a single 125 // function and are densely numbered, but may contain gaps. 126 // Values and other Instructions share the same ID space. 127 // Globally, values are identified by their addresses. However, 128 // IDs exist to facilitate efficient storage of mappings between 129 // values and data when analysing functions. 130 // 131 // NB: IDs are allocated late in the IR construction process and 132 // are not available to early stages of said process. 133 ID() ID 134 135 // If this value is an Instruction, String returns its 136 // disassembled form; otherwise it returns unspecified 137 // human-readable information about the Value, such as its 138 // kind, name and type. 139 String() string 140 141 // Type returns the type of this value. Many instructions 142 // (e.g. IndexAddr) change their behaviour depending on the 143 // types of their operands. 144 Type() types.Type 145 146 // Parent returns the function to which this Value belongs. 147 // It returns nil for named Functions, Builtin and Global. 148 Parent() *Function 149 150 // Referrers returns the list of instructions that have this 151 // value as one of their operands; it may contain duplicates 152 // if an instruction has a repeated operand. 153 // 154 // Referrers actually returns a pointer through which the 155 // caller may perform mutations to the object's state. 156 // 157 // Referrers is currently only defined if Parent()!=nil, 158 // i.e. for the function-local values FreeVar, Parameter, 159 // Functions (iff anonymous) and all value-defining instructions. 160 // It returns nil for named Functions, Builtin and Global. 161 // 162 // Instruction.Operands contains the inverse of this relation. 163 Referrers() *[]Instruction 164 165 Operands(rands []*Value) []*Value // nil for non-Instructions 166 167 // Source returns the AST node responsible for creating this 168 // value. A single AST node may be responsible for more than one 169 // value, and not all values have an associated AST node. 170 // 171 // Do not use this method to find a Value given an ast.Expr; use 172 // ValueForExpr instead. 173 Source() ast.Node 174 175 // Pos returns Source().Pos() if Source is not nil, else it 176 // returns token.NoPos. 177 Pos() token.Pos 178 } 179 180 // An Instruction is an IR instruction that computes a new Value or 181 // has some effect. 182 // 183 // An Instruction that defines a value (e.g. BinOp) also implements 184 // the Value interface; an Instruction that only has an effect (e.g. Store) 185 // does not. 186 type Instruction interface { 187 setSource(ast.Node) 188 setID(ID) 189 190 Comment() string 191 192 // String returns the disassembled form of this value. 193 // 194 // Examples of Instructions that are Values: 195 // "BinOp <int> {+} t1 t2" (BinOp) 196 // "Call <int> len t1" (Call) 197 // Note that the name of the Value is not printed. 198 // 199 // Examples of Instructions that are not Values: 200 // "Return t1" (Return) 201 // "Store {int} t2 t1" (Store) 202 // 203 // (The separation of Value.Name() from Value.String() is useful 204 // for some analyses which distinguish the operation from the 205 // value it defines, e.g., 'y = local int' is both an allocation 206 // of memory 'local int' and a definition of a pointer y.) 207 String() string 208 209 // ID returns the ID of this instruction. IDs are unique within a single 210 // function and are densely numbered, but may contain gaps. 211 // Globally, instructions are identified by their addresses. However, 212 // IDs exist to facilitate efficient storage of mappings between 213 // instructions and data when analysing functions. 214 // 215 // NB: IDs are allocated late in the IR construction process and 216 // are not available to early stages of said process. 217 ID() ID 218 219 // Parent returns the function to which this instruction 220 // belongs. 221 Parent() *Function 222 223 // Block returns the basic block to which this instruction 224 // belongs. 225 Block() *BasicBlock 226 227 // setBlock sets the basic block to which this instruction belongs. 228 setBlock(*BasicBlock) 229 230 // Operands returns the operands of this instruction: the 231 // set of Values it references. 232 // 233 // Specifically, it appends their addresses to rands, a 234 // user-provided slice, and returns the resulting slice, 235 // permitting avoidance of memory allocation. 236 // 237 // The operands are appended in undefined order, but the order 238 // is consistent for a given Instruction; the addresses are 239 // always non-nil but may point to a nil Value. Clients may 240 // store through the pointers, e.g. to effect a value 241 // renaming. 242 // 243 // Value.Referrers is a subset of the inverse of this 244 // relation. (Referrers are not tracked for all types of 245 // Values.) 246 Operands(rands []*Value) []*Value 247 248 Referrers() *[]Instruction // nil for non-Values 249 250 // Source returns the AST node responsible for creating this 251 // instruction. A single AST node may be responsible for more than 252 // one instruction, and not all instructions have an associated 253 // AST node. 254 Source() ast.Node 255 256 // Pos returns Source().Pos() if Source is not nil, else it 257 // returns token.NoPos. 258 Pos() token.Pos 259 } 260 261 // A Node is a node in the IR value graph. Every concrete type that 262 // implements Node is also either a Value, an Instruction, or both. 263 // 264 // Node contains the methods common to Value and Instruction, plus the 265 // Operands and Referrers methods generalized to return nil for 266 // non-Instructions and non-Values, respectively. 267 // 268 // Node is provided to simplify IR graph algorithms. Clients should 269 // use the more specific and informative Value or Instruction 270 // interfaces where appropriate. 271 type Node interface { 272 setID(ID) 273 274 // Common methods: 275 ID() ID 276 String() string 277 Source() ast.Node 278 Pos() token.Pos 279 Parent() *Function 280 281 // Partial methods: 282 Operands(rands []*Value) []*Value // nil for non-Instructions 283 Referrers() *[]Instruction // nil for non-Values 284 } 285 286 type Synthetic int 287 288 const ( 289 SyntheticLoadedFromExportData Synthetic = iota + 1 290 SyntheticPackageInitializer 291 SyntheticThunk 292 SyntheticWrapper 293 SyntheticBound 294 SyntheticGeneric 295 ) 296 297 func (syn Synthetic) String() string { 298 switch syn { 299 case SyntheticLoadedFromExportData: 300 return "loaded from export data" 301 case SyntheticPackageInitializer: 302 return "package initializer" 303 case SyntheticThunk: 304 return "thunk" 305 case SyntheticWrapper: 306 return "wrapper" 307 case SyntheticBound: 308 return "bound" 309 case SyntheticGeneric: 310 return "generic" 311 default: 312 return fmt.Sprintf("Synthetic(%d)", syn) 313 } 314 } 315 316 // Function represents the parameters, results, and code of a function 317 // or method. 318 // 319 // If Blocks is nil, this indicates an external function for which no 320 // Go source code is available. In this case, FreeVars and Locals 321 // are nil too. Clients performing whole-program analysis must 322 // handle external functions specially. 323 // 324 // Blocks contains the function's control-flow graph (CFG). 325 // Blocks[0] is the function entry point; block order is not otherwise 326 // semantically significant, though it may affect the readability of 327 // the disassembly. 328 // To iterate over the blocks in dominance order, use DomPreorder(). 329 // 330 // A nested function (Parent()!=nil) that refers to one or more 331 // lexically enclosing local variables ("free variables") has FreeVars. 332 // Such functions cannot be called directly but require a 333 // value created by MakeClosure which, via its Bindings, supplies 334 // values for these parameters. 335 // 336 // If the function is a method (Signature.Recv() != nil) then the first 337 // element of Params is the receiver parameter. 338 // 339 // A Go package may declare many functions called "init". 340 // For each one, Object().Name() returns "init" but Name() returns 341 // "init#1", etc, in declaration order. 342 // 343 // Pos() returns the declaring ast.FuncLit.Type.Func or the position 344 // of the ast.FuncDecl.Name, if the function was explicit in the 345 // source. Synthetic wrappers, for which Synthetic != "", may share 346 // the same position as the function they wrap. 347 // Syntax.Pos() always returns the position of the declaring "func" token. 348 // 349 // Type() returns the function's Signature. 350 type Function struct { 351 node 352 353 name string 354 object types.Object // a declared *types.Func or one of its wrappers 355 method *types.Selection // info about provenance of synthetic methods 356 Signature *types.Signature 357 generics instanceWrapperMap 358 359 Synthetic Synthetic 360 parent *Function // enclosing function if anon; nil if global 361 Pkg *Package // enclosing package; nil for shared funcs (wrappers and error.Error) 362 Prog *Program // enclosing program 363 Params []*Parameter // function parameters; for methods, includes receiver 364 FreeVars []*FreeVar // free variables whose values must be supplied by closure 365 Locals []*Alloc // local variables of this function 366 Blocks []*BasicBlock // basic blocks of the function; nil => external 367 Exit *BasicBlock // The function's exit block 368 AnonFuncs []*Function // anonymous functions directly beneath this one 369 referrers []Instruction // referring instructions (iff Parent() != nil) 370 NoReturn NoReturn // Calling this function will always terminate control flow. 371 372 *functionBody 373 } 374 375 type instanceWrapperMap struct { 376 h typeutil.Hasher 377 entries map[uint32][]struct { 378 key *types.TypeList 379 val *Function 380 } 381 len int 382 } 383 384 func typeListIdentical(l1, l2 *types.TypeList) bool { 385 if l1.Len() != l2.Len() { 386 return false 387 } 388 for i := 0; i < l1.Len(); i++ { 389 t1 := l1.At(i) 390 t2 := l2.At(i) 391 if !types.Identical(t1, t2) { 392 return false 393 } 394 } 395 return true 396 } 397 398 func (m *instanceWrapperMap) At(key *types.TypeList) *Function { 399 if m.entries == nil { 400 m.entries = make(map[uint32][]struct { 401 key *types.TypeList 402 val *Function 403 }) 404 m.h = typeutil.MakeHasher() 405 } 406 407 var hash uint32 408 for i := 0; i < key.Len(); i++ { 409 t := key.At(i) 410 hash += m.h.Hash(t) 411 } 412 413 for _, e := range m.entries[hash] { 414 if typeListIdentical(e.key, key) { 415 return e.val 416 } 417 } 418 return nil 419 } 420 421 func (m *instanceWrapperMap) Set(key *types.TypeList, val *Function) { 422 if m.entries == nil { 423 m.entries = make(map[uint32][]struct { 424 key *types.TypeList 425 val *Function 426 }) 427 m.h = typeutil.MakeHasher() 428 } 429 430 var hash uint32 431 for i := 0; i < key.Len(); i++ { 432 t := key.At(i) 433 hash += m.h.Hash(t) 434 } 435 for i, e := range m.entries[hash] { 436 if typeListIdentical(e.key, key) { 437 m.entries[hash][i].val = val 438 return 439 } 440 } 441 m.entries[hash] = append(m.entries[hash], struct { 442 key *types.TypeList 443 val *Function 444 }{key, val}) 445 m.len++ 446 } 447 448 func (m *instanceWrapperMap) Len() int { 449 return m.len 450 } 451 452 type NoReturn uint8 453 454 const ( 455 Returns NoReturn = iota 456 AlwaysExits 457 AlwaysUnwinds 458 NeverReturns 459 ) 460 461 type constValue struct { 462 c Constant 463 idx int 464 } 465 466 type functionBody struct { 467 // The following fields are set transiently during building, 468 // then cleared. 469 currentBlock *BasicBlock // where to emit code 470 objects map[types.Object]Value // addresses of local variables 471 namedResults []*Alloc // tuple of named results 472 implicitResults []*Alloc // tuple of results 473 targets *targets // linked stack of branch targets 474 lblocks map[types.Object]*lblock // labelled blocks 475 476 consts map[constKey]constValue 477 aggregateConsts typeutil.Map[[]*AggregateConst] 478 479 wr *HTMLWriter 480 fakeExits BlockSet 481 blocksets [5]BlockSet 482 hasDefer bool 483 484 // a contiguous block of instructions that will be used by blocks, 485 // to avoid making multiple allocations. 486 scratchInstructions []Instruction 487 } 488 489 func (fn *Function) results() []*Alloc { 490 if len(fn.namedResults) > 0 { 491 return fn.namedResults 492 } 493 return fn.implicitResults 494 } 495 496 // BasicBlock represents an IR basic block. 497 // 498 // The final element of Instrs is always an explicit transfer of 499 // control (If, Jump, Return, Panic, or Unreachable). 500 // 501 // A block may contain no Instructions only if it is unreachable, 502 // i.e., Preds is nil. Empty blocks are typically pruned. 503 // 504 // BasicBlocks and their Preds/Succs relation form a (possibly cyclic) 505 // graph independent of the IR Value graph: the control-flow graph or 506 // CFG. It is illegal for multiple edges to exist between the same 507 // pair of blocks. 508 // 509 // Each BasicBlock is also a node in the dominator tree of the CFG. 510 // The tree may be navigated using Idom()/Dominees() and queried using 511 // Dominates(). 512 // 513 // The order of Preds and Succs is significant (to Phi and If 514 // instructions, respectively). 515 type BasicBlock struct { 516 Index int // index of this block within Parent().Blocks 517 Comment string // optional label; no semantic significance 518 parent *Function // parent function 519 Instrs []Instruction // instructions in order 520 Preds, Succs []*BasicBlock // predecessors and successors 521 succs2 [2]*BasicBlock // initial space for Succs 522 dom domInfo // dominator tree info 523 pdom domInfo // post-dominator tree info 524 post int 525 gaps int // number of nil Instrs (transient) 526 rundefers int // number of rundefers (transient) 527 } 528 529 // Pure values ---------------------------------------- 530 531 // A FreeVar represents a free variable of the function to which it 532 // belongs. 533 // 534 // FreeVars are used to implement anonymous functions, whose free 535 // variables are lexically captured in a closure formed by 536 // MakeClosure. The value of such a free var is an Alloc or another 537 // FreeVar and is considered a potentially escaping heap address, with 538 // pointer type. 539 // 540 // FreeVars are also used to implement bound method closures. Such a 541 // free var represents the receiver value and may be of any type that 542 // has concrete methods. 543 // 544 // Pos() returns the position of the value that was captured, which 545 // belongs to an enclosing function. 546 type FreeVar struct { 547 node 548 549 name string 550 typ types.Type 551 parent *Function 552 referrers []Instruction 553 554 // Transiently needed during building. 555 outer Value // the Value captured from the enclosing context. 556 } 557 558 // A Parameter represents an input parameter of a function. 559 type Parameter struct { 560 register 561 562 name string 563 object types.Object // a *types.Var; nil for non-source locals 564 } 565 566 // A Const represents the value of a constant expression. 567 // 568 // The underlying type of a constant may be any boolean, numeric, or 569 // string type. In addition, a Const may represent the nil value of 570 // any reference type---interface, map, channel, pointer, slice, or 571 // function---but not "untyped nil". 572 // 573 // All source-level constant expressions are represented by a Const 574 // of the same type and value. 575 // 576 // Value holds the exact value of the constant, independent of its 577 // Type(), using the same representation as package go/constant uses for 578 // constants, or nil for a typed nil value. 579 // 580 // Pos() returns token.NoPos. 581 // 582 // Example printed form: 583 // 584 // Const <int> {42} 585 // Const <untyped string> {"test"} 586 // Const <MyComplex> {(3 + 4i)} 587 type Const struct { 588 register 589 590 Value constant.Value 591 } 592 593 type AggregateConst struct { 594 register 595 596 Values []Value 597 } 598 599 type CompositeValue struct { 600 register 601 602 // Bitmap records which elements were explicitly provided. For example, [4]byte{2: x} would have a bitmap of 0010. 603 Bitmap big.Int 604 // The number of bits set in Bitmap 605 NumSet int 606 // Dense list of values in the composite literal. Omitted elements are filled in with zero values. 607 Values []Value 608 } 609 610 // TODO add the element's zero constant to ArrayConst 611 type ArrayConst struct { 612 register 613 } 614 615 type GenericConst struct { 616 register 617 } 618 619 type Constant interface { 620 Instruction 621 Value 622 aConstant() 623 RelString(*types.Package) string 624 equal(Constant) bool 625 setType(types.Type) 626 } 627 628 func (*Const) aConstant() {} 629 func (*AggregateConst) aConstant() {} 630 func (*ArrayConst) aConstant() {} 631 func (*GenericConst) aConstant() {} 632 633 // A Global is a named Value holding the address of a package-level 634 // variable. 635 // 636 // Pos() returns the position of the ast.ValueSpec.Names[*] 637 // identifier. 638 type Global struct { 639 node 640 641 name string 642 object types.Object // a *types.Var; may be nil for synthetics e.g. init$guard 643 typ types.Type 644 645 Pkg *Package 646 } 647 648 // A Builtin represents a specific use of a built-in function, e.g. len. 649 // 650 // Builtins are immutable values. Builtins do not have addresses. 651 // Builtins can only appear in CallCommon.Func. 652 // 653 // Name() indicates the function: one of the built-in functions from the 654 // Go spec (excluding "make" and "new") or one of these ir-defined 655 // intrinsics: 656 // 657 // // wrapnilchk returns ptr if non-nil, panics otherwise. 658 // // (For use in indirection wrappers.) 659 // func ir:wrapnilchk(ptr *T, recvType, methodName string) *T 660 // 661 // // noreturnWasPanic returns true if the previously called 662 // // function panicked, false if it exited the process. 663 // func ir:noreturnWasPanic() bool 664 // 665 // Object() returns a *types.Builtin for built-ins defined by the spec, 666 // nil for others. 667 // 668 // Type() returns a *types.Signature representing the effective 669 // signature of the built-in for this call. 670 type Builtin struct { 671 node 672 673 name string 674 sig *types.Signature 675 } 676 677 // Value-defining instructions ---------------------------------------- 678 679 // The Alloc instruction reserves space for a variable of the given type, 680 // zero-initializes it, and yields its address. 681 // 682 // Alloc values are always addresses, and have pointer types, so the 683 // type of the allocated variable is actually 684 // Type().Underlying().(*types.Pointer).Elem(). 685 // 686 // If Heap is false, Alloc allocates space in the function's 687 // activation record (frame); we refer to an Alloc(Heap=false) as a 688 // "stack" alloc. Each stack Alloc returns the same address each time 689 // it is executed within the same activation; the space is 690 // re-initialized to zero. 691 // 692 // If Heap is true, Alloc allocates space in the heap; we 693 // refer to an Alloc(Heap=true) as a "heap" alloc. Each heap Alloc 694 // returns a different address each time it is executed. 695 // 696 // When Alloc is applied to a channel, map or slice type, it returns 697 // the address of an uninitialized (nil) reference of that kind; store 698 // the result of MakeSlice, MakeMap or MakeChan in that location to 699 // instantiate these types. 700 // 701 // Pos() returns the ast.CompositeLit.Lbrace for a composite literal, 702 // or the ast.CallExpr.Rparen for a call to new() or for a call that 703 // allocates a varargs slice. 704 // 705 // Example printed form: 706 // 707 // t1 = StackAlloc <*int> 708 // t2 = HeapAlloc <*int> (new) 709 type Alloc struct { 710 register 711 Heap bool 712 index int // dense numbering; for lifting 713 } 714 715 var _ Instruction = (*Sigma)(nil) 716 var _ Value = (*Sigma)(nil) 717 718 // The Sigma instruction represents an SSI σ-node, which splits values 719 // at branches in the control flow. 720 // 721 // Conceptually, σ-nodes exist at the end of blocks that branch and 722 // constitute parallel assignments to one value per destination block. 723 // However, such a representation would be awkward to work with, so 724 // instead we place σ-nodes at the beginning of branch targets. The 725 // From field denotes to which incoming edge the node applies. 726 // 727 // Within a block, all σ-nodes must appear before all non-σ nodes. 728 // 729 // Example printed form: 730 // 731 // t2 = Sigma <int> [#0] t1 (x) 732 type Sigma struct { 733 register 734 From *BasicBlock 735 X Value 736 737 live bool // used during lifting 738 } 739 740 type CopyInfo uint64 741 742 const ( 743 CopyInfoUnspecified CopyInfo = 0 744 CopyInfoNotNil CopyInfo = 1 << iota 745 CopyInfoNotZeroLength 746 CopyInfoNotNegative 747 CopyInfoSingleConcreteType 748 CopyInfoClosed 749 ) 750 751 type Copy struct { 752 register 753 X Value 754 Why Instruction 755 Info CopyInfo 756 } 757 758 // The Phi instruction represents an SSA φ-node, which combines values 759 // that differ across incoming control-flow edges and yields a new 760 // value. Within a block, all φ-nodes must appear before all non-φ, non-σ 761 // nodes. 762 // 763 // Pos() returns the position of the && or || for short-circuit 764 // control-flow joins, or that of the *Alloc for φ-nodes inserted 765 // during SSA renaming. 766 // 767 // Example printed form: 768 // 769 // t3 = Phi <int> 2:t1 4:t2 (x) 770 type Phi struct { 771 register 772 Edges []Value // Edges[i] is value for Block().Preds[i] 773 774 live bool // used during lifting 775 } 776 777 // The Call instruction represents a function or method call. 778 // 779 // The Call instruction yields the function result if there is exactly 780 // one. Otherwise it returns a tuple, the components of which are 781 // accessed via Extract. 782 // 783 // See CallCommon for generic function call documentation. 784 // 785 // Pos() returns the ast.CallExpr.Lparen, if explicit in the source. 786 // 787 // Example printed form: 788 // 789 // t3 = Call <()> println t1 t2 790 // t4 = Call <()> foo$1 791 // t6 = Invoke <string> t5.String 792 type Call struct { 793 register 794 Call CallCommon 795 } 796 797 // The BinOp instruction yields the result of binary operation X Op Y. 798 // 799 // Pos() returns the ast.BinaryExpr.OpPos, if explicit in the source. 800 // 801 // Example printed form: 802 // 803 // t3 = BinOp <int> {+} t2 t1 804 type BinOp struct { 805 register 806 // One of: 807 // ADD SUB MUL QUO REM + - * / % 808 // AND OR XOR SHL SHR AND_NOT & | ^ << >> &^ 809 // EQL NEQ LSS LEQ GTR GEQ == != < <= < >= 810 Op token.Token 811 X, Y Value 812 } 813 814 // The UnOp instruction yields the result of Op X. 815 // XOR is bitwise complement. 816 // SUB is negation. 817 // NOT is logical negation. 818 // 819 // Example printed form: 820 // 821 // t2 = UnOp <int> {^} t1 822 type UnOp struct { 823 register 824 Op token.Token // One of: NOT SUB XOR ! - ^ 825 X Value 826 } 827 828 // The Load instruction loads a value from a memory address. 829 // 830 // For implicit memory loads, Pos() returns the position of the 831 // most closely associated source-level construct; the details are not 832 // specified. 833 // 834 // Example printed form: 835 // 836 // t2 = Load <int> t1 837 type Load struct { 838 register 839 X Value 840 } 841 842 // The ChangeType instruction applies to X a value-preserving type 843 // change to Type(). 844 // 845 // Type changes are permitted: 846 // - between a named type and its underlying type. 847 // - between two named types of the same underlying type. 848 // - between (possibly named) pointers to identical base types. 849 // - from a bidirectional channel to a read- or write-channel, 850 // optionally adding/removing a name. 851 // 852 // This operation cannot fail dynamically. 853 // 854 // Pos() returns the ast.CallExpr.Lparen, if the instruction arose 855 // from an explicit conversion in the source. 856 // 857 // Example printed form: 858 // 859 // t2 = ChangeType <*T> t1 860 type ChangeType struct { 861 register 862 X Value 863 } 864 865 // The Convert instruction yields the conversion of value X to type 866 // Type(). One or both of those types is basic (but possibly named). 867 // 868 // A conversion may change the value and representation of its operand. 869 // Conversions are permitted: 870 // - between real numeric types. 871 // - between complex numeric types. 872 // - between string and []byte or []rune. 873 // - between pointers and unsafe.Pointer. 874 // - between unsafe.Pointer and uintptr. 875 // - from (Unicode) integer to (UTF-8) string. 876 // 877 // A conversion may imply a type name change also. 878 // 879 // This operation cannot fail dynamically. 880 // 881 // Conversions of untyped string/number/bool constants to a specific 882 // representation are eliminated during IR construction. 883 // 884 // Pos() returns the ast.CallExpr.Lparen, if the instruction arose 885 // from an explicit conversion in the source. 886 // 887 // Example printed form: 888 // 889 // t2 = Convert <[]byte> t1 890 type Convert struct { 891 register 892 X Value 893 } 894 895 // ChangeInterface constructs a value of one interface type from a 896 // value of another interface type known to be assignable to it. 897 // This operation cannot fail. 898 // 899 // Pos() returns the ast.CallExpr.Lparen if the instruction arose from 900 // an explicit T(e) conversion; the ast.TypeAssertExpr.Lparen if the 901 // instruction arose from an explicit e.(T) operation; or token.NoPos 902 // otherwise. 903 // 904 // Example printed form: 905 // 906 // t2 = ChangeInterface <I1> t1 907 type ChangeInterface struct { 908 register 909 X Value 910 } 911 912 // The SliceToArrayPointer instruction yields the conversion of slice X to 913 // array pointer. 914 // 915 // Pos() returns the ast.CallExpr.Lparen, if the instruction arose 916 // from an explicit conversion in the source. 917 // 918 // Example printed form: 919 // 920 // t2 = SliceToArrayPointer <*[4]byte> t1 921 type SliceToArrayPointer struct { 922 register 923 X Value 924 } 925 926 // The SliceToArray instruction yields the conversion of slice X to 927 // array. 928 // 929 // Pos() returns the ast.CallExpr.Lparen, if the instruction arose 930 // from an explicit conversion in the source. 931 // 932 // Example printed form: 933 // 934 // t2 = SliceToArray <[4]byte> t1 935 type SliceToArray struct { 936 register 937 X Value 938 } 939 940 // MakeInterface constructs an instance of an interface type from a 941 // value of a concrete type. 942 // 943 // Use Program.MethodSets.MethodSet(X.Type()) to find the method-set 944 // of X, and Program.MethodValue(m) to find the implementation of a method. 945 // 946 // To construct the zero value of an interface type T, use: 947 // 948 // NewConst(constant.MakeNil(), T, pos) 949 // 950 // Pos() returns the ast.CallExpr.Lparen, if the instruction arose 951 // from an explicit conversion in the source. 952 // 953 // Example printed form: 954 // 955 // t2 = MakeInterface <interface{}> t1 956 type MakeInterface struct { 957 register 958 X Value 959 } 960 961 // The MakeClosure instruction yields a closure value whose code is 962 // Fn and whose free variables' values are supplied by Bindings. 963 // 964 // Type() returns a (possibly named) *types.Signature. 965 // 966 // Pos() returns the ast.FuncLit.Type.Func for a function literal 967 // closure or the ast.SelectorExpr.Sel for a bound method closure. 968 // 969 // Example printed form: 970 // 971 // t1 = MakeClosure <func()> foo$1 t1 t2 972 // t5 = MakeClosure <func(int)> (T).foo$bound t4 973 type MakeClosure struct { 974 register 975 Fn Value // always a *Function 976 Bindings []Value // values for each free variable in Fn.FreeVars 977 } 978 979 // The MakeMap instruction creates a new hash-table-based map object 980 // and yields a value of kind map. 981 // 982 // Type() returns a (possibly named) *types.Map. 983 // 984 // Pos() returns the ast.CallExpr.Lparen, if created by make(map), or 985 // the ast.CompositeLit.Lbrack if created by a literal. 986 // 987 // Example printed form: 988 // 989 // t1 = MakeMap <map[string]int> 990 // t2 = MakeMap <StringIntMap> t1 991 type MakeMap struct { 992 register 993 Reserve Value // initial space reservation; nil => default 994 } 995 996 // The MakeChan instruction creates a new channel object and yields a 997 // value of kind chan. 998 // 999 // Type() returns a (possibly named) *types.Chan. 1000 // 1001 // Pos() returns the ast.CallExpr.Lparen for the make(chan) that 1002 // created it. 1003 // 1004 // Example printed form: 1005 // 1006 // t3 = MakeChan <chan int> t1 1007 // t4 = MakeChan <chan IntChan> t2 1008 type MakeChan struct { 1009 register 1010 Size Value // int; size of buffer; zero => synchronous. 1011 } 1012 1013 // The MakeSlice instruction yields a slice of length Len backed by a 1014 // newly allocated array of length Cap. 1015 // 1016 // Both Len and Cap must be non-nil Values of integer type. 1017 // 1018 // (Alloc(types.Array) followed by Slice will not suffice because 1019 // Alloc can only create arrays of constant length.) 1020 // 1021 // Type() returns a (possibly named) *types.Slice. 1022 // 1023 // Pos() returns the ast.CallExpr.Lparen for the make([]T) that 1024 // created it. 1025 // 1026 // Example printed form: 1027 // 1028 // t3 = MakeSlice <[]string> t1 t2 1029 // t4 = MakeSlice <StringSlice> t1 t2 1030 type MakeSlice struct { 1031 register 1032 Len Value 1033 Cap Value 1034 } 1035 1036 // The Slice instruction yields a slice of an existing string, slice 1037 // or *array X between optional integer bounds Low and High. 1038 // 1039 // Dynamically, this instruction panics if X evaluates to a nil *array 1040 // pointer. 1041 // 1042 // Type() returns string if the type of X was string, otherwise a 1043 // *types.Slice with the same element type as X. 1044 // 1045 // Pos() returns the ast.SliceExpr.Lbrack if created by a x[:] slice 1046 // operation, the ast.CompositeLit.Lbrace if created by a literal, or 1047 // NoPos if not explicit in the source (e.g. a variadic argument slice). 1048 // 1049 // Example printed form: 1050 // 1051 // t4 = Slice <[]int> t3 t2 t1 <nil> 1052 type Slice struct { 1053 register 1054 X Value // slice, string, or *array 1055 Low, High, Max Value // each may be nil 1056 } 1057 1058 // The FieldAddr instruction yields the address of Field of *struct X. 1059 // 1060 // The field is identified by its index within the field list of the 1061 // struct type of X. 1062 // 1063 // Dynamically, this instruction panics if X evaluates to a nil 1064 // pointer. 1065 // 1066 // Type() returns a (possibly named) *types.Pointer. 1067 // 1068 // Pos() returns the position of the ast.SelectorExpr.Sel for the 1069 // field, if explicit in the source. 1070 // 1071 // Example printed form: 1072 // 1073 // t2 = FieldAddr <*int> [0] (X) t1 1074 type FieldAddr struct { 1075 register 1076 X Value // *struct 1077 Field int // field is X.Type().Underlying().(*types.Pointer).Elem().Underlying().(*types.Struct).Field(Field) 1078 } 1079 1080 // The Field instruction yields the Field of struct X. 1081 // 1082 // The field is identified by its index within the field list of the 1083 // struct type of X; by using numeric indices we avoid ambiguity of 1084 // package-local identifiers and permit compact representations. 1085 // 1086 // Pos() returns the position of the ast.SelectorExpr.Sel for the 1087 // field, if explicit in the source. 1088 // 1089 // Example printed form: 1090 // 1091 // t2 = FieldAddr <int> [0] (X) t1 1092 type Field struct { 1093 register 1094 X Value // struct 1095 Field int // index into X.Type().(*types.Struct).Fields 1096 } 1097 1098 // The IndexAddr instruction yields the address of the element at 1099 // index Index of collection X. Index is an integer expression. 1100 // 1101 // The elements of maps and strings are not addressable; use StringLookup, MapLookup or 1102 // MapUpdate instead. 1103 // 1104 // Dynamically, this instruction panics if X evaluates to a nil *array 1105 // pointer. 1106 // 1107 // Type() returns a (possibly named) *types.Pointer. 1108 // 1109 // Pos() returns the ast.IndexExpr.Lbrack for the index operation, if 1110 // explicit in the source. 1111 // 1112 // Example printed form: 1113 // 1114 // t3 = IndexAddr <*int> t2 t1 1115 type IndexAddr struct { 1116 register 1117 X Value // slice or *array, 1118 Index Value // numeric index 1119 } 1120 1121 // The Index instruction yields element Index of array X. 1122 // 1123 // Pos() returns the ast.IndexExpr.Lbrack for the index operation, if 1124 // explicit in the source. 1125 // 1126 // Example printed form: 1127 // 1128 // t3 = Index <int> t2 t1 1129 type Index struct { 1130 register 1131 X Value // array 1132 Index Value // integer index 1133 } 1134 1135 // The MapLookup instruction yields element Index of collection X, a map. 1136 // 1137 // If CommaOk, the result is a 2-tuple of the value above and a 1138 // boolean indicating the result of a map membership test for the key. 1139 // The components of the tuple are accessed using Extract. 1140 // 1141 // Pos() returns the ast.IndexExpr.Lbrack, if explicit in the source. 1142 // 1143 // Example printed form: 1144 // 1145 // t4 = MapLookup <string> t3 t1 1146 // t6 = MapLookup <(string, bool)> t3 t2 1147 type MapLookup struct { 1148 register 1149 X Value // map 1150 Index Value // key-typed index 1151 CommaOk bool // return a value,ok pair 1152 } 1153 1154 // The StringLookup instruction yields element Index of collection X, a string. 1155 // Index is an integer expression. 1156 // 1157 // Pos() returns the ast.IndexExpr.Lbrack, if explicit in the source. 1158 // 1159 // Example printed form: 1160 // 1161 // t3 = StringLookup <uint8> t2 t1 1162 type StringLookup struct { 1163 register 1164 X Value // string 1165 Index Value // numeric index 1166 } 1167 1168 // SelectState is a helper for Select. 1169 // It represents one goal state and its corresponding communication. 1170 type SelectState struct { 1171 Dir types.ChanDir // direction of case (SendOnly or RecvOnly) 1172 Chan Value // channel to use (for send or receive) 1173 Send Value // value to send (for send) 1174 Pos token.Pos // position of token.ARROW 1175 DebugNode ast.Node // ast.SendStmt or ast.UnaryExpr(<-) [debug mode] 1176 } 1177 1178 // The Select instruction tests whether (or blocks until) one 1179 // of the specified sent or received states is entered. 1180 // 1181 // Let n be the number of States for which Dir==RECV and Tᵢ (0 ≤ i < n) 1182 // be the element type of each such state's Chan. 1183 // Select returns an n+2-tuple 1184 // 1185 // (index int, recvOk bool, r₀ T₀, ... rₙ-1 Tₙ-1) 1186 // 1187 // The tuple's components, described below, must be accessed via the 1188 // Extract instruction. 1189 // 1190 // If Blocking, select waits until exactly one state holds, i.e. a 1191 // channel becomes ready for the designated operation of sending or 1192 // receiving; select chooses one among the ready states 1193 // pseudorandomly, performs the send or receive operation, and sets 1194 // 'index' to the index of the chosen channel. 1195 // 1196 // If !Blocking, select doesn't block if no states hold; instead it 1197 // returns immediately with index equal to -1. 1198 // 1199 // If the chosen channel was used for a receive, the rᵢ component is 1200 // set to the received value, where i is the index of that state among 1201 // all n receive states; otherwise rᵢ has the zero value of type Tᵢ. 1202 // Note that the receive index i is not the same as the state 1203 // index index. 1204 // 1205 // The second component of the triple, recvOk, is a boolean whose value 1206 // is true iff the selected operation was a receive and the receive 1207 // successfully yielded a value. 1208 // 1209 // Pos() returns the ast.SelectStmt.Select. 1210 // 1211 // Example printed form: 1212 // 1213 // t6 = SelectNonBlocking <(index int, ok bool, int)> [<-t4, t5<-t1] 1214 // t11 = SelectBlocking <(index int, ok bool)> [] 1215 type Select struct { 1216 register 1217 States []*SelectState 1218 Blocking bool 1219 } 1220 1221 // The Range instruction yields an iterator over the domain and range 1222 // of X, which must be a string or map. 1223 // 1224 // Elements are accessed via Next. 1225 // 1226 // Type() returns an opaque and degenerate "rangeIter" type. 1227 // 1228 // Pos() returns the ast.RangeStmt.For. 1229 // 1230 // Example printed form: 1231 // 1232 // t2 = Range <iter> t1 1233 type Range struct { 1234 register 1235 X Value // string or map 1236 } 1237 1238 // The Next instruction reads and advances the (map or string) 1239 // iterator Iter and returns a 3-tuple value (ok, k, v). If the 1240 // iterator is not exhausted, ok is true and k and v are the next 1241 // elements of the domain and range, respectively. Otherwise ok is 1242 // false and k and v are undefined. 1243 // 1244 // Components of the tuple are accessed using Extract. 1245 // 1246 // The IsString field distinguishes iterators over strings from those 1247 // over maps, as the Type() alone is insufficient: consider 1248 // map[int]rune. 1249 // 1250 // Type() returns a *types.Tuple for the triple (ok, k, v). 1251 // The types of k and/or v may be types.Invalid. 1252 // 1253 // Example printed form: 1254 // 1255 // t5 = Next <(ok bool, k int, v rune)> t2 1256 // t5 = Next <(ok bool, k invalid type, v invalid type)> t2 1257 type Next struct { 1258 register 1259 Iter Value 1260 IsString bool // true => string iterator; false => map iterator. 1261 } 1262 1263 // The TypeAssert instruction tests whether interface value X has type 1264 // AssertedType. 1265 // 1266 // If !CommaOk, on success it returns v, the result of the conversion 1267 // (defined below); on failure it panics. 1268 // 1269 // If CommaOk: on success it returns a pair (v, true) where v is the 1270 // result of the conversion; on failure it returns (z, false) where z 1271 // is AssertedType's zero value. The components of the pair must be 1272 // accessed using the Extract instruction. 1273 // 1274 // If AssertedType is a concrete type, TypeAssert checks whether the 1275 // dynamic type in interface X is equal to it, and if so, the result 1276 // of the conversion is a copy of the value in the interface. 1277 // 1278 // If AssertedType is an interface, TypeAssert checks whether the 1279 // dynamic type of the interface is assignable to it, and if so, the 1280 // result of the conversion is a copy of the interface value X. 1281 // If AssertedType is a superinterface of X.Type(), the operation will 1282 // fail iff the operand is nil. (Contrast with ChangeInterface, which 1283 // performs no nil-check.) 1284 // 1285 // Type() reflects the actual type of the result, possibly a 1286 // 2-types.Tuple; AssertedType is the asserted type. 1287 // 1288 // Pos() returns the ast.CallExpr.Lparen if the instruction arose from 1289 // an explicit T(e) conversion; the ast.TypeAssertExpr.Lparen if the 1290 // instruction arose from an explicit e.(T) operation; or the 1291 // ast.CaseClause.Case if the instruction arose from a case of a 1292 // type-switch statement. 1293 // 1294 // Example printed form: 1295 // 1296 // t2 = TypeAssert <int> t1 1297 // t4 = TypeAssert <(value fmt.Stringer, ok bool)> t1 1298 type TypeAssert struct { 1299 register 1300 X Value 1301 AssertedType types.Type 1302 CommaOk bool 1303 } 1304 1305 // The Extract instruction yields component Index of Tuple. 1306 // 1307 // This is used to access the results of instructions with multiple 1308 // return values, such as Call, TypeAssert, Next, Recv, 1309 // MapLookup and others. 1310 // 1311 // Example printed form: 1312 // 1313 // t7 = Extract <bool> [1] (ok) t4 1314 type Extract struct { 1315 register 1316 Tuple Value 1317 Index int 1318 } 1319 1320 // Instructions executed for effect. They do not yield a value. -------------------- 1321 1322 // The Jump instruction transfers control to the sole successor of its 1323 // owning block. 1324 // 1325 // A Jump must be the last instruction of its containing BasicBlock. 1326 // 1327 // Pos() returns NoPos. 1328 // 1329 // Example printed form: 1330 // 1331 // Jump → b1 1332 type Jump struct { 1333 anInstruction 1334 } 1335 1336 // The Unreachable pseudo-instruction signals that execution cannot 1337 // continue after the preceding function call because it terminates 1338 // the process. 1339 // 1340 // The instruction acts as a control instruction, jumping to the exit 1341 // block. However, this jump will never execute. 1342 // 1343 // An Unreachable instruction must be the last instruction of its 1344 // containing BasicBlock. 1345 // 1346 // Example printed form: 1347 // 1348 // Unreachable → b1 1349 type Unreachable struct { 1350 anInstruction 1351 } 1352 1353 // The If instruction transfers control to one of the two successors 1354 // of its owning block, depending on the boolean Cond: the first if 1355 // true, the second if false. 1356 // 1357 // An If instruction must be the last instruction of its containing 1358 // BasicBlock. 1359 // 1360 // Pos() returns the *ast.IfStmt, if explicit in the source. 1361 // 1362 // Example printed form: 1363 // 1364 // If t2 → b1 b2 1365 type If struct { 1366 anInstruction 1367 Cond Value 1368 } 1369 1370 type ConstantSwitch struct { 1371 anInstruction 1372 Tag Value 1373 // Constant branch conditions. A nil Value denotes the (implicit 1374 // or explicit) default branch. 1375 Conds []Value 1376 } 1377 1378 type TypeSwitch struct { 1379 register 1380 Tag Value 1381 Conds []types.Type 1382 } 1383 1384 // The Return instruction returns values and control back to the calling 1385 // function. 1386 // 1387 // len(Results) is always equal to the number of results in the 1388 // function's signature. 1389 // 1390 // If len(Results) > 1, Return returns a tuple value with the specified 1391 // components which the caller must access using Extract instructions. 1392 // 1393 // There is no instruction to return a ready-made tuple like those 1394 // returned by a "value,ok"-mode TypeAssert, MapLookup or Recv or 1395 // a tail-call to a function with multiple result parameters. 1396 // 1397 // Return must be the last instruction of its containing BasicBlock. 1398 // Such a block has no successors. 1399 // 1400 // Pos() returns the ast.ReturnStmt.Return, if explicit in the source. 1401 // 1402 // Example printed form: 1403 // 1404 // Return 1405 // Return t1 t2 1406 type Return struct { 1407 anInstruction 1408 Results []Value 1409 } 1410 1411 // The RunDefers instruction pops and invokes the entire stack of 1412 // procedure calls pushed by Defer instructions in this function. 1413 // 1414 // It is legal to encounter multiple 'rundefers' instructions in a 1415 // single control-flow path through a function; this is useful in 1416 // the combined init() function, for example. 1417 // 1418 // Pos() returns NoPos. 1419 // 1420 // Example printed form: 1421 // 1422 // RunDefers 1423 type RunDefers struct { 1424 anInstruction 1425 } 1426 1427 // The Panic instruction initiates a panic with value X. 1428 // 1429 // A Panic instruction must be the last instruction of its containing 1430 // BasicBlock, which must have one successor, the exit block. 1431 // 1432 // NB: 'go panic(x)' and 'defer panic(x)' do not use this instruction; 1433 // they are treated as calls to a built-in function. 1434 // 1435 // Pos() returns the ast.CallExpr.Lparen if this panic was explicit 1436 // in the source. 1437 // 1438 // Example printed form: 1439 // 1440 // Panic t1 1441 type Panic struct { 1442 anInstruction 1443 X Value // an interface{} 1444 } 1445 1446 // The Go instruction creates a new goroutine and calls the specified 1447 // function within it. 1448 // 1449 // See CallCommon for generic function call documentation. 1450 // 1451 // Pos() returns the ast.GoStmt.Go. 1452 // 1453 // Example printed form: 1454 // 1455 // Go println t1 1456 // Go t3 1457 // GoInvoke t4.Bar t2 1458 type Go struct { 1459 anInstruction 1460 Call CallCommon 1461 } 1462 1463 // The Defer instruction pushes the specified call onto a stack of 1464 // functions to be called by a RunDefers instruction or by a panic. 1465 // 1466 // See CallCommon for generic function call documentation. 1467 // 1468 // Pos() returns the ast.DeferStmt.Defer. 1469 // 1470 // Example printed form: 1471 // 1472 // Defer println t1 1473 // Defer t3 1474 // DeferInvoke t4.Bar t2 1475 type Defer struct { 1476 anInstruction 1477 Call CallCommon 1478 } 1479 1480 // The Send instruction sends X on channel Chan. 1481 // 1482 // Pos() returns the ast.SendStmt.Arrow, if explicit in the source. 1483 // 1484 // Example printed form: 1485 // 1486 // Send t2 t1 1487 type Send struct { 1488 anInstruction 1489 Chan, X Value 1490 } 1491 1492 // The Recv instruction receives from channel Chan. 1493 // 1494 // If CommaOk, the result is a 2-tuple of the value above 1495 // and a boolean indicating the success of the receive. The 1496 // components of the tuple are accessed using Extract. 1497 // 1498 // Pos() returns the ast.UnaryExpr.OpPos, if explicit in the source. 1499 // For receive operations implicit in ranging over a channel, 1500 // Pos() returns the ast.RangeStmt.For. 1501 // 1502 // Example printed form: 1503 // 1504 // t2 = Recv <int> t1 1505 // t3 = Recv <(int, bool)> t1 1506 type Recv struct { 1507 register 1508 Chan Value 1509 CommaOk bool 1510 } 1511 1512 // The Store instruction stores Val at address Addr. 1513 // Stores can be of arbitrary types. 1514 // 1515 // Pos() returns the position of the source-level construct most closely 1516 // associated with the memory store operation. 1517 // Since implicit memory stores are numerous and varied and depend upon 1518 // implementation choices, the details are not specified. 1519 // 1520 // Example printed form: 1521 // 1522 // Store {int} t2 t1 1523 type Store struct { 1524 anInstruction 1525 Addr Value 1526 Val Value 1527 } 1528 1529 // The BlankStore instruction is emitted for assignments to the blank 1530 // identifier. 1531 // 1532 // BlankStore is a pseudo-instruction: it has no dynamic effect. 1533 // 1534 // Pos() returns NoPos. 1535 // 1536 // Example printed form: 1537 // 1538 // BlankStore t1 1539 type BlankStore struct { 1540 anInstruction 1541 Val Value 1542 } 1543 1544 // The MapUpdate instruction updates the association of Map[Key] to 1545 // Value. 1546 // 1547 // Pos() returns the ast.KeyValueExpr.Colon or ast.IndexExpr.Lbrack, 1548 // if explicit in the source. 1549 // 1550 // Example printed form: 1551 // 1552 // MapUpdate t3 t1 t2 1553 type MapUpdate struct { 1554 anInstruction 1555 Map Value 1556 Key Value 1557 Value Value 1558 } 1559 1560 // A DebugRef instruction maps a source-level expression Expr to the 1561 // IR value X that represents the value (!IsAddr) or address (IsAddr) 1562 // of that expression. 1563 // 1564 // DebugRef is a pseudo-instruction: it has no dynamic effect. 1565 // 1566 // Pos() returns Expr.Pos(), the start position of the source-level 1567 // expression. This is not the same as the "designated" token as 1568 // documented at Value.Pos(). e.g. CallExpr.Pos() does not return the 1569 // position of the ("designated") Lparen token. 1570 // 1571 // DebugRefs are generated only for functions built with debugging 1572 // enabled; see Package.SetDebugMode() and the GlobalDebug builder 1573 // mode flag. 1574 // 1575 // DebugRefs are not emitted for ast.Idents referring to constants or 1576 // predeclared identifiers, since they are trivial and numerous. 1577 // Nor are they emitted for ast.ParenExprs. 1578 // 1579 // (By representing these as instructions, rather than out-of-band, 1580 // consistency is maintained during transformation passes by the 1581 // ordinary SSA renaming machinery.) 1582 // 1583 // Example printed form: 1584 // 1585 // ; *ast.CallExpr @ 102:9 is t5 1586 // ; var x float64 @ 109:72 is x 1587 // ; address of *ast.CompositeLit @ 216:10 is t0 1588 type DebugRef struct { 1589 anInstruction 1590 Expr ast.Expr // the referring expression (never *ast.ParenExpr) 1591 object types.Object // the identity of the source var/func 1592 IsAddr bool // Expr is addressable and X is the address it denotes 1593 X Value // the value or address of Expr 1594 } 1595 1596 // Embeddable mix-ins and helpers for common parts of other structs. ----------- 1597 1598 // register is a mix-in embedded by all IR values that are also 1599 // instructions, i.e. virtual registers, and provides a uniform 1600 // implementation of most of the Value interface: Value.Name() is a 1601 // numbered register (e.g. "t0"); the other methods are field accessors. 1602 // 1603 // Temporary names are automatically assigned to each register on 1604 // completion of building a function in IR form. 1605 type register struct { 1606 anInstruction 1607 typ types.Type // type of virtual register 1608 referrers []Instruction 1609 } 1610 1611 type node struct { 1612 source ast.Node 1613 id ID 1614 } 1615 1616 func (n *node) setID(id ID) { n.id = id } 1617 func (n node) ID() ID { return n.id } 1618 1619 func (n *node) setSource(source ast.Node) { n.source = source } 1620 func (n *node) Source() ast.Node { return n.source } 1621 1622 func (n *node) Pos() token.Pos { 1623 if n.source != nil { 1624 return n.source.Pos() 1625 } 1626 return token.NoPos 1627 } 1628 1629 // anInstruction is a mix-in embedded by all Instructions. 1630 // It provides the implementations of the Block and setBlock methods. 1631 type anInstruction struct { 1632 node 1633 block *BasicBlock // the basic block of this instruction 1634 comment string 1635 } 1636 1637 func (instr anInstruction) Comment() string { 1638 return instr.comment 1639 } 1640 1641 // CallCommon is contained by Go, Defer and Call to hold the 1642 // common parts of a function or method call. 1643 // 1644 // Each CallCommon exists in one of two modes, function call and 1645 // interface method invocation, or "call" and "invoke" for short. 1646 // 1647 // 1. "call" mode: when Method is nil (!IsInvoke), a CallCommon 1648 // represents an ordinary function call of the value in Value, 1649 // which may be a *Builtin, a *Function or any other value of kind 1650 // 'func'. 1651 // 1652 // Value may be one of: 1653 // 1654 // (a) a *Function, indicating a statically dispatched call 1655 // to a package-level function, an anonymous function, or 1656 // a method of a named type. 1657 // (b) a *MakeClosure, indicating an immediately applied 1658 // function literal with free variables. 1659 // (c) a *Builtin, indicating a statically dispatched call 1660 // to a built-in function. 1661 // (d) any other value, indicating a dynamically dispatched 1662 // function call. 1663 // 1664 // StaticCallee returns the identity of the callee in cases 1665 // (a) and (b), nil otherwise. 1666 // 1667 // Args contains the arguments to the call. If Value is a method, 1668 // Args[0] contains the receiver parameter. 1669 // 1670 // Example printed form: 1671 // 1672 // t3 = Call <()> println t1 t2 1673 // Go t3 1674 // Defer t3 1675 // 1676 // 2. "invoke" mode: when Method is non-nil (IsInvoke), a CallCommon 1677 // represents a dynamically dispatched call to an interface method. 1678 // In this mode, Value is the interface value and Method is the 1679 // interface's abstract method. Note: an abstract method may be 1680 // shared by multiple interfaces due to embedding; Value.Type() 1681 // provides the specific interface used for this call. 1682 // 1683 // Value is implicitly supplied to the concrete method implementation 1684 // as the receiver parameter; in other words, Args[0] holds not the 1685 // receiver but the first true argument. 1686 // 1687 // Example printed form: 1688 // 1689 // t6 = Invoke <string> t5.String 1690 // GoInvoke t4.Bar t2 1691 // DeferInvoke t4.Bar t2 1692 // 1693 // For all calls to variadic functions (Signature().Variadic()), 1694 // the last element of Args is a slice. 1695 type CallCommon struct { 1696 Value Value // receiver (invoke mode) or func value (call mode) 1697 Method *types.Func // abstract method (invoke mode) 1698 Args []Value // actual parameters (in static method call, includes receiver) 1699 TypeArgs []types.Type 1700 Results Value 1701 } 1702 1703 // IsInvoke returns true if this call has "invoke" (not "call") mode. 1704 func (c *CallCommon) IsInvoke() bool { 1705 return c.Method != nil 1706 } 1707 1708 // Signature returns the signature of the called function. 1709 // 1710 // For an "invoke"-mode call, the signature of the interface method is 1711 // returned. 1712 // 1713 // In either "call" or "invoke" mode, if the callee is a method, its 1714 // receiver is represented by sig.Recv, not sig.Params().At(0). 1715 func (c *CallCommon) Signature() *types.Signature { 1716 if c.Method != nil { 1717 return c.Method.Type().(*types.Signature) 1718 } 1719 return typeutil.CoreType(c.Value.Type()).(*types.Signature) 1720 } 1721 1722 // StaticCallee returns the callee if this is a trivially static 1723 // "call"-mode call to a function. 1724 func (c *CallCommon) StaticCallee() *Function { 1725 switch fn := c.Value.(type) { 1726 case *Function: 1727 return fn 1728 case *MakeClosure: 1729 return fn.Fn.(*Function) 1730 } 1731 return nil 1732 } 1733 1734 // Description returns a description of the mode of this call suitable 1735 // for a user interface, e.g., "static method call". 1736 func (c *CallCommon) Description() string { 1737 switch fn := c.Value.(type) { 1738 case *Builtin: 1739 return "built-in function call" 1740 case *MakeClosure: 1741 return "static function closure call" 1742 case *Function: 1743 if fn.Signature.Recv() != nil { 1744 return "static method call" 1745 } 1746 return "static function call" 1747 } 1748 if c.IsInvoke() { 1749 return "dynamic method call" // ("invoke" mode) 1750 } 1751 return "dynamic function call" 1752 } 1753 1754 // The CallInstruction interface, implemented by *Go, *Defer and *Call, 1755 // exposes the common parts of function-calling instructions, 1756 // yet provides a way back to the Value defined by *Call alone. 1757 type CallInstruction interface { 1758 Instruction 1759 Common() *CallCommon // returns the common parts of the call 1760 Value() *Call 1761 } 1762 1763 func (s *Call) Common() *CallCommon { return &s.Call } 1764 func (s *Defer) Common() *CallCommon { return &s.Call } 1765 func (s *Go) Common() *CallCommon { return &s.Call } 1766 1767 func (s *Call) Value() *Call { return s } 1768 func (s *Defer) Value() *Call { return nil } 1769 func (s *Go) Value() *Call { return nil } 1770 1771 func (v *Builtin) Type() types.Type { return v.sig } 1772 func (v *Builtin) Name() string { return v.name } 1773 func (*Builtin) Referrers() *[]Instruction { return nil } 1774 func (v *Builtin) Pos() token.Pos { return token.NoPos } 1775 func (v *Builtin) Object() types.Object { return types.Universe.Lookup(v.name) } 1776 func (v *Builtin) Parent() *Function { return nil } 1777 1778 func (v *FreeVar) Type() types.Type { return v.typ } 1779 func (v *FreeVar) Name() string { return v.name } 1780 func (v *FreeVar) Referrers() *[]Instruction { return &v.referrers } 1781 func (v *FreeVar) Parent() *Function { return v.parent } 1782 1783 func (v *Global) Type() types.Type { return v.typ } 1784 func (v *Global) Name() string { return v.name } 1785 func (v *Global) Parent() *Function { return nil } 1786 func (v *Global) Referrers() *[]Instruction { return nil } 1787 func (v *Global) Token() token.Token { return token.VAR } 1788 func (v *Global) Object() types.Object { return v.object } 1789 func (v *Global) String() string { return v.RelString(nil) } 1790 func (v *Global) Package() *Package { return v.Pkg } 1791 func (v *Global) RelString(from *types.Package) string { return relString(v, from) } 1792 1793 func (v *Function) Name() string { return v.name } 1794 func (v *Function) Type() types.Type { return v.Signature } 1795 func (v *Function) Token() token.Token { return token.FUNC } 1796 func (v *Function) Object() types.Object { return v.object } 1797 func (v *Function) String() string { return v.RelString(nil) } 1798 func (v *Function) Package() *Package { return v.Pkg } 1799 func (v *Function) Parent() *Function { return v.parent } 1800 func (v *Function) Referrers() *[]Instruction { 1801 if v.parent != nil { 1802 return &v.referrers 1803 } 1804 return nil 1805 } 1806 1807 func (v *Parameter) Object() types.Object { return v.object } 1808 1809 func (v *Alloc) Type() types.Type { return v.typ } 1810 func (v *Alloc) Referrers() *[]Instruction { return &v.referrers } 1811 1812 func (v *register) Type() types.Type { return v.typ } 1813 func (v *register) setType(typ types.Type) { v.typ = typ } 1814 func (v *register) Name() string { return fmt.Sprintf("t%d", v.id) } 1815 func (v *register) Referrers() *[]Instruction { return &v.referrers } 1816 1817 func (v *anInstruction) Parent() *Function { return v.block.parent } 1818 func (v *anInstruction) Block() *BasicBlock { return v.block } 1819 func (v *anInstruction) setBlock(block *BasicBlock) { v.block = block } 1820 func (v *anInstruction) Referrers() *[]Instruction { return nil } 1821 1822 func (t *Type) Name() string { return t.object.Name() } 1823 func (t *Type) Pos() token.Pos { return t.object.Pos() } 1824 func (t *Type) Type() types.Type { return t.object.Type() } 1825 func (t *Type) Token() token.Token { return token.TYPE } 1826 func (t *Type) Object() types.Object { return t.object } 1827 func (t *Type) String() string { return t.RelString(nil) } 1828 func (t *Type) Package() *Package { return t.pkg } 1829 func (t *Type) RelString(from *types.Package) string { return relString(t, from) } 1830 1831 func (c *NamedConst) Name() string { return c.object.Name() } 1832 func (c *NamedConst) Pos() token.Pos { return c.object.Pos() } 1833 func (c *NamedConst) String() string { return c.RelString(nil) } 1834 func (c *NamedConst) Type() types.Type { return c.object.Type() } 1835 func (c *NamedConst) Token() token.Token { return token.CONST } 1836 func (c *NamedConst) Object() types.Object { return c.object } 1837 func (c *NamedConst) Package() *Package { return c.pkg } 1838 func (c *NamedConst) RelString(from *types.Package) string { return relString(c, from) } 1839 1840 // Func returns the package-level function of the specified name, 1841 // or nil if not found. 1842 func (p *Package) Func(name string) (f *Function) { 1843 f, _ = p.Members[name].(*Function) 1844 return 1845 } 1846 1847 // Var returns the package-level variable of the specified name, 1848 // or nil if not found. 1849 func (p *Package) Var(name string) (g *Global) { 1850 g, _ = p.Members[name].(*Global) 1851 return 1852 } 1853 1854 // Const returns the package-level constant of the specified name, 1855 // or nil if not found. 1856 func (p *Package) Const(name string) (c *NamedConst) { 1857 c, _ = p.Members[name].(*NamedConst) 1858 return 1859 } 1860 1861 // Type returns the package-level type of the specified name, 1862 // or nil if not found. 1863 func (p *Package) Type(name string) (t *Type) { 1864 t, _ = p.Members[name].(*Type) 1865 return 1866 } 1867 1868 func (s *DebugRef) Pos() token.Pos { return s.Expr.Pos() } 1869 1870 // Operands. 1871 1872 func (v *Alloc) Operands(rands []*Value) []*Value { 1873 return rands 1874 } 1875 1876 func (v *BinOp) Operands(rands []*Value) []*Value { 1877 return append(rands, &v.X, &v.Y) 1878 } 1879 1880 func (c *CallCommon) Operands(rands []*Value) []*Value { 1881 rands = append(rands, &c.Value) 1882 for i := range c.Args { 1883 rands = append(rands, &c.Args[i]) 1884 } 1885 return rands 1886 } 1887 1888 func (s *Go) Operands(rands []*Value) []*Value { 1889 return s.Call.Operands(rands) 1890 } 1891 1892 func (s *Call) Operands(rands []*Value) []*Value { 1893 return s.Call.Operands(rands) 1894 } 1895 1896 func (s *Defer) Operands(rands []*Value) []*Value { 1897 return s.Call.Operands(rands) 1898 } 1899 1900 func (v *ChangeInterface) Operands(rands []*Value) []*Value { 1901 return append(rands, &v.X) 1902 } 1903 1904 func (v *ChangeType) Operands(rands []*Value) []*Value { 1905 return append(rands, &v.X) 1906 } 1907 1908 func (v *Convert) Operands(rands []*Value) []*Value { 1909 return append(rands, &v.X) 1910 } 1911 1912 func (v *SliceToArrayPointer) Operands(rands []*Value) []*Value { 1913 return append(rands, &v.X) 1914 } 1915 1916 func (v *SliceToArray) Operands(rands []*Value) []*Value { 1917 return append(rands, &v.X) 1918 } 1919 1920 func (s *DebugRef) Operands(rands []*Value) []*Value { 1921 return append(rands, &s.X) 1922 } 1923 1924 func (s *Copy) Operands(rands []*Value) []*Value { 1925 return append(rands, &s.X) 1926 } 1927 1928 func (v *Extract) Operands(rands []*Value) []*Value { 1929 return append(rands, &v.Tuple) 1930 } 1931 1932 func (v *Field) Operands(rands []*Value) []*Value { 1933 return append(rands, &v.X) 1934 } 1935 1936 func (v *FieldAddr) Operands(rands []*Value) []*Value { 1937 return append(rands, &v.X) 1938 } 1939 1940 func (s *If) Operands(rands []*Value) []*Value { 1941 return append(rands, &s.Cond) 1942 } 1943 1944 func (s *ConstantSwitch) Operands(rands []*Value) []*Value { 1945 rands = append(rands, &s.Tag) 1946 for i := range s.Conds { 1947 rands = append(rands, &s.Conds[i]) 1948 } 1949 return rands 1950 } 1951 1952 func (s *TypeSwitch) Operands(rands []*Value) []*Value { 1953 rands = append(rands, &s.Tag) 1954 return rands 1955 } 1956 1957 func (v *Index) Operands(rands []*Value) []*Value { 1958 return append(rands, &v.X, &v.Index) 1959 } 1960 1961 func (v *IndexAddr) Operands(rands []*Value) []*Value { 1962 return append(rands, &v.X, &v.Index) 1963 } 1964 1965 func (*Jump) Operands(rands []*Value) []*Value { 1966 return rands 1967 } 1968 1969 func (*Unreachable) Operands(rands []*Value) []*Value { 1970 return rands 1971 } 1972 1973 func (v *MapLookup) Operands(rands []*Value) []*Value { 1974 return append(rands, &v.X, &v.Index) 1975 } 1976 1977 func (v *StringLookup) Operands(rands []*Value) []*Value { 1978 return append(rands, &v.X, &v.Index) 1979 } 1980 1981 func (v *MakeChan) Operands(rands []*Value) []*Value { 1982 return append(rands, &v.Size) 1983 } 1984 1985 func (v *MakeClosure) Operands(rands []*Value) []*Value { 1986 rands = append(rands, &v.Fn) 1987 for i := range v.Bindings { 1988 rands = append(rands, &v.Bindings[i]) 1989 } 1990 return rands 1991 } 1992 1993 func (v *MakeInterface) Operands(rands []*Value) []*Value { 1994 return append(rands, &v.X) 1995 } 1996 1997 func (v *MakeMap) Operands(rands []*Value) []*Value { 1998 return append(rands, &v.Reserve) 1999 } 2000 2001 func (v *MakeSlice) Operands(rands []*Value) []*Value { 2002 return append(rands, &v.Len, &v.Cap) 2003 } 2004 2005 func (v *MapUpdate) Operands(rands []*Value) []*Value { 2006 return append(rands, &v.Map, &v.Key, &v.Value) 2007 } 2008 2009 func (v *Next) Operands(rands []*Value) []*Value { 2010 return append(rands, &v.Iter) 2011 } 2012 2013 func (s *Panic) Operands(rands []*Value) []*Value { 2014 return append(rands, &s.X) 2015 } 2016 2017 func (v *Sigma) Operands(rands []*Value) []*Value { 2018 return append(rands, &v.X) 2019 } 2020 2021 func (v *Phi) Operands(rands []*Value) []*Value { 2022 for i := range v.Edges { 2023 rands = append(rands, &v.Edges[i]) 2024 } 2025 return rands 2026 } 2027 2028 func (v *Range) Operands(rands []*Value) []*Value { 2029 return append(rands, &v.X) 2030 } 2031 2032 func (s *Return) Operands(rands []*Value) []*Value { 2033 for i := range s.Results { 2034 rands = append(rands, &s.Results[i]) 2035 } 2036 return rands 2037 } 2038 2039 func (*RunDefers) Operands(rands []*Value) []*Value { 2040 return rands 2041 } 2042 2043 func (v *Select) Operands(rands []*Value) []*Value { 2044 for i := range v.States { 2045 rands = append(rands, &v.States[i].Chan, &v.States[i].Send) 2046 } 2047 return rands 2048 } 2049 2050 func (s *Send) Operands(rands []*Value) []*Value { 2051 return append(rands, &s.Chan, &s.X) 2052 } 2053 2054 func (recv *Recv) Operands(rands []*Value) []*Value { 2055 return append(rands, &recv.Chan) 2056 } 2057 2058 func (v *Slice) Operands(rands []*Value) []*Value { 2059 return append(rands, &v.X, &v.Low, &v.High, &v.Max) 2060 } 2061 2062 func (s *Store) Operands(rands []*Value) []*Value { 2063 return append(rands, &s.Addr, &s.Val) 2064 } 2065 2066 func (s *BlankStore) Operands(rands []*Value) []*Value { 2067 return append(rands, &s.Val) 2068 } 2069 2070 func (v *TypeAssert) Operands(rands []*Value) []*Value { 2071 return append(rands, &v.X) 2072 } 2073 2074 func (v *UnOp) Operands(rands []*Value) []*Value { 2075 return append(rands, &v.X) 2076 } 2077 2078 func (v *Load) Operands(rands []*Value) []*Value { 2079 return append(rands, &v.X) 2080 } 2081 2082 func (v *AggregateConst) Operands(rands []*Value) []*Value { 2083 for i := range v.Values { 2084 rands = append(rands, &v.Values[i]) 2085 } 2086 return rands 2087 } 2088 2089 func (v *CompositeValue) Operands(rands []*Value) []*Value { 2090 for i := range v.Values { 2091 rands = append(rands, &v.Values[i]) 2092 } 2093 return rands 2094 } 2095 2096 // Non-Instruction Values: 2097 func (v *Builtin) Operands(rands []*Value) []*Value { return rands } 2098 func (v *FreeVar) Operands(rands []*Value) []*Value { return rands } 2099 func (v *Const) Operands(rands []*Value) []*Value { return rands } 2100 func (v *ArrayConst) Operands(rands []*Value) []*Value { return rands } 2101 func (v *GenericConst) Operands(rands []*Value) []*Value { return rands } 2102 func (v *Function) Operands(rands []*Value) []*Value { return rands } 2103 func (v *Global) Operands(rands []*Value) []*Value { return rands } 2104 func (v *Parameter) Operands(rands []*Value) []*Value { return rands }