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