blob: 354db2ec8646e4bc761622a3f11f73e6c730ecd3 [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 Donovanbe28dbb2013-05-31 16:14:13 -040014 "code.google.com/p/go.tools/importer"
Rob Pike83f21b92013-05-17 13:25:48 -070015)
16
17// A Program is a partial or complete Go program converted to SSA form.
Rob Pike83f21b92013-05-17 13:25:48 -070018//
19type Program struct {
Alan Donovan341a07a2013-06-13 14:43:35 -040020 Files *token.FileSet // position information for the files of this Program [TODO: rename Fset]
21 Packages map[string]*Package // all loaded Packages, keyed by import path [TODO rename packagesByPath]
22 packages map[*types.Package]*Package // all loaded Packages, keyed by object [TODO rename Packages]
23 Builtins map[types.Object]*Builtin // all built-in functions, keyed by typechecker objects.
24 concreteMethods map[*types.Func]*Function // maps named concrete methods to their code
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:
28 methodSets map[types.Type]MethodSet // concrete method set each type [TODO(adonovan): de-dup]
29 indirectionWrappers map[*Function]*Function // func(*T) wrappers for T-methods
30 boundMethodWrappers map[*Function]*Function // wrappers for curried x.Method closures
31 ifaceMethodWrappers map[*types.Func]*Function // wrappers for curried I.Method functions
Rob Pike83f21b92013-05-17 13:25:48 -070032}
33
34// A Package is a single analyzed Go package containing Members for
35// all package-level functions, variables, constants and types it
36// declares. These may be accessed directly via Members, or via the
37// type-specific accessor methods Func, Type, Var and Const.
38//
39type Package struct {
Alan Donovan4d628a02013-06-03 14:15:19 -040040 Prog *Program // the owning program
41 Types *types.Package // the type checker's package object for this package [TODO rename Object]
42 Members map[string]Member // all package members keyed by name
43 values map[types.Object]Value // package-level vars and funcs, keyed by object
44 Init *Function // the package's (concatenated) init function
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
52// A Member is a member of a Go package, implemented by *Constant,
53// *Global, *Function, or *Type; they are created by package-level
54// const, var, func and type declarations respectively.
55//
56type Member interface {
Alan Donovan341a07a2013-06-13 14:43:35 -040057 Name() string // the declared name of the package member
58 String() string // human-readable information about the value
59 Pos() token.Pos // position of member's declaration, if known
60 Type() types.Type // the type of the package member
61 Token() token.Token // token.{VAR,FUNC,CONST,TYPE}
Rob Pike83f21b92013-05-17 13:25:48 -070062}
63
64// An Id identifies the name of a field of a struct type, or the name
65// of a method of an interface or a named type.
66//
67// For exported names, i.e. those beginning with a Unicode upper-case
68// letter, a simple string is unambiguous.
69//
70// However, a method set or struct may contain multiple unexported
71// names with identical spelling that are logically distinct because
72// they originate in different packages. Unexported names must
73// therefore be disambiguated by their package too.
74//
75// The Pkg field of an Id is therefore nil iff the name is exported.
76//
77// This type is suitable for use as a map key because the equivalence
78// relation == is consistent with identifier equality.
79type Id struct {
80 Pkg *types.Package
81 Name string
82}
83
Alan Donovan341a07a2013-06-13 14:43:35 -040084// A MethodSet contains all the methods for a particular type T.
Rob Pike83f21b92013-05-17 13:25:48 -070085// The method sets for T and *T are distinct entities.
Alan Donovan341a07a2013-06-13 14:43:35 -040086//
87// All methods in the method set for T have a receiver type of exactly
88// T. The method set of *T may contain synthetic indirection methods
89// that wrap methods whose receiver type is T.
Rob Pike83f21b92013-05-17 13:25:48 -070090//
91type MethodSet map[Id]*Function
92
Alan Donovan341a07a2013-06-13 14:43:35 -040093// A Type is a Member of a Package representing a package-level named type.
94//
95// Type() returns a *types.Named.
Rob Pike83f21b92013-05-17 13:25:48 -070096//
97type Type struct {
Alan Donovan341a07a2013-06-13 14:43:35 -040098 Object *types.TypeName
Rob Pike83f21b92013-05-17 13:25:48 -070099}
100
101// A Constant is a Member of Package representing a package-level
102// constant value.
103//
Rob Pike87334f42013-05-17 14:02:47 -0700104// Pos() returns the position of the declaring ast.ValueSpec.Names[*]
105// identifier.
106//
107// NB: a Constant is not a Value; it contains a literal Value, which
108// it augments with the name and position of its 'const' declaration.
109//
Alan Donovan6c7ce1c2013-05-30 09:59:17 -0400110// TODO(adonovan): if we decide to add a token.Pos to literal, we
111// should then add a name too, and merge Constant and Literal.
112// Experiment.
113//
Rob Pike83f21b92013-05-17 13:25:48 -0700114type Constant struct {
Alan Donovan6c7ce1c2013-05-30 09:59:17 -0400115 name string
Rob Pike83f21b92013-05-17 13:25:48 -0700116 Value *Literal
Rob Pike87334f42013-05-17 14:02:47 -0700117 pos token.Pos
Rob Pike83f21b92013-05-17 13:25:48 -0700118}
119
120// An SSA value that can be referenced by an instruction.
121type Value interface {
122 // Name returns the name of this value, and determines how
123 // this Value appears when used as an operand of an
124 // Instruction.
125 //
126 // This is the same as the source name for Parameters,
127 // Builtins, Functions, Captures, Globals and some Allocs.
128 // For literals, it is a representation of the literal's value
129 // and type. For all other Values this is the name of the
130 // virtual register defined by the instruction.
131 //
132 // The name of an SSA Value is not semantically significant,
133 // and may not even be unique within a function.
134 Name() string
135
136 // If this value is an Instruction, String returns its
137 // disassembled form; otherwise it returns unspecified
138 // human-readable information about the Value, such as its
139 // kind, name and type.
140 String() string
141
142 // Type returns the type of this value. Many instructions
143 // (e.g. IndexAddr) change the behaviour depending on the
144 // types of their operands.
145 Type() types.Type
146
147 // Referrers returns the list of instructions that have this
148 // value as one of their operands; it may contain duplicates
149 // if an instruction has a repeated operand.
150 //
151 // Referrers actually returns a pointer through which the
152 // caller may perform mutations to the object's state.
153 //
154 // Referrers is currently only defined for the function-local
155 // values Capture, Parameter and all value-defining instructions.
156 // It returns nil for Function, Builtin, Literal and Global.
157 //
158 // Instruction.Operands contains the inverse of this relation.
159 Referrers() *[]Instruction
160
Alan Donovan6c7ce1c2013-05-30 09:59:17 -0400161 // Pos returns the location of the source construct that
162 // gave rise to this value, or token.NoPos if it was not
163 // explicit in the source.
164 //
165 // For each ast.Expr type, a particular field is designated as
166 // the canonical location for the expression, e.g. the Lparen
167 // for an *ast.CallExpr. This enables us to find the value
168 // corresponding to a given piece of source syntax.
169 //
170 Pos() token.Pos
Rob Pike83f21b92013-05-17 13:25:48 -0700171}
172
173// An Instruction is an SSA instruction that computes a new Value or
174// has some effect.
175//
176// An Instruction that defines a value (e.g. BinOp) also implements
177// the Value interface; an Instruction that only has an effect (e.g. Store)
178// does not.
179//
180type Instruction interface {
181 // String returns the disassembled form of this value. e.g.
182 //
183 // Examples of Instructions that define a Value:
184 // e.g. "x + y" (BinOp)
185 // "len([])" (Call)
186 // Note that the name of the Value is not printed.
187 //
188 // Examples of Instructions that do define (are) Values:
189 // e.g. "ret x" (Ret)
190 // "*y = x" (Store)
191 //
192 // (This separation is useful for some analyses which
193 // distinguish the operation from the value it
194 // defines. e.g. 'y = local int' is both an allocation of
195 // memory 'local int' and a definition of a pointer y.)
196 String() string
197
Alan Donovan341a07a2013-06-13 14:43:35 -0400198 // Parent returns the function to which this instruction
199 // belongs.
200 Parent() *Function
201
Rob Pike83f21b92013-05-17 13:25:48 -0700202 // Block returns the basic block to which this instruction
203 // belongs.
204 Block() *BasicBlock
205
206 // SetBlock sets the basic block to which this instruction
207 // belongs.
208 SetBlock(*BasicBlock)
209
210 // Operands returns the operands of this instruction: the
211 // set of Values it references.
212 //
213 // Specifically, it appends their addresses to rands, a
214 // user-provided slice, and returns the resulting slice,
215 // permitting avoidance of memory allocation.
216 //
217 // The operands are appended in undefined order; the addresses
218 // are always non-nil but may point to a nil Value. Clients
219 // may store through the pointers, e.g. to effect a value
220 // renaming.
221 //
222 // Value.Referrers is a subset of the inverse of this
223 // relation. (Referrers are not tracked for all types of
224 // Values.)
225 Operands(rands []*Value) []*Value
226
Rob Pike87334f42013-05-17 14:02:47 -0700227 // Pos returns the location of the source construct that
228 // gave rise to this instruction, or token.NoPos if it was not
229 // explicit in the source.
230 //
231 // For each ast.Expr type, a particular field is designated as
232 // the canonical location for the expression, e.g. the Lparen
233 // for an *ast.CallExpr. This enables us to find the
234 // instruction corresponding to a given piece of source
235 // syntax.
236 //
237 Pos() token.Pos
Rob Pike83f21b92013-05-17 13:25:48 -0700238}
239
240// Function represents the parameters, results and code of a function
241// or method.
242//
243// If Blocks is nil, this indicates an external function for which no
244// Go source code is available. In this case, Captures and Locals
245// will be nil too. Clients performing whole-program analysis must
246// handle external functions specially.
247//
248// Functions are immutable values; they do not have addresses.
249//
250// Blocks[0] is the function entry point; block order is not otherwise
251// semantically significant, though it may affect the readability of
252// the disassembly.
253//
254// A nested function that refers to one or more lexically enclosing
255// local variables ("free variables") has Capture parameters. Such
256// functions cannot be called directly but require a value created by
257// MakeClosure which, via its Bindings, supplies values for these
Alan Donovan8cdf1f12013-05-22 17:56:18 -0400258// parameters.
Rob Pike83f21b92013-05-17 13:25:48 -0700259//
Rob Pike87334f42013-05-17 14:02:47 -0700260// If the function is a method (Signature.Recv() != nil) then the first
Rob Pike83f21b92013-05-17 13:25:48 -0700261// element of Params is the receiver parameter.
262//
Rob Pike87334f42013-05-17 14:02:47 -0700263// Pos() returns the declaring ast.FuncLit.Type.Func or the position
264// of the ast.FuncDecl.Name, if the function was explicit in the
265// source.
266//
Rob Pike83f21b92013-05-17 13:25:48 -0700267// Type() returns the function's Signature.
268//
269type Function struct {
Alan Donovan6c7ce1c2013-05-30 09:59:17 -0400270 name string
Rob Pike83f21b92013-05-17 13:25:48 -0700271 Signature *types.Signature
Rob Pike87334f42013-05-17 14:02:47 -0700272 pos token.Pos
Alan Donovan6c7ce1c2013-05-30 09:59:17 -0400273
Rob Pike83f21b92013-05-17 13:25:48 -0700274 Enclosing *Function // enclosing function if anon; nil if global
275 Pkg *Package // enclosing package for Go source functions; otherwise nil
276 Prog *Program // enclosing program
277 Params []*Parameter // function parameters; for methods, includes receiver
278 FreeVars []*Capture // free variables whose values must be supplied by closure
279 Locals []*Alloc
280 Blocks []*BasicBlock // basic blocks of the function; nil => external
281 AnonFuncs []*Function // anonymous functions directly beneath this one
282
283 // The following fields are set transiently during building,
284 // then cleared.
285 currentBlock *BasicBlock // where to emit code
286 objects map[types.Object]Value // addresses of local variables
287 namedResults []*Alloc // tuple of named results
288 syntax *funcSyntax // abstract syntax trees for Go source functions
289 targets *targets // linked stack of branch targets
290 lblocks map[*ast.Object]*lblock // labelled blocks
291}
292
293// An SSA basic block.
294//
295// The final element of Instrs is always an explicit transfer of
296// control (If, Jump, Ret or Panic).
297//
298// A block may contain no Instructions only if it is unreachable,
299// i.e. Preds is nil. Empty blocks are typically pruned.
300//
301// BasicBlocks and their Preds/Succs relation form a (possibly cyclic)
302// graph independent of the SSA Value graph. It is illegal for
303// multiple edges to exist between the same pair of blocks.
304//
305// The order of Preds and Succs are significant (to Phi and If
306// instructions, respectively).
307//
308type BasicBlock struct {
309 Index int // index of this block within Func.Blocks
310 Comment string // optional label; no semantic significance
Alan Donovan341a07a2013-06-13 14:43:35 -0400311 parent *Function // parent function
Rob Pike83f21b92013-05-17 13:25:48 -0700312 Instrs []Instruction // instructions in order
313 Preds, Succs []*BasicBlock // predecessors and successors
314 succs2 [2]*BasicBlock // initial space for Succs.
315 dom *domNode // node in dominator tree; optional.
316 gaps int // number of nil Instrs (transient).
317 rundefers int // number of rundefers (transient)
318}
319
320// Pure values ----------------------------------------
321
Alan Donovan8cdf1f12013-05-22 17:56:18 -0400322// A Capture represents a free variable of the function to which it
323// belongs.
Rob Pike83f21b92013-05-17 13:25:48 -0700324//
Alan Donovan8cdf1f12013-05-22 17:56:18 -0400325// Captures are used to implement anonymous functions, whose free
326// variables are lexically captured in a closure formed by
327// MakeClosure. The referent of such a capture is an Alloc or another
328// Capture and is considered a potentially escaping heap address, with
329// pointer type.
330//
331// Captures are also used to implement bound method closures. Such a
332// capture represents the receiver value and may be of any type that
333// has concrete methods.
Rob Pike83f21b92013-05-17 13:25:48 -0700334//
Alan Donovan6c7ce1c2013-05-30 09:59:17 -0400335// Pos() returns the position of the value that was captured, which
336// belongs to an enclosing function.
337//
Rob Pike83f21b92013-05-17 13:25:48 -0700338type Capture struct {
Alan Donovan341a07a2013-06-13 14:43:35 -0400339 name string
340 typ types.Type
341 pos token.Pos
342 parent *Function
Rob Pike83f21b92013-05-17 13:25:48 -0700343 referrers []Instruction
Alan Donovan8cdf1f12013-05-22 17:56:18 -0400344
345 // Transiently needed during building.
346 outer Value // the Value captured from the enclosing context.
Rob Pike83f21b92013-05-17 13:25:48 -0700347}
348
349// A Parameter represents an input parameter of a function.
350//
351type Parameter struct {
Alan Donovan341a07a2013-06-13 14:43:35 -0400352 name string
353 typ types.Type
354 pos token.Pos
355 parent *Function
Rob Pike83f21b92013-05-17 13:25:48 -0700356 referrers []Instruction
357}
358
Rob Pike87334f42013-05-17 14:02:47 -0700359// A Literal represents the value of a constant expression.
Rob Pike83f21b92013-05-17 13:25:48 -0700360//
Rob Pike87334f42013-05-17 14:02:47 -0700361// It may have a nil, boolean, string or numeric (integer, fraction or
362// complex) value, or a []byte or []rune conversion of a string
363// literal.
364//
365// Literals may be of named types. A literal's underlying type can be
366// a basic type, possibly one of the "untyped" types, or a slice type
367// whose elements' underlying type is byte or rune. A nil literal can
368// have any reference type: interface, map, channel, pointer, slice,
369// or function---but not "untyped nil".
Rob Pike83f21b92013-05-17 13:25:48 -0700370//
371// All source-level constant expressions are represented by a Literal
372// of equal type and value.
373//
374// Value holds the exact value of the literal, independent of its
Rob Pike87334f42013-05-17 14:02:47 -0700375// Type(), using the same representation as package go/exact uses for
Rob Pike83f21b92013-05-17 13:25:48 -0700376// constants.
377//
Alan Donovan8097dad2013-06-24 14:15:13 -0400378// Pos() returns the canonical position (see CanonicalPos) of the
379// originating constant expression, if explicit in the source.
Alan Donovan6c7ce1c2013-05-30 09:59:17 -0400380//
Rob Pike83f21b92013-05-17 13:25:48 -0700381// Example printed form:
382// 42:int
383// "hello":untyped string
384// 3+4i:MyComplex
385//
386type Literal struct {
Alan Donovan6c7ce1c2013-05-30 09:59:17 -0400387 typ types.Type
Rob Pike83f21b92013-05-17 13:25:48 -0700388 Value exact.Value
Alan Donovan8097dad2013-06-24 14:15:13 -0400389 pos token.Pos
Rob Pike83f21b92013-05-17 13:25:48 -0700390}
391
392// A Global is a named Value holding the address of a package-level
393// variable.
394//
Rob Pike87334f42013-05-17 14:02:47 -0700395// Pos() returns the position of the ast.ValueSpec.Names[*]
396// identifier.
397//
Rob Pike83f21b92013-05-17 13:25:48 -0700398type Global struct {
Alan Donovan6c7ce1c2013-05-30 09:59:17 -0400399 name string
400 typ types.Type
401 pos token.Pos
402
403 Pkg *Package
Rob Pike83f21b92013-05-17 13:25:48 -0700404
405 // The following fields are set transiently during building,
406 // then cleared.
407 spec *ast.ValueSpec // explained at buildGlobal
408}
409
Rob Pike87334f42013-05-17 14:02:47 -0700410// A Builtin represents a built-in function, e.g. len.
Rob Pike83f21b92013-05-17 13:25:48 -0700411//
Rob Pike87334f42013-05-17 14:02:47 -0700412// Builtins are immutable values. Builtins do not have addresses.
Rob Pike83f21b92013-05-17 13:25:48 -0700413//
Rob Pike87334f42013-05-17 14:02:47 -0700414// Type() returns a *types.Builtin.
415// Built-in functions may have polymorphic or variadic types that are
416// not expressible in Go's type system.
Rob Pike83f21b92013-05-17 13:25:48 -0700417//
418type Builtin struct {
419 Object *types.Func // canonical types.Universe object for this built-in
420}
421
422// Value-defining instructions ----------------------------------------
423
424// The Alloc instruction reserves space for a value of the given type,
425// zero-initializes it, and yields its address.
426//
427// Alloc values are always addresses, and have pointer types, so the
428// type of the allocated space is actually indirect(Type()).
429//
430// If Heap is false, Alloc allocates space in the function's
431// activation record (frame); we refer to an Alloc(Heap=false) as a
432// "local" alloc. Each local Alloc returns the same address each time
433// it is executed within the same activation; the space is
434// re-initialized to zero.
435//
436// If Heap is true, Alloc allocates space in the heap, and returns; we
437// refer to an Alloc(Heap=true) as a "new" alloc. Each new Alloc
438// returns a different address each time it is executed.
439//
440// When Alloc is applied to a channel, map or slice type, it returns
441// the address of an uninitialized (nil) reference of that kind; store
442// the result of MakeSlice, MakeMap or MakeChan in that location to
443// instantiate these types.
444//
Rob Pike87334f42013-05-17 14:02:47 -0700445// Pos() returns the ast.CompositeLit.Lbrace for a composite literal,
446// or the ast.CallExpr.Lparen for a call to new() or for a call that
447// allocates a varargs slice.
448//
Rob Pike83f21b92013-05-17 13:25:48 -0700449// Example printed form:
450// t0 = local int
451// t1 = new int
452//
453type Alloc struct {
454 anInstruction
Alan Donovan6c7ce1c2013-05-30 09:59:17 -0400455 name string
456 typ types.Type
Rob Pike83f21b92013-05-17 13:25:48 -0700457 Heap bool
Rob Pike87334f42013-05-17 14:02:47 -0700458 pos token.Pos
Rob Pike83f21b92013-05-17 13:25:48 -0700459 referrers []Instruction
460 index int // dense numbering; for lifting
461}
462
Rob Pike87334f42013-05-17 14:02:47 -0700463// The Phi instruction represents an SSA φ-node, which combines values
464// that differ across incoming control-flow edges and yields a new
465// value. Within a block, all φ-nodes must appear before all non-φ
466// nodes.
467//
Alan Donovan6c7ce1c2013-05-30 09:59:17 -0400468// Pos() returns the position of the && or || for short-circuit
469// control-flow joins, or that of the *Alloc for φ-nodes inserted
470// during SSA renaming.
Rob Pike83f21b92013-05-17 13:25:48 -0700471//
472// Example printed form:
473// t2 = phi [0.start: t0, 1.if.then: t1, ...]
474//
475type Phi struct {
476 Register
477 Comment string // a hint as to its purpose
478 Edges []Value // Edges[i] is value for Block().Preds[i]
479}
480
Rob Pike87334f42013-05-17 14:02:47 -0700481// The Call instruction represents a function or method call.
Rob Pike83f21b92013-05-17 13:25:48 -0700482//
483// The Call instruction yields the function result, if there is
484// exactly one, or a tuple (empty or len>1) whose components are
485// accessed via Extract.
486//
487// See CallCommon for generic function call documentation.
488//
Rob Pike87334f42013-05-17 14:02:47 -0700489// Pos() returns the ast.CallExpr.Lparen, if explicit in the source.
490//
Rob Pike83f21b92013-05-17 13:25:48 -0700491// Example printed form:
492// t2 = println(t0, t1)
493// t4 = t3()
494// t7 = invoke t5.Println(...t6)
495//
496type Call struct {
497 Register
498 Call CallCommon
499}
500
Rob Pike87334f42013-05-17 14:02:47 -0700501// The BinOp instruction yields the result of binary operation X Op Y.
502//
503// Pos() returns the ast.BinaryExpr.OpPos, if explicit in the source.
Rob Pike83f21b92013-05-17 13:25:48 -0700504//
505// Example printed form:
506// t1 = t0 + 1:int
507//
508type BinOp struct {
509 Register
510 // One of:
511 // ADD SUB MUL QUO REM + - * / %
512 // AND OR XOR SHL SHR AND_NOT & | ^ << >> &~
513 // EQL LSS GTR NEQ LEQ GEQ == != < <= < >=
514 Op token.Token
515 X, Y Value
516}
517
Rob Pike87334f42013-05-17 14:02:47 -0700518// The UnOp instruction yields the result of Op X.
Rob Pike83f21b92013-05-17 13:25:48 -0700519// ARROW is channel receive.
520// MUL is pointer indirection (load).
521// XOR is bitwise complement.
522// SUB is negation.
523//
524// If CommaOk and Op=ARROW, the result is a 2-tuple of the value above
525// and a boolean indicating the success of the receive. The
526// components of the tuple are accessed using Extract.
527//
Alan Donovan6c7ce1c2013-05-30 09:59:17 -0400528// Pos() returns the ast.UnaryExpr.OpPos, if explicit in the source,
Rob Pike87334f42013-05-17 14:02:47 -0700529//
Rob Pike83f21b92013-05-17 13:25:48 -0700530// Example printed form:
531// t0 = *x
532// t2 = <-t1,ok
533//
534type UnOp struct {
535 Register
536 Op token.Token // One of: NOT SUB ARROW MUL XOR ! - <- * ^
537 X Value
538 CommaOk bool
539}
540
Rob Pike87334f42013-05-17 14:02:47 -0700541// The ChangeType instruction applies to X a value-preserving type
542// change to Type().
Rob Pike83f21b92013-05-17 13:25:48 -0700543//
Rob Pike87334f42013-05-17 14:02:47 -0700544// Type changes are permitted:
545// - between a named type and its underlying type.
546// - between two named types of the same underlying type.
547// - between (possibly named) pointers to identical base types.
548// - between f(T) functions and (T) func f() methods.
549// - from a bidirectional channel to a read- or write-channel,
550// optionally adding/removing a name.
Rob Pike83f21b92013-05-17 13:25:48 -0700551//
Rob Pike87334f42013-05-17 14:02:47 -0700552// This operation cannot fail dynamically.
Rob Pike83f21b92013-05-17 13:25:48 -0700553//
Rob Pike87334f42013-05-17 14:02:47 -0700554// Pos() returns the ast.CallExpr.Lparen, if the instruction arose
555// from an explicit conversion in the source.
Rob Pike83f21b92013-05-17 13:25:48 -0700556//
Rob Pike87334f42013-05-17 14:02:47 -0700557// Example printed form:
558// t1 = changetype *int <- IntPtr (t0)
559//
560type ChangeType struct {
561 Register
562 X Value
563}
564
565// The Convert instruction yields the conversion of value X to type
Alan Donovan8097dad2013-06-24 14:15:13 -0400566// Type(). One or both of those types is basic (but possibly named).
Rob Pike87334f42013-05-17 14:02:47 -0700567//
568// A conversion may change the value and representation of its operand.
569// Conversions are permitted:
570// - between real numeric types.
571// - between complex numeric types.
572// - between string and []byte or []rune.
Alan Donovan8097dad2013-06-24 14:15:13 -0400573// - between pointers and unsafe.Pointer.
574// - between unsafe.Pointer and uintptr.
Rob Pike87334f42013-05-17 14:02:47 -0700575// - from (Unicode) integer to (UTF-8) string.
576// A conversion may imply a type name change also.
577//
578// This operation cannot fail dynamically.
Rob Pike83f21b92013-05-17 13:25:48 -0700579//
580// Conversions of untyped string/number/bool constants to a specific
581// representation are eliminated during SSA construction.
582//
Rob Pike87334f42013-05-17 14:02:47 -0700583// Pos() returns the ast.CallExpr.Lparen, if the instruction arose
584// from an explicit conversion in the source.
Rob Pike83f21b92013-05-17 13:25:48 -0700585//
Rob Pike87334f42013-05-17 14:02:47 -0700586// Example printed form:
587// t1 = convert []byte <- string (t0)
588//
589type Convert struct {
Rob Pike83f21b92013-05-17 13:25:48 -0700590 Register
591 X Value
592}
593
594// ChangeInterface constructs a value of one interface type from a
595// value of another interface type known to be assignable to it.
596//
Alan Donovan0f26bba2013-06-13 17:31:32 -0400597// This operation fails if the operand is nil.
598// For all other operands, well-typedness ensures success.
599// Use TypeAssert for interface conversions that are uncertain.
Rob Pike87334f42013-05-17 14:02:47 -0700600//
Alan Donovan341a07a2013-06-13 14:43:35 -0400601// Pos() returns the ast.CallExpr.Lparen if the instruction arose from
602// an explicit T(e) conversion; the ast.TypeAssertExpr.Lparen if the
603// instruction arose from an explicit e.(T) operation; or token.NoPos
604// otherwise.
605//
Rob Pike83f21b92013-05-17 13:25:48 -0700606// Example printed form:
607// t1 = change interface interface{} <- I (t0)
608//
609type ChangeInterface struct {
610 Register
611 X Value
612}
613
614// MakeInterface constructs an instance of an interface type from a
Alan Donovan341a07a2013-06-13 14:43:35 -0400615// value of a concrete type.
616//
617// Use Program.MethodSet(X.Type()) to find the method-set of X.
Rob Pike83f21b92013-05-17 13:25:48 -0700618//
619// To construct the zero value of an interface type T, use:
Alan Donovan8097dad2013-06-24 14:15:13 -0400620// NewLiteral(exact.MakeNil(), T, pos)
Rob Pike87334f42013-05-17 14:02:47 -0700621//
622// Pos() returns the ast.CallExpr.Lparen, if the instruction arose
623// from an explicit conversion in the source.
Rob Pike83f21b92013-05-17 13:25:48 -0700624//
625// Example printed form:
Alan Donovan341a07a2013-06-13 14:43:35 -0400626// t1 = make interface{} <- int (42:int)
627// t2 = make Stringer <- t0
Rob Pike83f21b92013-05-17 13:25:48 -0700628//
629type MakeInterface struct {
630 Register
Alan Donovan341a07a2013-06-13 14:43:35 -0400631 X Value
Rob Pike83f21b92013-05-17 13:25:48 -0700632}
633
Alan Donovan8cdf1f12013-05-22 17:56:18 -0400634// The MakeClosure instruction yields a closure value whose code is
635// Fn and whose free variables' values are supplied by Bindings.
Rob Pike83f21b92013-05-17 13:25:48 -0700636//
637// Type() returns a (possibly named) *types.Signature.
638//
Alan Donovan8cdf1f12013-05-22 17:56:18 -0400639// Pos() returns the ast.FuncLit.Type.Func for a function literal
640// closure or the ast.SelectorExpr.Sel for a bound method closure.
Rob Pike87334f42013-05-17 14:02:47 -0700641//
Rob Pike83f21b92013-05-17 13:25:48 -0700642// Example printed form:
643// t0 = make closure anon@1.2 [x y z]
Alan Donovan8cdf1f12013-05-22 17:56:18 -0400644// t1 = make closure bound$(main.I).add [i]
Rob Pike83f21b92013-05-17 13:25:48 -0700645//
646type MakeClosure struct {
647 Register
648 Fn Value // always a *Function
649 Bindings []Value // values for each free variable in Fn.FreeVars
650}
651
652// The MakeMap instruction creates a new hash-table-based map object
653// and yields a value of kind map.
654//
655// Type() returns a (possibly named) *types.Map.
656//
Rob Pike87334f42013-05-17 14:02:47 -0700657// Pos() returns the ast.CallExpr.Lparen, if created by make(map), or
658// the ast.CompositeLit.Lbrack if created by a literal.
659//
Rob Pike83f21b92013-05-17 13:25:48 -0700660// Example printed form:
661// t1 = make map[string]int t0
Alan Donovan341a07a2013-06-13 14:43:35 -0400662// t1 = make StringIntMap t0
Rob Pike83f21b92013-05-17 13:25:48 -0700663//
664type MakeMap struct {
665 Register
666 Reserve Value // initial space reservation; nil => default
Rob Pike83f21b92013-05-17 13:25:48 -0700667}
668
669// The MakeChan instruction creates a new channel object and yields a
670// value of kind chan.
671//
672// Type() returns a (possibly named) *types.Chan.
673//
Rob Pike87334f42013-05-17 14:02:47 -0700674// Pos() returns the ast.CallExpr.Lparen for the make(chan) that
675// created it.
676//
Rob Pike83f21b92013-05-17 13:25:48 -0700677// Example printed form:
678// t0 = make chan int 0
Alan Donovan341a07a2013-06-13 14:43:35 -0400679// t0 = make IntChan 0
Rob Pike83f21b92013-05-17 13:25:48 -0700680//
681type MakeChan struct {
682 Register
683 Size Value // int; size of buffer; zero => synchronous.
Rob Pike83f21b92013-05-17 13:25:48 -0700684}
685
Rob Pike87334f42013-05-17 14:02:47 -0700686// The MakeSlice instruction yields a slice of length Len backed by a
687// newly allocated array of length Cap.
Rob Pike83f21b92013-05-17 13:25:48 -0700688//
689// Both Len and Cap must be non-nil Values of integer type.
690//
691// (Alloc(types.Array) followed by Slice will not suffice because
692// Alloc can only create arrays of statically known length.)
693//
694// Type() returns a (possibly named) *types.Slice.
695//
Rob Pike87334f42013-05-17 14:02:47 -0700696// Pos() returns the ast.CallExpr.Lparen for the make([]T) that
697// created it.
698//
Rob Pike83f21b92013-05-17 13:25:48 -0700699// Example printed form:
Alan Donovan341a07a2013-06-13 14:43:35 -0400700// t1 = make []string 1:int t0
701// t1 = make StringSlice 1:int t0
Rob Pike83f21b92013-05-17 13:25:48 -0700702//
703type MakeSlice struct {
704 Register
705 Len Value
706 Cap Value
Rob Pike83f21b92013-05-17 13:25:48 -0700707}
708
Rob Pike87334f42013-05-17 14:02:47 -0700709// The Slice instruction yields a slice of an existing string, slice
710// or *array X between optional integer bounds Low and High.
Rob Pike83f21b92013-05-17 13:25:48 -0700711//
712// Type() returns string if the type of X was string, otherwise a
713// *types.Slice with the same element type as X.
714//
Rob Pike87334f42013-05-17 14:02:47 -0700715// Pos() returns the ast.SliceExpr.Lbrack if created by a x[:] slice
716// operation, the ast.CompositeLit.Lbrace if created by a literal, or
717// NoPos if not explicit in the source (e.g. a variadic argument slice).
718//
Rob Pike83f21b92013-05-17 13:25:48 -0700719// Example printed form:
720// t1 = slice t0[1:]
721//
722type Slice struct {
723 Register
724 X Value // slice, string, or *array
725 Low, High Value // either may be nil
726}
727
Rob Pike87334f42013-05-17 14:02:47 -0700728// The FieldAddr instruction yields the address of 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.
732//
733// Type() returns a (possibly named) *types.Pointer.
734//
Rob Pike87334f42013-05-17 14:02:47 -0700735// Pos() returns the position of the ast.SelectorExpr.Sel for the
736// field, if explicit in the source.
737//
Rob Pike83f21b92013-05-17 13:25:48 -0700738// Example printed form:
739// t1 = &t0.name [#1]
740//
741type FieldAddr struct {
742 Register
743 X Value // *struct
Alan Donovan8097dad2013-06-24 14:15:13 -0400744 Field int // index into X.Type().Deref().(*types.Struct).Fields
Rob Pike83f21b92013-05-17 13:25:48 -0700745}
746
Rob Pike87334f42013-05-17 14:02:47 -0700747// The Field instruction yields the Field of struct X.
Rob Pike83f21b92013-05-17 13:25:48 -0700748//
749// The field is identified by its index within the field list of the
750// struct type of X; by using numeric indices we avoid ambiguity of
751// package-local identifiers and permit compact representations.
752//
Rob Pike87334f42013-05-17 14:02:47 -0700753// Pos() returns the position of the ast.SelectorExpr.Sel for the
754// field, if explicit in the source.
755//
Rob Pike83f21b92013-05-17 13:25:48 -0700756// Example printed form:
757// t1 = t0.name [#1]
758//
759type Field struct {
760 Register
761 X Value // struct
762 Field int // index into X.Type().(*types.Struct).Fields
763}
764
Rob Pike87334f42013-05-17 14:02:47 -0700765// The IndexAddr instruction yields the address of the element at
766// index Index of collection X. Index is an integer expression.
Rob Pike83f21b92013-05-17 13:25:48 -0700767//
768// The elements of maps and strings are not addressable; use Lookup or
769// MapUpdate instead.
770//
771// Type() returns a (possibly named) *types.Pointer.
772//
Rob Pike87334f42013-05-17 14:02:47 -0700773// Pos() returns the ast.IndexExpr.Lbrack for the index operation, if
774// explicit in the source.
775//
Rob Pike83f21b92013-05-17 13:25:48 -0700776// Example printed form:
777// t2 = &t0[t1]
778//
779type IndexAddr struct {
780 Register
781 X Value // slice or *array,
782 Index Value // numeric index
783}
784
Rob Pike87334f42013-05-17 14:02:47 -0700785// The Index instruction yields element Index of array X.
786//
787// Pos() returns the ast.IndexExpr.Lbrack for the index operation, if
788// explicit in the source.
Rob Pike83f21b92013-05-17 13:25:48 -0700789//
790// Example printed form:
791// t2 = t0[t1]
792//
793type Index struct {
794 Register
795 X Value // array
796 Index Value // integer index
797}
798
Rob Pike87334f42013-05-17 14:02:47 -0700799// The Lookup instruction yields element Index of collection X, a map
800// or string. Index is an integer expression if X is a string or the
801// appropriate key type if X is a map.
Rob Pike83f21b92013-05-17 13:25:48 -0700802//
803// If CommaOk, the result is a 2-tuple of the value above and a
804// boolean indicating the result of a map membership test for the key.
805// The components of the tuple are accessed using Extract.
806//
Rob Pike87334f42013-05-17 14:02:47 -0700807// Pos() returns the ast.IndexExpr.Lbrack, if explicit in the source.
808//
Rob Pike83f21b92013-05-17 13:25:48 -0700809// Example printed form:
810// t2 = t0[t1]
811// t5 = t3[t4],ok
812//
813type Lookup struct {
814 Register
815 X Value // string or map
816 Index Value // numeric or key-typed index
817 CommaOk bool // return a value,ok pair
818}
819
820// SelectState is a helper for Select.
821// It represents one goal state and its corresponding communication.
822//
823type SelectState struct {
824 Dir ast.ChanDir // direction of case
825 Chan Value // channel to use (for send or receive)
826 Send Value // value to send (for send)
827}
828
Rob Pike87334f42013-05-17 14:02:47 -0700829// The Select instruction tests whether (or blocks until) one or more
830// of the specified sent or received states is entered.
Rob Pike83f21b92013-05-17 13:25:48 -0700831//
Alan Donovan8097dad2013-06-24 14:15:13 -0400832// Let n be the number of States for which Dir==RECV and T_i (0<=i<n)
833// be the element type of each such state's Chan.
834// Select returns an n+2-tuple
835// (index int, recvOk bool, r_0 T_0, ... r_n-1 T_n-1)
836// The tuple's components, described below, must be accessed via the
837// Extract instruction.
Rob Pike83f21b92013-05-17 13:25:48 -0700838//
839// If Blocking, select waits until exactly one state holds, i.e. a
840// channel becomes ready for the designated operation of sending or
841// receiving; select chooses one among the ready states
842// pseudorandomly, performs the send or receive operation, and sets
843// 'index' to the index of the chosen channel.
844//
845// If !Blocking, select doesn't block if no states hold; instead it
846// returns immediately with index equal to -1.
847//
Alan Donovan8097dad2013-06-24 14:15:13 -0400848// If the chosen channel was used for a receive, the r_i component is
849// set to the received value, where i is the index of that state among
850// all n receive states; otherwise r_i has the zero value of type T_i.
851// Note that the the receive index i is not the same as the state
852// index index.
Rob Pike83f21b92013-05-17 13:25:48 -0700853//
Alan Donovan8097dad2013-06-24 14:15:13 -0400854// The second component of the triple, recvOk, is a boolean whose value
Rob Pike83f21b92013-05-17 13:25:48 -0700855// is true iff the selected operation was a receive and the receive
856// successfully yielded a value.
857//
Rob Pike87334f42013-05-17 14:02:47 -0700858// Pos() returns the ast.SelectStmt.Select.
859//
Rob Pike83f21b92013-05-17 13:25:48 -0700860// Example printed form:
861// t3 = select nonblocking [<-t0, t1<-t2, ...]
862// t4 = select blocking []
863//
864type Select struct {
865 Register
866 States []SelectState
867 Blocking bool
868}
869
Rob Pike87334f42013-05-17 14:02:47 -0700870// The Range instruction yields an iterator over the domain and range
871// of X, which must be a string or map.
Rob Pike83f21b92013-05-17 13:25:48 -0700872//
873// Elements are accessed via Next.
874//
Alan Donovan8097dad2013-06-24 14:15:13 -0400875// Type() returns an opaque and degenerate "rangeIter" type.
Rob Pike83f21b92013-05-17 13:25:48 -0700876//
Rob Pike87334f42013-05-17 14:02:47 -0700877// Pos() returns the ast.RangeStmt.For.
878//
Rob Pike83f21b92013-05-17 13:25:48 -0700879// Example printed form:
880// t0 = range "hello":string
881//
882type Range struct {
883 Register
884 X Value // string or map
885}
886
Rob Pike87334f42013-05-17 14:02:47 -0700887// The Next instruction reads and advances the (map or string)
888// iterator Iter and returns a 3-tuple value (ok, k, v). If the
889// iterator is not exhausted, ok is true and k and v are the next
890// elements of the domain and range, respectively. Otherwise ok is
891// false and k and v are undefined.
Rob Pike83f21b92013-05-17 13:25:48 -0700892//
893// Components of the tuple are accessed using Extract.
894//
895// The IsString field distinguishes iterators over strings from those
896// over maps, as the Type() alone is insufficient: consider
897// map[int]rune.
898//
Alan Donovan6c7ce1c2013-05-30 09:59:17 -0400899// Type() returns a *types.Tuple for the triple (ok, k, v).
900// The types of k and/or v may be types.Invalid.
Rob Pike83f21b92013-05-17 13:25:48 -0700901//
902// Example printed form:
903// t1 = next t0
904//
905type Next struct {
906 Register
907 Iter Value
908 IsString bool // true => string iterator; false => map iterator.
909}
910
Rob Pike87334f42013-05-17 14:02:47 -0700911// The TypeAssert instruction tests whether interface value X has type
912// AssertedType.
Rob Pike83f21b92013-05-17 13:25:48 -0700913//
914// If !CommaOk, on success it returns v, the result of the conversion
915// (defined below); on failure it panics.
916//
917// If CommaOk: on success it returns a pair (v, true) where v is the
918// result of the conversion; on failure it returns (z, false) where z
919// is AssertedType's zero value. The components of the pair must be
920// accessed using the Extract instruction.
921//
922// If AssertedType is a concrete type, TypeAssert checks whether the
923// dynamic type in interface X is equal to it, and if so, the result
924// of the conversion is a copy of the value in the interface.
925//
926// If AssertedType is an interface, TypeAssert checks whether the
927// dynamic type of the interface is assignable to it, and if so, the
928// result of the conversion is a copy of the interface value X.
929// If AssertedType is a superinterface of X.Type(), the operation
930// cannot fail; ChangeInterface is preferred in this case.
931//
Alan Donovan6c7ce1c2013-05-30 09:59:17 -0400932// Type() reflects the actual type of the result, possibly a
933// 2-types.Tuple; AssertedType is the asserted type.
Rob Pike83f21b92013-05-17 13:25:48 -0700934//
Alan Donovan341a07a2013-06-13 14:43:35 -0400935// Pos() returns the ast.CallExpr.Lparen if the instruction arose from
936// an explicit T(e) conversion; the ast.TypeAssertExpr.Lparen if the
937// instruction arose from an explicit e.(T) operation; or token.NoPos
938// otherwise.
939//
Rob Pike83f21b92013-05-17 13:25:48 -0700940// Example printed form:
941// t1 = typeassert t0.(int)
942// t3 = typeassert,ok t2.(T)
943//
944type TypeAssert struct {
945 Register
946 X Value
947 AssertedType types.Type
948 CommaOk bool
949}
950
Rob Pike87334f42013-05-17 14:02:47 -0700951// The Extract instruction yields component Index of Tuple.
Rob Pike83f21b92013-05-17 13:25:48 -0700952//
953// This is used to access the results of instructions with multiple
954// return values, such as Call, TypeAssert, Next, UnOp(ARROW) and
955// IndexExpr(Map).
956//
957// Example printed form:
958// t1 = extract t0 #1
959//
960type Extract struct {
961 Register
962 Tuple Value
963 Index int
964}
965
966// Instructions executed for effect. They do not yield a value. --------------------
967
Rob Pike87334f42013-05-17 14:02:47 -0700968// The Jump instruction transfers control to the sole successor of its
969// owning block.
Rob Pike83f21b92013-05-17 13:25:48 -0700970//
Rob Pike87334f42013-05-17 14:02:47 -0700971// A Jump must be the last instruction of its containing BasicBlock.
972//
973// Pos() returns NoPos.
Rob Pike83f21b92013-05-17 13:25:48 -0700974//
975// Example printed form:
976// jump done
977//
978type Jump struct {
979 anInstruction
980}
981
982// The If instruction transfers control to one of the two successors
983// of its owning block, depending on the boolean Cond: the first if
984// true, the second if false.
985//
986// An If instruction must be the last instruction of its containing
987// BasicBlock.
988//
Rob Pike87334f42013-05-17 14:02:47 -0700989// Pos() returns NoPos.
990//
Rob Pike83f21b92013-05-17 13:25:48 -0700991// Example printed form:
992// if t0 goto done else body
993//
994type If struct {
995 anInstruction
996 Cond Value
997}
998
Rob Pike87334f42013-05-17 14:02:47 -0700999// The Ret instruction returns values and control back to the calling
1000// function.
Rob Pike83f21b92013-05-17 13:25:48 -07001001//
1002// len(Results) is always equal to the number of results in the
1003// function's signature.
1004//
1005// If len(Results) > 1, Ret returns a tuple value with the specified
1006// components which the caller must access using Extract instructions.
1007//
1008// There is no instruction to return a ready-made tuple like those
1009// returned by a "value,ok"-mode TypeAssert, Lookup or UnOp(ARROW) or
1010// a tail-call to a function with multiple result parameters.
1011//
1012// Ret must be the last instruction of its containing BasicBlock.
1013// Such a block has no successors.
1014//
Rob Pike87334f42013-05-17 14:02:47 -07001015// Pos() returns the ast.ReturnStmt.Return, if explicit in the source.
1016//
Rob Pike83f21b92013-05-17 13:25:48 -07001017// Example printed form:
1018// ret
1019// ret nil:I, 2:int
1020//
1021type Ret struct {
1022 anInstruction
1023 Results []Value
Rob Pike87334f42013-05-17 14:02:47 -07001024 pos token.Pos
Rob Pike83f21b92013-05-17 13:25:48 -07001025}
1026
Rob Pike87334f42013-05-17 14:02:47 -07001027// The RunDefers instruction pops and invokes the entire stack of
1028// procedure calls pushed by Defer instructions in this function.
Rob Pike83f21b92013-05-17 13:25:48 -07001029//
1030// It is legal to encounter multiple 'rundefers' instructions in a
1031// single control-flow path through a function; this is useful in
1032// the combined init() function, for example.
1033//
Rob Pike87334f42013-05-17 14:02:47 -07001034// Pos() returns NoPos.
1035//
Rob Pike83f21b92013-05-17 13:25:48 -07001036// Example printed form:
1037// rundefers
1038//
1039type RunDefers struct {
1040 anInstruction
1041}
1042
Rob Pike87334f42013-05-17 14:02:47 -07001043// The Panic instruction initiates a panic with value X.
Rob Pike83f21b92013-05-17 13:25:48 -07001044//
1045// A Panic instruction must be the last instruction of its containing
1046// BasicBlock, which must have no successors.
1047//
1048// NB: 'go panic(x)' and 'defer panic(x)' do not use this instruction;
1049// they are treated as calls to a built-in function.
1050//
Rob Pike87334f42013-05-17 14:02:47 -07001051// Pos() returns the ast.CallExpr.Lparen if this panic was explicit
1052// in the source.
1053//
Rob Pike83f21b92013-05-17 13:25:48 -07001054// Example printed form:
1055// panic t0
1056//
1057type Panic struct {
1058 anInstruction
Rob Pike87334f42013-05-17 14:02:47 -07001059 X Value // an interface{}
1060 pos token.Pos
Rob Pike83f21b92013-05-17 13:25:48 -07001061}
1062
Rob Pike87334f42013-05-17 14:02:47 -07001063// The Go instruction creates a new goroutine and calls the specified
1064// function within it.
Rob Pike83f21b92013-05-17 13:25:48 -07001065//
1066// See CallCommon for generic function call documentation.
1067//
1068// Example printed form:
1069// go println(t0, t1)
1070// go t3()
1071// go invoke t5.Println(...t6)
1072//
1073type Go struct {
1074 anInstruction
1075 Call CallCommon
1076}
1077
Rob Pike87334f42013-05-17 14:02:47 -07001078// The Defer instruction pushes the specified call onto a stack of
1079// functions to be called by a RunDefers instruction or by a panic.
Rob Pike83f21b92013-05-17 13:25:48 -07001080//
1081// See CallCommon for generic function call documentation.
1082//
1083// Example printed form:
1084// defer println(t0, t1)
1085// defer t3()
1086// defer invoke t5.Println(...t6)
1087//
1088type Defer struct {
1089 anInstruction
1090 Call CallCommon
1091}
1092
Rob Pike87334f42013-05-17 14:02:47 -07001093// The Send instruction sends X on channel Chan.
1094//
1095// Pos() returns the ast.SendStmt.Arrow, if explicit in the source.
Rob Pike83f21b92013-05-17 13:25:48 -07001096//
1097// Example printed form:
1098// send t0 <- t1
1099//
1100type Send struct {
1101 anInstruction
1102 Chan, X Value
Rob Pike87334f42013-05-17 14:02:47 -07001103 pos token.Pos
Rob Pike83f21b92013-05-17 13:25:48 -07001104}
1105
Rob Pike87334f42013-05-17 14:02:47 -07001106// The Store instruction stores Val at address Addr.
Rob Pike83f21b92013-05-17 13:25:48 -07001107// Stores can be of arbitrary types.
1108//
Rob Pike87334f42013-05-17 14:02:47 -07001109// Pos() returns the ast.StarExpr.Star, if explicit in the source.
Rob Pike87334f42013-05-17 14:02:47 -07001110//
Rob Pike83f21b92013-05-17 13:25:48 -07001111// Example printed form:
1112// *x = y
1113//
1114type Store struct {
1115 anInstruction
1116 Addr Value
1117 Val Value
Rob Pike87334f42013-05-17 14:02:47 -07001118 pos token.Pos
Rob Pike83f21b92013-05-17 13:25:48 -07001119}
1120
Rob Pike87334f42013-05-17 14:02:47 -07001121// The MapUpdate instruction updates the association of Map[Key] to
1122// Value.
1123//
1124// Pos() returns the ast.KeyValueExpr.Colon, if explicit in the source.
Rob Pike83f21b92013-05-17 13:25:48 -07001125//
1126// Example printed form:
1127// t0[t1] = t2
1128//
1129type MapUpdate struct {
1130 anInstruction
1131 Map Value
1132 Key Value
1133 Value Value
Rob Pike87334f42013-05-17 14:02:47 -07001134 pos token.Pos
Rob Pike83f21b92013-05-17 13:25:48 -07001135}
1136
1137// Embeddable mix-ins and helpers for common parts of other structs. -----------
1138
1139// Register is a mix-in embedded by all SSA values that are also
1140// instructions, i.e. virtual registers, and provides implementations
1141// of the Value interface's Name() and Type() methods: the name is
1142// simply a numbered register (e.g. "t0") and the type is the Type_
1143// field.
1144//
1145// Temporary names are automatically assigned to each Register on
1146// completion of building a function in SSA form.
1147//
1148// Clients must not assume that the 'id' value (and the Name() derived
1149// from it) is unique within a function. As always in this API,
1150// semantics are determined only by identity; names exist only to
1151// facilitate debugging.
1152//
1153type Register struct {
1154 anInstruction
1155 num int // "name" of virtual register, e.g. "t0". Not guaranteed unique.
Alan Donovan6c7ce1c2013-05-30 09:59:17 -04001156 typ types.Type // type of virtual register
Rob Pike87334f42013-05-17 14:02:47 -07001157 pos token.Pos // position of source expression, or NoPos
Rob Pike83f21b92013-05-17 13:25:48 -07001158 referrers []Instruction
1159}
1160
1161// anInstruction is a mix-in embedded by all Instructions.
1162// It provides the implementations of the Block and SetBlock methods.
1163type anInstruction struct {
Alan Donovan6c7ce1c2013-05-30 09:59:17 -04001164 block *BasicBlock // the basic block of this instruction
Rob Pike83f21b92013-05-17 13:25:48 -07001165}
1166
1167// CallCommon is contained by Go, Defer and Call to hold the
1168// common parts of a function or method call.
1169//
1170// Each CallCommon exists in one of two modes, function call and
1171// interface method invocation, or "call" and "invoke" for short.
1172//
1173// 1. "call" mode: when Recv is nil (!IsInvoke), a CallCommon
1174// represents an ordinary function call of the value in Func.
1175//
1176// In the common case in which Func is a *Function, this indicates a
1177// statically dispatched call to a package-level function, an
1178// anonymous function, or a method of a named type. Also statically
1179// dispatched, but less common, Func may be a *MakeClosure, indicating
1180// an immediately applied function literal with free variables. Any
1181// other Value of Func indicates a dynamically dispatched function
1182// call. The StaticCallee method returns the callee in these cases.
1183//
1184// Args contains the arguments to the call. If Func is a method,
1185// Args[0] contains the receiver parameter. Recv and Method are not
1186// used in this mode.
1187//
1188// Example printed form:
1189// t2 = println(t0, t1)
1190// go t3()
1191// defer t5(...t6)
1192//
1193// 2. "invoke" mode: when Recv is non-nil (IsInvoke), a CallCommon
1194// represents a dynamically dispatched call to an interface method.
1195// In this mode, Recv is the interface value and Method is the index
1196// of the method within the interface type of the receiver.
1197//
1198// Recv is implicitly supplied to the concrete method implementation
1199// as the receiver parameter; in other words, Args[0] holds not the
1200// receiver but the first true argument. Func is not used in this
1201// mode.
1202//
Rob Pike83f21b92013-05-17 13:25:48 -07001203// Example printed form:
1204// t1 = invoke t0.String()
1205// go invoke t3.Run(t2)
1206// defer invoke t4.Handle(...t5)
1207//
1208// In both modes, HasEllipsis is true iff the last element of Args is
1209// a slice value containing zero or more arguments to a variadic
1210// function. (This is not semantically significant since the type of
1211// the called function is sufficient to determine this, but it aids
1212// readability of the printed form.)
1213//
1214type CallCommon struct {
1215 Recv Value // receiver, iff interface method invocation
1216 Method int // index of interface method; call MethodId() for its Id
1217 Func Value // target of call, iff function call
1218 Args []Value // actual parameters, including receiver in invoke mode
1219 HasEllipsis bool // true iff last Args is a slice of '...' args (needed?)
Rob Pike87334f42013-05-17 14:02:47 -07001220 pos token.Pos // position of CallExpr.Lparen, iff explicit in source
Rob Pike83f21b92013-05-17 13:25:48 -07001221}
1222
1223// IsInvoke returns true if this call has "invoke" (not "call") mode.
1224func (c *CallCommon) IsInvoke() bool {
1225 return c.Recv != nil
1226}
1227
Rob Pike87334f42013-05-17 14:02:47 -07001228func (c *CallCommon) Pos() token.Pos { return c.pos }
1229
Alan Donovan8097dad2013-06-24 14:15:13 -04001230// Signature returns the signature of the called function.
1231//
1232// For an "invoke"-mode call, the signature of the interface method is
1233// returned; the receiver is represented by sig.Recv, not
1234// sig.Params().At(0).
1235//
1236func (c *CallCommon) Signature() *types.Signature {
1237 if c.Recv != nil {
1238 iface := c.Recv.Type().Underlying().(*types.Interface)
1239 return iface.Method(c.Method).Type().(*types.Signature)
1240 }
1241 return c.Func.Type().Underlying().(*types.Signature)
1242}
1243
Rob Pike83f21b92013-05-17 13:25:48 -07001244// StaticCallee returns the called function if this is a trivially
1245// static "call"-mode call.
1246func (c *CallCommon) StaticCallee() *Function {
1247 switch fn := c.Func.(type) {
1248 case *Function:
1249 return fn
1250 case *MakeClosure:
1251 return fn.Fn.(*Function)
1252 }
1253 return nil
1254}
1255
1256// MethodId returns the Id for the method called by c, which must
1257// have "invoke" mode.
1258func (c *CallCommon) MethodId() Id {
Rob Pike87334f42013-05-17 14:02:47 -07001259 m := c.Recv.Type().Underlying().(*types.Interface).Method(c.Method)
1260 return MakeId(m.Name(), m.Pkg())
Rob Pike83f21b92013-05-17 13:25:48 -07001261}
1262
1263// Description returns a description of the mode of this call suitable
1264// for a user interface, e.g. "static method call".
1265func (c *CallCommon) Description() string {
1266 switch fn := c.Func.(type) {
1267 case nil:
1268 return "dynamic method call" // ("invoke" mode)
1269 case *MakeClosure:
1270 return "static function closure call"
1271 case *Function:
Rob Pike87334f42013-05-17 14:02:47 -07001272 if fn.Signature.Recv() != nil {
Rob Pike83f21b92013-05-17 13:25:48 -07001273 return "static method call"
1274 }
1275 return "static function call"
1276 }
1277 return "dynamic function call"
1278}
1279
Alan Donovan8097dad2013-06-24 14:15:13 -04001280// The CallInstruction interface, implemented by *Go, *Defer and *Call,
1281// exposes the common parts of function calling instructions,
1282// yet provides a way back to the Value defined by *Call alone.
1283//
1284type CallInstruction interface {
1285 Instruction
1286 Common() *CallCommon // returns the common parts of the call
1287 Value() *Call // returns the result value of the call (*Call) or nil (*Go, *Defer)
1288}
1289
1290func (s *Call) Common() *CallCommon { return &s.Call }
1291func (s *Defer) Common() *CallCommon { return &s.Call }
1292func (s *Go) Common() *CallCommon { return &s.Call }
1293
1294func (s *Call) Value() *Call { return s }
1295func (s *Defer) Value() *Call { return nil }
1296func (s *Go) Value() *Call { return nil }
1297
Rob Pike87334f42013-05-17 14:02:47 -07001298func (v *Builtin) Type() types.Type { return v.Object.Type() }
1299func (v *Builtin) Name() string { return v.Object.Name() }
Rob Pike83f21b92013-05-17 13:25:48 -07001300func (*Builtin) Referrers() *[]Instruction { return nil }
Alan Donovan6c7ce1c2013-05-30 09:59:17 -04001301func (v *Builtin) Pos() token.Pos { return token.NoPos }
Rob Pike83f21b92013-05-17 13:25:48 -07001302
Alan Donovan6c7ce1c2013-05-30 09:59:17 -04001303func (v *Capture) Type() types.Type { return v.typ }
1304func (v *Capture) Name() string { return v.name }
Rob Pike83f21b92013-05-17 13:25:48 -07001305func (v *Capture) Referrers() *[]Instruction { return &v.referrers }
Alan Donovan6c7ce1c2013-05-30 09:59:17 -04001306func (v *Capture) Pos() token.Pos { return v.pos }
Alan Donovan341a07a2013-06-13 14:43:35 -04001307func (v *Capture) Parent() *Function { return v.parent }
Rob Pike83f21b92013-05-17 13:25:48 -07001308
Alan Donovan6c7ce1c2013-05-30 09:59:17 -04001309func (v *Global) Type() types.Type { return v.typ }
1310func (v *Global) Name() string { return v.name }
Rob Pike87334f42013-05-17 14:02:47 -07001311func (v *Global) Pos() token.Pos { return v.pos }
Rob Pike83f21b92013-05-17 13:25:48 -07001312func (*Global) Referrers() *[]Instruction { return nil }
Alan Donovan341a07a2013-06-13 14:43:35 -04001313func (v *Global) Token() token.Token { return token.VAR }
Rob Pike83f21b92013-05-17 13:25:48 -07001314
Alan Donovan6c7ce1c2013-05-30 09:59:17 -04001315func (v *Function) Name() string { return v.name }
Rob Pike83f21b92013-05-17 13:25:48 -07001316func (v *Function) Type() types.Type { return v.Signature }
Rob Pike87334f42013-05-17 14:02:47 -07001317func (v *Function) Pos() token.Pos { return v.pos }
Rob Pike83f21b92013-05-17 13:25:48 -07001318func (*Function) Referrers() *[]Instruction { return nil }
Alan Donovan341a07a2013-06-13 14:43:35 -04001319func (v *Function) Token() token.Token { return token.FUNC }
Rob Pike83f21b92013-05-17 13:25:48 -07001320
Alan Donovan6c7ce1c2013-05-30 09:59:17 -04001321func (v *Parameter) Type() types.Type { return v.typ }
1322func (v *Parameter) Name() string { return v.name }
Rob Pike83f21b92013-05-17 13:25:48 -07001323func (v *Parameter) Referrers() *[]Instruction { return &v.referrers }
Alan Donovan6c7ce1c2013-05-30 09:59:17 -04001324func (v *Parameter) Pos() token.Pos { return v.pos }
Alan Donovan341a07a2013-06-13 14:43:35 -04001325func (v *Parameter) Parent() *Function { return v.parent }
Rob Pike83f21b92013-05-17 13:25:48 -07001326
Alan Donovan6c7ce1c2013-05-30 09:59:17 -04001327func (v *Alloc) Type() types.Type { return v.typ }
1328func (v *Alloc) Name() string { return v.name }
Rob Pike83f21b92013-05-17 13:25:48 -07001329func (v *Alloc) Referrers() *[]Instruction { return &v.referrers }
Alan Donovan6c7ce1c2013-05-30 09:59:17 -04001330func (v *Alloc) Pos() token.Pos { return v.pos }
Rob Pike83f21b92013-05-17 13:25:48 -07001331
Alan Donovan6c7ce1c2013-05-30 09:59:17 -04001332func (v *Register) Type() types.Type { return v.typ }
1333func (v *Register) setType(typ types.Type) { v.typ = typ }
Rob Pike83f21b92013-05-17 13:25:48 -07001334func (v *Register) Name() string { return fmt.Sprintf("t%d", v.num) }
1335func (v *Register) setNum(num int) { v.num = num }
1336func (v *Register) Referrers() *[]Instruction { return &v.referrers }
1337func (v *Register) asRegister() *Register { return v }
Rob Pike87334f42013-05-17 14:02:47 -07001338func (v *Register) Pos() token.Pos { return v.pos }
1339func (v *Register) setPos(pos token.Pos) { v.pos = pos }
Rob Pike83f21b92013-05-17 13:25:48 -07001340
Alan Donovan341a07a2013-06-13 14:43:35 -04001341func (v *anInstruction) Parent() *Function { return v.block.parent }
Alan Donovan6c7ce1c2013-05-30 09:59:17 -04001342func (v *anInstruction) Block() *BasicBlock { return v.block }
1343func (v *anInstruction) SetBlock(block *BasicBlock) { v.block = block }
Rob Pike83f21b92013-05-17 13:25:48 -07001344
Alan Donovan341a07a2013-06-13 14:43:35 -04001345func (t *Type) Name() string { return t.Object.Name() }
1346func (t *Type) Pos() token.Pos { return t.Object.Pos() }
1347func (t *Type) String() string { return t.Name() }
1348func (t *Type) Type() types.Type { return t.Object.Type() }
1349func (t *Type) Token() token.Token { return token.TYPE }
Rob Pike83f21b92013-05-17 13:25:48 -07001350
Alan Donovan341a07a2013-06-13 14:43:35 -04001351func (c *Constant) Name() string { return c.name }
1352func (c *Constant) Pos() token.Pos { return c.pos }
1353func (c *Constant) String() string { return c.Name() }
1354func (c *Constant) Type() types.Type { return c.Value.Type() }
1355func (c *Constant) Token() token.Token { return token.CONST }
Rob Pike83f21b92013-05-17 13:25:48 -07001356
1357// Func returns the package-level function of the specified name,
1358// or nil if not found.
1359//
1360func (p *Package) Func(name string) (f *Function) {
1361 f, _ = p.Members[name].(*Function)
1362 return
1363}
1364
1365// Var returns the package-level variable of the specified name,
1366// or nil if not found.
1367//
1368func (p *Package) Var(name string) (g *Global) {
1369 g, _ = p.Members[name].(*Global)
1370 return
1371}
1372
1373// Const returns the package-level constant of the specified name,
1374// or nil if not found.
1375//
1376func (p *Package) Const(name string) (c *Constant) {
1377 c, _ = p.Members[name].(*Constant)
1378 return
1379}
1380
1381// Type returns the package-level type of the specified name,
1382// or nil if not found.
1383//
1384func (p *Package) Type(name string) (t *Type) {
1385 t, _ = p.Members[name].(*Type)
1386 return
1387}
1388
Alan Donovan4d628a02013-06-03 14:15:19 -04001389// Value returns the program-level value corresponding to the
1390// specified named object, which may be a universal built-in
1391// (*Builtin) or a package-level var (*Global) or func (*Function) of
1392// some package in prog. It returns nil if the object is not found.
1393//
1394func (prog *Program) Value(obj types.Object) Value {
1395 if p := obj.Pkg(); p != nil {
1396 if pkg, ok := prog.packages[p]; ok {
1397 return pkg.values[obj]
1398 }
1399 return nil
1400 }
1401 return prog.Builtins[obj]
1402}
1403
1404// Package returns the SSA package corresponding to the specified
Alan Donovan341a07a2013-06-13 14:43:35 -04001405// type-checker package object.
1406// It returns nil if no such SSA package has been created.
Alan Donovan4d628a02013-06-03 14:15:19 -04001407//
1408func (prog *Program) Package(pkg *types.Package) *Package {
1409 return prog.packages[pkg]
1410}
1411
Rob Pike87334f42013-05-17 14:02:47 -07001412func (v *Call) Pos() token.Pos { return v.Call.pos }
1413func (s *Defer) Pos() token.Pos { return s.Call.pos }
1414func (s *Go) Pos() token.Pos { return s.Call.pos }
1415func (s *MapUpdate) Pos() token.Pos { return s.pos }
1416func (s *Panic) Pos() token.Pos { return s.pos }
1417func (s *Ret) Pos() token.Pos { return s.pos }
1418func (s *Send) Pos() token.Pos { return s.pos }
1419func (s *Store) Pos() token.Pos { return s.pos }
1420func (s *If) Pos() token.Pos { return token.NoPos }
1421func (s *Jump) Pos() token.Pos { return token.NoPos }
1422func (s *RunDefers) Pos() token.Pos { return token.NoPos }
Rob Pike83f21b92013-05-17 13:25:48 -07001423
Rob Pike87334f42013-05-17 14:02:47 -07001424// Operands.
Rob Pike83f21b92013-05-17 13:25:48 -07001425
1426func (v *Alloc) Operands(rands []*Value) []*Value {
1427 return rands
1428}
1429
1430func (v *BinOp) Operands(rands []*Value) []*Value {
1431 return append(rands, &v.X, &v.Y)
1432}
1433
1434func (c *CallCommon) Operands(rands []*Value) []*Value {
1435 rands = append(rands, &c.Recv, &c.Func)
1436 for i := range c.Args {
1437 rands = append(rands, &c.Args[i])
1438 }
1439 return rands
1440}
1441
1442func (s *Go) Operands(rands []*Value) []*Value {
1443 return s.Call.Operands(rands)
1444}
1445
1446func (s *Call) Operands(rands []*Value) []*Value {
1447 return s.Call.Operands(rands)
1448}
1449
1450func (s *Defer) Operands(rands []*Value) []*Value {
1451 return s.Call.Operands(rands)
1452}
1453
1454func (v *ChangeInterface) Operands(rands []*Value) []*Value {
1455 return append(rands, &v.X)
1456}
1457
Rob Pike87334f42013-05-17 14:02:47 -07001458func (v *ChangeType) Operands(rands []*Value) []*Value {
1459 return append(rands, &v.X)
1460}
1461
1462func (v *Convert) Operands(rands []*Value) []*Value {
Rob Pike83f21b92013-05-17 13:25:48 -07001463 return append(rands, &v.X)
1464}
1465
1466func (v *Extract) Operands(rands []*Value) []*Value {
1467 return append(rands, &v.Tuple)
1468}
1469
1470func (v *Field) Operands(rands []*Value) []*Value {
1471 return append(rands, &v.X)
1472}
1473
1474func (v *FieldAddr) Operands(rands []*Value) []*Value {
1475 return append(rands, &v.X)
1476}
1477
1478func (s *If) Operands(rands []*Value) []*Value {
1479 return append(rands, &s.Cond)
1480}
1481
1482func (v *Index) Operands(rands []*Value) []*Value {
1483 return append(rands, &v.X, &v.Index)
1484}
1485
1486func (v *IndexAddr) Operands(rands []*Value) []*Value {
1487 return append(rands, &v.X, &v.Index)
1488}
1489
1490func (*Jump) Operands(rands []*Value) []*Value {
1491 return rands
1492}
1493
1494func (v *Lookup) Operands(rands []*Value) []*Value {
1495 return append(rands, &v.X, &v.Index)
1496}
1497
1498func (v *MakeChan) Operands(rands []*Value) []*Value {
1499 return append(rands, &v.Size)
1500}
1501
1502func (v *MakeClosure) Operands(rands []*Value) []*Value {
1503 rands = append(rands, &v.Fn)
1504 for i := range v.Bindings {
1505 rands = append(rands, &v.Bindings[i])
1506 }
1507 return rands
1508}
1509
1510func (v *MakeInterface) Operands(rands []*Value) []*Value {
1511 return append(rands, &v.X)
1512}
1513
1514func (v *MakeMap) Operands(rands []*Value) []*Value {
1515 return append(rands, &v.Reserve)
1516}
1517
1518func (v *MakeSlice) Operands(rands []*Value) []*Value {
1519 return append(rands, &v.Len, &v.Cap)
1520}
1521
1522func (v *MapUpdate) Operands(rands []*Value) []*Value {
1523 return append(rands, &v.Map, &v.Key, &v.Value)
1524}
1525
1526func (v *Next) Operands(rands []*Value) []*Value {
1527 return append(rands, &v.Iter)
1528}
1529
1530func (s *Panic) Operands(rands []*Value) []*Value {
1531 return append(rands, &s.X)
1532}
1533
1534func (v *Phi) Operands(rands []*Value) []*Value {
1535 for i := range v.Edges {
1536 rands = append(rands, &v.Edges[i])
1537 }
1538 return rands
1539}
1540
1541func (v *Range) Operands(rands []*Value) []*Value {
1542 return append(rands, &v.X)
1543}
1544
1545func (s *Ret) Operands(rands []*Value) []*Value {
1546 for i := range s.Results {
1547 rands = append(rands, &s.Results[i])
1548 }
1549 return rands
1550}
1551
1552func (*RunDefers) Operands(rands []*Value) []*Value {
1553 return rands
1554}
1555
1556func (v *Select) Operands(rands []*Value) []*Value {
1557 for i := range v.States {
1558 rands = append(rands, &v.States[i].Chan, &v.States[i].Send)
1559 }
1560 return rands
1561}
1562
1563func (s *Send) Operands(rands []*Value) []*Value {
1564 return append(rands, &s.Chan, &s.X)
1565}
1566
1567func (v *Slice) Operands(rands []*Value) []*Value {
1568 return append(rands, &v.X, &v.Low, &v.High)
1569}
1570
1571func (s *Store) Operands(rands []*Value) []*Value {
1572 return append(rands, &s.Addr, &s.Val)
1573}
1574
1575func (v *TypeAssert) Operands(rands []*Value) []*Value {
1576 return append(rands, &v.X)
1577}
1578
1579func (v *UnOp) Operands(rands []*Value) []*Value {
1580 return append(rands, &v.X)
1581}