]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/compile/internal/walk/order.go
[dev.typeparams] cmd/compile: desugar ORECOVER into ORECOVERFP
[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.OCHECKNIL, ir.OCLOSE, ir.OPANIC, 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.ORECOVERFP:
781                 n := n.(*ir.CallExpr)
782                 t := o.markTemp()
783                 o.call(n)
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                 o.wrapGoDefer(n)
794                 o.out = append(o.out, n)
795                 o.cleanTemp(t)
796
797         case ir.ODELETE:
798                 n := n.(*ir.CallExpr)
799                 t := o.markTemp()
800                 n.Args[0] = o.expr(n.Args[0], nil)
801                 n.Args[1] = o.expr(n.Args[1], nil)
802                 n.Args[1] = o.mapKeyTemp(n.Args[0].Type(), n.Args[1])
803                 o.out = append(o.out, n)
804                 o.cleanTemp(t)
805
806         // Clean temporaries from condition evaluation at
807         // beginning of loop body and after for statement.
808         case ir.OFOR:
809                 n := n.(*ir.ForStmt)
810                 t := o.markTemp()
811                 n.Cond = o.exprInPlace(n.Cond)
812                 n.Body.Prepend(o.cleanTempNoPop(t)...)
813                 orderBlock(&n.Body, o.free)
814                 n.Post = orderStmtInPlace(n.Post, o.free)
815                 o.out = append(o.out, n)
816                 o.cleanTemp(t)
817
818         // Clean temporaries from condition at
819         // beginning of both branches.
820         case ir.OIF:
821                 n := n.(*ir.IfStmt)
822                 t := o.markTemp()
823                 n.Cond = o.exprInPlace(n.Cond)
824                 n.Body.Prepend(o.cleanTempNoPop(t)...)
825                 n.Else.Prepend(o.cleanTempNoPop(t)...)
826                 o.popTemp(t)
827                 orderBlock(&n.Body, o.free)
828                 orderBlock(&n.Else, o.free)
829                 o.out = append(o.out, n)
830
831         case ir.ORANGE:
832                 // n.Right is the expression being ranged over.
833                 // order it, and then make a copy if we need one.
834                 // We almost always do, to ensure that we don't
835                 // see any value changes made during the loop.
836                 // Usually the copy is cheap (e.g., array pointer,
837                 // chan, slice, string are all tiny).
838                 // The exception is ranging over an array value
839                 // (not a slice, not a pointer to array),
840                 // which must make a copy to avoid seeing updates made during
841                 // the range body. Ranging over an array value is uncommon though.
842
843                 // Mark []byte(str) range expression to reuse string backing storage.
844                 // It is safe because the storage cannot be mutated.
845                 n := n.(*ir.RangeStmt)
846                 if n.X.Op() == ir.OSTR2BYTES {
847                         n.X.(*ir.ConvExpr).SetOp(ir.OSTR2BYTESTMP)
848                 }
849
850                 t := o.markTemp()
851                 n.X = o.expr(n.X, nil)
852
853                 orderBody := true
854                 xt := typecheck.RangeExprType(n.X.Type())
855                 switch xt.Kind() {
856                 default:
857                         base.Fatalf("order.stmt range %v", n.Type())
858
859                 case types.TARRAY, types.TSLICE:
860                         if n.Value == nil || ir.IsBlank(n.Value) {
861                                 // for i := range x will only use x once, to compute len(x).
862                                 // No need to copy it.
863                                 break
864                         }
865                         fallthrough
866
867                 case types.TCHAN, types.TSTRING:
868                         // chan, string, slice, array ranges use value multiple times.
869                         // make copy.
870                         r := n.X
871
872                         if r.Type().IsString() && r.Type() != types.Types[types.TSTRING] {
873                                 r = ir.NewConvExpr(base.Pos, ir.OCONV, nil, r)
874                                 r.SetType(types.Types[types.TSTRING])
875                                 r = typecheck.Expr(r)
876                         }
877
878                         n.X = o.copyExpr(r)
879
880                 case types.TMAP:
881                         if isMapClear(n) {
882                                 // Preserve the body of the map clear pattern so it can
883                                 // be detected during walk. The loop body will not be used
884                                 // when optimizing away the range loop to a runtime call.
885                                 orderBody = false
886                                 break
887                         }
888
889                         // copy the map value in case it is a map literal.
890                         // TODO(rsc): Make tmp = literal expressions reuse tmp.
891                         // For maps tmp is just one word so it hardly matters.
892                         r := n.X
893                         n.X = o.copyExpr(r)
894
895                         // n.Prealloc is the temp for the iterator.
896                         // MapIterType contains pointers and needs to be zeroed.
897                         n.Prealloc = o.newTemp(reflectdata.MapIterType(xt), true)
898                 }
899                 n.Key = o.exprInPlace(n.Key)
900                 n.Value = o.exprInPlace(n.Value)
901                 if orderBody {
902                         orderBlock(&n.Body, o.free)
903                 }
904                 o.out = append(o.out, n)
905                 o.cleanTemp(t)
906
907         case ir.ORETURN:
908                 n := n.(*ir.ReturnStmt)
909                 o.exprList(n.Results)
910                 o.out = append(o.out, n)
911
912         // Special: clean case temporaries in each block entry.
913         // Select must enter one of its blocks, so there is no
914         // need for a cleaning at the end.
915         // Doubly special: evaluation order for select is stricter
916         // than ordinary expressions. Even something like p.c
917         // has to be hoisted into a temporary, so that it cannot be
918         // reordered after the channel evaluation for a different
919         // case (if p were nil, then the timing of the fault would
920         // give this away).
921         case ir.OSELECT:
922                 n := n.(*ir.SelectStmt)
923                 t := o.markTemp()
924                 for _, ncas := range n.Cases {
925                         r := ncas.Comm
926                         ir.SetPos(ncas)
927
928                         // Append any new body prologue to ninit.
929                         // The next loop will insert ninit into nbody.
930                         if len(ncas.Init()) != 0 {
931                                 base.Fatalf("order select ninit")
932                         }
933                         if r == nil {
934                                 continue
935                         }
936                         switch r.Op() {
937                         default:
938                                 ir.Dump("select case", r)
939                                 base.Fatalf("unknown op in select %v", r.Op())
940
941                         case ir.OSELRECV2:
942                                 // case x, ok = <-c
943                                 r := r.(*ir.AssignListStmt)
944                                 recv := r.Rhs[0].(*ir.UnaryExpr)
945                                 recv.X = o.expr(recv.X, nil)
946                                 if !ir.IsAutoTmp(recv.X) {
947                                         recv.X = o.copyExpr(recv.X)
948                                 }
949                                 init := ir.TakeInit(r)
950
951                                 colas := r.Def
952                                 do := func(i int, t *types.Type) {
953                                         n := r.Lhs[i]
954                                         if ir.IsBlank(n) {
955                                                 return
956                                         }
957                                         // If this is case x := <-ch or case x, y := <-ch, the case has
958                                         // the ODCL nodes to declare x and y. We want to delay that
959                                         // declaration (and possible allocation) until inside the case body.
960                                         // Delete the ODCL nodes here and recreate them inside the body below.
961                                         if colas {
962                                                 if len(init) > 0 && init[0].Op() == ir.ODCL && init[0].(*ir.Decl).X == n {
963                                                         init = init[1:]
964                                                 }
965                                                 dcl := typecheck.Stmt(ir.NewDecl(base.Pos, ir.ODCL, n.(*ir.Name)))
966                                                 ncas.PtrInit().Append(dcl)
967                                         }
968                                         tmp := o.newTemp(t, t.HasPointers())
969                                         as := typecheck.Stmt(ir.NewAssignStmt(base.Pos, n, typecheck.Conv(tmp, n.Type())))
970                                         ncas.PtrInit().Append(as)
971                                         r.Lhs[i] = tmp
972                                 }
973                                 do(0, recv.X.Type().Elem())
974                                 do(1, types.Types[types.TBOOL])
975                                 if len(init) != 0 {
976                                         ir.DumpList("ninit", r.Init())
977                                         base.Fatalf("ninit on select recv")
978                                 }
979                                 orderBlock(ncas.PtrInit(), o.free)
980
981                         case ir.OSEND:
982                                 r := r.(*ir.SendStmt)
983                                 if len(r.Init()) != 0 {
984                                         ir.DumpList("ninit", r.Init())
985                                         base.Fatalf("ninit on select send")
986                                 }
987
988                                 // case c <- x
989                                 // r->left is c, r->right is x, both are always evaluated.
990                                 r.Chan = o.expr(r.Chan, nil)
991
992                                 if !ir.IsAutoTmp(r.Chan) {
993                                         r.Chan = o.copyExpr(r.Chan)
994                                 }
995                                 r.Value = o.expr(r.Value, nil)
996                                 if !ir.IsAutoTmp(r.Value) {
997                                         r.Value = o.copyExpr(r.Value)
998                                 }
999                         }
1000                 }
1001                 // Now that we have accumulated all the temporaries, clean them.
1002                 // Also insert any ninit queued during the previous loop.
1003                 // (The temporary cleaning must follow that ninit work.)
1004                 for _, cas := range n.Cases {
1005                         orderBlock(&cas.Body, o.free)
1006                         cas.Body.Prepend(o.cleanTempNoPop(t)...)
1007
1008                         // TODO(mdempsky): Is this actually necessary?
1009                         // walkSelect appears to walk Ninit.
1010                         cas.Body.Prepend(ir.TakeInit(cas)...)
1011                 }
1012
1013                 o.out = append(o.out, n)
1014                 o.popTemp(t)
1015
1016         // Special: value being sent is passed as a pointer; make it addressable.
1017         case ir.OSEND:
1018                 n := n.(*ir.SendStmt)
1019                 t := o.markTemp()
1020                 n.Chan = o.expr(n.Chan, nil)
1021                 n.Value = o.expr(n.Value, nil)
1022                 if base.Flag.Cfg.Instrumenting {
1023                         // Force copying to the stack so that (chan T)(nil) <- x
1024                         // is still instrumented as a read of x.
1025                         n.Value = o.copyExpr(n.Value)
1026                 } else {
1027                         n.Value = o.addrTemp(n.Value)
1028                 }
1029                 o.out = append(o.out, n)
1030                 o.cleanTemp(t)
1031
1032         // TODO(rsc): Clean temporaries more aggressively.
1033         // Note that because walkSwitch will rewrite some of the
1034         // switch into a binary search, this is not as easy as it looks.
1035         // (If we ran that code here we could invoke order.stmt on
1036         // the if-else chain instead.)
1037         // For now just clean all the temporaries at the end.
1038         // In practice that's fine.
1039         case ir.OSWITCH:
1040                 n := n.(*ir.SwitchStmt)
1041                 if base.Debug.Libfuzzer != 0 && !hasDefaultCase(n) {
1042                         // Add empty "default:" case for instrumentation.
1043                         n.Cases = append(n.Cases, ir.NewCaseStmt(base.Pos, nil, nil))
1044                 }
1045
1046                 t := o.markTemp()
1047                 n.Tag = o.expr(n.Tag, nil)
1048                 for _, ncas := range n.Cases {
1049                         o.exprListInPlace(ncas.List)
1050                         orderBlock(&ncas.Body, o.free)
1051                 }
1052
1053                 o.out = append(o.out, n)
1054                 o.cleanTemp(t)
1055         }
1056
1057         base.Pos = lno
1058 }
1059
1060 func hasDefaultCase(n *ir.SwitchStmt) bool {
1061         for _, ncas := range n.Cases {
1062                 if len(ncas.List) == 0 {
1063                         return true
1064                 }
1065         }
1066         return false
1067 }
1068
1069 // exprList orders the expression list l into o.
1070 func (o *orderState) exprList(l ir.Nodes) {
1071         s := l
1072         for i := range s {
1073                 s[i] = o.expr(s[i], nil)
1074         }
1075 }
1076
1077 // exprListInPlace orders the expression list l but saves
1078 // the side effects on the individual expression ninit lists.
1079 func (o *orderState) exprListInPlace(l ir.Nodes) {
1080         s := l
1081         for i := range s {
1082                 s[i] = o.exprInPlace(s[i])
1083         }
1084 }
1085
1086 func (o *orderState) exprNoLHS(n ir.Node) ir.Node {
1087         return o.expr(n, nil)
1088 }
1089
1090 // expr orders a single expression, appending side
1091 // effects to o.out as needed.
1092 // If this is part of an assignment lhs = *np, lhs is given.
1093 // Otherwise lhs == nil. (When lhs != nil it may be possible
1094 // to avoid copying the result of the expression to a temporary.)
1095 // The result of expr MUST be assigned back to n, e.g.
1096 //      n.Left = o.expr(n.Left, lhs)
1097 func (o *orderState) expr(n, lhs ir.Node) ir.Node {
1098         if n == nil {
1099                 return n
1100         }
1101         lno := ir.SetPos(n)
1102         n = o.expr1(n, lhs)
1103         base.Pos = lno
1104         return n
1105 }
1106
1107 func (o *orderState) expr1(n, lhs ir.Node) ir.Node {
1108         o.init(n)
1109
1110         switch n.Op() {
1111         default:
1112                 if o.edit == nil {
1113                         o.edit = o.exprNoLHS // create closure once
1114                 }
1115                 ir.EditChildren(n, o.edit)
1116                 return n
1117
1118         // Addition of strings turns into a function call.
1119         // Allocate a temporary to hold the strings.
1120         // Fewer than 5 strings use direct runtime helpers.
1121         case ir.OADDSTR:
1122                 n := n.(*ir.AddStringExpr)
1123                 o.exprList(n.List)
1124
1125                 if len(n.List) > 5 {
1126                         t := types.NewArray(types.Types[types.TSTRING], int64(len(n.List)))
1127                         n.Prealloc = o.newTemp(t, false)
1128                 }
1129
1130                 // Mark string(byteSlice) arguments to reuse byteSlice backing
1131                 // buffer during conversion. String concatenation does not
1132                 // memorize the strings for later use, so it is safe.
1133                 // However, we can do it only if there is at least one non-empty string literal.
1134                 // Otherwise if all other arguments are empty strings,
1135                 // concatstrings will return the reference to the temp string
1136                 // to the caller.
1137                 hasbyte := false
1138
1139                 haslit := false
1140                 for _, n1 := range n.List {
1141                         hasbyte = hasbyte || n1.Op() == ir.OBYTES2STR
1142                         haslit = haslit || n1.Op() == ir.OLITERAL && len(ir.StringVal(n1)) != 0
1143                 }
1144
1145                 if haslit && hasbyte {
1146                         for _, n2 := range n.List {
1147                                 if n2.Op() == ir.OBYTES2STR {
1148                                         n2 := n2.(*ir.ConvExpr)
1149                                         n2.SetOp(ir.OBYTES2STRTMP)
1150                                 }
1151                         }
1152                 }
1153                 return n
1154
1155         case ir.OINDEXMAP:
1156                 n := n.(*ir.IndexExpr)
1157                 n.X = o.expr(n.X, nil)
1158                 n.Index = o.expr(n.Index, nil)
1159                 needCopy := false
1160
1161                 if !n.Assigned {
1162                         // Enforce that any []byte slices we are not copying
1163                         // can not be changed before the map index by forcing
1164                         // the map index to happen immediately following the
1165                         // conversions. See copyExpr a few lines below.
1166                         needCopy = mapKeyReplaceStrConv(n.Index)
1167
1168                         if base.Flag.Cfg.Instrumenting {
1169                                 // Race detector needs the copy.
1170                                 needCopy = true
1171                         }
1172                 }
1173
1174                 // key must be addressable
1175                 n.Index = o.mapKeyTemp(n.X.Type(), n.Index)
1176                 if needCopy {
1177                         return o.copyExpr(n)
1178                 }
1179                 return n
1180
1181         // concrete type (not interface) argument might need an addressable
1182         // temporary to pass to the runtime conversion routine.
1183         case ir.OCONVIFACE:
1184                 n := n.(*ir.ConvExpr)
1185                 n.X = o.expr(n.X, nil)
1186                 if n.X.Type().IsInterface() {
1187                         return n
1188                 }
1189                 if _, _, needsaddr := convFuncName(n.X.Type(), n.Type()); needsaddr || isStaticCompositeLiteral(n.X) {
1190                         // Need a temp if we need to pass the address to the conversion function.
1191                         // We also process static composite literal node here, making a named static global
1192                         // whose address we can put directly in an interface (see OCONVIFACE case in walk).
1193                         n.X = o.addrTemp(n.X)
1194                 }
1195                 return n
1196
1197         case ir.OCONVNOP:
1198                 n := n.(*ir.ConvExpr)
1199                 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) {
1200                         call := n.X.(*ir.CallExpr)
1201                         // When reordering unsafe.Pointer(f()) into a separate
1202                         // statement, the conversion and function call must stay
1203                         // together. See golang.org/issue/15329.
1204                         o.init(call)
1205                         o.call(call)
1206                         if lhs == nil || lhs.Op() != ir.ONAME || base.Flag.Cfg.Instrumenting {
1207                                 return o.copyExpr(n)
1208                         }
1209                 } else {
1210                         n.X = o.expr(n.X, nil)
1211                 }
1212                 return n
1213
1214         case ir.OANDAND, ir.OOROR:
1215                 // ... = LHS && RHS
1216                 //
1217                 // var r bool
1218                 // r = LHS
1219                 // if r {       // or !r, for OROR
1220                 //     r = RHS
1221                 // }
1222                 // ... = r
1223
1224                 n := n.(*ir.LogicalExpr)
1225                 r := o.newTemp(n.Type(), false)
1226
1227                 // Evaluate left-hand side.
1228                 lhs := o.expr(n.X, nil)
1229                 o.out = append(o.out, typecheck.Stmt(ir.NewAssignStmt(base.Pos, r, lhs)))
1230
1231                 // Evaluate right-hand side, save generated code.
1232                 saveout := o.out
1233                 o.out = nil
1234                 t := o.markTemp()
1235                 o.edge()
1236                 rhs := o.expr(n.Y, nil)
1237                 o.out = append(o.out, typecheck.Stmt(ir.NewAssignStmt(base.Pos, r, rhs)))
1238                 o.cleanTemp(t)
1239                 gen := o.out
1240                 o.out = saveout
1241
1242                 // If left-hand side doesn't cause a short-circuit, issue right-hand side.
1243                 nif := ir.NewIfStmt(base.Pos, r, nil, nil)
1244                 if n.Op() == ir.OANDAND {
1245                         nif.Body = gen
1246                 } else {
1247                         nif.Else = gen
1248                 }
1249                 o.out = append(o.out, nif)
1250                 return r
1251
1252         case ir.OCALLFUNC,
1253                 ir.OCALLINTER,
1254                 ir.OCALLMETH,
1255                 ir.OCAP,
1256                 ir.OCOMPLEX,
1257                 ir.OCOPY,
1258                 ir.OIMAG,
1259                 ir.OLEN,
1260                 ir.OMAKECHAN,
1261                 ir.OMAKEMAP,
1262                 ir.OMAKESLICE,
1263                 ir.OMAKESLICECOPY,
1264                 ir.ONEW,
1265                 ir.OREAL,
1266                 ir.ORECOVERFP,
1267                 ir.OSTR2BYTES,
1268                 ir.OSTR2BYTESTMP,
1269                 ir.OSTR2RUNES:
1270
1271                 if isRuneCount(n) {
1272                         // len([]rune(s)) is rewritten to runtime.countrunes(s) later.
1273                         conv := n.(*ir.UnaryExpr).X.(*ir.ConvExpr)
1274                         conv.X = o.expr(conv.X, nil)
1275                 } else {
1276                         o.call(n)
1277                 }
1278
1279                 if lhs == nil || lhs.Op() != ir.ONAME || base.Flag.Cfg.Instrumenting {
1280                         return o.copyExpr(n)
1281                 }
1282                 return n
1283
1284         case ir.OAPPEND:
1285                 // Check for append(x, make([]T, y)...) .
1286                 n := n.(*ir.CallExpr)
1287                 if isAppendOfMake(n) {
1288                         n.Args[0] = o.expr(n.Args[0], nil) // order x
1289                         mk := n.Args[1].(*ir.MakeExpr)
1290                         mk.Len = o.expr(mk.Len, nil) // order y
1291                 } else {
1292                         o.exprList(n.Args)
1293                 }
1294
1295                 if lhs == nil || lhs.Op() != ir.ONAME && !ir.SameSafeExpr(lhs, n.Args[0]) {
1296                         return o.copyExpr(n)
1297                 }
1298                 return n
1299
1300         case ir.OSLICE, ir.OSLICEARR, ir.OSLICESTR, ir.OSLICE3, ir.OSLICE3ARR:
1301                 n := n.(*ir.SliceExpr)
1302                 n.X = o.expr(n.X, nil)
1303                 n.Low = o.cheapExpr(o.expr(n.Low, nil))
1304                 n.High = o.cheapExpr(o.expr(n.High, nil))
1305                 n.Max = o.cheapExpr(o.expr(n.Max, nil))
1306                 if lhs == nil || lhs.Op() != ir.ONAME && !ir.SameSafeExpr(lhs, n.X) {
1307                         return o.copyExpr(n)
1308                 }
1309                 return n
1310
1311         case ir.OCLOSURE:
1312                 n := n.(*ir.ClosureExpr)
1313                 if n.Transient() && len(n.Func.ClosureVars) > 0 {
1314                         n.Prealloc = o.newTemp(typecheck.ClosureType(n), false)
1315                 }
1316                 return n
1317
1318         case ir.OCALLPART:
1319                 n := n.(*ir.SelectorExpr)
1320                 n.X = o.expr(n.X, nil)
1321                 if n.Transient() {
1322                         t := typecheck.PartialCallType(n)
1323                         n.Prealloc = o.newTemp(t, false)
1324                 }
1325                 return n
1326
1327         case ir.OSLICELIT:
1328                 n := n.(*ir.CompLitExpr)
1329                 o.exprList(n.List)
1330                 if n.Transient() {
1331                         t := types.NewArray(n.Type().Elem(), n.Len)
1332                         n.Prealloc = o.newTemp(t, false)
1333                 }
1334                 return n
1335
1336         case ir.ODOTTYPE, ir.ODOTTYPE2:
1337                 n := n.(*ir.TypeAssertExpr)
1338                 n.X = o.expr(n.X, nil)
1339                 if !types.IsDirectIface(n.Type()) || base.Flag.Cfg.Instrumenting {
1340                         return o.copyExprClear(n)
1341                 }
1342                 return n
1343
1344         case ir.ORECV:
1345                 n := n.(*ir.UnaryExpr)
1346                 n.X = o.expr(n.X, nil)
1347                 return o.copyExprClear(n)
1348
1349         case ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE:
1350                 n := n.(*ir.BinaryExpr)
1351                 n.X = o.expr(n.X, nil)
1352                 n.Y = o.expr(n.Y, nil)
1353
1354                 t := n.X.Type()
1355                 switch {
1356                 case t.IsString():
1357                         // Mark string(byteSlice) arguments to reuse byteSlice backing
1358                         // buffer during conversion. String comparison does not
1359                         // memorize the strings for later use, so it is safe.
1360                         if n.X.Op() == ir.OBYTES2STR {
1361                                 n.X.(*ir.ConvExpr).SetOp(ir.OBYTES2STRTMP)
1362                         }
1363                         if n.Y.Op() == ir.OBYTES2STR {
1364                                 n.Y.(*ir.ConvExpr).SetOp(ir.OBYTES2STRTMP)
1365                         }
1366
1367                 case t.IsStruct() || t.IsArray():
1368                         // for complex comparisons, we need both args to be
1369                         // addressable so we can pass them to the runtime.
1370                         n.X = o.addrTemp(n.X)
1371                         n.Y = o.addrTemp(n.Y)
1372                 }
1373                 return n
1374
1375         case ir.OMAPLIT:
1376                 // Order map by converting:
1377                 //   map[int]int{
1378                 //     a(): b(),
1379                 //     c(): d(),
1380                 //     e(): f(),
1381                 //   }
1382                 // to
1383                 //   m := map[int]int{}
1384                 //   m[a()] = b()
1385                 //   m[c()] = d()
1386                 //   m[e()] = f()
1387                 // Then order the result.
1388                 // Without this special case, order would otherwise compute all
1389                 // the keys and values before storing any of them to the map.
1390                 // See issue 26552.
1391                 n := n.(*ir.CompLitExpr)
1392                 entries := n.List
1393                 statics := entries[:0]
1394                 var dynamics []*ir.KeyExpr
1395                 for _, r := range entries {
1396                         r := r.(*ir.KeyExpr)
1397
1398                         if !isStaticCompositeLiteral(r.Key) || !isStaticCompositeLiteral(r.Value) {
1399                                 dynamics = append(dynamics, r)
1400                                 continue
1401                         }
1402
1403                         // Recursively ordering some static entries can change them to dynamic;
1404                         // e.g., OCONVIFACE nodes. See #31777.
1405                         r = o.expr(r, nil).(*ir.KeyExpr)
1406                         if !isStaticCompositeLiteral(r.Key) || !isStaticCompositeLiteral(r.Value) {
1407                                 dynamics = append(dynamics, r)
1408                                 continue
1409                         }
1410
1411                         statics = append(statics, r)
1412                 }
1413                 n.List = statics
1414
1415                 if len(dynamics) == 0 {
1416                         return n
1417                 }
1418
1419                 // Emit the creation of the map (with all its static entries).
1420                 m := o.newTemp(n.Type(), false)
1421                 as := ir.NewAssignStmt(base.Pos, m, n)
1422                 typecheck.Stmt(as)
1423                 o.stmt(as)
1424
1425                 // Emit eval+insert of dynamic entries, one at a time.
1426                 for _, r := range dynamics {
1427                         as := ir.NewAssignStmt(base.Pos, ir.NewIndexExpr(base.Pos, m, r.Key), r.Value)
1428                         typecheck.Stmt(as) // Note: this converts the OINDEX to an OINDEXMAP
1429                         o.stmt(as)
1430                 }
1431                 return m
1432         }
1433
1434         // No return - type-assertions above. Each case must return for itself.
1435 }
1436
1437 // as2func orders OAS2FUNC nodes. It creates temporaries to ensure left-to-right assignment.
1438 // The caller should order the right-hand side of the assignment before calling order.as2func.
1439 // It rewrites,
1440 //      a, b, a = ...
1441 // as
1442 //      tmp1, tmp2, tmp3 = ...
1443 //      a, b, a = tmp1, tmp2, tmp3
1444 // This is necessary to ensure left to right assignment order.
1445 func (o *orderState) as2func(n *ir.AssignListStmt) {
1446         results := n.Rhs[0].Type()
1447         as := ir.NewAssignListStmt(n.Pos(), ir.OAS2, nil, nil)
1448         for i, nl := range n.Lhs {
1449                 if !ir.IsBlank(nl) {
1450                         typ := results.Field(i).Type
1451                         tmp := o.newTemp(typ, typ.HasPointers())
1452                         n.Lhs[i] = tmp
1453                         as.Lhs = append(as.Lhs, nl)
1454                         as.Rhs = append(as.Rhs, tmp)
1455                 }
1456         }
1457
1458         o.out = append(o.out, n)
1459         o.stmt(typecheck.Stmt(as))
1460 }
1461
1462 // as2ok orders OAS2XXX with ok.
1463 // Just like as2func, this also adds temporaries to ensure left-to-right assignment.
1464 func (o *orderState) as2ok(n *ir.AssignListStmt) {
1465         as := ir.NewAssignListStmt(n.Pos(), ir.OAS2, nil, nil)
1466
1467         do := func(i int, typ *types.Type) {
1468                 if nl := n.Lhs[i]; !ir.IsBlank(nl) {
1469                         var tmp ir.Node = o.newTemp(typ, typ.HasPointers())
1470                         n.Lhs[i] = tmp
1471                         as.Lhs = append(as.Lhs, nl)
1472                         if i == 1 {
1473                                 // The "ok" result is an untyped boolean according to the Go
1474                                 // spec. We need to explicitly convert it to the LHS type in
1475                                 // case the latter is a defined boolean type (#8475).
1476                                 tmp = typecheck.Conv(tmp, nl.Type())
1477                         }
1478                         as.Rhs = append(as.Rhs, tmp)
1479                 }
1480         }
1481
1482         do(0, n.Rhs[0].Type())
1483         do(1, types.Types[types.TBOOL])
1484
1485         o.out = append(o.out, n)
1486         o.stmt(typecheck.Stmt(as))
1487 }
1488
1489 var wrapGoDefer_prgen int
1490
1491 // wrapGoDefer wraps the target of a "go" or "defer" statement with a
1492 // new "function with no arguments" closure. Specifically, it converts
1493 //
1494 //   defer f(x, y)
1495 //
1496 // to
1497 //
1498 //   x1, y1 := x, y
1499 //   defer func() { f(x1, y1) }()
1500 //
1501 // This is primarily to enable a quicker bringup of defers under the
1502 // new register ABI; by doing this conversion, we can simplify the
1503 // code in the runtime that invokes defers on the panic path.
1504 func (o *orderState) wrapGoDefer(n *ir.GoDeferStmt) {
1505         call := n.Call
1506
1507         var callX ir.Node        // thing being called
1508         var callArgs []ir.Node   // call arguments
1509         var keepAlive []*ir.Name // KeepAlive list from call, if present
1510
1511         // A helper to recreate the call within the closure.
1512         var mkNewCall func(pos src.XPos, op ir.Op, fun ir.Node, args []ir.Node) ir.Node
1513
1514         // Defer calls come in many shapes and sizes; not all of them
1515         // are ir.CallExpr's. Examine the type to see what we're dealing with.
1516         switch x := call.(type) {
1517         case *ir.CallExpr:
1518                 callX = x.X
1519                 callArgs = x.Args
1520                 keepAlive = x.KeepAlive
1521                 mkNewCall = func(pos src.XPos, op ir.Op, fun ir.Node, args []ir.Node) ir.Node {
1522                         newcall := ir.NewCallExpr(pos, op, fun, args)
1523                         newcall.IsDDD = x.IsDDD
1524                         return ir.Node(newcall)
1525                 }
1526         case *ir.UnaryExpr: // ex: OCLOSE
1527                 callArgs = []ir.Node{x.X}
1528                 mkNewCall = func(pos src.XPos, op ir.Op, fun ir.Node, args []ir.Node) ir.Node {
1529                         if len(args) != 1 {
1530                                 panic("internal error, expecting single arg")
1531                         }
1532                         return ir.Node(ir.NewUnaryExpr(pos, op, args[0]))
1533                 }
1534         case *ir.BinaryExpr: // ex: OCOPY
1535                 callArgs = []ir.Node{x.X, x.Y}
1536                 mkNewCall = func(pos src.XPos, op ir.Op, fun ir.Node, args []ir.Node) ir.Node {
1537                         if len(args) != 2 {
1538                                 panic("internal error, expecting two args")
1539                         }
1540                         return ir.Node(ir.NewBinaryExpr(pos, op, args[0], args[1]))
1541                 }
1542         default:
1543                 panic("unhandled op")
1544         }
1545
1546         // No need to wrap if called func has no args, no receiver, and no results.
1547         // However in the case of "defer func() { ... }()" we need to
1548         // protect against the possibility of directClosureCall rewriting
1549         // things so that the call does have arguments.
1550         //
1551         // Do wrap method calls (OCALLMETH, OCALLINTER), because it has
1552         // a receiver.
1553         //
1554         // Also do wrap builtin functions, because they may be expanded to
1555         // calls with arguments (e.g. ORECOVER).
1556         //
1557         // TODO: maybe not wrap if the called function has no arguments and
1558         // only in-register results?
1559         if len(callArgs) == 0 && call.Op() == ir.OCALLFUNC && callX.Type().NumResults() == 0 {
1560                 if callX.Op() == ir.OCLOSURE {
1561                         clo := callX.(*ir.ClosureExpr)
1562                         clo.IsGoWrap = true
1563                 }
1564                 return
1565         }
1566
1567         if c, ok := call.(*ir.CallExpr); ok {
1568                 // To simplify things, turn f(a, b, []T{c, d, e}...) back
1569                 // into f(a, b, c, d, e) -- when the final call is run through the
1570                 // type checker below, it will rebuild the proper slice literal.
1571                 undoVariadic(c)
1572                 callX = c.X
1573                 callArgs = c.Args
1574         }
1575
1576         // This is set to true if the closure we're generating escapes
1577         // (needs heap allocation).
1578         cloEscapes := func() bool {
1579                 if n.Op() == ir.OGO {
1580                         // For "go", assume that all closures escape.
1581                         return true
1582                 }
1583                 // For defer, just use whatever result escape analysis
1584                 // has determined for the defer.
1585                 return n.Esc() != ir.EscNever
1586         }()
1587
1588         // A helper for making a copy of an argument. Note that it is
1589         // not safe to use o.copyExpr(arg) if we're putting a
1590         // reference to the temp into the closure (as opposed to
1591         // copying it in by value), since in the by-reference case we
1592         // need a temporary whose lifetime extends to the end of the
1593         // function (as opposed to being local to the current block or
1594         // statement being ordered).
1595         mkArgCopy := func(arg ir.Node) *ir.Name {
1596                 t := arg.Type()
1597                 byval := t.Size() <= 128 || cloEscapes
1598                 var argCopy *ir.Name
1599                 if byval {
1600                         argCopy = o.copyExpr(arg)
1601                 } else {
1602                         argCopy = typecheck.Temp(t)
1603                         o.append(ir.NewAssignStmt(base.Pos, argCopy, arg))
1604                 }
1605                 // The value of 128 below is meant to be consistent with code
1606                 // in escape analysis that picks byval/byaddr based on size.
1607                 argCopy.SetByval(byval)
1608                 return argCopy
1609         }
1610
1611         // getUnsafeArg looks for an unsafe.Pointer arg that has been
1612         // previously captured into the call's keepalive list, returning
1613         // the name node for it if found.
1614         getUnsafeArg := func(arg ir.Node) *ir.Name {
1615                 // Look for uintptr(unsafe.Pointer(name))
1616                 if arg.Op() != ir.OCONVNOP {
1617                         return nil
1618                 }
1619                 if !arg.Type().IsUintptr() {
1620                         return nil
1621                 }
1622                 if !arg.(*ir.ConvExpr).X.Type().IsUnsafePtr() {
1623                         return nil
1624                 }
1625                 arg = arg.(*ir.ConvExpr).X
1626                 argname, ok := arg.(*ir.Name)
1627                 if !ok {
1628                         return nil
1629                 }
1630                 for i := range keepAlive {
1631                         if argname == keepAlive[i] {
1632                                 return argname
1633                         }
1634                 }
1635                 return nil
1636         }
1637
1638         // Copy the arguments to the function into temps.
1639         //
1640         // For calls with uintptr(unsafe.Pointer(...)) args that are being
1641         // kept alive (see code in (*orderState).call that does this), use
1642         // the existing arg copy instead of creating a new copy.
1643         unsafeArgs := make([]*ir.Name, len(callArgs))
1644         origArgs := callArgs
1645         var newNames []*ir.Name
1646         for i := range callArgs {
1647                 arg := callArgs[i]
1648                 var argname *ir.Name
1649                 unsafeArgName := getUnsafeArg(arg)
1650                 if unsafeArgName != nil {
1651                         // arg has been copied already, use keepalive copy
1652                         argname = unsafeArgName
1653                         unsafeArgs[i] = unsafeArgName
1654                 } else {
1655                         argname = mkArgCopy(arg)
1656                 }
1657                 newNames = append(newNames, argname)
1658         }
1659
1660         // Deal with cases where the function expression (what we're
1661         // calling) is not a simple function symbol.
1662         var fnExpr *ir.Name
1663         var methSelectorExpr *ir.SelectorExpr
1664         if callX != nil {
1665                 switch {
1666                 case callX.Op() == ir.ODOTMETH || callX.Op() == ir.ODOTINTER:
1667                         // Handle defer of a method call, e.g. "defer v.MyMethod(x, y)"
1668                         n := callX.(*ir.SelectorExpr)
1669                         n.X = mkArgCopy(n.X)
1670                         methSelectorExpr = n
1671                         if callX.Op() == ir.ODOTINTER {
1672                                 // Currently for "defer i.M()" if i is nil it panics at the
1673                                 // point of defer statement, not when deferred function is called.
1674                                 // (I think there is an issue discussing what is the intended
1675                                 // behavior but I cannot find it.)
1676                                 // We need to do the nil check outside of the wrapper.
1677                                 tab := typecheck.Expr(ir.NewUnaryExpr(base.Pos, ir.OITAB, n.X))
1678                                 c := ir.NewUnaryExpr(n.Pos(), ir.OCHECKNIL, tab)
1679                                 c.SetTypecheck(1)
1680                                 o.append(c)
1681                         }
1682                 case !(callX.Op() == ir.ONAME && callX.(*ir.Name).Class == ir.PFUNC):
1683                         // Deal with "defer returnsafunc()(x, y)" (for
1684                         // example) by copying the callee expression.
1685                         fnExpr = mkArgCopy(callX)
1686                 }
1687         }
1688
1689         // Create a new no-argument function that we'll hand off to defer.
1690         fn := ir.NewClosureFunc(base.Pos, true)
1691         fn.Nname.SetType(types.NewSignature(types.LocalPkg, nil, nil, nil, nil))
1692         fn.SetWrapper(true)
1693
1694         // helper for capturing reference to a var declared in an outer scope.
1695         capName := func(pos src.XPos, fn *ir.Func, n *ir.Name) *ir.Name {
1696                 t := n.Type()
1697                 cv := ir.CaptureName(pos, fn, n)
1698                 cv.SetType(t)
1699                 return typecheck.Expr(cv).(*ir.Name)
1700         }
1701
1702         // Call args (x1, y1) need to be captured as part of the newly
1703         // created closure.
1704         newCallArgs := []ir.Node{}
1705         for i := range newNames {
1706                 var arg ir.Node
1707                 arg = capName(callArgs[i].Pos(), fn, newNames[i])
1708                 if unsafeArgs[i] != nil {
1709                         arg = ir.NewConvExpr(arg.Pos(), origArgs[i].Op(), origArgs[i].Type(), arg)
1710                 }
1711                 newCallArgs = append(newCallArgs, arg)
1712         }
1713         // Also capture the function or method expression (if needed) into
1714         // the closure.
1715         if fnExpr != nil {
1716                 callX = capName(callX.Pos(), fn, fnExpr)
1717         }
1718         if methSelectorExpr != nil {
1719                 methSelectorExpr.X = capName(callX.Pos(), fn, methSelectorExpr.X.(*ir.Name))
1720         }
1721
1722         // This flags a builtin as opposed to a regular call.
1723         irregular := (call.Op() != ir.OCALLFUNC &&
1724                 call.Op() != ir.OCALLMETH &&
1725                 call.Op() != ir.OCALLINTER)
1726
1727         // Construct new function body:  f(x1, y1)
1728         op := ir.OCALL
1729         if irregular {
1730                 op = call.Op()
1731         }
1732         newcall := mkNewCall(call.Pos(), op, callX, newCallArgs)
1733
1734         // Finalize body, register function on the main decls list.
1735         fn.Body = []ir.Node{newcall}
1736         ir.FinishCaptureNames(n.Pos(), ir.CurFunc, fn)
1737
1738         // Create closure expr
1739         clo := typecheck.Expr(fn.OClosure).(*ir.ClosureExpr)
1740
1741         // Set escape properties for closure.
1742         if n.Op() == ir.OGO {
1743                 // For "go", assume that the closure is going to escape.
1744                 clo.SetEsc(ir.EscHeap)
1745                 clo.IsGoWrap = true
1746         } else {
1747                 // For defer, just use whatever result escape analysis
1748                 // has determined for the defer.
1749                 if n.Esc() == ir.EscNever {
1750                         clo.SetTransient(true)
1751                         clo.SetEsc(ir.EscNone)
1752                 }
1753         }
1754
1755         // Create new top level call to closure over argless function.
1756         topcall := ir.NewCallExpr(n.Pos(), ir.OCALL, clo, nil)
1757         typecheck.Call(topcall)
1758
1759         // Finally, point the defer statement at the newly generated call.
1760         n.Call = topcall
1761 }
1762
1763 // isFuncPCIntrinsic returns whether n is a direct call of internal/abi.FuncPCABIxxx functions.
1764 func isFuncPCIntrinsic(n *ir.CallExpr) bool {
1765         if n.Op() != ir.OCALLFUNC || n.X.Op() != ir.ONAME {
1766                 return false
1767         }
1768         fn := n.X.(*ir.Name).Sym()
1769         return (fn.Name == "FuncPCABI0" || fn.Name == "FuncPCABIInternal") &&
1770                 (fn.Pkg.Path == "internal/abi" || fn.Pkg == types.LocalPkg && base.Ctxt.Pkgpath == "internal/abi")
1771 }
1772
1773 // isIfaceOfFunc returns whether n is an interface conversion from a direct reference of a func.
1774 func isIfaceOfFunc(n ir.Node) bool {
1775         return n.Op() == ir.OCONVIFACE && n.(*ir.ConvExpr).X.Op() == ir.ONAME && n.(*ir.ConvExpr).X.(*ir.Name).Class == ir.PFUNC
1776 }