blob: 07e2540d8844ce04dc291a02421414db600f24da [file] [log] [blame]
Rob Pike83f21b92013-05-17 13:25:48 -07001package ssa
2
3// This package defines a high-level intermediate representation for
4// Go programs using static single-assignment (SSA) form.
5
6import (
7 "fmt"
8 "go/ast"
9 "go/token"
10 "sync"
11
12 "code.google.com/p/go.tools/go/exact"
13 "code.google.com/p/go.tools/go/types"
Alan Donovan4df74772013-07-10 18:01:11 -040014 "code.google.com/p/go.tools/go/types/typemap"
Alan Donovanbe28dbb2013-05-31 16:14:13 -040015 "code.google.com/p/go.tools/importer"
Rob Pike83f21b92013-05-17 13:25:48 -070016)
17
18// A Program is a partial or complete Go program converted to SSA form.
Rob Pike83f21b92013-05-17 13:25:48 -070019//
20type Program struct {
Alan Donovanfb0642f2013-07-29 14:24:09 -040021 Fset *token.FileSet // position information for the files of this Program
22 PackagesByPath map[string]*Package // all loaded Packages, keyed by import path
23 packages map[*types.Package]*Package // all loaded Packages, keyed by object
24 builtins map[types.Object]*Builtin // all built-in functions, keyed by typechecker objects.
25 mode BuilderMode // set of mode bits for SSA construction
Rob Pike83f21b92013-05-17 13:25:48 -070026
Alan Donovanf1d4d012013-06-14 15:50:37 -040027 methodsMu sync.Mutex // guards the following maps:
Alan Donovan2a3a1292013-07-30 14:28:14 -040028 methodSets typemap.M // maps type to its concrete methodSet
Alan Donovan4da31df2013-07-26 11:22:34 -040029 boundMethodWrappers map[*types.Func]*Function // wrappers for curried x.Method closures
Alan Donovanf1d4d012013-06-14 15:50:37 -040030 ifaceMethodWrappers map[*types.Func]*Function // wrappers for curried I.Method functions
Rob Pike83f21b92013-05-17 13:25:48 -070031}
32
33// A Package is a single analyzed Go package containing Members for
34// all package-level functions, variables, constants and types it
35// declares. These may be accessed directly via Members, or via the
36// type-specific accessor methods Func, Type, Var and Const.
37//
38type Package struct {
Alan Donovan4d628a02013-06-03 14:15:19 -040039 Prog *Program // the owning program
Alan Donovan6ae930a2013-07-01 15:24:50 -040040 Object *types.Package // the type checker's package object for this package
Alan Donovan4d628a02013-06-03 14:15:19 -040041 Members map[string]Member // all package members keyed by name
Alan Donovanfb0642f2013-07-29 14:24:09 -040042 values map[types.Object]Value // package-level vars & funcs (incl. methods), keyed by object
Alan Donovan32f601b2013-07-10 18:37:52 -040043 init *Function // Func("init"); the package's (concatenated) init function
Alan Donovanc28bf6e2013-07-31 13:13:05 -040044 debug bool // include full debug info in this package.
Rob Pike83f21b92013-05-17 13:25:48 -070045
Alan Donovan4d628a02013-06-03 14:15:19 -040046 // The following fields are set transiently, then cleared
47 // after building.
Alan Donovanfc4c97d2013-06-03 16:46:57 -040048 started int32 // atomically tested and set at start of build phase
49 info *importer.PackageInfo // package ASTs and type information
Rob Pike83f21b92013-05-17 13:25:48 -070050}
51
Alan Donovan732dbe92013-07-16 13:50:08 -040052// A Member is a member of a Go package, implemented by *NamedConst,
Rob Pike83f21b92013-05-17 13:25:48 -070053// *Global, *Function, or *Type; they are created by package-level
54// const, var, func and type declarations respectively.
55//
56type Member interface {
Alan Donovanbc1f7242013-07-11 14:12:30 -040057 Name() string // declared name of the package member
58 String() string // package-qualified name of the package member
59 Object() types.Object // typechecker's object for this member, if any
60 Pos() token.Pos // position of member's declaration, if known
61 Type() types.Type // type of the package member
62 Token() token.Token // token.{VAR,FUNC,CONST,TYPE}
Rob Pike83f21b92013-05-17 13:25:48 -070063}
64
Alan Donovan341a07a2013-06-13 14:43:35 -040065// A Type is a Member of a Package representing a package-level named type.
66//
67// Type() returns a *types.Named.
Rob Pike83f21b92013-05-17 13:25:48 -070068//
69type Type struct {
Alan Donovanbc1f7242013-07-11 14:12:30 -040070 object *types.TypeName
Rob Pike83f21b92013-05-17 13:25:48 -070071}
72
Alan Donovan732dbe92013-07-16 13:50:08 -040073// A NamedConst is a Member of Package representing a package-level
74// named constant value.
Rob Pike83f21b92013-05-17 13:25:48 -070075//
Rob Pike87334f42013-05-17 14:02:47 -070076// Pos() returns the position of the declaring ast.ValueSpec.Names[*]
77// identifier.
78//
Alan Donovan732dbe92013-07-16 13:50:08 -040079// NB: a NamedConst is not a Value; it contains a constant Value, which
Rob Pike87334f42013-05-17 14:02:47 -070080// it augments with the name and position of its 'const' declaration.
81//
Alan Donovan732dbe92013-07-16 13:50:08 -040082type NamedConst struct {
Alan Donovanbc1f7242013-07-11 14:12:30 -040083 object *types.Const
Alan Donovan732dbe92013-07-16 13:50:08 -040084 Value *Const
Alan Donovanbc1f7242013-07-11 14:12:30 -040085 pos token.Pos
Rob Pike83f21b92013-05-17 13:25:48 -070086}
87
88// An SSA value that can be referenced by an instruction.
89type Value interface {
90 // Name returns the name of this value, and determines how
91 // this Value appears when used as an operand of an
92 // Instruction.
93 //
94 // This is the same as the source name for Parameters,
95 // Builtins, Functions, Captures, Globals and some Allocs.
Alan Donovan732dbe92013-07-16 13:50:08 -040096 // For constants, it is a representation of the constant's value
Rob Pike83f21b92013-05-17 13:25:48 -070097 // and type. For all other Values this is the name of the
98 // virtual register defined by the instruction.
99 //
100 // The name of an SSA Value is not semantically significant,
101 // and may not even be unique within a function.
102 Name() string
103
104 // If this value is an Instruction, String returns its
105 // disassembled form; otherwise it returns unspecified
106 // human-readable information about the Value, such as its
107 // kind, name and type.
108 String() string
109
110 // Type returns the type of this value. Many instructions
111 // (e.g. IndexAddr) change the behaviour depending on the
112 // types of their operands.
113 Type() types.Type
114
115 // Referrers returns the list of instructions that have this
116 // value as one of their operands; it may contain duplicates
117 // if an instruction has a repeated operand.
118 //
119 // Referrers actually returns a pointer through which the
120 // caller may perform mutations to the object's state.
121 //
122 // Referrers is currently only defined for the function-local
123 // values Capture, Parameter and all value-defining instructions.
Alan Donovan732dbe92013-07-16 13:50:08 -0400124 // It returns nil for Function, Builtin, Const and Global.
Rob Pike83f21b92013-05-17 13:25:48 -0700125 //
126 // Instruction.Operands contains the inverse of this relation.
127 Referrers() *[]Instruction
128
Alan Donovanc28bf6e2013-07-31 13:13:05 -0400129 // Pos returns the location of the AST token most closely
130 // associated with the operation that gave rise to this value,
131 // or token.NoPos if it was not explicit in the source.
Alan Donovan6c7ce1c2013-05-30 09:59:17 -0400132 //
Alan Donovanc28bf6e2013-07-31 13:13:05 -0400133 // For each ast.Node type, a particular token is designated as
134 // the closest location for the expression, e.g. the Lparen
135 // for an *ast.CallExpr. This permits a compact but
136 // approximate mapping from Values to source positions for use
137 // in diagnostic messages, for example.
138 //
139 // (Do not use this position to determine which Value
140 // corresponds to an ast.Expr; use Function.ValueForExpr
141 // instead. NB: it requires that the function was built with
142 // debug information.)
Alan Donovan6c7ce1c2013-05-30 09:59:17 -0400143 //
144 Pos() token.Pos
Rob Pike83f21b92013-05-17 13:25:48 -0700145}
146
147// An Instruction is an SSA instruction that computes a new Value or
148// has some effect.
149//
150// An Instruction that defines a value (e.g. BinOp) also implements
151// the Value interface; an Instruction that only has an effect (e.g. Store)
152// does not.
153//
154type Instruction interface {
155 // String returns the disassembled form of this value. e.g.
156 //
157 // Examples of Instructions that define a Value:
158 // e.g. "x + y" (BinOp)
159 // "len([])" (Call)
160 // Note that the name of the Value is not printed.
161 //
162 // Examples of Instructions that do define (are) Values:
163 // e.g. "ret x" (Ret)
164 // "*y = x" (Store)
165 //
166 // (This separation is useful for some analyses which
167 // distinguish the operation from the value it
168 // defines. e.g. 'y = local int' is both an allocation of
169 // memory 'local int' and a definition of a pointer y.)
170 String() string
171
Alan Donovan341a07a2013-06-13 14:43:35 -0400172 // Parent returns the function to which this instruction
173 // belongs.
174 Parent() *Function
175
Rob Pike83f21b92013-05-17 13:25:48 -0700176 // Block returns the basic block to which this instruction
177 // belongs.
178 Block() *BasicBlock
179
180 // SetBlock sets the basic block to which this instruction
181 // belongs.
182 SetBlock(*BasicBlock)
183
184 // Operands returns the operands of this instruction: the
185 // set of Values it references.
186 //
187 // Specifically, it appends their addresses to rands, a
188 // user-provided slice, and returns the resulting slice,
189 // permitting avoidance of memory allocation.
190 //
191 // The operands are appended in undefined order; the addresses
192 // are always non-nil but may point to a nil Value. Clients
193 // may store through the pointers, e.g. to effect a value
194 // renaming.
195 //
196 // Value.Referrers is a subset of the inverse of this
197 // relation. (Referrers are not tracked for all types of
198 // Values.)
199 Operands(rands []*Value) []*Value
200
Alan Donovanc28bf6e2013-07-31 13:13:05 -0400201 // Pos returns the location of the AST token most closely
202 // associated with the operation that gave rise to this
203 // instruction, or token.NoPos if it was not explicit in the
204 // source.
Rob Pike87334f42013-05-17 14:02:47 -0700205 //
Alan Donovanc28bf6e2013-07-31 13:13:05 -0400206 // For each ast.Node type, a particular token is designated as
207 // the closest location for the expression, e.g. the Go token
208 // for an *ast.GoStmt. This permits a compact but approximate
209 // mapping from Instructions to source positions for use in
210 // diagnostic messages, for example.
211 //
212 // (Do not use this position to determine which Instruction
213 // corresponds to an ast.Expr; see the notes for Value.Pos.
214 // This position may be used to determine which non-Value
215 // Instruction corresponds to some ast.Stmts, but not all: If
216 // and Jump instructions have no Pos(), for example.)
Rob Pike87334f42013-05-17 14:02:47 -0700217 //
218 Pos() token.Pos
Rob Pike83f21b92013-05-17 13:25:48 -0700219}
220
221// Function represents the parameters, results and code of a function
222// or method.
223//
224// If Blocks is nil, this indicates an external function for which no
225// Go source code is available. In this case, Captures and Locals
226// will be nil too. Clients performing whole-program analysis must
227// handle external functions specially.
228//
229// Functions are immutable values; they do not have addresses.
230//
231// Blocks[0] is the function entry point; block order is not otherwise
232// semantically significant, though it may affect the readability of
233// the disassembly.
234//
235// A nested function that refers to one or more lexically enclosing
236// local variables ("free variables") has Capture parameters. Such
237// functions cannot be called directly but require a value created by
238// MakeClosure which, via its Bindings, supplies values for these
Alan Donovan8cdf1f12013-05-22 17:56:18 -0400239// parameters.
Rob Pike83f21b92013-05-17 13:25:48 -0700240//
Rob Pike87334f42013-05-17 14:02:47 -0700241// If the function is a method (Signature.Recv() != nil) then the first
Rob Pike83f21b92013-05-17 13:25:48 -0700242// element of Params is the receiver parameter.
243//
Rob Pike87334f42013-05-17 14:02:47 -0700244// Pos() returns the declaring ast.FuncLit.Type.Func or the position
245// of the ast.FuncDecl.Name, if the function was explicit in the
Alan Donovan1fa3f782013-07-03 17:57:20 -0400246// source. Synthetic wrappers, for which Synthetic != "", may share
247// the same position as the function they wrap.
Rob Pike87334f42013-05-17 14:02:47 -0700248//
Rob Pike83f21b92013-05-17 13:25:48 -0700249// Type() returns the function's Signature.
250//
251type Function struct {
Alan Donovan6c7ce1c2013-05-30 09:59:17 -0400252 name string
Robert Griesemer64ea46e2013-07-26 22:27:48 -0700253 object types.Object // a declared *types.Func; nil for init, wrappers, etc.
254 method *types.Selection // info about provenance of synthetic methods [currently unused]
Rob Pike83f21b92013-05-17 13:25:48 -0700255 Signature *types.Signature
Rob Pike87334f42013-05-17 14:02:47 -0700256 pos token.Pos
Alan Donovan6c7ce1c2013-05-30 09:59:17 -0400257
Alan Donovan1fa3f782013-07-03 17:57:20 -0400258 Synthetic string // provenance of synthetic function; "" for true source functions
Rob Pike83f21b92013-05-17 13:25:48 -0700259 Enclosing *Function // enclosing function if anon; nil if global
260 Pkg *Package // enclosing package for Go source functions; otherwise nil
261 Prog *Program // enclosing program
262 Params []*Parameter // function parameters; for methods, includes receiver
263 FreeVars []*Capture // free variables whose values must be supplied by closure
264 Locals []*Alloc
265 Blocks []*BasicBlock // basic blocks of the function; nil => external
266 AnonFuncs []*Function // anonymous functions directly beneath this one
267
268 // The following fields are set transiently during building,
269 // then cleared.
270 currentBlock *BasicBlock // where to emit code
271 objects map[types.Object]Value // addresses of local variables
272 namedResults []*Alloc // tuple of named results
273 syntax *funcSyntax // abstract syntax trees for Go source functions
274 targets *targets // linked stack of branch targets
275 lblocks map[*ast.Object]*lblock // labelled blocks
276}
277
278// An SSA basic block.
279//
280// The final element of Instrs is always an explicit transfer of
281// control (If, Jump, Ret or Panic).
282//
283// A block may contain no Instructions only if it is unreachable,
284// i.e. Preds is nil. Empty blocks are typically pruned.
285//
286// BasicBlocks and their Preds/Succs relation form a (possibly cyclic)
287// graph independent of the SSA Value graph. It is illegal for
288// multiple edges to exist between the same pair of blocks.
289//
290// The order of Preds and Succs are significant (to Phi and If
291// instructions, respectively).
292//
293type BasicBlock struct {
294 Index int // index of this block within Func.Blocks
295 Comment string // optional label; no semantic significance
Alan Donovan341a07a2013-06-13 14:43:35 -0400296 parent *Function // parent function
Rob Pike83f21b92013-05-17 13:25:48 -0700297 Instrs []Instruction // instructions in order
298 Preds, Succs []*BasicBlock // predecessors and successors
299 succs2 [2]*BasicBlock // initial space for Succs.
300 dom *domNode // node in dominator tree; optional.
301 gaps int // number of nil Instrs (transient).
302 rundefers int // number of rundefers (transient)
303}
304
305// Pure values ----------------------------------------
306
Alan Donovan8cdf1f12013-05-22 17:56:18 -0400307// A Capture represents a free variable of the function to which it
308// belongs.
Rob Pike83f21b92013-05-17 13:25:48 -0700309//
Alan Donovan8cdf1f12013-05-22 17:56:18 -0400310// Captures are used to implement anonymous functions, whose free
311// variables are lexically captured in a closure formed by
312// MakeClosure. The referent of such a capture is an Alloc or another
313// Capture and is considered a potentially escaping heap address, with
314// pointer type.
315//
316// Captures are also used to implement bound method closures. Such a
317// capture represents the receiver value and may be of any type that
318// has concrete methods.
Rob Pike83f21b92013-05-17 13:25:48 -0700319//
Alan Donovan6c7ce1c2013-05-30 09:59:17 -0400320// Pos() returns the position of the value that was captured, which
321// belongs to an enclosing function.
322//
Rob Pike83f21b92013-05-17 13:25:48 -0700323type Capture struct {
Alan Donovan341a07a2013-06-13 14:43:35 -0400324 name string
325 typ types.Type
326 pos token.Pos
327 parent *Function
Rob Pike83f21b92013-05-17 13:25:48 -0700328 referrers []Instruction
Alan Donovan8cdf1f12013-05-22 17:56:18 -0400329
330 // Transiently needed during building.
331 outer Value // the Value captured from the enclosing context.
Rob Pike83f21b92013-05-17 13:25:48 -0700332}
333
334// A Parameter represents an input parameter of a function.
335//
336type Parameter struct {
Alan Donovan341a07a2013-06-13 14:43:35 -0400337 name string
Alan Donovan55d678e2013-07-15 13:56:46 -0400338 object types.Object // a *types.Var; nil for non-source locals
Alan Donovan341a07a2013-06-13 14:43:35 -0400339 typ types.Type
340 pos token.Pos
341 parent *Function
Rob Pike83f21b92013-05-17 13:25:48 -0700342 referrers []Instruction
343}
344
Alan Donovan732dbe92013-07-16 13:50:08 -0400345// A Const represents the value of a constant expression.
Rob Pike83f21b92013-05-17 13:25:48 -0700346//
Rob Pike87334f42013-05-17 14:02:47 -0700347// It may have a nil, boolean, string or numeric (integer, fraction or
348// complex) value, or a []byte or []rune conversion of a string
Alan Donovan732dbe92013-07-16 13:50:08 -0400349// constant.
Rob Pike87334f42013-05-17 14:02:47 -0700350//
Alan Donovan732dbe92013-07-16 13:50:08 -0400351// Consts may be of named types. A constant's underlying type can be
Rob Pike87334f42013-05-17 14:02:47 -0700352// a basic type, possibly one of the "untyped" types, or a slice type
Alan Donovan732dbe92013-07-16 13:50:08 -0400353// whose elements' underlying type is byte or rune. A nil constant can
Rob Pike87334f42013-05-17 14:02:47 -0700354// have any reference type: interface, map, channel, pointer, slice,
355// or function---but not "untyped nil".
Rob Pike83f21b92013-05-17 13:25:48 -0700356//
Alan Donovan732dbe92013-07-16 13:50:08 -0400357// All source-level constant expressions are represented by a Const
Rob Pike83f21b92013-05-17 13:25:48 -0700358// of equal type and value.
359//
Alan Donovan732dbe92013-07-16 13:50:08 -0400360// Value holds the exact value of the constant, independent of its
Rob Pike87334f42013-05-17 14:02:47 -0700361// Type(), using the same representation as package go/exact uses for
Rob Pike83f21b92013-05-17 13:25:48 -0700362// constants.
363//
Alan Donovana399e262013-07-15 16:10:08 -0400364// Pos() returns token.NoPos.
Alan Donovan6c7ce1c2013-05-30 09:59:17 -0400365//
Rob Pike83f21b92013-05-17 13:25:48 -0700366// Example printed form:
367// 42:int
368// "hello":untyped string
369// 3+4i:MyComplex
370//
Alan Donovan732dbe92013-07-16 13:50:08 -0400371type Const struct {
Alan Donovan6c7ce1c2013-05-30 09:59:17 -0400372 typ types.Type
Rob Pike83f21b92013-05-17 13:25:48 -0700373 Value exact.Value
374}
375
376// A Global is a named Value holding the address of a package-level
377// variable.
378//
Rob Pike87334f42013-05-17 14:02:47 -0700379// Pos() returns the position of the ast.ValueSpec.Names[*]
380// identifier.
381//
Rob Pike83f21b92013-05-17 13:25:48 -0700382type Global struct {
Alan Donovanbc1f7242013-07-11 14:12:30 -0400383 name string
384 object types.Object // a *types.Var; may be nil for synthetics e.g. init$guard
385 typ types.Type
386 pos token.Pos
Alan Donovan6c7ce1c2013-05-30 09:59:17 -0400387
388 Pkg *Package
Rob Pike83f21b92013-05-17 13:25:48 -0700389
390 // The following fields are set transiently during building,
391 // then cleared.
392 spec *ast.ValueSpec // explained at buildGlobal
393}
394
Rob Pike87334f42013-05-17 14:02:47 -0700395// A Builtin represents a built-in function, e.g. len.
Rob Pike83f21b92013-05-17 13:25:48 -0700396//
Rob Pike87334f42013-05-17 14:02:47 -0700397// Builtins are immutable values. Builtins do not have addresses.
Alan Donovan55d678e2013-07-15 13:56:46 -0400398// Builtins can only appear in CallCommon.Func.
Rob Pike83f21b92013-05-17 13:25:48 -0700399//
Rob Pike87334f42013-05-17 14:02:47 -0700400// Type() returns a *types.Builtin.
401// Built-in functions may have polymorphic or variadic types that are
402// not expressible in Go's type system.
Rob Pike83f21b92013-05-17 13:25:48 -0700403//
404type Builtin struct {
Alan Donovan55d678e2013-07-15 13:56:46 -0400405 object *types.Func // canonical types.Universe object for this built-in
Rob Pike83f21b92013-05-17 13:25:48 -0700406}
407
408// Value-defining instructions ----------------------------------------
409
410// The Alloc instruction reserves space for a value of the given type,
411// zero-initializes it, and yields its address.
412//
413// Alloc values are always addresses, and have pointer types, so the
414// type of the allocated space is actually indirect(Type()).
415//
416// If Heap is false, Alloc allocates space in the function's
417// activation record (frame); we refer to an Alloc(Heap=false) as a
418// "local" alloc. Each local Alloc returns the same address each time
419// it is executed within the same activation; the space is
420// re-initialized to zero.
421//
422// If Heap is true, Alloc allocates space in the heap, and returns; we
423// refer to an Alloc(Heap=true) as a "new" alloc. Each new Alloc
424// returns a different address each time it is executed.
425//
426// When Alloc is applied to a channel, map or slice type, it returns
427// the address of an uninitialized (nil) reference of that kind; store
428// the result of MakeSlice, MakeMap or MakeChan in that location to
429// instantiate these types.
430//
Rob Pike87334f42013-05-17 14:02:47 -0700431// Pos() returns the ast.CompositeLit.Lbrace for a composite literal,
432// or the ast.CallExpr.Lparen for a call to new() or for a call that
433// allocates a varargs slice.
434//
Rob Pike83f21b92013-05-17 13:25:48 -0700435// Example printed form:
436// t0 = local int
437// t1 = new int
438//
439type Alloc struct {
Alan Donovan5cc33ea2013-08-01 14:06:10 -0400440 Register
441 Comment string
442 Heap bool
443 index int // dense numbering; for lifting
Rob Pike83f21b92013-05-17 13:25:48 -0700444}
445
Rob Pike87334f42013-05-17 14:02:47 -0700446// The Phi instruction represents an SSA φ-node, which combines values
447// that differ across incoming control-flow edges and yields a new
448// value. Within a block, all φ-nodes must appear before all non-φ
449// nodes.
450//
Alan Donovan6c7ce1c2013-05-30 09:59:17 -0400451// Pos() returns the position of the && or || for short-circuit
452// control-flow joins, or that of the *Alloc for φ-nodes inserted
453// during SSA renaming.
Rob Pike83f21b92013-05-17 13:25:48 -0700454//
455// Example printed form:
456// t2 = phi [0.start: t0, 1.if.then: t1, ...]
457//
458type Phi struct {
459 Register
460 Comment string // a hint as to its purpose
461 Edges []Value // Edges[i] is value for Block().Preds[i]
462}
463
Rob Pike87334f42013-05-17 14:02:47 -0700464// The Call instruction represents a function or method call.
Rob Pike83f21b92013-05-17 13:25:48 -0700465//
466// The Call instruction yields the function result, if there is
467// exactly one, or a tuple (empty or len>1) whose components are
468// accessed via Extract.
469//
470// See CallCommon for generic function call documentation.
471//
Rob Pike87334f42013-05-17 14:02:47 -0700472// Pos() returns the ast.CallExpr.Lparen, if explicit in the source.
473//
Rob Pike83f21b92013-05-17 13:25:48 -0700474// Example printed form:
475// t2 = println(t0, t1)
476// t4 = t3()
477// t7 = invoke t5.Println(...t6)
478//
479type Call struct {
480 Register
481 Call CallCommon
482}
483
Rob Pike87334f42013-05-17 14:02:47 -0700484// The BinOp instruction yields the result of binary operation X Op Y.
485//
486// Pos() returns the ast.BinaryExpr.OpPos, if explicit in the source.
Rob Pike83f21b92013-05-17 13:25:48 -0700487//
488// Example printed form:
489// t1 = t0 + 1:int
490//
491type BinOp struct {
492 Register
493 // One of:
494 // ADD SUB MUL QUO REM + - * / %
495 // AND OR XOR SHL SHR AND_NOT & | ^ << >> &~
496 // EQL LSS GTR NEQ LEQ GEQ == != < <= < >=
497 Op token.Token
498 X, Y Value
499}
500
Rob Pike87334f42013-05-17 14:02:47 -0700501// The UnOp instruction yields the result of Op X.
Rob Pike83f21b92013-05-17 13:25:48 -0700502// ARROW is channel receive.
503// MUL is pointer indirection (load).
504// XOR is bitwise complement.
505// SUB is negation.
506//
507// If CommaOk and Op=ARROW, the result is a 2-tuple of the value above
508// and a boolean indicating the success of the receive. The
509// components of the tuple are accessed using Extract.
510//
Alan Donovan6c7ce1c2013-05-30 09:59:17 -0400511// Pos() returns the ast.UnaryExpr.OpPos, if explicit in the source,
Rob Pike87334f42013-05-17 14:02:47 -0700512//
Rob Pike83f21b92013-05-17 13:25:48 -0700513// Example printed form:
514// t0 = *x
515// t2 = <-t1,ok
516//
517type UnOp struct {
518 Register
519 Op token.Token // One of: NOT SUB ARROW MUL XOR ! - <- * ^
520 X Value
521 CommaOk bool
522}
523
Rob Pike87334f42013-05-17 14:02:47 -0700524// The ChangeType instruction applies to X a value-preserving type
525// change to Type().
Rob Pike83f21b92013-05-17 13:25:48 -0700526//
Rob Pike87334f42013-05-17 14:02:47 -0700527// Type changes are permitted:
528// - between a named type and its underlying type.
529// - between two named types of the same underlying type.
530// - between (possibly named) pointers to identical base types.
531// - between f(T) functions and (T) func f() methods.
532// - from a bidirectional channel to a read- or write-channel,
533// optionally adding/removing a name.
Rob Pike83f21b92013-05-17 13:25:48 -0700534//
Rob Pike87334f42013-05-17 14:02:47 -0700535// This operation cannot fail dynamically.
Rob Pike83f21b92013-05-17 13:25:48 -0700536//
Rob Pike87334f42013-05-17 14:02:47 -0700537// Pos() returns the ast.CallExpr.Lparen, if the instruction arose
538// from an explicit conversion in the source.
Rob Pike83f21b92013-05-17 13:25:48 -0700539//
Rob Pike87334f42013-05-17 14:02:47 -0700540// Example printed form:
541// t1 = changetype *int <- IntPtr (t0)
542//
543type ChangeType struct {
544 Register
545 X Value
546}
547
548// The Convert instruction yields the conversion of value X to type
Alan Donovan8097dad2013-06-24 14:15:13 -0400549// Type(). One or both of those types is basic (but possibly named).
Rob Pike87334f42013-05-17 14:02:47 -0700550//
551// A conversion may change the value and representation of its operand.
552// Conversions are permitted:
553// - between real numeric types.
554// - between complex numeric types.
555// - between string and []byte or []rune.
Alan Donovan8097dad2013-06-24 14:15:13 -0400556// - between pointers and unsafe.Pointer.
557// - between unsafe.Pointer and uintptr.
Rob Pike87334f42013-05-17 14:02:47 -0700558// - from (Unicode) integer to (UTF-8) string.
559// A conversion may imply a type name change also.
560//
561// This operation cannot fail dynamically.
Rob Pike83f21b92013-05-17 13:25:48 -0700562//
563// Conversions of untyped string/number/bool constants to a specific
564// representation are eliminated during SSA construction.
565//
Rob Pike87334f42013-05-17 14:02:47 -0700566// Pos() returns the ast.CallExpr.Lparen, if the instruction arose
567// from an explicit conversion in the source.
Rob Pike83f21b92013-05-17 13:25:48 -0700568//
Rob Pike87334f42013-05-17 14:02:47 -0700569// Example printed form:
570// t1 = convert []byte <- string (t0)
571//
572type Convert struct {
Rob Pike83f21b92013-05-17 13:25:48 -0700573 Register
574 X Value
575}
576
577// ChangeInterface constructs a value of one interface type from a
578// value of another interface type known to be assignable to it.
Alan Donovanae801632013-07-26 21:49:27 -0400579// This operation cannot fail.
Rob Pike87334f42013-05-17 14:02:47 -0700580//
Alan Donovan341a07a2013-06-13 14:43:35 -0400581// Pos() returns the ast.CallExpr.Lparen if the instruction arose from
582// an explicit T(e) conversion; the ast.TypeAssertExpr.Lparen if the
583// instruction arose from an explicit e.(T) operation; or token.NoPos
584// otherwise.
585//
Rob Pike83f21b92013-05-17 13:25:48 -0700586// Example printed form:
587// t1 = change interface interface{} <- I (t0)
588//
589type ChangeInterface struct {
590 Register
591 X Value
592}
593
594// MakeInterface constructs an instance of an interface type from a
Alan Donovan341a07a2013-06-13 14:43:35 -0400595// value of a concrete type.
596//
Alan Donovan2a3a1292013-07-30 14:28:14 -0400597// Use X.Type().MethodSet() to find the method-set of X, and
Alan Donovan2f6855a2013-07-30 16:36:58 -0400598// Program.Method(m) to find the implementation of a method.
Rob Pike83f21b92013-05-17 13:25:48 -0700599//
600// To construct the zero value of an interface type T, use:
Alan Donovan732dbe92013-07-16 13:50:08 -0400601// NewConst(exact.MakeNil(), T, pos)
Rob Pike87334f42013-05-17 14:02:47 -0700602//
603// Pos() returns the ast.CallExpr.Lparen, if the instruction arose
604// from an explicit conversion in the source.
Rob Pike83f21b92013-05-17 13:25:48 -0700605//
606// Example printed form:
Alan Donovan341a07a2013-06-13 14:43:35 -0400607// t1 = make interface{} <- int (42:int)
608// t2 = make Stringer <- t0
Rob Pike83f21b92013-05-17 13:25:48 -0700609//
610type MakeInterface struct {
611 Register
Alan Donovan341a07a2013-06-13 14:43:35 -0400612 X Value
Rob Pike83f21b92013-05-17 13:25:48 -0700613}
614
Alan Donovan8cdf1f12013-05-22 17:56:18 -0400615// The MakeClosure instruction yields a closure value whose code is
616// Fn and whose free variables' values are supplied by Bindings.
Rob Pike83f21b92013-05-17 13:25:48 -0700617//
618// Type() returns a (possibly named) *types.Signature.
619//
Alan Donovan8cdf1f12013-05-22 17:56:18 -0400620// Pos() returns the ast.FuncLit.Type.Func for a function literal
621// closure or the ast.SelectorExpr.Sel for a bound method closure.
Rob Pike87334f42013-05-17 14:02:47 -0700622//
Rob Pike83f21b92013-05-17 13:25:48 -0700623// Example printed form:
624// t0 = make closure anon@1.2 [x y z]
Alan Donovan8cdf1f12013-05-22 17:56:18 -0400625// t1 = make closure bound$(main.I).add [i]
Rob Pike83f21b92013-05-17 13:25:48 -0700626//
627type MakeClosure struct {
628 Register
629 Fn Value // always a *Function
630 Bindings []Value // values for each free variable in Fn.FreeVars
631}
632
633// The MakeMap instruction creates a new hash-table-based map object
634// and yields a value of kind map.
635//
636// Type() returns a (possibly named) *types.Map.
637//
Rob Pike87334f42013-05-17 14:02:47 -0700638// Pos() returns the ast.CallExpr.Lparen, if created by make(map), or
639// the ast.CompositeLit.Lbrack if created by a literal.
640//
Rob Pike83f21b92013-05-17 13:25:48 -0700641// Example printed form:
642// t1 = make map[string]int t0
Alan Donovan341a07a2013-06-13 14:43:35 -0400643// t1 = make StringIntMap t0
Rob Pike83f21b92013-05-17 13:25:48 -0700644//
645type MakeMap struct {
646 Register
647 Reserve Value // initial space reservation; nil => default
Rob Pike83f21b92013-05-17 13:25:48 -0700648}
649
650// The MakeChan instruction creates a new channel object and yields a
651// value of kind chan.
652//
653// Type() returns a (possibly named) *types.Chan.
654//
Rob Pike87334f42013-05-17 14:02:47 -0700655// Pos() returns the ast.CallExpr.Lparen for the make(chan) that
656// created it.
657//
Rob Pike83f21b92013-05-17 13:25:48 -0700658// Example printed form:
659// t0 = make chan int 0
Alan Donovan341a07a2013-06-13 14:43:35 -0400660// t0 = make IntChan 0
Rob Pike83f21b92013-05-17 13:25:48 -0700661//
662type MakeChan struct {
663 Register
664 Size Value // int; size of buffer; zero => synchronous.
Rob Pike83f21b92013-05-17 13:25:48 -0700665}
666
Rob Pike87334f42013-05-17 14:02:47 -0700667// The MakeSlice instruction yields a slice of length Len backed by a
668// newly allocated array of length Cap.
Rob Pike83f21b92013-05-17 13:25:48 -0700669//
670// Both Len and Cap must be non-nil Values of integer type.
671//
672// (Alloc(types.Array) followed by Slice will not suffice because
673// Alloc can only create arrays of statically known length.)
674//
675// Type() returns a (possibly named) *types.Slice.
676//
Rob Pike87334f42013-05-17 14:02:47 -0700677// Pos() returns the ast.CallExpr.Lparen for the make([]T) that
678// created it.
679//
Rob Pike83f21b92013-05-17 13:25:48 -0700680// Example printed form:
Alan Donovan341a07a2013-06-13 14:43:35 -0400681// t1 = make []string 1:int t0
682// t1 = make StringSlice 1:int t0
Rob Pike83f21b92013-05-17 13:25:48 -0700683//
684type MakeSlice struct {
685 Register
686 Len Value
687 Cap Value
Rob Pike83f21b92013-05-17 13:25:48 -0700688}
689
Rob Pike87334f42013-05-17 14:02:47 -0700690// The Slice instruction yields a slice of an existing string, slice
691// or *array X between optional integer bounds Low and High.
Rob Pike83f21b92013-05-17 13:25:48 -0700692//
693// Type() returns string if the type of X was string, otherwise a
694// *types.Slice with the same element type as X.
695//
Rob Pike87334f42013-05-17 14:02:47 -0700696// Pos() returns the ast.SliceExpr.Lbrack if created by a x[:] slice
697// operation, the ast.CompositeLit.Lbrace if created by a literal, or
698// NoPos if not explicit in the source (e.g. a variadic argument slice).
699//
Rob Pike83f21b92013-05-17 13:25:48 -0700700// Example printed form:
701// t1 = slice t0[1:]
702//
703type Slice struct {
704 Register
705 X Value // slice, string, or *array
706 Low, High Value // either may be nil
707}
708
Rob Pike87334f42013-05-17 14:02:47 -0700709// The FieldAddr instruction yields the address of Field of *struct X.
Rob Pike83f21b92013-05-17 13:25:48 -0700710//
711// The field is identified by its index within the field list of the
712// struct type of X.
713//
714// Type() returns a (possibly named) *types.Pointer.
715//
Rob Pike87334f42013-05-17 14:02:47 -0700716// Pos() returns the position of the ast.SelectorExpr.Sel for the
717// field, if explicit in the source.
718//
Rob Pike83f21b92013-05-17 13:25:48 -0700719// Example printed form:
720// t1 = &t0.name [#1]
721//
722type FieldAddr struct {
723 Register
724 X Value // *struct
Alan Donovan8097dad2013-06-24 14:15:13 -0400725 Field int // index into X.Type().Deref().(*types.Struct).Fields
Rob Pike83f21b92013-05-17 13:25:48 -0700726}
727
Rob Pike87334f42013-05-17 14:02:47 -0700728// The Field instruction yields the Field of struct X.
Rob Pike83f21b92013-05-17 13:25:48 -0700729//
730// The field is identified by its index within the field list of the
731// struct type of X; by using numeric indices we avoid ambiguity of
732// package-local identifiers and permit compact representations.
733//
Rob Pike87334f42013-05-17 14:02:47 -0700734// Pos() returns the position of the ast.SelectorExpr.Sel for the
735// field, if explicit in the source.
736//
Rob Pike83f21b92013-05-17 13:25:48 -0700737// Example printed form:
738// t1 = t0.name [#1]
739//
740type Field struct {
741 Register
742 X Value // struct
743 Field int // index into X.Type().(*types.Struct).Fields
744}
745
Rob Pike87334f42013-05-17 14:02:47 -0700746// The IndexAddr instruction yields the address of the element at
747// index Index of collection X. Index is an integer expression.
Rob Pike83f21b92013-05-17 13:25:48 -0700748//
749// The elements of maps and strings are not addressable; use Lookup or
750// MapUpdate instead.
751//
752// Type() returns a (possibly named) *types.Pointer.
753//
Rob Pike87334f42013-05-17 14:02:47 -0700754// Pos() returns the ast.IndexExpr.Lbrack for the index operation, if
755// explicit in the source.
756//
Rob Pike83f21b92013-05-17 13:25:48 -0700757// Example printed form:
758// t2 = &t0[t1]
759//
760type IndexAddr struct {
761 Register
762 X Value // slice or *array,
763 Index Value // numeric index
764}
765
Rob Pike87334f42013-05-17 14:02:47 -0700766// The Index instruction yields element Index of array X.
767//
768// Pos() returns the ast.IndexExpr.Lbrack for the index operation, if
769// explicit in the source.
Rob Pike83f21b92013-05-17 13:25:48 -0700770//
771// Example printed form:
772// t2 = t0[t1]
773//
774type Index struct {
775 Register
776 X Value // array
777 Index Value // integer index
778}
779
Rob Pike87334f42013-05-17 14:02:47 -0700780// The Lookup instruction yields element Index of collection X, a map
781// or string. Index is an integer expression if X is a string or the
782// appropriate key type if X is a map.
Rob Pike83f21b92013-05-17 13:25:48 -0700783//
784// If CommaOk, the result is a 2-tuple of the value above and a
785// boolean indicating the result of a map membership test for the key.
786// The components of the tuple are accessed using Extract.
787//
Rob Pike87334f42013-05-17 14:02:47 -0700788// Pos() returns the ast.IndexExpr.Lbrack, if explicit in the source.
789//
Rob Pike83f21b92013-05-17 13:25:48 -0700790// Example printed form:
791// t2 = t0[t1]
792// t5 = t3[t4],ok
793//
794type Lookup struct {
795 Register
796 X Value // string or map
797 Index Value // numeric or key-typed index
798 CommaOk bool // return a value,ok pair
799}
800
801// SelectState is a helper for Select.
802// It represents one goal state and its corresponding communication.
803//
804type SelectState struct {
Alan Donovanc28bf6e2013-07-31 13:13:05 -0400805 Dir ast.ChanDir // direction of case
806 Chan Value // channel to use (for send or receive)
807 Send Value // value to send (for send)
808 Pos token.Pos // position of token.ARROW
809 DebugNode ast.Node // ast.SendStmt or ast.UnaryExpr(<-) [debug mode]
Rob Pike83f21b92013-05-17 13:25:48 -0700810}
811
Rob Pike87334f42013-05-17 14:02:47 -0700812// The Select instruction tests whether (or blocks until) one or more
813// of the specified sent or received states is entered.
Rob Pike83f21b92013-05-17 13:25:48 -0700814//
Alan Donovan8097dad2013-06-24 14:15:13 -0400815// Let n be the number of States for which Dir==RECV and T_i (0<=i<n)
816// be the element type of each such state's Chan.
817// Select returns an n+2-tuple
818// (index int, recvOk bool, r_0 T_0, ... r_n-1 T_n-1)
819// The tuple's components, described below, must be accessed via the
820// Extract instruction.
Rob Pike83f21b92013-05-17 13:25:48 -0700821//
822// If Blocking, select waits until exactly one state holds, i.e. a
823// channel becomes ready for the designated operation of sending or
824// receiving; select chooses one among the ready states
825// pseudorandomly, performs the send or receive operation, and sets
826// 'index' to the index of the chosen channel.
827//
828// If !Blocking, select doesn't block if no states hold; instead it
829// returns immediately with index equal to -1.
830//
Alan Donovan8097dad2013-06-24 14:15:13 -0400831// If the chosen channel was used for a receive, the r_i component is
832// set to the received value, where i is the index of that state among
833// all n receive states; otherwise r_i has the zero value of type T_i.
834// Note that the the receive index i is not the same as the state
835// index index.
Rob Pike83f21b92013-05-17 13:25:48 -0700836//
Alan Donovan8097dad2013-06-24 14:15:13 -0400837// The second component of the triple, recvOk, is a boolean whose value
Rob Pike83f21b92013-05-17 13:25:48 -0700838// is true iff the selected operation was a receive and the receive
839// successfully yielded a value.
840//
Rob Pike87334f42013-05-17 14:02:47 -0700841// Pos() returns the ast.SelectStmt.Select.
842//
Rob Pike83f21b92013-05-17 13:25:48 -0700843// Example printed form:
844// t3 = select nonblocking [<-t0, t1<-t2, ...]
845// t4 = select blocking []
846//
847type Select struct {
848 Register
Alan Donovanc28bf6e2013-07-31 13:13:05 -0400849 States []*SelectState
Rob Pike83f21b92013-05-17 13:25:48 -0700850 Blocking bool
851}
852
Rob Pike87334f42013-05-17 14:02:47 -0700853// The Range instruction yields an iterator over the domain and range
854// of X, which must be a string or map.
Rob Pike83f21b92013-05-17 13:25:48 -0700855//
856// Elements are accessed via Next.
857//
Alan Donovan8097dad2013-06-24 14:15:13 -0400858// Type() returns an opaque and degenerate "rangeIter" type.
Rob Pike83f21b92013-05-17 13:25:48 -0700859//
Rob Pike87334f42013-05-17 14:02:47 -0700860// Pos() returns the ast.RangeStmt.For.
861//
Rob Pike83f21b92013-05-17 13:25:48 -0700862// Example printed form:
863// t0 = range "hello":string
864//
865type Range struct {
866 Register
867 X Value // string or map
868}
869
Rob Pike87334f42013-05-17 14:02:47 -0700870// The Next instruction reads and advances the (map or string)
871// iterator Iter and returns a 3-tuple value (ok, k, v). If the
872// iterator is not exhausted, ok is true and k and v are the next
873// elements of the domain and range, respectively. Otherwise ok is
874// false and k and v are undefined.
Rob Pike83f21b92013-05-17 13:25:48 -0700875//
876// Components of the tuple are accessed using Extract.
877//
878// The IsString field distinguishes iterators over strings from those
879// over maps, as the Type() alone is insufficient: consider
880// map[int]rune.
881//
Alan Donovan6c7ce1c2013-05-30 09:59:17 -0400882// Type() returns a *types.Tuple for the triple (ok, k, v).
883// The types of k and/or v may be types.Invalid.
Rob Pike83f21b92013-05-17 13:25:48 -0700884//
885// Example printed form:
886// t1 = next t0
887//
888type Next struct {
889 Register
890 Iter Value
891 IsString bool // true => string iterator; false => map iterator.
892}
893
Rob Pike87334f42013-05-17 14:02:47 -0700894// The TypeAssert instruction tests whether interface value X has type
895// AssertedType.
Rob Pike83f21b92013-05-17 13:25:48 -0700896//
897// If !CommaOk, on success it returns v, the result of the conversion
898// (defined below); on failure it panics.
899//
900// If CommaOk: on success it returns a pair (v, true) where v is the
901// result of the conversion; on failure it returns (z, false) where z
902// is AssertedType's zero value. The components of the pair must be
903// accessed using the Extract instruction.
904//
905// If AssertedType is a concrete type, TypeAssert checks whether the
906// dynamic type in interface X is equal to it, and if so, the result
907// of the conversion is a copy of the value in the interface.
908//
909// If AssertedType is an interface, TypeAssert checks whether the
910// dynamic type of the interface is assignable to it, and if so, the
911// result of the conversion is a copy of the interface value X.
Alan Donovanae801632013-07-26 21:49:27 -0400912// If AssertedType is a superinterface of X.Type(), the operation will
913// fail iff the operand is nil. (Contrast with ChangeInterface, which
914// performs no nil-check.)
Rob Pike83f21b92013-05-17 13:25:48 -0700915//
Alan Donovan6c7ce1c2013-05-30 09:59:17 -0400916// Type() reflects the actual type of the result, possibly a
917// 2-types.Tuple; AssertedType is the asserted type.
Rob Pike83f21b92013-05-17 13:25:48 -0700918//
Alan Donovan341a07a2013-06-13 14:43:35 -0400919// Pos() returns the ast.CallExpr.Lparen if the instruction arose from
920// an explicit T(e) conversion; the ast.TypeAssertExpr.Lparen if the
Alan Donovanc28bf6e2013-07-31 13:13:05 -0400921// instruction arose from an explicit e.(T) operation; or the
922// ast.CaseClause.Case if the instruction arose from a case of a
923// type-switch statement.
Alan Donovan341a07a2013-06-13 14:43:35 -0400924//
Rob Pike83f21b92013-05-17 13:25:48 -0700925// Example printed form:
926// t1 = typeassert t0.(int)
927// t3 = typeassert,ok t2.(T)
928//
929type TypeAssert struct {
930 Register
931 X Value
932 AssertedType types.Type
933 CommaOk bool
934}
935
Rob Pike87334f42013-05-17 14:02:47 -0700936// The Extract instruction yields component Index of Tuple.
Rob Pike83f21b92013-05-17 13:25:48 -0700937//
938// This is used to access the results of instructions with multiple
939// return values, such as Call, TypeAssert, Next, UnOp(ARROW) and
940// IndexExpr(Map).
941//
942// Example printed form:
943// t1 = extract t0 #1
944//
945type Extract struct {
946 Register
947 Tuple Value
948 Index int
949}
950
951// Instructions executed for effect. They do not yield a value. --------------------
952
Rob Pike87334f42013-05-17 14:02:47 -0700953// The Jump instruction transfers control to the sole successor of its
954// owning block.
Rob Pike83f21b92013-05-17 13:25:48 -0700955//
Rob Pike87334f42013-05-17 14:02:47 -0700956// A Jump must be the last instruction of its containing BasicBlock.
957//
958// Pos() returns NoPos.
Rob Pike83f21b92013-05-17 13:25:48 -0700959//
960// Example printed form:
961// jump done
962//
963type Jump struct {
964 anInstruction
965}
966
967// The If instruction transfers control to one of the two successors
968// of its owning block, depending on the boolean Cond: the first if
969// true, the second if false.
970//
971// An If instruction must be the last instruction of its containing
972// BasicBlock.
973//
Rob Pike87334f42013-05-17 14:02:47 -0700974// Pos() returns NoPos.
975//
Rob Pike83f21b92013-05-17 13:25:48 -0700976// Example printed form:
977// if t0 goto done else body
978//
979type If struct {
980 anInstruction
981 Cond Value
982}
983
Rob Pike87334f42013-05-17 14:02:47 -0700984// The Ret instruction returns values and control back to the calling
985// function.
Rob Pike83f21b92013-05-17 13:25:48 -0700986//
987// len(Results) is always equal to the number of results in the
988// function's signature.
989//
990// If len(Results) > 1, Ret returns a tuple value with the specified
991// components which the caller must access using Extract instructions.
992//
993// There is no instruction to return a ready-made tuple like those
994// returned by a "value,ok"-mode TypeAssert, Lookup or UnOp(ARROW) or
995// a tail-call to a function with multiple result parameters.
996//
997// Ret must be the last instruction of its containing BasicBlock.
998// Such a block has no successors.
999//
Rob Pike87334f42013-05-17 14:02:47 -07001000// Pos() returns the ast.ReturnStmt.Return, if explicit in the source.
1001//
Rob Pike83f21b92013-05-17 13:25:48 -07001002// Example printed form:
1003// ret
1004// ret nil:I, 2:int
1005//
1006type Ret struct {
1007 anInstruction
1008 Results []Value
Rob Pike87334f42013-05-17 14:02:47 -07001009 pos token.Pos
Rob Pike83f21b92013-05-17 13:25:48 -07001010}
1011
Rob Pike87334f42013-05-17 14:02:47 -07001012// The RunDefers instruction pops and invokes the entire stack of
1013// procedure calls pushed by Defer instructions in this function.
Rob Pike83f21b92013-05-17 13:25:48 -07001014//
1015// It is legal to encounter multiple 'rundefers' instructions in a
1016// single control-flow path through a function; this is useful in
1017// the combined init() function, for example.
1018//
Rob Pike87334f42013-05-17 14:02:47 -07001019// Pos() returns NoPos.
1020//
Rob Pike83f21b92013-05-17 13:25:48 -07001021// Example printed form:
1022// rundefers
1023//
1024type RunDefers struct {
1025 anInstruction
1026}
1027
Rob Pike87334f42013-05-17 14:02:47 -07001028// The Panic instruction initiates a panic with value X.
Rob Pike83f21b92013-05-17 13:25:48 -07001029//
1030// A Panic instruction must be the last instruction of its containing
1031// BasicBlock, which must have no successors.
1032//
1033// NB: 'go panic(x)' and 'defer panic(x)' do not use this instruction;
1034// they are treated as calls to a built-in function.
1035//
Rob Pike87334f42013-05-17 14:02:47 -07001036// Pos() returns the ast.CallExpr.Lparen if this panic was explicit
1037// in the source.
1038//
Rob Pike83f21b92013-05-17 13:25:48 -07001039// Example printed form:
1040// panic t0
1041//
1042type Panic struct {
1043 anInstruction
Rob Pike87334f42013-05-17 14:02:47 -07001044 X Value // an interface{}
1045 pos token.Pos
Rob Pike83f21b92013-05-17 13:25:48 -07001046}
1047
Rob Pike87334f42013-05-17 14:02:47 -07001048// The Go instruction creates a new goroutine and calls the specified
1049// function within it.
Rob Pike83f21b92013-05-17 13:25:48 -07001050//
1051// See CallCommon for generic function call documentation.
1052//
Alan Donovanc28bf6e2013-07-31 13:13:05 -04001053// Pos() returns the ast.GoStmt.Go.
1054//
Rob Pike83f21b92013-05-17 13:25:48 -07001055// Example printed form:
1056// go println(t0, t1)
1057// go t3()
1058// go invoke t5.Println(...t6)
1059//
1060type Go struct {
1061 anInstruction
1062 Call CallCommon
Alan Donovanc28bf6e2013-07-31 13:13:05 -04001063 pos token.Pos
Rob Pike83f21b92013-05-17 13:25:48 -07001064}
1065
Rob Pike87334f42013-05-17 14:02:47 -07001066// The Defer instruction pushes the specified call onto a stack of
1067// functions to be called by a RunDefers instruction or by a panic.
Rob Pike83f21b92013-05-17 13:25:48 -07001068//
1069// See CallCommon for generic function call documentation.
1070//
Alan Donovanc28bf6e2013-07-31 13:13:05 -04001071// Pos() returns the ast.DeferStmt.Defer.
1072//
Rob Pike83f21b92013-05-17 13:25:48 -07001073// Example printed form:
1074// defer println(t0, t1)
1075// defer t3()
1076// defer invoke t5.Println(...t6)
1077//
1078type Defer struct {
1079 anInstruction
1080 Call CallCommon
Alan Donovanc28bf6e2013-07-31 13:13:05 -04001081 pos token.Pos
Rob Pike83f21b92013-05-17 13:25:48 -07001082}
1083
Rob Pike87334f42013-05-17 14:02:47 -07001084// The Send instruction sends X on channel Chan.
1085//
1086// Pos() returns the ast.SendStmt.Arrow, if explicit in the source.
Rob Pike83f21b92013-05-17 13:25:48 -07001087//
1088// Example printed form:
1089// send t0 <- t1
1090//
1091type Send struct {
1092 anInstruction
1093 Chan, X Value
Rob Pike87334f42013-05-17 14:02:47 -07001094 pos token.Pos
Rob Pike83f21b92013-05-17 13:25:48 -07001095}
1096
Rob Pike87334f42013-05-17 14:02:47 -07001097// The Store instruction stores Val at address Addr.
Rob Pike83f21b92013-05-17 13:25:48 -07001098// Stores can be of arbitrary types.
1099//
Rob Pike87334f42013-05-17 14:02:47 -07001100// Pos() returns the ast.StarExpr.Star, if explicit in the source.
Rob Pike87334f42013-05-17 14:02:47 -07001101//
Rob Pike83f21b92013-05-17 13:25:48 -07001102// Example printed form:
1103// *x = y
1104//
1105type Store struct {
1106 anInstruction
1107 Addr Value
1108 Val Value
Rob Pike87334f42013-05-17 14:02:47 -07001109 pos token.Pos
Rob Pike83f21b92013-05-17 13:25:48 -07001110}
1111
Rob Pike87334f42013-05-17 14:02:47 -07001112// The MapUpdate instruction updates the association of Map[Key] to
1113// Value.
1114//
1115// Pos() returns the ast.KeyValueExpr.Colon, if explicit in the source.
Rob Pike83f21b92013-05-17 13:25:48 -07001116//
1117// Example printed form:
1118// t0[t1] = t2
1119//
1120type MapUpdate struct {
1121 anInstruction
1122 Map Value
1123 Key Value
1124 Value Value
Rob Pike87334f42013-05-17 14:02:47 -07001125 pos token.Pos
Rob Pike83f21b92013-05-17 13:25:48 -07001126}
1127
Alan Donovan55d678e2013-07-15 13:56:46 -04001128// A DebugRef instruction provides the position information for a
Alan Donovanc28bf6e2013-07-31 13:13:05 -04001129// specific source-level expression that compiles to the SSA value X.
Alan Donovan55d678e2013-07-15 13:56:46 -04001130//
1131// DebugRef is a pseudo-instruction: it has no dynamic effect.
1132//
Alan Donovanc28bf6e2013-07-31 13:13:05 -04001133// Pos() returns Expr.Pos(), the position of the source-level
1134// expression.
Alan Donovan55d678e2013-07-15 13:56:46 -04001135//
Alan Donovanc28bf6e2013-07-31 13:13:05 -04001136// Object() returns the source-level (var/const/func) object denoted
1137// by Expr if it is an *ast.Ident; otherwise it is nil.
Alan Donovan55d678e2013-07-15 13:56:46 -04001138//
1139// (By representing these as instructions, rather than out-of-band,
1140// consistency is maintained during transformation passes by the
1141// ordinary SSA renaming machinery.)
1142//
1143type DebugRef struct {
1144 anInstruction
1145 X Value // the value whose position we're declaring
Alan Donovanc28bf6e2013-07-31 13:13:05 -04001146 Expr ast.Expr // the referring expression
1147 object types.Object // the identity of the source var/const/func
Alan Donovan55d678e2013-07-15 13:56:46 -04001148}
1149
Rob Pike83f21b92013-05-17 13:25:48 -07001150// Embeddable mix-ins and helpers for common parts of other structs. -----------
1151
1152// Register is a mix-in embedded by all SSA values that are also
1153// instructions, i.e. virtual registers, and provides implementations
1154// of the Value interface's Name() and Type() methods: the name is
Alan Donovana399e262013-07-15 16:10:08 -04001155// simply a numbered register (e.g. "t0") and the type is the typ
Rob Pike83f21b92013-05-17 13:25:48 -07001156// field.
1157//
1158// Temporary names are automatically assigned to each Register on
1159// completion of building a function in SSA form.
1160//
1161// Clients must not assume that the 'id' value (and the Name() derived
1162// from it) is unique within a function. As always in this API,
1163// semantics are determined only by identity; names exist only to
1164// facilitate debugging.
1165//
1166type Register struct {
1167 anInstruction
1168 num int // "name" of virtual register, e.g. "t0". Not guaranteed unique.
Alan Donovan6c7ce1c2013-05-30 09:59:17 -04001169 typ types.Type // type of virtual register
Rob Pike87334f42013-05-17 14:02:47 -07001170 pos token.Pos // position of source expression, or NoPos
Rob Pike83f21b92013-05-17 13:25:48 -07001171 referrers []Instruction
1172}
1173
1174// anInstruction is a mix-in embedded by all Instructions.
1175// It provides the implementations of the Block and SetBlock methods.
1176type anInstruction struct {
Alan Donovan6c7ce1c2013-05-30 09:59:17 -04001177 block *BasicBlock // the basic block of this instruction
Rob Pike83f21b92013-05-17 13:25:48 -07001178}
1179
1180// CallCommon is contained by Go, Defer and Call to hold the
1181// common parts of a function or method call.
1182//
1183// Each CallCommon exists in one of two modes, function call and
1184// interface method invocation, or "call" and "invoke" for short.
1185//
Alan Donovan4da31df2013-07-26 11:22:34 -04001186// 1. "call" mode: when Method is nil (!IsInvoke), a CallCommon
Alan Donovan118786e2013-07-26 14:06:26 -04001187// represents an ordinary function call of the value in Value.
Rob Pike83f21b92013-05-17 13:25:48 -07001188//
Alan Donovan118786e2013-07-26 14:06:26 -04001189// In the common case in which Value is a *Function, this indicates a
Rob Pike83f21b92013-05-17 13:25:48 -07001190// statically dispatched call to a package-level function, an
1191// anonymous function, or a method of a named type. Also statically
Alan Donovan118786e2013-07-26 14:06:26 -04001192// dispatched, but less common, Value may be a *MakeClosure, indicating
Rob Pike83f21b92013-05-17 13:25:48 -07001193// an immediately applied function literal with free variables. Any
Alan Donovan118786e2013-07-26 14:06:26 -04001194// other value of Value indicates a dynamically dispatched function
Rob Pike83f21b92013-05-17 13:25:48 -07001195// call. The StaticCallee method returns the callee in these cases.
1196//
Alan Donovan118786e2013-07-26 14:06:26 -04001197// Args contains the arguments to the call. If Value is a method,
1198// Args[0] contains the receiver parameter.
Rob Pike83f21b92013-05-17 13:25:48 -07001199//
1200// Example printed form:
1201// t2 = println(t0, t1)
1202// go t3()
1203// defer t5(...t6)
1204//
Alan Donovan4da31df2013-07-26 11:22:34 -04001205// 2. "invoke" mode: when Method is non-nil (IsInvoke), a CallCommon
Rob Pike83f21b92013-05-17 13:25:48 -07001206// represents a dynamically dispatched call to an interface method.
Alan Donovan118786e2013-07-26 14:06:26 -04001207// In this mode, Value is the interface value and Method is the
Alan Donovan4da31df2013-07-26 11:22:34 -04001208// interface's abstract method.
Rob Pike83f21b92013-05-17 13:25:48 -07001209//
Alan Donovan118786e2013-07-26 14:06:26 -04001210// Value is implicitly supplied to the concrete method implementation
Rob Pike83f21b92013-05-17 13:25:48 -07001211// as the receiver parameter; in other words, Args[0] holds not the
Alan Donovan118786e2013-07-26 14:06:26 -04001212// receiver but the first true argument.
Rob Pike83f21b92013-05-17 13:25:48 -07001213//
Rob Pike83f21b92013-05-17 13:25:48 -07001214// Example printed form:
1215// t1 = invoke t0.String()
1216// go invoke t3.Run(t2)
1217// defer invoke t4.Handle(...t5)
1218//
1219// In both modes, HasEllipsis is true iff the last element of Args is
1220// a slice value containing zero or more arguments to a variadic
1221// function. (This is not semantically significant since the type of
1222// the called function is sufficient to determine this, but it aids
1223// readability of the printed form.)
1224//
1225type CallCommon struct {
Alan Donovan118786e2013-07-26 14:06:26 -04001226 Value Value // receiver (invoke mode) or func value (call mode)
1227 Method *types.Func // abstract method (invoke mode)
1228 Args []Value // actual parameters (in static method call, includes receiver)
Alan Donovan4da31df2013-07-26 11:22:34 -04001229 HasEllipsis bool // true iff last Args is a slice of '...' args (needed?)
1230 pos token.Pos // position of CallExpr.Lparen, iff explicit in source
Rob Pike83f21b92013-05-17 13:25:48 -07001231}
1232
1233// IsInvoke returns true if this call has "invoke" (not "call") mode.
1234func (c *CallCommon) IsInvoke() bool {
Alan Donovan4da31df2013-07-26 11:22:34 -04001235 return c.Method != nil
Rob Pike83f21b92013-05-17 13:25:48 -07001236}
1237
Rob Pike87334f42013-05-17 14:02:47 -07001238func (c *CallCommon) Pos() token.Pos { return c.pos }
1239
Alan Donovan8097dad2013-06-24 14:15:13 -04001240// Signature returns the signature of the called function.
1241//
1242// For an "invoke"-mode call, the signature of the interface method is
Alan Donovanb68a0292013-06-26 12:38:08 -04001243// returned.
1244//
1245// In either "call" or "invoke" mode, if the callee is a method, its
1246// receiver is represented by sig.Recv, not sig.Params().At(0).
Alan Donovan8097dad2013-06-24 14:15:13 -04001247//
Alan Donovanea8ba6f2013-07-03 15:10:49 -04001248// Signature returns nil for a call to a built-in function.
1249//
Alan Donovan8097dad2013-06-24 14:15:13 -04001250func (c *CallCommon) Signature() *types.Signature {
Alan Donovan4da31df2013-07-26 11:22:34 -04001251 if c.Method != nil {
1252 return c.Method.Type().(*types.Signature)
Alan Donovan8097dad2013-06-24 14:15:13 -04001253 }
Alan Donovan118786e2013-07-26 14:06:26 -04001254 sig, _ := c.Value.Type().Underlying().(*types.Signature) // nil for *Builtin
Alan Donovanea8ba6f2013-07-03 15:10:49 -04001255 return sig
Alan Donovan8097dad2013-06-24 14:15:13 -04001256}
1257
Rob Pike83f21b92013-05-17 13:25:48 -07001258// StaticCallee returns the called function if this is a trivially
1259// static "call"-mode call.
1260func (c *CallCommon) StaticCallee() *Function {
Alan Donovan118786e2013-07-26 14:06:26 -04001261 switch fn := c.Value.(type) {
Rob Pike83f21b92013-05-17 13:25:48 -07001262 case *Function:
1263 return fn
1264 case *MakeClosure:
1265 return fn.Fn.(*Function)
1266 }
1267 return nil
1268}
1269
Rob Pike83f21b92013-05-17 13:25:48 -07001270// Description returns a description of the mode of this call suitable
1271// for a user interface, e.g. "static method call".
1272func (c *CallCommon) Description() string {
Alan Donovan118786e2013-07-26 14:06:26 -04001273 switch fn := c.Value.(type) {
Rob Pike83f21b92013-05-17 13:25:48 -07001274 case nil:
1275 return "dynamic method call" // ("invoke" mode)
1276 case *MakeClosure:
1277 return "static function closure call"
1278 case *Function:
Rob Pike87334f42013-05-17 14:02:47 -07001279 if fn.Signature.Recv() != nil {
Rob Pike83f21b92013-05-17 13:25:48 -07001280 return "static method call"
1281 }
1282 return "static function call"
1283 }
1284 return "dynamic function call"
1285}
1286
Alan Donovan8097dad2013-06-24 14:15:13 -04001287// The CallInstruction interface, implemented by *Go, *Defer and *Call,
1288// exposes the common parts of function calling instructions,
1289// yet provides a way back to the Value defined by *Call alone.
1290//
1291type CallInstruction interface {
1292 Instruction
1293 Common() *CallCommon // returns the common parts of the call
1294 Value() *Call // returns the result value of the call (*Call) or nil (*Go, *Defer)
1295}
1296
1297func (s *Call) Common() *CallCommon { return &s.Call }
1298func (s *Defer) Common() *CallCommon { return &s.Call }
1299func (s *Go) Common() *CallCommon { return &s.Call }
1300
1301func (s *Call) Value() *Call { return s }
1302func (s *Defer) Value() *Call { return nil }
1303func (s *Go) Value() *Call { return nil }
1304
Alan Donovan55d678e2013-07-15 13:56:46 -04001305func (v *Builtin) Type() types.Type { return v.object.Type() }
1306func (v *Builtin) Name() string { return v.object.Name() }
Rob Pike83f21b92013-05-17 13:25:48 -07001307func (*Builtin) Referrers() *[]Instruction { return nil }
Alan Donovan6c7ce1c2013-05-30 09:59:17 -04001308func (v *Builtin) Pos() token.Pos { return token.NoPos }
Alan Donovan55d678e2013-07-15 13:56:46 -04001309func (v *Builtin) Object() types.Object { return v.object }
Rob Pike83f21b92013-05-17 13:25:48 -07001310
Alan Donovan6c7ce1c2013-05-30 09:59:17 -04001311func (v *Capture) Type() types.Type { return v.typ }
1312func (v *Capture) Name() string { return v.name }
Rob Pike83f21b92013-05-17 13:25:48 -07001313func (v *Capture) Referrers() *[]Instruction { return &v.referrers }
Alan Donovan6c7ce1c2013-05-30 09:59:17 -04001314func (v *Capture) Pos() token.Pos { return v.pos }
Alan Donovan341a07a2013-06-13 14:43:35 -04001315func (v *Capture) Parent() *Function { return v.parent }
Rob Pike83f21b92013-05-17 13:25:48 -07001316
Alan Donovan6c7ce1c2013-05-30 09:59:17 -04001317func (v *Global) Type() types.Type { return v.typ }
1318func (v *Global) Name() string { return v.name }
Rob Pike87334f42013-05-17 14:02:47 -07001319func (v *Global) Pos() token.Pos { return v.pos }
Rob Pike83f21b92013-05-17 13:25:48 -07001320func (*Global) Referrers() *[]Instruction { return nil }
Alan Donovan341a07a2013-06-13 14:43:35 -04001321func (v *Global) Token() token.Token { return token.VAR }
Alan Donovanbc1f7242013-07-11 14:12:30 -04001322func (v *Global) Object() types.Object { return v.object }
Rob Pike83f21b92013-05-17 13:25:48 -07001323
Alan Donovan6c7ce1c2013-05-30 09:59:17 -04001324func (v *Function) Name() string { return v.name }
Rob Pike83f21b92013-05-17 13:25:48 -07001325func (v *Function) Type() types.Type { return v.Signature }
Rob Pike87334f42013-05-17 14:02:47 -07001326func (v *Function) Pos() token.Pos { return v.pos }
Rob Pike83f21b92013-05-17 13:25:48 -07001327func (*Function) Referrers() *[]Instruction { return nil }
Alan Donovan341a07a2013-06-13 14:43:35 -04001328func (v *Function) Token() token.Token { return token.FUNC }
Alan Donovanbc1f7242013-07-11 14:12:30 -04001329func (v *Function) Object() types.Object { return v.object }
Rob Pike83f21b92013-05-17 13:25:48 -07001330
Alan Donovan6c7ce1c2013-05-30 09:59:17 -04001331func (v *Parameter) Type() types.Type { return v.typ }
1332func (v *Parameter) Name() string { return v.name }
Alan Donovan55d678e2013-07-15 13:56:46 -04001333func (v *Parameter) Object() types.Object { return v.object }
Rob Pike83f21b92013-05-17 13:25:48 -07001334func (v *Parameter) Referrers() *[]Instruction { return &v.referrers }
Alan Donovan6c7ce1c2013-05-30 09:59:17 -04001335func (v *Parameter) Pos() token.Pos { return v.pos }
Alan Donovan341a07a2013-06-13 14:43:35 -04001336func (v *Parameter) Parent() *Function { return v.parent }
Rob Pike83f21b92013-05-17 13:25:48 -07001337
Alan Donovan6c7ce1c2013-05-30 09:59:17 -04001338func (v *Alloc) Type() types.Type { return v.typ }
Rob Pike83f21b92013-05-17 13:25:48 -07001339func (v *Alloc) Referrers() *[]Instruction { return &v.referrers }
Alan Donovan6c7ce1c2013-05-30 09:59:17 -04001340func (v *Alloc) Pos() token.Pos { return v.pos }
Rob Pike83f21b92013-05-17 13:25:48 -07001341
Alan Donovan6c7ce1c2013-05-30 09:59:17 -04001342func (v *Register) Type() types.Type { return v.typ }
1343func (v *Register) setType(typ types.Type) { v.typ = typ }
Rob Pike83f21b92013-05-17 13:25:48 -07001344func (v *Register) Name() string { return fmt.Sprintf("t%d", v.num) }
1345func (v *Register) setNum(num int) { v.num = num }
1346func (v *Register) Referrers() *[]Instruction { return &v.referrers }
1347func (v *Register) asRegister() *Register { return v }
Rob Pike87334f42013-05-17 14:02:47 -07001348func (v *Register) Pos() token.Pos { return v.pos }
1349func (v *Register) setPos(pos token.Pos) { v.pos = pos }
Rob Pike83f21b92013-05-17 13:25:48 -07001350
Alan Donovan341a07a2013-06-13 14:43:35 -04001351func (v *anInstruction) Parent() *Function { return v.block.parent }
Alan Donovan6c7ce1c2013-05-30 09:59:17 -04001352func (v *anInstruction) Block() *BasicBlock { return v.block }
1353func (v *anInstruction) SetBlock(block *BasicBlock) { v.block = block }
Rob Pike83f21b92013-05-17 13:25:48 -07001354
Alan Donovanbc1f7242013-07-11 14:12:30 -04001355func (t *Type) Name() string { return t.object.Name() }
1356func (t *Type) Pos() token.Pos { return t.object.Pos() }
1357func (t *Type) Type() types.Type { return t.object.Type() }
1358func (t *Type) Token() token.Token { return token.TYPE }
1359func (t *Type) Object() types.Object { return t.object }
1360func (t *Type) String() string {
1361 return fmt.Sprintf("%s.%s", t.object.Pkg().Path(), t.object.Name())
1362}
Rob Pike83f21b92013-05-17 13:25:48 -07001363
Alan Donovan732dbe92013-07-16 13:50:08 -04001364func (c *NamedConst) Name() string { return c.object.Name() }
1365func (c *NamedConst) Pos() token.Pos { return c.object.Pos() }
1366func (c *NamedConst) String() string {
Alan Donovanbc1f7242013-07-11 14:12:30 -04001367 return fmt.Sprintf("%s.%s", c.object.Pkg().Path(), c.object.Name())
1368}
Alan Donovan732dbe92013-07-16 13:50:08 -04001369func (c *NamedConst) Type() types.Type { return c.object.Type() }
1370func (c *NamedConst) Token() token.Token { return token.CONST }
1371func (c *NamedConst) Object() types.Object { return c.object }
Rob Pike83f21b92013-05-17 13:25:48 -07001372
1373// Func returns the package-level function of the specified name,
1374// or nil if not found.
1375//
1376func (p *Package) Func(name string) (f *Function) {
1377 f, _ = p.Members[name].(*Function)
1378 return
1379}
1380
1381// Var returns the package-level variable of the specified name,
1382// or nil if not found.
1383//
1384func (p *Package) Var(name string) (g *Global) {
1385 g, _ = p.Members[name].(*Global)
1386 return
1387}
1388
1389// Const returns the package-level constant of the specified name,
1390// or nil if not found.
1391//
Alan Donovan732dbe92013-07-16 13:50:08 -04001392func (p *Package) Const(name string) (c *NamedConst) {
1393 c, _ = p.Members[name].(*NamedConst)
Rob Pike83f21b92013-05-17 13:25:48 -07001394 return
1395}
1396
1397// Type returns the package-level type of the specified name,
1398// or nil if not found.
1399//
1400func (p *Package) Type(name string) (t *Type) {
1401 t, _ = p.Members[name].(*Type)
1402 return
1403}
1404
Rob Pike87334f42013-05-17 14:02:47 -07001405func (v *Call) Pos() token.Pos { return v.Call.pos }
Alan Donovanc28bf6e2013-07-31 13:13:05 -04001406func (s *Defer) Pos() token.Pos { return s.pos }
1407func (s *Go) Pos() token.Pos { return s.pos }
Rob Pike87334f42013-05-17 14:02:47 -07001408func (s *MapUpdate) Pos() token.Pos { return s.pos }
1409func (s *Panic) Pos() token.Pos { return s.pos }
1410func (s *Ret) Pos() token.Pos { return s.pos }
1411func (s *Send) Pos() token.Pos { return s.pos }
1412func (s *Store) Pos() token.Pos { return s.pos }
1413func (s *If) Pos() token.Pos { return token.NoPos }
1414func (s *Jump) Pos() token.Pos { return token.NoPos }
1415func (s *RunDefers) Pos() token.Pos { return token.NoPos }
Alan Donovanc28bf6e2013-07-31 13:13:05 -04001416func (s *DebugRef) Pos() token.Pos { return s.Expr.Pos() }
Rob Pike83f21b92013-05-17 13:25:48 -07001417
Rob Pike87334f42013-05-17 14:02:47 -07001418// Operands.
Rob Pike83f21b92013-05-17 13:25:48 -07001419
1420func (v *Alloc) Operands(rands []*Value) []*Value {
1421 return rands
1422}
1423
1424func (v *BinOp) Operands(rands []*Value) []*Value {
1425 return append(rands, &v.X, &v.Y)
1426}
1427
1428func (c *CallCommon) Operands(rands []*Value) []*Value {
Alan Donovan118786e2013-07-26 14:06:26 -04001429 rands = append(rands, &c.Value)
Rob Pike83f21b92013-05-17 13:25:48 -07001430 for i := range c.Args {
1431 rands = append(rands, &c.Args[i])
1432 }
1433 return rands
1434}
1435
1436func (s *Go) Operands(rands []*Value) []*Value {
1437 return s.Call.Operands(rands)
1438}
1439
1440func (s *Call) Operands(rands []*Value) []*Value {
1441 return s.Call.Operands(rands)
1442}
1443
1444func (s *Defer) Operands(rands []*Value) []*Value {
1445 return s.Call.Operands(rands)
1446}
1447
1448func (v *ChangeInterface) Operands(rands []*Value) []*Value {
1449 return append(rands, &v.X)
1450}
1451
Rob Pike87334f42013-05-17 14:02:47 -07001452func (v *ChangeType) Operands(rands []*Value) []*Value {
1453 return append(rands, &v.X)
1454}
1455
1456func (v *Convert) Operands(rands []*Value) []*Value {
Rob Pike83f21b92013-05-17 13:25:48 -07001457 return append(rands, &v.X)
1458}
1459
Alan Donovan55d678e2013-07-15 13:56:46 -04001460func (s *DebugRef) Operands(rands []*Value) []*Value {
1461 return append(rands, &s.X)
1462}
1463
Rob Pike83f21b92013-05-17 13:25:48 -07001464func (v *Extract) Operands(rands []*Value) []*Value {
1465 return append(rands, &v.Tuple)
1466}
1467
1468func (v *Field) Operands(rands []*Value) []*Value {
1469 return append(rands, &v.X)
1470}
1471
1472func (v *FieldAddr) Operands(rands []*Value) []*Value {
1473 return append(rands, &v.X)
1474}
1475
1476func (s *If) Operands(rands []*Value) []*Value {
1477 return append(rands, &s.Cond)
1478}
1479
1480func (v *Index) Operands(rands []*Value) []*Value {
1481 return append(rands, &v.X, &v.Index)
1482}
1483
1484func (v *IndexAddr) Operands(rands []*Value) []*Value {
1485 return append(rands, &v.X, &v.Index)
1486}
1487
1488func (*Jump) Operands(rands []*Value) []*Value {
1489 return rands
1490}
1491
1492func (v *Lookup) Operands(rands []*Value) []*Value {
1493 return append(rands, &v.X, &v.Index)
1494}
1495
1496func (v *MakeChan) Operands(rands []*Value) []*Value {
1497 return append(rands, &v.Size)
1498}
1499
1500func (v *MakeClosure) Operands(rands []*Value) []*Value {
1501 rands = append(rands, &v.Fn)
1502 for i := range v.Bindings {
1503 rands = append(rands, &v.Bindings[i])
1504 }
1505 return rands
1506}
1507
1508func (v *MakeInterface) Operands(rands []*Value) []*Value {
1509 return append(rands, &v.X)
1510}
1511
1512func (v *MakeMap) Operands(rands []*Value) []*Value {
1513 return append(rands, &v.Reserve)
1514}
1515
1516func (v *MakeSlice) Operands(rands []*Value) []*Value {
1517 return append(rands, &v.Len, &v.Cap)
1518}
1519
1520func (v *MapUpdate) Operands(rands []*Value) []*Value {
1521 return append(rands, &v.Map, &v.Key, &v.Value)
1522}
1523
1524func (v *Next) Operands(rands []*Value) []*Value {
1525 return append(rands, &v.Iter)
1526}
1527
1528func (s *Panic) Operands(rands []*Value) []*Value {
1529 return append(rands, &s.X)
1530}
1531
1532func (v *Phi) Operands(rands []*Value) []*Value {
1533 for i := range v.Edges {
1534 rands = append(rands, &v.Edges[i])
1535 }
1536 return rands
1537}
1538
1539func (v *Range) Operands(rands []*Value) []*Value {
1540 return append(rands, &v.X)
1541}
1542
1543func (s *Ret) Operands(rands []*Value) []*Value {
1544 for i := range s.Results {
1545 rands = append(rands, &s.Results[i])
1546 }
1547 return rands
1548}
1549
1550func (*RunDefers) Operands(rands []*Value) []*Value {
1551 return rands
1552}
1553
1554func (v *Select) Operands(rands []*Value) []*Value {
1555 for i := range v.States {
1556 rands = append(rands, &v.States[i].Chan, &v.States[i].Send)
1557 }
1558 return rands
1559}
1560
1561func (s *Send) Operands(rands []*Value) []*Value {
1562 return append(rands, &s.Chan, &s.X)
1563}
1564
1565func (v *Slice) Operands(rands []*Value) []*Value {
1566 return append(rands, &v.X, &v.Low, &v.High)
1567}
1568
1569func (s *Store) Operands(rands []*Value) []*Value {
1570 return append(rands, &s.Addr, &s.Val)
1571}
1572
1573func (v *TypeAssert) Operands(rands []*Value) []*Value {
1574 return append(rands, &v.X)
1575}
1576
1577func (v *UnOp) Operands(rands []*Value) []*Value {
1578 return append(rands, &v.X)
1579}