]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/compile/internal/walk/order.go
[dev.typeparams] all: merge master (785a8f6) into dev.typeparams
[gostls13.git] / src / cmd / compile / internal / walk / order.go
1 // Copyright 2012 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package walk
6
7 import (
8         "fmt"
9         "go/constant"
10
11         "cmd/compile/internal/base"
12         "cmd/compile/internal/escape"
13         "cmd/compile/internal/ir"
14         "cmd/compile/internal/reflectdata"
15         "cmd/compile/internal/staticinit"
16         "cmd/compile/internal/typecheck"
17         "cmd/compile/internal/types"
18         "cmd/internal/src"
19 )
20
21 // Rewrite tree to use separate statements to enforce
22 // order of evaluation. Makes walk easier, because it
23 // can (after this runs) reorder at will within an expression.
24 //
25 // Rewrite m[k] op= r into m[k] = m[k] op r if op is / or %.
26 //
27 // Introduce temporaries as needed by runtime routines.
28 // For example, the map runtime routines take the map key
29 // by reference, so make sure all map keys are addressable
30 // by copying them to temporaries as needed.
31 // The same is true for channel operations.
32 //
33 // Arrange that map index expressions only appear in direct
34 // assignments x = m[k] or m[k] = x, never in larger expressions.
35 //
36 // Arrange that receive expressions only appear in direct assignments
37 // x = <-c or as standalone statements <-c, never in larger expressions.
38
39 // TODO(rsc): The temporary introduction during multiple assignments
40 // should be moved into this file, so that the temporaries can be cleaned
41 // and so that conversions implicit in the OAS2FUNC and OAS2RECV
42 // nodes can be made explicit and then have their temporaries cleaned.
43
44 // TODO(rsc): Goto and multilevel break/continue can jump over
45 // inserted VARKILL annotations. Work out a way to handle these.
46 // The current implementation is safe, in that it will execute correctly.
47 // But it won't reuse temporaries as aggressively as it might, and
48 // it can result in unnecessary zeroing of those variables in the function
49 // prologue.
50
51 // orderState holds state during the ordering process.
52 type orderState struct {
53         out  []ir.Node             // list of generated statements
54         temp []*ir.Name            // stack of temporary variables
55         free map[string][]*ir.Name // free list of unused temporaries, by type.LongString().
56         edit func(ir.Node) ir.Node // cached closure of o.exprNoLHS
57 }
58
59 // Order rewrites fn.Nbody to apply the ordering constraints
60 // described in the comment at the top of the file.
61 func order(fn *ir.Func) {
62         if base.Flag.W > 1 {
63                 s := fmt.Sprintf("\nbefore order %v", fn.Sym())
64                 ir.DumpList(s, fn.Body)
65         }
66
67         orderBlock(&fn.Body, map[string][]*ir.Name{})
68 }
69
70 // append typechecks stmt and appends it to out.
71 func (o *orderState) append(stmt ir.Node) {
72         o.out = append(o.out, typecheck.Stmt(stmt))
73 }
74
75 // newTemp allocates a new temporary with the given type,
76 // pushes it onto the temp stack, and returns it.
77 // If clear is true, newTemp emits code to zero the temporary.
78 func (o *orderState) newTemp(t *types.Type, clear bool) *ir.Name {
79         var v *ir.Name
80         // Note: LongString is close to the type equality we want,
81         // but not exactly. We still need to double-check with types.Identical.
82         key := t.LongString()
83         a := o.free[key]
84         for i, n := range a {
85                 if types.Identical(t, n.Type()) {
86                         v = a[i]
87                         a[i] = a[len(a)-1]
88                         a = a[:len(a)-1]
89                         o.free[key] = a
90                         break
91                 }
92         }
93         if v == nil {
94                 v = typecheck.Temp(t)
95         }
96         if clear {
97                 o.append(ir.NewAssignStmt(base.Pos, v, nil))
98         }
99
100         o.temp = append(o.temp, v)
101         return v
102 }
103
104 // copyExpr behaves like newTemp but also emits
105 // code to initialize the temporary to the value n.
106 func (o *orderState) copyExpr(n ir.Node) *ir.Name {
107         return o.copyExpr1(n, false)
108 }
109
110 // copyExprClear is like copyExpr but clears the temp before assignment.
111 // It is provided for use when the evaluation of tmp = n turns into
112 // a function call that is passed a pointer to the temporary as the output space.
113 // If the call blocks before tmp has been written,
114 // the garbage collector will still treat the temporary as live,
115 // so we must zero it before entering that call.
116 // Today, this only happens for channel receive operations.
117 // (The other candidate would be map access, but map access
118 // returns a pointer to the result data instead of taking a pointer
119 // to be filled in.)
120 func (o *orderState) copyExprClear(n ir.Node) *ir.Name {
121         return o.copyExpr1(n, true)
122 }
123
124 func (o *orderState) copyExpr1(n ir.Node, clear bool) *ir.Name {
125         t := n.Type()
126         v := o.newTemp(t, clear)
127         o.append(ir.NewAssignStmt(base.Pos, v, n))
128         return v
129 }
130
131 // cheapExpr returns a cheap version of n.
132 // The definition of cheap is that n is a variable or constant.
133 // If not, cheapExpr allocates a new tmp, emits tmp = n,
134 // and then returns tmp.
135 func (o *orderState) cheapExpr(n ir.Node) ir.Node {
136         if n == nil {
137                 return nil
138         }
139
140         switch n.Op() {
141         case ir.ONAME, ir.OLITERAL, ir.ONIL:
142                 return n
143         case ir.OLEN, ir.OCAP:
144                 n := n.(*ir.UnaryExpr)
145                 l := o.cheapExpr(n.X)
146                 if l == n.X {
147                         return n
148                 }
149                 a := ir.SepCopy(n).(*ir.UnaryExpr)
150                 a.X = l
151                 return typecheck.Expr(a)
152         }
153
154         return o.copyExpr(n)
155 }
156
157 // safeExpr returns a safe version of n.
158 // The definition of safe is that n can appear multiple times
159 // without violating the semantics of the original program,
160 // and that assigning to the safe version has the same effect
161 // as assigning to the original n.
162 //
163 // The intended use is to apply to x when rewriting x += y into x = x + y.
164 func (o *orderState) safeExpr(n ir.Node) ir.Node {
165         switch n.Op() {
166         case ir.ONAME, ir.OLITERAL, ir.ONIL:
167                 return n
168
169         case ir.OLEN, ir.OCAP:
170                 n := n.(*ir.UnaryExpr)
171                 l := o.safeExpr(n.X)
172                 if l == n.X {
173                         return n
174                 }
175                 a := ir.SepCopy(n).(*ir.UnaryExpr)
176                 a.X = l
177                 return typecheck.Expr(a)
178
179         case ir.ODOT:
180                 n := n.(*ir.SelectorExpr)
181                 l := o.safeExpr(n.X)
182                 if l == n.X {
183                         return n
184                 }
185                 a := ir.SepCopy(n).(*ir.SelectorExpr)
186                 a.X = l
187                 return typecheck.Expr(a)
188
189         case ir.ODOTPTR:
190                 n := n.(*ir.SelectorExpr)
191                 l := o.cheapExpr(n.X)
192                 if l == n.X {
193                         return n
194                 }
195                 a := ir.SepCopy(n).(*ir.SelectorExpr)
196                 a.X = l
197                 return typecheck.Expr(a)
198
199         case ir.ODEREF:
200                 n := n.(*ir.StarExpr)
201                 l := o.cheapExpr(n.X)
202                 if l == n.X {
203                         return n
204                 }
205                 a := ir.SepCopy(n).(*ir.StarExpr)
206                 a.X = l
207                 return typecheck.Expr(a)
208
209         case ir.OINDEX, ir.OINDEXMAP:
210                 n := n.(*ir.IndexExpr)
211                 var l ir.Node
212                 if n.X.Type().IsArray() {
213                         l = o.safeExpr(n.X)
214                 } else {
215                         l = o.cheapExpr(n.X)
216                 }
217                 r := o.cheapExpr(n.Index)
218                 if l == n.X && r == n.Index {
219                         return n
220                 }
221                 a := ir.SepCopy(n).(*ir.IndexExpr)
222                 a.X = l
223                 a.Index = r
224                 return typecheck.Expr(a)
225
226         default:
227                 base.Fatalf("order.safeExpr %v", n.Op())
228                 return nil // not reached
229         }
230 }
231
232 // isaddrokay reports whether it is okay to pass n's address to runtime routines.
233 // Taking the address of a variable makes the liveness and optimization analyses
234 // lose track of where the variable's lifetime ends. To avoid hurting the analyses
235 // of ordinary stack variables, those are not 'isaddrokay'. Temporaries are okay,
236 // because we emit explicit VARKILL instructions marking the end of those
237 // temporaries' lifetimes.
238 func isaddrokay(n ir.Node) bool {
239         return ir.IsAddressable(n) && (n.Op() != ir.ONAME || n.(*ir.Name).Class == ir.PEXTERN || ir.IsAutoTmp(n))
240 }
241
242 // addrTemp ensures that n is okay to pass by address to runtime routines.
243 // If the original argument n is not okay, addrTemp creates a tmp, emits
244 // tmp = n, and then returns tmp.
245 // The result of addrTemp MUST be assigned back to n, e.g.
246 //      n.Left = o.addrTemp(n.Left)
247 func (o *orderState) addrTemp(n ir.Node) ir.Node {
248         if n.Op() == ir.OLITERAL || n.Op() == ir.ONIL {
249                 // TODO: expand this to all static composite literal nodes?
250                 n = typecheck.DefaultLit(n, nil)
251                 types.CalcSize(n.Type())
252                 vstat := readonlystaticname(n.Type())
253                 var s staticinit.Schedule
254                 s.StaticAssign(vstat, 0, n, n.Type())
255                 if s.Out != nil {
256                         base.Fatalf("staticassign of const generated code: %+v", n)
257                 }
258                 vstat = typecheck.Expr(vstat).(*ir.Name)
259                 return vstat
260         }
261         if isaddrokay(n) {
262                 return n
263         }
264         return o.copyExpr(n)
265 }
266
267 // mapKeyTemp prepares n to be a key in a map runtime call and returns n.
268 // It should only be used for map runtime calls which have *_fast* versions.
269 func (o *orderState) mapKeyTemp(t *types.Type, n ir.Node) ir.Node {
270         // Most map calls need to take the address of the key.
271         // Exception: map*_fast* calls. See golang.org/issue/19015.
272         alg := mapfast(t)
273         if alg == mapslow {
274                 return o.addrTemp(n)
275         }
276         var kt *types.Type
277         switch alg {
278         case mapfast32:
279                 kt = types.Types[types.TUINT32]
280         case mapfast64:
281                 kt = types.Types[types.TUINT64]
282         case mapfast32ptr, mapfast64ptr:
283                 kt = types.Types[types.TUNSAFEPTR]
284         case mapfaststr:
285                 kt = types.Types[types.TSTRING]
286         }
287         nt := n.Type()
288         switch {
289         case nt == kt:
290                 return n
291         case nt.Kind() == kt.Kind(), nt.IsPtrShaped() && kt.IsPtrShaped():
292                 // can directly convert (e.g. named type to underlying type, or one pointer to another)
293                 return typecheck.Expr(ir.NewConvExpr(n.Pos(), ir.OCONVNOP, kt, n))
294         case nt.IsInteger() && kt.IsInteger():
295                 // can directly convert (e.g. int32 to uint32)
296                 if n.Op() == ir.OLITERAL && nt.IsSigned() {
297                         // avoid constant overflow error
298                         n = ir.NewConstExpr(constant.MakeUint64(uint64(ir.Int64Val(n))), n)
299                         n.SetType(kt)
300                         return n
301                 }
302                 return typecheck.Expr(ir.NewConvExpr(n.Pos(), ir.OCONV, kt, n))
303         default:
304                 // Unsafe cast through memory.
305                 // We'll need to do a load with type kt. Create a temporary of type kt to
306                 // ensure sufficient alignment. nt may be under-aligned.
307                 if kt.Align < nt.Align {
308                         base.Fatalf("mapKeyTemp: key type is not sufficiently aligned, kt=%v nt=%v", kt, nt)
309                 }
310                 tmp := o.newTemp(kt, true)
311                 // *(*nt)(&tmp) = n
312                 var e ir.Node = typecheck.NodAddr(tmp)
313                 e = ir.NewConvExpr(n.Pos(), ir.OCONVNOP, nt.PtrTo(), e)
314                 e = ir.NewStarExpr(n.Pos(), e)
315                 o.append(ir.NewAssignStmt(base.Pos, e, n))
316                 return tmp
317         }
318 }
319
320 // mapKeyReplaceStrConv replaces OBYTES2STR by OBYTES2STRTMP
321 // in n to avoid string allocations for keys in map lookups.
322 // Returns a bool that signals if a modification was made.
323 //
324 // For:
325 //  x = m[string(k)]
326 //  x = m[T1{... Tn{..., string(k), ...}]
327 // where k is []byte, T1 to Tn is a nesting of struct and array literals,
328 // the allocation of backing bytes for the string can be avoided
329 // by reusing the []byte backing array. These are special cases
330 // for avoiding allocations when converting byte slices to strings.
331 // It would be nice to handle these generally, but because
332 // []byte keys are not allowed in maps, the use of string(k)
333 // comes up in important cases in practice. See issue 3512.
334 func mapKeyReplaceStrConv(n ir.Node) bool {
335         var replaced bool
336         switch n.Op() {
337         case ir.OBYTES2STR:
338                 n := n.(*ir.ConvExpr)
339                 n.SetOp(ir.OBYTES2STRTMP)
340                 replaced = true
341         case ir.OSTRUCTLIT:
342                 n := n.(*ir.CompLitExpr)
343                 for _, elem := range n.List {
344                         elem := elem.(*ir.StructKeyExpr)
345                         if mapKeyReplaceStrConv(elem.Value) {
346                                 replaced = true
347                         }
348                 }
349         case ir.OARRAYLIT:
350                 n := n.(*ir.CompLitExpr)
351                 for _, elem := range n.List {
352                         if elem.Op() == ir.OKEY {
353                                 elem = elem.(*ir.KeyExpr).Value
354                         }
355                         if mapKeyReplaceStrConv(elem) {
356                                 replaced = true
357                         }
358                 }
359         }
360         return replaced
361 }
362
363 type ordermarker int
364
365 // markTemp returns the top of the temporary variable stack.
366 func (o *orderState) markTemp() ordermarker {
367         return ordermarker(len(o.temp))
368 }
369
370 // popTemp pops temporaries off the stack until reaching the mark,
371 // which must have been returned by markTemp.
372 func (o *orderState) popTemp(mark ordermarker) {
373         for _, n := range o.temp[mark:] {
374                 key := n.Type().LongString()
375                 o.free[key] = append(o.free[key], n)
376         }
377         o.temp = o.temp[:mark]
378 }
379
380 // cleanTempNoPop emits VARKILL instructions to *out
381 // for each temporary above the mark on the temporary stack.
382 // It does not pop the temporaries from the stack.
383 func (o *orderState) cleanTempNoPop(mark ordermarker) []ir.Node {
384         var out []ir.Node
385         for i := len(o.temp) - 1; i >= int(mark); i-- {
386                 n := o.temp[i]
387                 out = append(out, typecheck.Stmt(ir.NewUnaryExpr(base.Pos, ir.OVARKILL, n)))
388         }
389         return out
390 }
391
392 // cleanTemp emits VARKILL instructions for each temporary above the
393 // mark on the temporary stack and removes them from the stack.
394 func (o *orderState) cleanTemp(top ordermarker) {
395         o.out = append(o.out, o.cleanTempNoPop(top)...)
396         o.popTemp(top)
397 }
398
399 // stmtList orders each of the statements in the list.
400 func (o *orderState) stmtList(l ir.Nodes) {
401         s := l
402         for i := range s {
403                 orderMakeSliceCopy(s[i:])
404                 o.stmt(s[i])
405         }
406 }
407
408 // orderMakeSliceCopy matches the pattern:
409 //  m = OMAKESLICE([]T, x); OCOPY(m, s)
410 // and rewrites it to:
411 //  m = OMAKESLICECOPY([]T, x, s); nil
412 func orderMakeSliceCopy(s []ir.Node) {
413         if base.Flag.N != 0 || base.Flag.Cfg.Instrumenting {
414                 return
415         }
416         if len(s) < 2 || s[0] == nil || s[0].Op() != ir.OAS || s[1] == nil || s[1].Op() != ir.OCOPY {
417                 return
418         }
419
420         as := s[0].(*ir.AssignStmt)
421         cp := s[1].(*ir.BinaryExpr)
422         if as.Y == nil || as.Y.Op() != ir.OMAKESLICE || ir.IsBlank(as.X) ||
423                 as.X.Op() != ir.ONAME || cp.X.Op() != ir.ONAME || cp.Y.Op() != ir.ONAME ||
424                 as.X.Name() != cp.X.Name() || cp.X.Name() == cp.Y.Name() {
425                 // The line above this one is correct with the differing equality operators:
426                 // we want as.X and cp.X to be the same name,
427                 // but we want the initial data to be coming from a different name.
428                 return
429         }
430
431         mk := as.Y.(*ir.MakeExpr)
432         if mk.Esc() == ir.EscNone || mk.Len == nil || mk.Cap != nil {
433                 return
434         }
435         mk.SetOp(ir.OMAKESLICECOPY)
436         mk.Cap = cp.Y
437         // Set bounded when m = OMAKESLICE([]T, len(s)); OCOPY(m, s)
438         mk.SetBounded(mk.Len.Op() == ir.OLEN && ir.SameSafeExpr(mk.Len.(*ir.UnaryExpr).X, cp.Y))
439         as.Y = typecheck.Expr(mk)
440         s[1] = nil // remove separate copy call
441 }
442
443 // edge inserts coverage instrumentation for libfuzzer.
444 func (o *orderState) edge() {
445         if base.Debug.Libfuzzer == 0 {
446                 return
447         }
448
449         // Create a new uint8 counter to be allocated in section
450         // __libfuzzer_extra_counters.
451         counter := staticinit.StaticName(types.Types[types.TUINT8])
452         counter.SetLibfuzzerExtraCounter(true)
453
454         // counter += 1
455         incr := ir.NewAssignOpStmt(base.Pos, ir.OADD, counter, ir.NewInt(1))
456         o.append(incr)
457 }
458
459 // orderBlock orders the block of statements in n into a new slice,
460 // and then replaces the old slice in n with the new slice.
461 // free is a map that can be used to obtain temporary variables by type.
462 func orderBlock(n *ir.Nodes, free map[string][]*ir.Name) {
463         var order orderState
464         order.free = free
465         mark := order.markTemp()
466         order.edge()
467         order.stmtList(*n)
468         order.cleanTemp(mark)
469         *n = order.out
470 }
471
472 // exprInPlace orders the side effects in *np and
473 // leaves them as the init list of the final *np.
474 // The result of exprInPlace MUST be assigned back to n, e.g.
475 //      n.Left = o.exprInPlace(n.Left)
476 func (o *orderState) exprInPlace(n ir.Node) ir.Node {
477         var order orderState
478         order.free = o.free
479         n = order.expr(n, nil)
480         n = ir.InitExpr(order.out, n)
481
482         // insert new temporaries from order
483         // at head of outer list.
484         o.temp = append(o.temp, order.temp...)
485         return n
486 }
487
488 // orderStmtInPlace orders the side effects of the single statement *np
489 // and replaces it with the resulting statement list.
490 // The result of orderStmtInPlace MUST be assigned back to n, e.g.
491 //      n.Left = orderStmtInPlace(n.Left)
492 // free is a map that can be used to obtain temporary variables by type.
493 func orderStmtInPlace(n ir.Node, free map[string][]*ir.Name) ir.Node {
494         var order orderState
495         order.free = free
496         mark := order.markTemp()
497         order.stmt(n)
498         order.cleanTemp(mark)
499         return ir.NewBlockStmt(src.NoXPos, order.out)
500 }
501
502 // init moves n's init list to o.out.
503 func (o *orderState) init(n ir.Node) {
504         if ir.MayBeShared(n) {
505                 // For concurrency safety, don't mutate potentially shared nodes.
506                 // First, ensure that no work is required here.
507                 if len(n.Init()) > 0 {
508                         base.Fatalf("order.init shared node with ninit")
509                 }
510                 return
511         }
512         o.stmtList(ir.TakeInit(n))
513 }
514
515 // call orders the call expression n.
516 // n.Op is OCALLMETH/OCALLFUNC/OCALLINTER or a builtin like OCOPY.
517 func (o *orderState) call(nn ir.Node) {
518         if len(nn.Init()) > 0 {
519                 // Caller should have already called o.init(nn).
520                 base.Fatalf("%v with unexpected ninit", nn.Op())
521         }
522
523         // Builtin functions.
524         if nn.Op() != ir.OCALLFUNC && nn.Op() != ir.OCALLMETH && nn.Op() != ir.OCALLINTER {
525                 switch n := nn.(type) {
526                 default:
527                         base.Fatalf("unexpected call: %+v", n)
528                 case *ir.UnaryExpr:
529                         n.X = o.expr(n.X, nil)
530                 case *ir.ConvExpr:
531                         n.X = o.expr(n.X, nil)
532                 case *ir.BinaryExpr:
533                         n.X = o.expr(n.X, nil)
534                         n.Y = o.expr(n.Y, nil)
535                 case *ir.MakeExpr:
536                         n.Len = o.expr(n.Len, nil)
537                         n.Cap = o.expr(n.Cap, nil)
538                 case *ir.CallExpr:
539                         o.exprList(n.Args)
540                 }
541                 return
542         }
543
544         n := nn.(*ir.CallExpr)
545         typecheck.FixVariadicCall(n)
546
547         if isFuncPCIntrinsic(n) && isIfaceOfFunc(n.Args[0]) {
548                 // For internal/abi.FuncPCABIxxx(fn), if fn is a defined function,
549                 // do not introduce temporaries here, so it is easier to rewrite it
550                 // to symbol address reference later in walk.
551                 return
552         }
553
554         n.X = o.expr(n.X, nil)
555         o.exprList(n.Args)
556
557         if n.Op() == ir.OCALLINTER {
558                 return
559         }
560         keepAlive := func(arg ir.Node) {
561                 // If the argument is really a pointer being converted to uintptr,
562                 // arrange for the pointer to be kept alive until the call returns,
563                 // by copying it into a temp and marking that temp
564                 // still alive when we pop the temp stack.
565                 if arg.Op() == ir.OCONVNOP {
566                         arg := arg.(*ir.ConvExpr)
567                         if arg.X.Type().IsUnsafePtr() {
568                                 x := o.copyExpr(arg.X)
569                                 arg.X = x
570                                 x.SetAddrtaken(true) // ensure SSA keeps the x variable
571                                 n.KeepAlive = append(n.KeepAlive, x)
572                         }
573                 }
574         }
575
576         // Check for "unsafe-uintptr" tag provided by escape analysis.
577         for i, param := range n.X.Type().Params().FieldSlice() {
578                 if param.Note == escape.UnsafeUintptrNote || param.Note == escape.UintptrEscapesNote {
579                         if arg := n.Args[i]; arg.Op() == ir.OSLICELIT {
580                                 arg := arg.(*ir.CompLitExpr)
581                                 for _, elt := range arg.List {
582                                         keepAlive(elt)
583                                 }
584                         } else {
585                                 keepAlive(arg)
586                         }
587                 }
588         }
589 }
590
591 // mapAssign appends n to o.out.
592 func (o *orderState) mapAssign(n ir.Node) {
593         switch n.Op() {
594         default:
595                 base.Fatalf("order.mapAssign %v", n.Op())
596
597         case ir.OAS:
598                 n := n.(*ir.AssignStmt)
599                 if n.X.Op() == ir.OINDEXMAP {
600                         n.Y = o.safeMapRHS(n.Y)
601                 }
602                 o.out = append(o.out, n)
603         case ir.OASOP:
604                 n := n.(*ir.AssignOpStmt)
605                 if n.X.Op() == ir.OINDEXMAP {
606                         n.Y = o.safeMapRHS(n.Y)
607                 }
608                 o.out = append(o.out, n)
609         }
610 }
611
612 func (o *orderState) safeMapRHS(r ir.Node) ir.Node {
613         // Make sure we evaluate the RHS before starting the map insert.
614         // We need to make sure the RHS won't panic.  See issue 22881.
615         if r.Op() == ir.OAPPEND {
616                 r := r.(*ir.CallExpr)
617                 s := r.Args[1:]
618                 for i, n := range s {
619                         s[i] = o.cheapExpr(n)
620                 }
621                 return r
622         }
623         return o.cheapExpr(r)
624 }
625
626 // stmt orders the statement n, appending to o.out.
627 // Temporaries created during the statement are cleaned
628 // up using VARKILL instructions as possible.
629 func (o *orderState) stmt(n ir.Node) {
630         if n == nil {
631                 return
632         }
633
634         lno := ir.SetPos(n)
635         o.init(n)
636
637         switch n.Op() {
638         default:
639                 base.Fatalf("order.stmt %v", n.Op())
640
641         case ir.OVARKILL, ir.OVARLIVE, ir.OINLMARK:
642                 o.out = append(o.out, n)
643
644         case ir.OAS:
645                 n := n.(*ir.AssignStmt)
646                 t := o.markTemp()
647                 n.X = o.expr(n.X, nil)
648                 n.Y = o.expr(n.Y, n.X)
649                 o.mapAssign(n)
650                 o.cleanTemp(t)
651
652         case ir.OASOP:
653                 n := n.(*ir.AssignOpStmt)
654                 t := o.markTemp()
655                 n.X = o.expr(n.X, nil)
656                 n.Y = o.expr(n.Y, nil)
657
658                 if base.Flag.Cfg.Instrumenting || n.X.Op() == ir.OINDEXMAP && (n.AsOp == ir.ODIV || n.AsOp == ir.OMOD) {
659                         // Rewrite m[k] op= r into m[k] = m[k] op r so
660                         // that we can ensure that if op panics
661                         // because r is zero, the panic happens before
662                         // the map assignment.
663                         // DeepCopy is a big hammer here, but safeExpr
664                         // makes sure there is nothing too deep being copied.
665                         l1 := o.safeExpr(n.X)
666                         l2 := ir.DeepCopy(src.NoXPos, l1)
667                         if l2.Op() == ir.OINDEXMAP {
668                                 l2 := l2.(*ir.IndexExpr)
669                                 l2.Assigned = false
670                         }
671                         l2 = o.copyExpr(l2)
672                         r := o.expr(typecheck.Expr(ir.NewBinaryExpr(n.Pos(), n.AsOp, l2, n.Y)), nil)
673                         as := typecheck.Stmt(ir.NewAssignStmt(n.Pos(), l1, r))
674                         o.mapAssign(as)
675                         o.cleanTemp(t)
676                         return
677                 }
678
679                 o.mapAssign(n)
680                 o.cleanTemp(t)
681
682         case ir.OAS2:
683                 n := n.(*ir.AssignListStmt)
684                 t := o.markTemp()
685                 o.exprList(n.Lhs)
686                 o.exprList(n.Rhs)
687                 o.out = append(o.out, n)
688                 o.cleanTemp(t)
689
690         // Special: avoid copy of func call n.Right
691         case ir.OAS2FUNC:
692                 n := n.(*ir.AssignListStmt)
693                 t := o.markTemp()
694                 o.exprList(n.Lhs)
695                 o.init(n.Rhs[0])
696                 o.call(n.Rhs[0])
697                 o.as2func(n)
698                 o.cleanTemp(t)
699
700         // Special: use temporary variables to hold result,
701         // so that runtime can take address of temporary.
702         // No temporary for blank assignment.
703         //
704         // OAS2MAPR: make sure key is addressable if needed,
705         //           and make sure OINDEXMAP is not copied out.
706         case ir.OAS2DOTTYPE, ir.OAS2RECV, ir.OAS2MAPR:
707                 n := n.(*ir.AssignListStmt)
708                 t := o.markTemp()
709                 o.exprList(n.Lhs)
710
711                 switch r := n.Rhs[0]; r.Op() {
712                 case ir.ODOTTYPE2:
713                         r := r.(*ir.TypeAssertExpr)
714                         r.X = o.expr(r.X, nil)
715                 case ir.ORECV:
716                         r := r.(*ir.UnaryExpr)
717                         r.X = o.expr(r.X, nil)
718                 case ir.OINDEXMAP:
719                         r := r.(*ir.IndexExpr)
720                         r.X = o.expr(r.X, nil)
721                         r.Index = o.expr(r.Index, nil)
722                         // See similar conversion for OINDEXMAP below.
723                         _ = mapKeyReplaceStrConv(r.Index)
724                         r.Index = o.mapKeyTemp(r.X.Type(), r.Index)
725                 default:
726                         base.Fatalf("order.stmt: %v", r.Op())
727                 }
728
729                 o.as2ok(n)
730                 o.cleanTemp(t)
731
732         // Special: does not save n onto out.
733         case ir.OBLOCK:
734                 n := n.(*ir.BlockStmt)
735                 o.stmtList(n.List)
736
737         // Special: n->left is not an expression; save as is.
738         case ir.OBREAK,
739                 ir.OCONTINUE,
740                 ir.ODCL,
741                 ir.ODCLCONST,
742                 ir.ODCLTYPE,
743                 ir.OFALL,
744                 ir.OGOTO,
745                 ir.OLABEL,
746                 ir.OTAILCALL:
747                 o.out = append(o.out, n)
748
749         // Special: handle call arguments.
750         case ir.OCALLFUNC, ir.OCALLINTER, ir.OCALLMETH:
751                 n := n.(*ir.CallExpr)
752                 t := o.markTemp()
753                 o.call(n)
754                 o.out = append(o.out, n)
755                 o.cleanTemp(t)
756
757         case ir.OCLOSE, ir.ORECV:
758                 n := n.(*ir.UnaryExpr)
759                 t := o.markTemp()
760                 n.X = o.expr(n.X, nil)
761                 o.out = append(o.out, n)
762                 o.cleanTemp(t)
763
764         case ir.OCOPY:
765                 n := n.(*ir.BinaryExpr)
766                 t := o.markTemp()
767                 n.X = o.expr(n.X, nil)
768                 n.Y = o.expr(n.Y, nil)
769                 o.out = append(o.out, n)
770                 o.cleanTemp(t)
771
772         case ir.OPRINT, ir.OPRINTN, ir.ORECOVER:
773                 n := n.(*ir.CallExpr)
774                 t := o.markTemp()
775                 o.exprList(n.Args)
776                 o.out = append(o.out, n)
777                 o.cleanTemp(t)
778
779         // Special: order arguments to inner call but not call itself.
780         case ir.ODEFER, ir.OGO:
781                 n := n.(*ir.GoDeferStmt)
782                 t := o.markTemp()
783                 o.init(n.Call)
784                 o.call(n.Call)
785                 if n.Call.Op() == ir.ORECOVER {
786                         // Special handling of "defer recover()". We need to evaluate the FP
787                         // argument before wrapping.
788                         var init ir.Nodes
789                         n.Call = walkRecover(n.Call.(*ir.CallExpr), &init)
790                         o.stmtList(init)
791                 }
792                 o.wrapGoDefer(n)
793                 o.out = append(o.out, n)
794                 o.cleanTemp(t)
795
796         case ir.ODELETE:
797                 n := n.(*ir.CallExpr)
798                 t := o.markTemp()
799                 n.Args[0] = o.expr(n.Args[0], nil)
800                 n.Args[1] = o.expr(n.Args[1], nil)
801                 n.Args[1] = o.mapKeyTemp(n.Args[0].Type(), n.Args[1])
802                 o.out = append(o.out, n)
803                 o.cleanTemp(t)
804
805         // Clean temporaries from condition evaluation at
806         // beginning of loop body and after for statement.
807         case ir.OFOR:
808                 n := n.(*ir.ForStmt)
809                 t := o.markTemp()
810                 n.Cond = o.exprInPlace(n.Cond)
811                 n.Body.Prepend(o.cleanTempNoPop(t)...)
812                 orderBlock(&n.Body, o.free)
813                 n.Post = orderStmtInPlace(n.Post, o.free)
814                 o.out = append(o.out, n)
815                 o.cleanTemp(t)
816
817         // Clean temporaries from condition at
818         // beginning of both branches.
819         case ir.OIF:
820                 n := n.(*ir.IfStmt)
821                 t := o.markTemp()
822                 n.Cond = o.exprInPlace(n.Cond)
823                 n.Body.Prepend(o.cleanTempNoPop(t)...)
824                 n.Else.Prepend(o.cleanTempNoPop(t)...)
825                 o.popTemp(t)
826                 orderBlock(&n.Body, o.free)
827                 orderBlock(&n.Else, o.free)
828                 o.out = append(o.out, n)
829
830         case ir.OPANIC:
831                 n := n.(*ir.UnaryExpr)
832                 t := o.markTemp()
833                 n.X = o.expr(n.X, nil)
834                 if !n.X.Type().IsEmptyInterface() {
835                         base.FatalfAt(n.Pos(), "bad argument to panic: %L", n.X)
836                 }
837                 o.out = append(o.out, n)
838                 o.cleanTemp(t)
839
840         case ir.ORANGE:
841                 // n.Right is the expression being ranged over.
842                 // order it, and then make a copy if we need one.
843                 // We almost always do, to ensure that we don't
844                 // see any value changes made during the loop.
845                 // Usually the copy is cheap (e.g., array pointer,
846                 // chan, slice, string are all tiny).
847                 // The exception is ranging over an array value
848                 // (not a slice, not a pointer to array),
849                 // which must make a copy to avoid seeing updates made during
850                 // the range body. Ranging over an array value is uncommon though.
851
852                 // Mark []byte(str) range expression to reuse string backing storage.
853                 // It is safe because the storage cannot be mutated.
854                 n := n.(*ir.RangeStmt)
855                 if n.X.Op() == ir.OSTR2BYTES {
856                         n.X.(*ir.ConvExpr).SetOp(ir.OSTR2BYTESTMP)
857                 }
858
859                 t := o.markTemp()
860                 n.X = o.expr(n.X, nil)
861
862                 orderBody := true
863                 xt := typecheck.RangeExprType(n.X.Type())
864                 switch xt.Kind() {
865                 default:
866                         base.Fatalf("order.stmt range %v", n.Type())
867
868                 case types.TARRAY, types.TSLICE:
869                         if n.Value == nil || ir.IsBlank(n.Value) {
870                                 // for i := range x will only use x once, to compute len(x).
871                                 // No need to copy it.
872                                 break
873                         }
874                         fallthrough
875
876                 case types.TCHAN, types.TSTRING:
877                         // chan, string, slice, array ranges use value multiple times.
878                         // make copy.
879                         r := n.X
880
881                         if r.Type().IsString() && r.Type() != types.Types[types.TSTRING] {
882                                 r = ir.NewConvExpr(base.Pos, ir.OCONV, nil, r)
883                                 r.SetType(types.Types[types.TSTRING])
884                                 r = typecheck.Expr(r)
885                         }
886
887                         n.X = o.copyExpr(r)
888
889                 case types.TMAP:
890                         if isMapClear(n) {
891                                 // Preserve the body of the map clear pattern so it can
892                                 // be detected during walk. The loop body will not be used
893                                 // when optimizing away the range loop to a runtime call.
894                                 orderBody = false
895                                 break
896                         }
897
898                         // copy the map value in case it is a map literal.
899                         // TODO(rsc): Make tmp = literal expressions reuse tmp.
900                         // For maps tmp is just one word so it hardly matters.
901                         r := n.X
902                         n.X = o.copyExpr(r)
903
904                         // n.Prealloc is the temp for the iterator.
905                         // MapIterType contains pointers and needs to be zeroed.
906                         n.Prealloc = o.newTemp(reflectdata.MapIterType(xt), true)
907                 }
908                 n.Key = o.exprInPlace(n.Key)
909                 n.Value = o.exprInPlace(n.Value)
910                 if orderBody {
911                         orderBlock(&n.Body, o.free)
912                 }
913                 o.out = append(o.out, n)
914                 o.cleanTemp(t)
915
916         case ir.ORETURN:
917                 n := n.(*ir.ReturnStmt)
918                 o.exprList(n.Results)
919                 o.out = append(o.out, n)
920
921         // Special: clean case temporaries in each block entry.
922         // Select must enter one of its blocks, so there is no
923         // need for a cleaning at the end.
924         // Doubly special: evaluation order for select is stricter
925         // than ordinary expressions. Even something like p.c
926         // has to be hoisted into a temporary, so that it cannot be
927         // reordered after the channel evaluation for a different
928         // case (if p were nil, then the timing of the fault would
929         // give this away).
930         case ir.OSELECT:
931                 n := n.(*ir.SelectStmt)
932                 t := o.markTemp()
933                 for _, ncas := range n.Cases {
934                         r := ncas.Comm
935                         ir.SetPos(ncas)
936
937                         // Append any new body prologue to ninit.
938                         // The next loop will insert ninit into nbody.
939                         if len(ncas.Init()) != 0 {
940                                 base.Fatalf("order select ninit")
941                         }
942                         if r == nil {
943                                 continue
944                         }
945                         switch r.Op() {
946                         default:
947                                 ir.Dump("select case", r)
948                                 base.Fatalf("unknown op in select %v", r.Op())
949
950                         case ir.OSELRECV2:
951                                 // case x, ok = <-c
952                                 r := r.(*ir.AssignListStmt)
953                                 recv := r.Rhs[0].(*ir.UnaryExpr)
954                                 recv.X = o.expr(recv.X, nil)
955                                 if !ir.IsAutoTmp(recv.X) {
956                                         recv.X = o.copyExpr(recv.X)
957                                 }
958                                 init := ir.TakeInit(r)
959
960                                 colas := r.Def
961                                 do := func(i int, t *types.Type) {
962                                         n := r.Lhs[i]
963                                         if ir.IsBlank(n) {
964                                                 return
965                                         }
966                                         // If this is case x := <-ch or case x, y := <-ch, the case has
967                                         // the ODCL nodes to declare x and y. We want to delay that
968                                         // declaration (and possible allocation) until inside the case body.
969                                         // Delete the ODCL nodes here and recreate them inside the body below.
970                                         if colas {
971                                                 if len(init) > 0 && init[0].Op() == ir.ODCL && init[0].(*ir.Decl).X == n {
972                                                         init = init[1:]
973                                                 }
974                                                 dcl := typecheck.Stmt(ir.NewDecl(base.Pos, ir.ODCL, n.(*ir.Name)))
975                                                 ncas.PtrInit().Append(dcl)
976                                         }
977                                         tmp := o.newTemp(t, t.HasPointers())
978                                         as := typecheck.Stmt(ir.NewAssignStmt(base.Pos, n, typecheck.Conv(tmp, n.Type())))
979                                         ncas.PtrInit().Append(as)
980                                         r.Lhs[i] = tmp
981                                 }
982                                 do(0, recv.X.Type().Elem())
983                                 do(1, types.Types[types.TBOOL])
984                                 if len(init) != 0 {
985                                         ir.DumpList("ninit", r.Init())
986                                         base.Fatalf("ninit on select recv")
987                                 }
988                                 orderBlock(ncas.PtrInit(), o.free)
989
990                         case ir.OSEND:
991                                 r := r.(*ir.SendStmt)
992                                 if len(r.Init()) != 0 {
993                                         ir.DumpList("ninit", r.Init())
994                                         base.Fatalf("ninit on select send")
995                                 }
996
997                                 // case c <- x
998                                 // r->left is c, r->right is x, both are always evaluated.
999                                 r.Chan = o.expr(r.Chan, nil)
1000
1001                                 if !ir.IsAutoTmp(r.Chan) {
1002                                         r.Chan = o.copyExpr(r.Chan)
1003                                 }
1004                                 r.Value = o.expr(r.Value, nil)
1005                                 if !ir.IsAutoTmp(r.Value) {
1006                                         r.Value = o.copyExpr(r.Value)
1007                                 }
1008                         }
1009                 }
1010                 // Now that we have accumulated all the temporaries, clean them.
1011                 // Also insert any ninit queued during the previous loop.
1012                 // (The temporary cleaning must follow that ninit work.)
1013                 for _, cas := range n.Cases {
1014                         orderBlock(&cas.Body, o.free)
1015                         cas.Body.Prepend(o.cleanTempNoPop(t)...)
1016
1017                         // TODO(mdempsky): Is this actually necessary?
1018                         // walkSelect appears to walk Ninit.
1019                         cas.Body.Prepend(ir.TakeInit(cas)...)
1020                 }
1021
1022                 o.out = append(o.out, n)
1023                 o.popTemp(t)
1024
1025         // Special: value being sent is passed as a pointer; make it addressable.
1026         case ir.OSEND:
1027                 n := n.(*ir.SendStmt)
1028                 t := o.markTemp()
1029                 n.Chan = o.expr(n.Chan, nil)
1030                 n.Value = o.expr(n.Value, nil)
1031                 if base.Flag.Cfg.Instrumenting {
1032                         // Force copying to the stack so that (chan T)(nil) <- x
1033                         // is still instrumented as a read of x.
1034                         n.Value = o.copyExpr(n.Value)
1035                 } else {
1036                         n.Value = o.addrTemp(n.Value)
1037                 }
1038                 o.out = append(o.out, n)
1039                 o.cleanTemp(t)
1040
1041         // TODO(rsc): Clean temporaries more aggressively.
1042         // Note that because walkSwitch will rewrite some of the
1043         // switch into a binary search, this is not as easy as it looks.
1044         // (If we ran that code here we could invoke order.stmt on
1045         // the if-else chain instead.)
1046         // For now just clean all the temporaries at the end.
1047         // In practice that's fine.
1048         case ir.OSWITCH:
1049                 n := n.(*ir.SwitchStmt)
1050                 if base.Debug.Libfuzzer != 0 && !hasDefaultCase(n) {
1051                         // Add empty "default:" case for instrumentation.
1052                         n.Cases = append(n.Cases, ir.NewCaseStmt(base.Pos, nil, nil))
1053                 }
1054
1055                 t := o.markTemp()
1056                 n.Tag = o.expr(n.Tag, nil)
1057                 for _, ncas := range n.Cases {
1058                         o.exprListInPlace(ncas.List)
1059                         orderBlock(&ncas.Body, o.free)
1060                 }
1061
1062                 o.out = append(o.out, n)
1063                 o.cleanTemp(t)
1064         }
1065
1066         base.Pos = lno
1067 }
1068
1069 func hasDefaultCase(n *ir.SwitchStmt) bool {
1070         for _, ncas := range n.Cases {
1071                 if len(ncas.List) == 0 {
1072                         return true
1073                 }
1074         }
1075         return false
1076 }
1077
1078 // exprList orders the expression list l into o.
1079 func (o *orderState) exprList(l ir.Nodes) {
1080         s := l
1081         for i := range s {
1082                 s[i] = o.expr(s[i], nil)
1083         }
1084 }
1085
1086 // exprListInPlace orders the expression list l but saves
1087 // the side effects on the individual expression ninit lists.
1088 func (o *orderState) exprListInPlace(l ir.Nodes) {
1089         s := l
1090         for i := range s {
1091                 s[i] = o.exprInPlace(s[i])
1092         }
1093 }
1094
1095 func (o *orderState) exprNoLHS(n ir.Node) ir.Node {
1096         return o.expr(n, nil)
1097 }
1098
1099 // expr orders a single expression, appending side
1100 // effects to o.out as needed.
1101 // If this is part of an assignment lhs = *np, lhs is given.
1102 // Otherwise lhs == nil. (When lhs != nil it may be possible
1103 // to avoid copying the result of the expression to a temporary.)
1104 // The result of expr MUST be assigned back to n, e.g.
1105 //      n.Left = o.expr(n.Left, lhs)
1106 func (o *orderState) expr(n, lhs ir.Node) ir.Node {
1107         if n == nil {
1108                 return n
1109         }
1110         lno := ir.SetPos(n)
1111         n = o.expr1(n, lhs)
1112         base.Pos = lno
1113         return n
1114 }
1115
1116 func (o *orderState) expr1(n, lhs ir.Node) ir.Node {
1117         o.init(n)
1118
1119         switch n.Op() {
1120         default:
1121                 if o.edit == nil {
1122                         o.edit = o.exprNoLHS // create closure once
1123                 }
1124                 ir.EditChildren(n, o.edit)
1125                 return n
1126
1127         // Addition of strings turns into a function call.
1128         // Allocate a temporary to hold the strings.
1129         // Fewer than 5 strings use direct runtime helpers.
1130         case ir.OADDSTR:
1131                 n := n.(*ir.AddStringExpr)
1132                 o.exprList(n.List)
1133
1134                 if len(n.List) > 5 {
1135                         t := types.NewArray(types.Types[types.TSTRING], int64(len(n.List)))
1136                         n.Prealloc = o.newTemp(t, false)
1137                 }
1138
1139                 // Mark string(byteSlice) arguments to reuse byteSlice backing
1140                 // buffer during conversion. String concatenation does not
1141                 // memorize the strings for later use, so it is safe.
1142                 // However, we can do it only if there is at least one non-empty string literal.
1143                 // Otherwise if all other arguments are empty strings,
1144                 // concatstrings will return the reference to the temp string
1145                 // to the caller.
1146                 hasbyte := false
1147
1148                 haslit := false
1149                 for _, n1 := range n.List {
1150                         hasbyte = hasbyte || n1.Op() == ir.OBYTES2STR
1151                         haslit = haslit || n1.Op() == ir.OLITERAL && len(ir.StringVal(n1)) != 0
1152                 }
1153
1154                 if haslit && hasbyte {
1155                         for _, n2 := range n.List {
1156                                 if n2.Op() == ir.OBYTES2STR {
1157                                         n2 := n2.(*ir.ConvExpr)
1158                                         n2.SetOp(ir.OBYTES2STRTMP)
1159                                 }
1160                         }
1161                 }
1162                 return n
1163
1164         case ir.OINDEXMAP:
1165                 n := n.(*ir.IndexExpr)
1166                 n.X = o.expr(n.X, nil)
1167                 n.Index = o.expr(n.Index, nil)
1168                 needCopy := false
1169
1170                 if !n.Assigned {
1171                         // Enforce that any []byte slices we are not copying
1172                         // can not be changed before the map index by forcing
1173                         // the map index to happen immediately following the
1174                         // conversions. See copyExpr a few lines below.
1175                         needCopy = mapKeyReplaceStrConv(n.Index)
1176
1177                         if base.Flag.Cfg.Instrumenting {
1178                                 // Race detector needs the copy.
1179                                 needCopy = true
1180                         }
1181                 }
1182
1183                 // key must be addressable
1184                 n.Index = o.mapKeyTemp(n.X.Type(), n.Index)
1185                 if needCopy {
1186                         return o.copyExpr(n)
1187                 }
1188                 return n
1189
1190         // concrete type (not interface) argument might need an addressable
1191         // temporary to pass to the runtime conversion routine.
1192         case ir.OCONVIFACE:
1193                 n := n.(*ir.ConvExpr)
1194                 n.X = o.expr(n.X, nil)
1195                 if n.X.Type().IsInterface() {
1196                         return n
1197                 }
1198                 if _, _, needsaddr := convFuncName(n.X.Type(), n.Type()); needsaddr || isStaticCompositeLiteral(n.X) {
1199                         // Need a temp if we need to pass the address to the conversion function.
1200                         // We also process static composite literal node here, making a named static global
1201                         // whose address we can put directly in an interface (see OCONVIFACE case in walk).
1202                         n.X = o.addrTemp(n.X)
1203                 }
1204                 return n
1205
1206         case ir.OCONVNOP:
1207                 n := n.(*ir.ConvExpr)
1208                 if n.Type().IsKind(types.TUNSAFEPTR) && n.X.Type().IsKind(types.TUINTPTR) && (n.X.Op() == ir.OCALLFUNC || n.X.Op() == ir.OCALLINTER || n.X.Op() == ir.OCALLMETH) {
1209                         call := n.X.(*ir.CallExpr)
1210                         // When reordering unsafe.Pointer(f()) into a separate
1211                         // statement, the conversion and function call must stay
1212                         // together. See golang.org/issue/15329.
1213                         o.init(call)
1214                         o.call(call)
1215                         if lhs == nil || lhs.Op() != ir.ONAME || base.Flag.Cfg.Instrumenting {
1216                                 return o.copyExpr(n)
1217                         }
1218                 } else {
1219                         n.X = o.expr(n.X, nil)
1220                 }
1221                 return n
1222
1223         case ir.OANDAND, ir.OOROR:
1224                 // ... = LHS && RHS
1225                 //
1226                 // var r bool
1227                 // r = LHS
1228                 // if r {       // or !r, for OROR
1229                 //     r = RHS
1230                 // }
1231                 // ... = r
1232
1233                 n := n.(*ir.LogicalExpr)
1234                 r := o.newTemp(n.Type(), false)
1235
1236                 // Evaluate left-hand side.
1237                 lhs := o.expr(n.X, nil)
1238                 o.out = append(o.out, typecheck.Stmt(ir.NewAssignStmt(base.Pos, r, lhs)))
1239
1240                 // Evaluate right-hand side, save generated code.
1241                 saveout := o.out
1242                 o.out = nil
1243                 t := o.markTemp()
1244                 o.edge()
1245                 rhs := o.expr(n.Y, nil)
1246                 o.out = append(o.out, typecheck.Stmt(ir.NewAssignStmt(base.Pos, r, rhs)))
1247                 o.cleanTemp(t)
1248                 gen := o.out
1249                 o.out = saveout
1250
1251                 // If left-hand side doesn't cause a short-circuit, issue right-hand side.
1252                 nif := ir.NewIfStmt(base.Pos, r, nil, nil)
1253                 if n.Op() == ir.OANDAND {
1254                         nif.Body = gen
1255                 } else {
1256                         nif.Else = gen
1257                 }
1258                 o.out = append(o.out, nif)
1259                 return r
1260
1261         case ir.OCALLFUNC,
1262                 ir.OCALLINTER,
1263                 ir.OCALLMETH,
1264                 ir.OCAP,
1265                 ir.OCOMPLEX,
1266                 ir.OCOPY,
1267                 ir.OIMAG,
1268                 ir.OLEN,
1269                 ir.OMAKECHAN,
1270                 ir.OMAKEMAP,
1271                 ir.OMAKESLICE,
1272                 ir.OMAKESLICECOPY,
1273                 ir.ONEW,
1274                 ir.OREAL,
1275                 ir.ORECOVER,
1276                 ir.OSTR2BYTES,
1277                 ir.OSTR2BYTESTMP,
1278                 ir.OSTR2RUNES:
1279
1280                 if isRuneCount(n) {
1281                         // len([]rune(s)) is rewritten to runtime.countrunes(s) later.
1282                         conv := n.(*ir.UnaryExpr).X.(*ir.ConvExpr)
1283                         conv.X = o.expr(conv.X, nil)
1284                 } else {
1285                         o.call(n)
1286                 }
1287
1288                 if lhs == nil || lhs.Op() != ir.ONAME || base.Flag.Cfg.Instrumenting {
1289                         return o.copyExpr(n)
1290                 }
1291                 return n
1292
1293         case ir.OAPPEND:
1294                 // Check for append(x, make([]T, y)...) .
1295                 n := n.(*ir.CallExpr)
1296                 if isAppendOfMake(n) {
1297                         n.Args[0] = o.expr(n.Args[0], nil) // order x
1298                         mk := n.Args[1].(*ir.MakeExpr)
1299                         mk.Len = o.expr(mk.Len, nil) // order y
1300                 } else {
1301                         o.exprList(n.Args)
1302                 }
1303
1304                 if lhs == nil || lhs.Op() != ir.ONAME && !ir.SameSafeExpr(lhs, n.Args[0]) {
1305                         return o.copyExpr(n)
1306                 }
1307                 return n
1308
1309         case ir.OSLICE, ir.OSLICEARR, ir.OSLICESTR, ir.OSLICE3, ir.OSLICE3ARR:
1310                 n := n.(*ir.SliceExpr)
1311                 n.X = o.expr(n.X, nil)
1312                 n.Low = o.cheapExpr(o.expr(n.Low, nil))
1313                 n.High = o.cheapExpr(o.expr(n.High, nil))
1314                 n.Max = o.cheapExpr(o.expr(n.Max, nil))
1315                 if lhs == nil || lhs.Op() != ir.ONAME && !ir.SameSafeExpr(lhs, n.X) {
1316                         return o.copyExpr(n)
1317                 }
1318                 return n
1319
1320         case ir.OCLOSURE:
1321                 n := n.(*ir.ClosureExpr)
1322                 if n.Transient() && len(n.Func.ClosureVars) > 0 {
1323                         n.Prealloc = o.newTemp(typecheck.ClosureType(n), false)
1324                 }
1325                 return n
1326
1327         case ir.OCALLPART:
1328                 n := n.(*ir.SelectorExpr)
1329                 n.X = o.expr(n.X, nil)
1330                 if n.Transient() {
1331                         t := typecheck.PartialCallType(n)
1332                         n.Prealloc = o.newTemp(t, false)
1333                 }
1334                 return n
1335
1336         case ir.OSLICELIT:
1337                 n := n.(*ir.CompLitExpr)
1338                 o.exprList(n.List)
1339                 if n.Transient() {
1340                         t := types.NewArray(n.Type().Elem(), n.Len)
1341                         n.Prealloc = o.newTemp(t, false)
1342                 }
1343                 return n
1344
1345         case ir.ODOTTYPE, ir.ODOTTYPE2:
1346                 n := n.(*ir.TypeAssertExpr)
1347                 n.X = o.expr(n.X, nil)
1348                 if !types.IsDirectIface(n.Type()) || base.Flag.Cfg.Instrumenting {
1349                         return o.copyExprClear(n)
1350                 }
1351                 return n
1352
1353         case ir.ORECV:
1354                 n := n.(*ir.UnaryExpr)
1355                 n.X = o.expr(n.X, nil)
1356                 return o.copyExprClear(n)
1357
1358         case ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE:
1359                 n := n.(*ir.BinaryExpr)
1360                 n.X = o.expr(n.X, nil)
1361                 n.Y = o.expr(n.Y, nil)
1362
1363                 t := n.X.Type()
1364                 switch {
1365                 case t.IsString():
1366                         // Mark string(byteSlice) arguments to reuse byteSlice backing
1367                         // buffer during conversion. String comparison does not
1368                         // memorize the strings for later use, so it is safe.
1369                         if n.X.Op() == ir.OBYTES2STR {
1370                                 n.X.(*ir.ConvExpr).SetOp(ir.OBYTES2STRTMP)
1371                         }
1372                         if n.Y.Op() == ir.OBYTES2STR {
1373                                 n.Y.(*ir.ConvExpr).SetOp(ir.OBYTES2STRTMP)
1374                         }
1375
1376                 case t.IsStruct() || t.IsArray():
1377                         // for complex comparisons, we need both args to be
1378                         // addressable so we can pass them to the runtime.
1379                         n.X = o.addrTemp(n.X)
1380                         n.Y = o.addrTemp(n.Y)
1381                 }
1382                 return n
1383
1384         case ir.OMAPLIT:
1385                 // Order map by converting:
1386                 //   map[int]int{
1387                 //     a(): b(),
1388                 //     c(): d(),
1389                 //     e(): f(),
1390                 //   }
1391                 // to
1392                 //   m := map[int]int{}
1393                 //   m[a()] = b()
1394                 //   m[c()] = d()
1395                 //   m[e()] = f()
1396                 // Then order the result.
1397                 // Without this special case, order would otherwise compute all
1398                 // the keys and values before storing any of them to the map.
1399                 // See issue 26552.
1400                 n := n.(*ir.CompLitExpr)
1401                 entries := n.List
1402                 statics := entries[:0]
1403                 var dynamics []*ir.KeyExpr
1404                 for _, r := range entries {
1405                         r := r.(*ir.KeyExpr)
1406
1407                         if !isStaticCompositeLiteral(r.Key) || !isStaticCompositeLiteral(r.Value) {
1408                                 dynamics = append(dynamics, r)
1409                                 continue
1410                         }
1411
1412                         // Recursively ordering some static entries can change them to dynamic;
1413                         // e.g., OCONVIFACE nodes. See #31777.
1414                         r = o.expr(r, nil).(*ir.KeyExpr)
1415                         if !isStaticCompositeLiteral(r.Key) || !isStaticCompositeLiteral(r.Value) {
1416                                 dynamics = append(dynamics, r)
1417                                 continue
1418                         }
1419
1420                         statics = append(statics, r)
1421                 }
1422                 n.List = statics
1423
1424                 if len(dynamics) == 0 {
1425                         return n
1426                 }
1427
1428                 // Emit the creation of the map (with all its static entries).
1429                 m := o.newTemp(n.Type(), false)
1430                 as := ir.NewAssignStmt(base.Pos, m, n)
1431                 typecheck.Stmt(as)
1432                 o.stmt(as)
1433
1434                 // Emit eval+insert of dynamic entries, one at a time.
1435                 for _, r := range dynamics {
1436                         as := ir.NewAssignStmt(base.Pos, ir.NewIndexExpr(base.Pos, m, r.Key), r.Value)
1437                         typecheck.Stmt(as) // Note: this converts the OINDEX to an OINDEXMAP
1438                         o.stmt(as)
1439                 }
1440                 return m
1441         }
1442
1443         // No return - type-assertions above. Each case must return for itself.
1444 }
1445
1446 // as2func orders OAS2FUNC nodes. It creates temporaries to ensure left-to-right assignment.
1447 // The caller should order the right-hand side of the assignment before calling order.as2func.
1448 // It rewrites,
1449 //      a, b, a = ...
1450 // as
1451 //      tmp1, tmp2, tmp3 = ...
1452 //      a, b, a = tmp1, tmp2, tmp3
1453 // This is necessary to ensure left to right assignment order.
1454 func (o *orderState) as2func(n *ir.AssignListStmt) {
1455         results := n.Rhs[0].Type()
1456         as := ir.NewAssignListStmt(n.Pos(), ir.OAS2, nil, nil)
1457         for i, nl := range n.Lhs {
1458                 if !ir.IsBlank(nl) {
1459                         typ := results.Field(i).Type
1460                         tmp := o.newTemp(typ, typ.HasPointers())
1461                         n.Lhs[i] = tmp
1462                         as.Lhs = append(as.Lhs, nl)
1463                         as.Rhs = append(as.Rhs, tmp)
1464                 }
1465         }
1466
1467         o.out = append(o.out, n)
1468         o.stmt(typecheck.Stmt(as))
1469 }
1470
1471 // as2ok orders OAS2XXX with ok.
1472 // Just like as2func, this also adds temporaries to ensure left-to-right assignment.
1473 func (o *orderState) as2ok(n *ir.AssignListStmt) {
1474         as := ir.NewAssignListStmt(n.Pos(), ir.OAS2, nil, nil)
1475
1476         do := func(i int, typ *types.Type) {
1477                 if nl := n.Lhs[i]; !ir.IsBlank(nl) {
1478                         var tmp ir.Node = o.newTemp(typ, typ.HasPointers())
1479                         n.Lhs[i] = tmp
1480                         as.Lhs = append(as.Lhs, nl)
1481                         if i == 1 {
1482                                 // The "ok" result is an untyped boolean according to the Go
1483                                 // spec. We need to explicitly convert it to the LHS type in
1484                                 // case the latter is a defined boolean type (#8475).
1485                                 tmp = typecheck.Conv(tmp, nl.Type())
1486                         }
1487                         as.Rhs = append(as.Rhs, tmp)
1488                 }
1489         }
1490
1491         do(0, n.Rhs[0].Type())
1492         do(1, types.Types[types.TBOOL])
1493
1494         o.out = append(o.out, n)
1495         o.stmt(typecheck.Stmt(as))
1496 }
1497
1498 var wrapGoDefer_prgen int
1499
1500 // wrapGoDefer wraps the target of a "go" or "defer" statement with a
1501 // new "function with no arguments" closure. Specifically, it converts
1502 //
1503 //   defer f(x, y)
1504 //
1505 // to
1506 //
1507 //   x1, y1 := x, y
1508 //   defer func() { f(x1, y1) }()
1509 //
1510 // This is primarily to enable a quicker bringup of defers under the
1511 // new register ABI; by doing this conversion, we can simplify the
1512 // code in the runtime that invokes defers on the panic path.
1513 func (o *orderState) wrapGoDefer(n *ir.GoDeferStmt) {
1514         call := n.Call
1515
1516         var callX ir.Node        // thing being called
1517         var callArgs []ir.Node   // call arguments
1518         var keepAlive []*ir.Name // KeepAlive list from call, if present
1519
1520         // A helper to recreate the call within the closure.
1521         var mkNewCall func(pos src.XPos, op ir.Op, fun ir.Node, args []ir.Node) ir.Node
1522
1523         // Defer calls come in many shapes and sizes; not all of them
1524         // are ir.CallExpr's. Examine the type to see what we're dealing with.
1525         switch x := call.(type) {
1526         case *ir.CallExpr:
1527                 callX = x.X
1528                 callArgs = x.Args
1529                 keepAlive = x.KeepAlive
1530                 mkNewCall = func(pos src.XPos, op ir.Op, fun ir.Node, args []ir.Node) ir.Node {
1531                         newcall := ir.NewCallExpr(pos, op, fun, args)
1532                         newcall.IsDDD = x.IsDDD
1533                         return ir.Node(newcall)
1534                 }
1535         case *ir.UnaryExpr: // ex: OCLOSE
1536                 callArgs = []ir.Node{x.X}
1537                 mkNewCall = func(pos src.XPos, op ir.Op, fun ir.Node, args []ir.Node) ir.Node {
1538                         if len(args) != 1 {
1539                                 panic("internal error, expecting single arg")
1540                         }
1541                         return ir.Node(ir.NewUnaryExpr(pos, op, args[0]))
1542                 }
1543         case *ir.BinaryExpr: // ex: OCOPY
1544                 callArgs = []ir.Node{x.X, x.Y}
1545                 mkNewCall = func(pos src.XPos, op ir.Op, fun ir.Node, args []ir.Node) ir.Node {
1546                         if len(args) != 2 {
1547                                 panic("internal error, expecting two args")
1548                         }
1549                         return ir.Node(ir.NewBinaryExpr(pos, op, args[0], args[1]))
1550                 }
1551         default:
1552                 panic("unhandled op")
1553         }
1554
1555         // No need to wrap if called func has no args, no receiver, and no results.
1556         // However in the case of "defer func() { ... }()" we need to
1557         // protect against the possibility of directClosureCall rewriting
1558         // things so that the call does have arguments.
1559         //
1560         // Do wrap method calls (OCALLMETH, OCALLINTER), because it has
1561         // a receiver.
1562         //
1563         // Also do wrap builtin functions, because they may be expanded to
1564         // calls with arguments (e.g. ORECOVER).
1565         //
1566         // TODO: maybe not wrap if the called function has no arguments and
1567         // only in-register results?
1568         if len(callArgs) == 0 && call.Op() == ir.OCALLFUNC && callX.Type().NumResults() == 0 {
1569                 if c, ok := call.(*ir.CallExpr); ok && callX != nil && callX.Op() == ir.OCLOSURE {
1570                         clo := callX.(*ir.ClosureExpr)
1571                         clo.Func.SetClosureCalled(false)
1572                         clo.IsGoWrap = true
1573                         c.PreserveClosure = true
1574                 }
1575                 return
1576         }
1577
1578         if c, ok := call.(*ir.CallExpr); ok {
1579                 // To simplify things, turn f(a, b, []T{c, d, e}...) back
1580                 // into f(a, b, c, d, e) -- when the final call is run through the
1581                 // type checker below, it will rebuild the proper slice literal.
1582                 undoVariadic(c)
1583                 callX = c.X
1584                 callArgs = c.Args
1585         }
1586
1587         // This is set to true if the closure we're generating escapes
1588         // (needs heap allocation).
1589         cloEscapes := func() bool {
1590                 if n.Op() == ir.OGO {
1591                         // For "go", assume that all closures escape.
1592                         return true
1593                 }
1594                 // For defer, just use whatever result escape analysis
1595                 // has determined for the defer.
1596                 return n.Esc() != ir.EscNever
1597         }()
1598
1599         // A helper for making a copy of an argument. Note that it is
1600         // not safe to use o.copyExpr(arg) if we're putting a
1601         // reference to the temp into the closure (as opposed to
1602         // copying it in by value), since in the by-reference case we
1603         // need a temporary whose lifetime extends to the end of the
1604         // function (as opposed to being local to the current block or
1605         // statement being ordered).
1606         mkArgCopy := func(arg ir.Node) *ir.Name {
1607                 t := arg.Type()
1608                 byval := t.Size() <= 128 || cloEscapes
1609                 var argCopy *ir.Name
1610                 if byval {
1611                         argCopy = o.copyExpr(arg)
1612                 } else {
1613                         argCopy = typecheck.Temp(t)
1614                         o.append(ir.NewAssignStmt(base.Pos, argCopy, arg))
1615                 }
1616                 // The value of 128 below is meant to be consistent with code
1617                 // in escape analysis that picks byval/byaddr based on size.
1618                 argCopy.SetByval(byval)
1619                 return argCopy
1620         }
1621
1622         // getUnsafeArg looks for an unsafe.Pointer arg that has been
1623         // previously captured into the call's keepalive list, returning
1624         // the name node for it if found.
1625         getUnsafeArg := func(arg ir.Node) *ir.Name {
1626                 // Look for uintptr(unsafe.Pointer(name))
1627                 if arg.Op() != ir.OCONVNOP {
1628                         return nil
1629                 }
1630                 if !arg.Type().IsUintptr() {
1631                         return nil
1632                 }
1633                 if !arg.(*ir.ConvExpr).X.Type().IsUnsafePtr() {
1634                         return nil
1635                 }
1636                 arg = arg.(*ir.ConvExpr).X
1637                 argname, ok := arg.(*ir.Name)
1638                 if !ok {
1639                         return nil
1640                 }
1641                 for i := range keepAlive {
1642                         if argname == keepAlive[i] {
1643                                 return argname
1644                         }
1645                 }
1646                 return nil
1647         }
1648
1649         // Copy the arguments to the function into temps.
1650         //
1651         // For calls with uintptr(unsafe.Pointer(...)) args that are being
1652         // kept alive (see code in (*orderState).call that does this), use
1653         // the existing arg copy instead of creating a new copy.
1654         unsafeArgs := make([]*ir.Name, len(callArgs))
1655         origArgs := callArgs
1656         var newNames []*ir.Name
1657         for i := range callArgs {
1658                 arg := callArgs[i]
1659                 var argname *ir.Name
1660                 unsafeArgName := getUnsafeArg(arg)
1661                 if unsafeArgName != nil {
1662                         // arg has been copied already, use keepalive copy
1663                         argname = unsafeArgName
1664                         unsafeArgs[i] = unsafeArgName
1665                 } else {
1666                         argname = mkArgCopy(arg)
1667                 }
1668                 newNames = append(newNames, argname)
1669         }
1670
1671         // Deal with cases where the function expression (what we're
1672         // calling) is not a simple function symbol.
1673         var fnExpr *ir.Name
1674         var methSelectorExpr *ir.SelectorExpr
1675         if callX != nil {
1676                 switch {
1677                 case callX.Op() == ir.ODOTMETH || callX.Op() == ir.ODOTINTER:
1678                         // Handle defer of a method call, e.g. "defer v.MyMethod(x, y)"
1679                         n := callX.(*ir.SelectorExpr)
1680                         n.X = mkArgCopy(n.X)
1681                         methSelectorExpr = n
1682                         if callX.Op() == ir.ODOTINTER {
1683                                 // Currently for "defer i.M()" if i is nil it panics at the
1684                                 // point of defer statement, not when deferred function is called.
1685                                 // (I think there is an issue discussing what is the intended
1686                                 // behavior but I cannot find it.)
1687                                 // We need to do the nil check outside of the wrapper.
1688                                 tab := typecheck.Expr(ir.NewUnaryExpr(base.Pos, ir.OITAB, n.X))
1689                                 c := ir.NewUnaryExpr(n.Pos(), ir.OCHECKNIL, tab)
1690                                 c.SetTypecheck(1)
1691                                 o.append(c)
1692                         }
1693                 case !(callX.Op() == ir.ONAME && callX.(*ir.Name).Class == ir.PFUNC):
1694                         // Deal with "defer returnsafunc()(x, y)" (for
1695                         // example) by copying the callee expression.
1696                         fnExpr = mkArgCopy(callX)
1697                         if callX.Op() == ir.OCLOSURE {
1698                                 // For "defer func(...)", in addition to copying the
1699                                 // closure into a temp, mark it as no longer directly
1700                                 // called.
1701                                 callX.(*ir.ClosureExpr).Func.SetClosureCalled(false)
1702                         }
1703                 }
1704         }
1705
1706         // Create a new no-argument function that we'll hand off to defer.
1707         fn := ir.NewClosureFunc(base.Pos, true)
1708         fn.Nname.SetType(types.NewSignature(types.LocalPkg, nil, nil, nil, nil))
1709         fn.SetWrapper(true)
1710
1711         // helper for capturing reference to a var declared in an outer scope.
1712         capName := func(pos src.XPos, fn *ir.Func, n *ir.Name) *ir.Name {
1713                 t := n.Type()
1714                 cv := ir.CaptureName(pos, fn, n)
1715                 cv.SetType(t)
1716                 return typecheck.Expr(cv).(*ir.Name)
1717         }
1718
1719         // Call args (x1, y1) need to be captured as part of the newly
1720         // created closure.
1721         newCallArgs := []ir.Node{}
1722         for i := range newNames {
1723                 var arg ir.Node
1724                 arg = capName(callArgs[i].Pos(), fn, newNames[i])
1725                 if unsafeArgs[i] != nil {
1726                         arg = ir.NewConvExpr(arg.Pos(), origArgs[i].Op(), origArgs[i].Type(), arg)
1727                 }
1728                 newCallArgs = append(newCallArgs, arg)
1729         }
1730         // Also capture the function or method expression (if needed) into
1731         // the closure.
1732         if fnExpr != nil {
1733                 callX = capName(callX.Pos(), fn, fnExpr)
1734         }
1735         if methSelectorExpr != nil {
1736                 methSelectorExpr.X = capName(callX.Pos(), fn, methSelectorExpr.X.(*ir.Name))
1737         }
1738
1739         // This flags a builtin as opposed to a regular call.
1740         irregular := (call.Op() != ir.OCALLFUNC &&
1741                 call.Op() != ir.OCALLMETH &&
1742                 call.Op() != ir.OCALLINTER)
1743
1744         // Construct new function body:  f(x1, y1)
1745         op := ir.OCALL
1746         if irregular {
1747                 op = call.Op()
1748         }
1749         newcall := mkNewCall(call.Pos(), op, callX, newCallArgs)
1750
1751         // Finalize body, register function on the main decls list.
1752         fn.Body = []ir.Node{newcall}
1753         ir.FinishCaptureNames(n.Pos(), ir.CurFunc, fn)
1754
1755         // Create closure expr
1756         clo := typecheck.Expr(fn.OClosure).(*ir.ClosureExpr)
1757
1758         // Set escape properties for closure.
1759         if n.Op() == ir.OGO {
1760                 // For "go", assume that the closure is going to escape.
1761                 clo.SetEsc(ir.EscHeap)
1762                 clo.IsGoWrap = true
1763         } else {
1764                 // For defer, just use whatever result escape analysis
1765                 // has determined for the defer.
1766                 if n.Esc() == ir.EscNever {
1767                         clo.SetTransient(true)
1768                         clo.SetEsc(ir.EscNone)
1769                 }
1770         }
1771
1772         // Create new top level call to closure over argless function.
1773         topcall := ir.NewCallExpr(n.Pos(), ir.OCALL, clo, nil)
1774         typecheck.Call(topcall)
1775
1776         // Tag the call to insure that directClosureCall doesn't undo our work.
1777         topcall.PreserveClosure = true
1778
1779         fn.SetClosureCalled(false)
1780
1781         // Finally, point the defer statement at the newly generated call.
1782         n.Call = topcall
1783 }
1784
1785 // isFuncPCIntrinsic returns whether n is a direct call of internal/abi.FuncPCABIxxx functions.
1786 func isFuncPCIntrinsic(n *ir.CallExpr) bool {
1787         if n.Op() != ir.OCALLFUNC || n.X.Op() != ir.ONAME {
1788                 return false
1789         }
1790         fn := n.X.(*ir.Name).Sym()
1791         return (fn.Name == "FuncPCABI0" || fn.Name == "FuncPCABIInternal") &&
1792                 (fn.Pkg.Path == "internal/abi" || fn.Pkg == types.LocalPkg && base.Ctxt.Pkgpath == "internal/abi")
1793 }
1794
1795 // isIfaceOfFunc returns whether n is an interface conversion from a direct reference of a func.
1796 func isIfaceOfFunc(n ir.Node) bool {
1797         return n.Op() == ir.OCONVIFACE && n.(*ir.ConvExpr).X.Op() == ir.ONAME && n.(*ir.ConvExpr).X.(*ir.Name).Class == ir.PFUNC
1798 }