blob: 593e81e3dc37a9839f6a67f36c5fd9dbd42a9146 [file] [log] [blame]
Russ Coxd970bea2015-03-05 10:45:56 -05001// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// “Abstract” syntax representation.
6
7package gc
8
9// A Node is a single node in the syntax tree.
10// Actually the syntax tree is a syntax DAG, because there is only one
11// node with Op=ONAME for a given instance of a variable x.
12// The same is true for Op=OTYPE and Op=OLITERAL.
13type Node struct {
Russ Coxcdb7d7d2015-03-05 13:57:36 -050014 // Tree structure.
15 // Generic recursive walks should follow these fields.
16 Left *Node
17 Right *Node
18 Ntest *Node
19 Nincr *Node
20 Ninit *NodeList
21 Nbody *NodeList
22 Nelse *NodeList
23 List *NodeList
24 Rlist *NodeList
25
Josh Bleecher Snyder57279ba2015-03-10 21:37:13 -070026 Op uint8
27 Nointerface bool
28 Ullman uint8 // sethi/ullman number
29 Addable uint8 // type of addressability - 0 is not addressable
30 Etype uint8 // op for OASOP, etype for OTYPE, exclam for export
31 Bounded bool // bounds check unnecessary
32 Class uint8 // PPARAM, PAUTO, PEXTERN, etc
33 Method uint8 // OCALLMETH name
34 Embedded uint8 // ODCLFIELD embedded type
35 Colas uint8 // OAS resulting from :=
36 Diag uint8 // already printed error about this
37 Noescape bool // func arguments do not escape; TODO(rsc): move Noescape to Func struct (see CL 7360)
38 Walkdef uint8
39 Typecheck uint8
40 Local bool
41 Dodata uint8
42 Initorder uint8
43 Used bool
44 Isddd bool // is the argument variadic
45 Readonly bool
46 Implicit bool
47 Addrtaken bool // address taken, even if not moved to heap
48 Assigned bool // is the variable ever assigned to
49 Captured bool // is the variable captured by a closure
50 Byval bool // is the variable captured by value or by reference
51 Reslice bool // this is a reslice x = x[0:y] or x = append(x, ...)
52 Likely int8 // likeliness of if statement
53 Hasbreak bool // has break statement
54 Needzero bool // if it contains pointers, needs to be zeroed on function entry
55 Esc uint8 // EscXXX
56 Funcdepth int32
Russ Coxcdb7d7d2015-03-05 13:57:36 -050057
58 // most nodes
Josh Bleecher Snyder57279ba2015-03-10 21:37:13 -070059 Type *Type
60 Orig *Node // original form, for printing, and tracking copies of ONAMEs
61 Nname *Node
Russ Coxcdb7d7d2015-03-05 13:57:36 -050062
63 // func
Josh Bleecher Snyder57279ba2015-03-10 21:37:13 -070064 *Func
Russ Coxcdb7d7d2015-03-05 13:57:36 -050065
66 // OLITERAL/OREGISTER
67 Val Val
68
69 // ONAME
70 Ntype *Node
71 Defn *Node // ONAME: initializing assignment; OLABEL: labeled statement
72 Pack *Node // real package for import . names
73 Curfn *Node // function for local variables
74 Paramfld *Type // TFIELD for this PPARAM; also for ODOT, curfn
75 Decldepth int // declaration loop depth, increased for every loop or label
76
77 // ONAME func param with PHEAP
78 Heapaddr *Node // temp holding heap address of param
79 Outerexpr *Node // expression copied into closure for variable
80 Stackparam *Node // OPARAM node referring to stack copy of param
81 Alloc *Node // allocation call
82
83 // ONAME closure param with PPARAMREF
84 Outer *Node // outer PPARAMREF in nested closure
85 Closure *Node // ONAME/PHEAP <-> ONAME/PPARAMREF
86 Top int // top context (Ecall, Eproc, etc)
87
88 // ONAME substitute while inlining
89 Inlvar *Node
90
91 // OPACK
92 Pkg *Pkg
93
94 // OARRAYLIT, OMAPLIT, OSTRUCTLIT.
95 Initplan *InitPlan
96
97 // Escape analysis.
98 Escflowsrc *NodeList // flow(this, src)
99 Escretval *NodeList // on OCALLxxx, list of dummy return values
100 Escloopdepth int // -1: global, 0: return variables, 1:function top level, increased inside function for every loop or label to mark scopes
101
Josh Bleecher Snyder57279ba2015-03-10 21:37:13 -0700102 Sym *Sym // various
103 Vargen int32 // unique name for OTYPE/ONAME
104 Lineno int32
105 Xoffset int64
106 Stkdelta int64 // offset added by stack frame compaction phase.
107 Ostk int32 // 6g only
108 Iota int32
109 Walkgen uint32
110 Esclevel int32
111 Opt interface{} // for optimization passes
112}
113
114// Func holds Node fields used only with function-like nodes.
115type Func struct {
116 Shortname *Node
117 Enter *NodeList
118 Exit *NodeList
119 Cvars *NodeList // closure params
120 Dcl *NodeList // autodcl for this func/closure
121 Inldcl *NodeList // copy of dcl for use in inlining
122 Closgen int
123 Outerfunc *Node
124
125 Inl *NodeList // copy of the body for use in inlining
126 InlCost int32
127
Russ Coxcdb7d7d2015-03-05 13:57:36 -0500128 Endlineno int32
Josh Bleecher Snyder57279ba2015-03-10 21:37:13 -0700129
130 Nosplit bool // func should not execute on separate stack
131 Nowritebarrier bool // emit compiler error instead of write barrier
132 Dupok bool // duplicate definitions ok
133 Wrapper bool // is method wrapper
134 Needctxt bool // function uses context register (has closure variables)
Russ Coxd970bea2015-03-05 10:45:56 -0500135}
136
137// Node ops.
138const (
139 OXXX = iota
Russ Coxcdb7d7d2015-03-05 13:57:36 -0500140
141 // names
142 ONAME // var, const or func name
143 ONONAME // unnamed arg or return value: f(int, string) (int, error) { etc }
144 OTYPE // type name
145 OPACK // import
146 OLITERAL // literal
147
148 // expressions
149 OADD // x + y
150 OSUB // x - y
151 OOR // x | y
152 OXOR // x ^ y
153 OADDSTR // s + "foo"
154 OADDR // &x
155 OANDAND // b0 && b1
156 OAPPEND // append
157 OARRAYBYTESTR // string(bytes)
158 OARRAYBYTESTRTMP // string(bytes) ephemeral
159 OARRAYRUNESTR // string(runes)
160 OSTRARRAYBYTE // []byte(s)
161 OSTRARRAYBYTETMP // []byte(s) ephemeral
162 OSTRARRAYRUNE // []rune(s)
163 OAS // x = y or x := y
164 OAS2 // x, y, z = xx, yy, zz
165 OAS2FUNC // x, y = f()
166 OAS2RECV // x, ok = <-c
167 OAS2MAPR // x, ok = m["foo"]
168 OAS2DOTTYPE // x, ok = I.(int)
169 OASOP // x += y
170 OCALL // function call, method call or type conversion, possibly preceded by defer or go.
171 OCALLFUNC // f()
172 OCALLMETH // t.Method()
173 OCALLINTER // err.Error()
174 OCALLPART // t.Method (without ())
175 OCAP // cap
176 OCLOSE // close
177 OCLOSURE // f = func() { etc }
178 OCMPIFACE // err1 == err2
179 OCMPSTR // s1 == s2
180 OCOMPLIT // composite literal, typechecking may convert to a more specific OXXXLIT.
181 OMAPLIT // M{"foo":3, "bar":4}
182 OSTRUCTLIT // T{x:3, y:4}
183 OARRAYLIT // [2]int{3, 4}
184 OPTRLIT // &T{x:3, y:4}
185 OCONV // var i int; var u uint; i = int(u)
186 OCONVIFACE // I(t)
187 OCONVNOP // type Int int; var i int; var j Int; i = int(j)
188 OCOPY // copy
189 ODCL // var x int
190 ODCLFUNC // func f() or func (r) f()
191 ODCLFIELD // struct field, interface field, or func/method argument/return value.
192 ODCLCONST // const pi = 3.14
193 ODCLTYPE // type Int int
194 ODELETE // delete
195 ODOT // t.x
196 ODOTPTR // p.x that is implicitly (*p).x
197 ODOTMETH // t.Method
198 ODOTINTER // err.Error
199 OXDOT // t.x, typechecking may convert to a more specific ODOTXXX.
200 ODOTTYPE // e = err.(MyErr)
201 ODOTTYPE2 // e, ok = err.(MyErr)
202 OEQ // x == y
203 ONE // x != y
204 OLT // x < y
205 OLE // x <= y
206 OGE // x >= y
207 OGT // x > y
208 OIND // *p
209 OINDEX // a[i]
210 OINDEXMAP // m[s]
211 OKEY // The x:3 in t{x:3, y:4}, the 1:2 in a[1:2], the 2:20 in [3]int{2:20}, etc.
212 OPARAM // The on-stack copy of a parameter or return value that escapes.
213 OLEN // len
214 OMAKE // make, typechecking may convert to a more specific OMAKEXXX.
215 OMAKECHAN // make(chan int)
216 OMAKEMAP // make(map[string]int)
217 OMAKESLICE // make([]int, 0)
218 OMUL // *
219 ODIV // x / y
220 OMOD // x % y
221 OLSH // x << u
222 ORSH // x >> u
223 OAND // x & y
224 OANDNOT // x &^ y
225 ONEW // new
226 ONOT // !b
227 OCOM // ^x
228 OPLUS // +x
229 OMINUS // -y
230 OOROR // b1 || b2
231 OPANIC // panic
232 OPRINT // print
233 OPRINTN // println
234 OPAREN // (x)
235 OSEND // c <- x
236 OSLICE // v[1:2], typechecking may convert to a more specific OSLICEXXX.
237 OSLICEARR // a[1:2]
238 OSLICESTR // s[1:2]
239 OSLICE3 // v[1:2:3], typechecking may convert to OSLICE3ARR.
240 OSLICE3ARR // a[1:2:3]
241 ORECOVER // recover
242 ORECV // <-c
243 ORUNESTR // string(i)
244 OSELRECV // case x = <-c:
245 OSELRECV2 // case x, ok = <-c:
246 OIOTA // iota
247 OREAL // real
248 OIMAG // imag
249 OCOMPLEX // complex
250
251 // statements
252 OBLOCK // block of code
253 OBREAK // break
254 OCASE // case, after being verified by swt.c's casebody.
255 OXCASE // case, before verification.
256 OCONTINUE // continue
257 ODEFER // defer
258 OEMPTY // no-op
259 OFALL // fallthrough, after being verified by swt.c's casebody.
260 OXFALL // fallthrough, before verification.
261 OFOR // for
262 OGOTO // goto
263 OIF // if
264 OLABEL // label:
265 OPROC // go
266 ORANGE // range
267 ORETURN // return
268 OSELECT // select
269 OSWITCH // switch x
270 OTYPESW // switch err.(type)
271
272 // types
273 OTCHAN // chan int
274 OTMAP // map[string]int
275 OTSTRUCT // struct{}
276 OTINTER // interface{}
277 OTFUNC // func()
278 OTARRAY // []int, [8]int, [N]int or [...]int
279
280 // misc
281 ODDD // func f(args ...int) or f(l...) or var a = [...]int{0, 1, 2}.
282 ODDDARG // func f(args ...int), introduced by escape analysis.
283 OINLCALL // intermediary representation of an inlined call.
284 OEFACE // itable and data words of an empty-interface value.
285 OITAB // itable word of an interface value.
286 OSPTR // base pointer of a slice or string.
287 OCLOSUREVAR // variable reference at beginning of closure function
288 OCFUNC // reference to c function pointer (not go func value)
289 OCHECKNIL // emit code to ensure pointer/interface not nil
290 OVARKILL // variable is dead
291
292 // thearch-specific registers
293 OREGISTER // a register, such as AX.
294 OINDREG // offset plus indirect of a register, such as 8(SP).
295
296 // 386/amd64-specific opcodes
297 OCMP // compare: ACMP.
298 ODEC // decrement: ADEC.
299 OINC // increment: AINC.
300 OEXTEND // extend: ACWD/ACDQ/ACQO.
301 OHMUL // high mul: AMUL/AIMUL for unsigned/signed (OMUL uses AIMUL for both).
302 OLROT // left rotate: AROL.
303 ORROTC // right rotate-carry: ARCR.
304 ORETJMP // return to other function
Russ Coxb115c352015-03-18 17:26:36 -0400305 OPS // compare parity set (for x86 NaN check)
Russ Coxcdb7d7d2015-03-05 13:57:36 -0500306
Russ Coxd970bea2015-03-05 10:45:56 -0500307 OEND
308)
309
310/*
311 * Every node has a walkgen field.
312 * If you want to do a traversal of a node graph that
313 * might contain duplicates and want to avoid
314 * visiting the same nodes twice, increment walkgen
315 * before starting. Then before processing a node, do
316 *
317 * if(n->walkgen == walkgen)
318 * return;
319 * n->walkgen = walkgen;
320 *
321 * Such a walk cannot call another such walk recursively,
322 * because of the use of the global walkgen.
323 */
324var walkgen uint32
325
326// A NodeList is a linked list of nodes.
327// TODO(rsc): Some uses of NodeList should be made into slices.
328// The remaining ones probably just need a simple linked list,
329// not one with concatenation support.
330type NodeList struct {
331 N *Node
332 Next *NodeList
333 End *NodeList
334}
335
336// concat returns the concatenation of the lists a and b.
337// The storage taken by both is reused for the result.
338func concat(a *NodeList, b *NodeList) *NodeList {
339 if a == nil {
340 return b
341 }
342 if b == nil {
343 return a
344 }
345
346 a.End.Next = b
347 a.End = b.End
348 b.End = nil
349 return a
350}
351
352// list1 returns a one-element list containing n.
353func list1(n *Node) *NodeList {
354 if n == nil {
355 return nil
356 }
357 if n.Op == OBLOCK && n.Ninit == nil {
358 // Flatten list and steal storage.
359 // Poison pointer to catch errant uses.
360 l := n.List
361
362 n.List = nil
363 return l
364 }
365
366 l := new(NodeList)
367 l.N = n
368 l.End = l
369 return l
370}
371
372// list returns the result of appending n to l.
373func list(l *NodeList, n *Node) *NodeList {
374 return concat(l, list1(n))
375}
376
377// listsort sorts *l in place according to the 3-way comparison function f.
378// The algorithm is mergesort, so it is guaranteed to be O(n log n).
379func listsort(l **NodeList, f func(*Node, *Node) int) {
380 if *l == nil || (*l).Next == nil {
381 return
382 }
383
384 l1 := *l
385 l2 := *l
386 for {
387 l2 = l2.Next
388 if l2 == nil {
389 break
390 }
391 l2 = l2.Next
392 if l2 == nil {
393 break
394 }
395 l1 = l1.Next
396 }
397
398 l2 = l1.Next
399 l1.Next = nil
400 l2.End = (*l).End
401 (*l).End = l1
402
403 l1 = *l
404 listsort(&l1, f)
405 listsort(&l2, f)
406
407 if f(l1.N, l2.N) < 0 {
408 *l = l1
409 } else {
410 *l = l2
411 l2 = l1
412 l1 = *l
413 }
414
415 // now l1 == *l; and l1 < l2
416
417 var le *NodeList
418 for (l1 != nil) && (l2 != nil) {
419 for (l1.Next != nil) && f(l1.Next.N, l2.N) < 0 {
420 l1 = l1.Next
421 }
422
423 // l1 is last one from l1 that is < l2
424 le = l1.Next // le is the rest of l1, first one that is >= l2
425 if le != nil {
426 le.End = (*l).End
427 }
428
429 (*l).End = l1 // cut *l at l1
430 *l = concat(*l, l2) // glue l2 to *l's tail
431
432 l1 = l2 // l1 is the first element of *l that is < the new l2
433 l2 = le // ... because l2 now is the old tail of l1
434 }
435
436 *l = concat(*l, l2) // any remainder
437}
438
439// count returns the length of the list l.
440func count(l *NodeList) int {
441 n := int64(0)
442 for ; l != nil; l = l.Next {
443 n++
444 }
445 if int64(int(n)) != n { // Overflow.
446 Yyerror("too many elements in list")
447 }
448 return int(n)
449}