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