]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/compile/internal/walk/order.go
[dev.fuzz] all: merge master (7764ee5) into dev.fuzz
[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
10         "cmd/compile/internal/base"
11         "cmd/compile/internal/escape"
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         if mapfast(t) == mapslow {
272                 return o.addrTemp(n)
273         }
274         return n
275 }
276
277 // mapKeyReplaceStrConv replaces OBYTES2STR by OBYTES2STRTMP
278 // in n to avoid string allocations for keys in map lookups.
279 // Returns a bool that signals if a modification was made.
280 //
281 // For:
282 //  x = m[string(k)]
283 //  x = m[T1{... Tn{..., string(k), ...}]
284 // where k is []byte, T1 to Tn is a nesting of struct and array literals,
285 // the allocation of backing bytes for the string can be avoided
286 // by reusing the []byte backing array. These are special cases
287 // for avoiding allocations when converting byte slices to strings.
288 // It would be nice to handle these generally, but because
289 // []byte keys are not allowed in maps, the use of string(k)
290 // comes up in important cases in practice. See issue 3512.
291 func mapKeyReplaceStrConv(n ir.Node) bool {
292         var replaced bool
293         switch n.Op() {
294         case ir.OBYTES2STR:
295                 n := n.(*ir.ConvExpr)
296                 n.SetOp(ir.OBYTES2STRTMP)
297                 replaced = true
298         case ir.OSTRUCTLIT:
299                 n := n.(*ir.CompLitExpr)
300                 for _, elem := range n.List {
301                         elem := elem.(*ir.StructKeyExpr)
302                         if mapKeyReplaceStrConv(elem.Value) {
303                                 replaced = true
304                         }
305                 }
306         case ir.OARRAYLIT:
307                 n := n.(*ir.CompLitExpr)
308                 for _, elem := range n.List {
309                         if elem.Op() == ir.OKEY {
310                                 elem = elem.(*ir.KeyExpr).Value
311                         }
312                         if mapKeyReplaceStrConv(elem) {
313                                 replaced = true
314                         }
315                 }
316         }
317         return replaced
318 }
319
320 type ordermarker int
321
322 // markTemp returns the top of the temporary variable stack.
323 func (o *orderState) markTemp() ordermarker {
324         return ordermarker(len(o.temp))
325 }
326
327 // popTemp pops temporaries off the stack until reaching the mark,
328 // which must have been returned by markTemp.
329 func (o *orderState) popTemp(mark ordermarker) {
330         for _, n := range o.temp[mark:] {
331                 key := n.Type().LongString()
332                 o.free[key] = append(o.free[key], n)
333         }
334         o.temp = o.temp[:mark]
335 }
336
337 // cleanTempNoPop emits VARKILL instructions to *out
338 // for each temporary above the mark on the temporary stack.
339 // It does not pop the temporaries from the stack.
340 func (o *orderState) cleanTempNoPop(mark ordermarker) []ir.Node {
341         var out []ir.Node
342         for i := len(o.temp) - 1; i >= int(mark); i-- {
343                 n := o.temp[i]
344                 out = append(out, typecheck.Stmt(ir.NewUnaryExpr(base.Pos, ir.OVARKILL, n)))
345         }
346         return out
347 }
348
349 // cleanTemp emits VARKILL instructions for each temporary above the
350 // mark on the temporary stack and removes them from the stack.
351 func (o *orderState) cleanTemp(top ordermarker) {
352         o.out = append(o.out, o.cleanTempNoPop(top)...)
353         o.popTemp(top)
354 }
355
356 // stmtList orders each of the statements in the list.
357 func (o *orderState) stmtList(l ir.Nodes) {
358         s := l
359         for i := range s {
360                 orderMakeSliceCopy(s[i:])
361                 o.stmt(s[i])
362         }
363 }
364
365 // orderMakeSliceCopy matches the pattern:
366 //  m = OMAKESLICE([]T, x); OCOPY(m, s)
367 // and rewrites it to:
368 //  m = OMAKESLICECOPY([]T, x, s); nil
369 func orderMakeSliceCopy(s []ir.Node) {
370         if base.Flag.N != 0 || base.Flag.Cfg.Instrumenting {
371                 return
372         }
373         if len(s) < 2 || s[0] == nil || s[0].Op() != ir.OAS || s[1] == nil || s[1].Op() != ir.OCOPY {
374                 return
375         }
376
377         as := s[0].(*ir.AssignStmt)
378         cp := s[1].(*ir.BinaryExpr)
379         if as.Y == nil || as.Y.Op() != ir.OMAKESLICE || ir.IsBlank(as.X) ||
380                 as.X.Op() != ir.ONAME || cp.X.Op() != ir.ONAME || cp.Y.Op() != ir.ONAME ||
381                 as.X.Name() != cp.X.Name() || cp.X.Name() == cp.Y.Name() {
382                 // The line above this one is correct with the differing equality operators:
383                 // we want as.X and cp.X to be the same name,
384                 // but we want the initial data to be coming from a different name.
385                 return
386         }
387
388         mk := as.Y.(*ir.MakeExpr)
389         if mk.Esc() == ir.EscNone || mk.Len == nil || mk.Cap != nil {
390                 return
391         }
392         mk.SetOp(ir.OMAKESLICECOPY)
393         mk.Cap = cp.Y
394         // Set bounded when m = OMAKESLICE([]T, len(s)); OCOPY(m, s)
395         mk.SetBounded(mk.Len.Op() == ir.OLEN && ir.SameSafeExpr(mk.Len.(*ir.UnaryExpr).X, cp.Y))
396         as.Y = typecheck.Expr(mk)
397         s[1] = nil // remove separate copy call
398 }
399
400 // edge inserts coverage instrumentation for libfuzzer.
401 func (o *orderState) edge() {
402         if base.Debug.Libfuzzer == 0 {
403                 return
404         }
405
406         // Create a new uint8 counter to be allocated in section
407         // __libfuzzer_extra_counters.
408         counter := staticinit.StaticName(types.Types[types.TUINT8])
409         counter.SetLibfuzzerExtraCounter(true)
410
411         // counter += 1
412         incr := ir.NewAssignOpStmt(base.Pos, ir.OADD, counter, ir.NewInt(1))
413         o.append(incr)
414 }
415
416 // orderBlock orders the block of statements in n into a new slice,
417 // and then replaces the old slice in n with the new slice.
418 // free is a map that can be used to obtain temporary variables by type.
419 func orderBlock(n *ir.Nodes, free map[string][]*ir.Name) {
420         var order orderState
421         order.free = free
422         mark := order.markTemp()
423         order.edge()
424         order.stmtList(*n)
425         order.cleanTemp(mark)
426         *n = order.out
427 }
428
429 // exprInPlace orders the side effects in *np and
430 // leaves them as the init list of the final *np.
431 // The result of exprInPlace MUST be assigned back to n, e.g.
432 //      n.Left = o.exprInPlace(n.Left)
433 func (o *orderState) exprInPlace(n ir.Node) ir.Node {
434         var order orderState
435         order.free = o.free
436         n = order.expr(n, nil)
437         n = ir.InitExpr(order.out, n)
438
439         // insert new temporaries from order
440         // at head of outer list.
441         o.temp = append(o.temp, order.temp...)
442         return n
443 }
444
445 // orderStmtInPlace orders the side effects of the single statement *np
446 // and replaces it with the resulting statement list.
447 // The result of orderStmtInPlace MUST be assigned back to n, e.g.
448 //      n.Left = orderStmtInPlace(n.Left)
449 // free is a map that can be used to obtain temporary variables by type.
450 func orderStmtInPlace(n ir.Node, free map[string][]*ir.Name) ir.Node {
451         var order orderState
452         order.free = free
453         mark := order.markTemp()
454         order.stmt(n)
455         order.cleanTemp(mark)
456         return ir.NewBlockStmt(src.NoXPos, order.out)
457 }
458
459 // init moves n's init list to o.out.
460 func (o *orderState) init(n ir.Node) {
461         if ir.MayBeShared(n) {
462                 // For concurrency safety, don't mutate potentially shared nodes.
463                 // First, ensure that no work is required here.
464                 if len(n.Init()) > 0 {
465                         base.Fatalf("order.init shared node with ninit")
466                 }
467                 return
468         }
469         o.stmtList(ir.TakeInit(n))
470 }
471
472 // call orders the call expression n.
473 // n.Op is OCALLMETH/OCALLFUNC/OCALLINTER or a builtin like OCOPY.
474 func (o *orderState) call(nn ir.Node) {
475         if len(nn.Init()) > 0 {
476                 // Caller should have already called o.init(nn).
477                 base.Fatalf("%v with unexpected ninit", nn.Op())
478         }
479
480         // Builtin functions.
481         if nn.Op() != ir.OCALLFUNC && nn.Op() != ir.OCALLMETH && nn.Op() != ir.OCALLINTER {
482                 switch n := nn.(type) {
483                 default:
484                         base.Fatalf("unexpected call: %+v", n)
485                 case *ir.UnaryExpr:
486                         n.X = o.expr(n.X, nil)
487                 case *ir.ConvExpr:
488                         n.X = o.expr(n.X, nil)
489                 case *ir.BinaryExpr:
490                         n.X = o.expr(n.X, nil)
491                         n.Y = o.expr(n.Y, nil)
492                 case *ir.MakeExpr:
493                         n.Len = o.expr(n.Len, nil)
494                         n.Cap = o.expr(n.Cap, nil)
495                 case *ir.CallExpr:
496                         o.exprList(n.Args)
497                 }
498                 return
499         }
500
501         n := nn.(*ir.CallExpr)
502         typecheck.FixVariadicCall(n)
503         n.X = o.expr(n.X, nil)
504         o.exprList(n.Args)
505
506         if n.Op() == ir.OCALLINTER {
507                 return
508         }
509         keepAlive := func(arg ir.Node) {
510                 // If the argument is really a pointer being converted to uintptr,
511                 // arrange for the pointer to be kept alive until the call returns,
512                 // by copying it into a temp and marking that temp
513                 // still alive when we pop the temp stack.
514                 if arg.Op() == ir.OCONVNOP {
515                         arg := arg.(*ir.ConvExpr)
516                         if arg.X.Type().IsUnsafePtr() {
517                                 x := o.copyExpr(arg.X)
518                                 arg.X = x
519                                 x.SetAddrtaken(true) // ensure SSA keeps the x variable
520                                 n.KeepAlive = append(n.KeepAlive, x)
521                         }
522                 }
523         }
524
525         // Check for "unsafe-uintptr" tag provided by escape analysis.
526         for i, param := range n.X.Type().Params().FieldSlice() {
527                 if param.Note == escape.UnsafeUintptrNote || param.Note == escape.UintptrEscapesNote {
528                         if arg := n.Args[i]; arg.Op() == ir.OSLICELIT {
529                                 arg := arg.(*ir.CompLitExpr)
530                                 for _, elt := range arg.List {
531                                         keepAlive(elt)
532                                 }
533                         } else {
534                                 keepAlive(arg)
535                         }
536                 }
537         }
538 }
539
540 // mapAssign appends n to o.out.
541 func (o *orderState) mapAssign(n ir.Node) {
542         switch n.Op() {
543         default:
544                 base.Fatalf("order.mapAssign %v", n.Op())
545
546         case ir.OAS:
547                 n := n.(*ir.AssignStmt)
548                 if n.X.Op() == ir.OINDEXMAP {
549                         n.Y = o.safeMapRHS(n.Y)
550                 }
551                 o.out = append(o.out, n)
552         case ir.OASOP:
553                 n := n.(*ir.AssignOpStmt)
554                 if n.X.Op() == ir.OINDEXMAP {
555                         n.Y = o.safeMapRHS(n.Y)
556                 }
557                 o.out = append(o.out, n)
558         }
559 }
560
561 func (o *orderState) safeMapRHS(r ir.Node) ir.Node {
562         // Make sure we evaluate the RHS before starting the map insert.
563         // We need to make sure the RHS won't panic.  See issue 22881.
564         if r.Op() == ir.OAPPEND {
565                 r := r.(*ir.CallExpr)
566                 s := r.Args[1:]
567                 for i, n := range s {
568                         s[i] = o.cheapExpr(n)
569                 }
570                 return r
571         }
572         return o.cheapExpr(r)
573 }
574
575 // stmt orders the statement n, appending to o.out.
576 // Temporaries created during the statement are cleaned
577 // up using VARKILL instructions as possible.
578 func (o *orderState) stmt(n ir.Node) {
579         if n == nil {
580                 return
581         }
582
583         lno := ir.SetPos(n)
584         o.init(n)
585
586         switch n.Op() {
587         default:
588                 base.Fatalf("order.stmt %v", n.Op())
589
590         case ir.OVARKILL, ir.OVARLIVE, ir.OINLMARK:
591                 o.out = append(o.out, n)
592
593         case ir.OAS:
594                 n := n.(*ir.AssignStmt)
595                 t := o.markTemp()
596                 n.X = o.expr(n.X, nil)
597                 n.Y = o.expr(n.Y, n.X)
598                 o.mapAssign(n)
599                 o.cleanTemp(t)
600
601         case ir.OASOP:
602                 n := n.(*ir.AssignOpStmt)
603                 t := o.markTemp()
604                 n.X = o.expr(n.X, nil)
605                 n.Y = o.expr(n.Y, nil)
606
607                 if base.Flag.Cfg.Instrumenting || n.X.Op() == ir.OINDEXMAP && (n.AsOp == ir.ODIV || n.AsOp == ir.OMOD) {
608                         // Rewrite m[k] op= r into m[k] = m[k] op r so
609                         // that we can ensure that if op panics
610                         // because r is zero, the panic happens before
611                         // the map assignment.
612                         // DeepCopy is a big hammer here, but safeExpr
613                         // makes sure there is nothing too deep being copied.
614                         l1 := o.safeExpr(n.X)
615                         l2 := ir.DeepCopy(src.NoXPos, l1)
616                         if l2.Op() == ir.OINDEXMAP {
617                                 l2 := l2.(*ir.IndexExpr)
618                                 l2.Assigned = false
619                         }
620                         l2 = o.copyExpr(l2)
621                         r := o.expr(typecheck.Expr(ir.NewBinaryExpr(n.Pos(), n.AsOp, l2, n.Y)), nil)
622                         as := typecheck.Stmt(ir.NewAssignStmt(n.Pos(), l1, r))
623                         o.mapAssign(as)
624                         o.cleanTemp(t)
625                         return
626                 }
627
628                 o.mapAssign(n)
629                 o.cleanTemp(t)
630
631         case ir.OAS2:
632                 n := n.(*ir.AssignListStmt)
633                 t := o.markTemp()
634                 o.exprList(n.Lhs)
635                 o.exprList(n.Rhs)
636                 o.out = append(o.out, n)
637                 o.cleanTemp(t)
638
639         // Special: avoid copy of func call n.Right
640         case ir.OAS2FUNC:
641                 n := n.(*ir.AssignListStmt)
642                 t := o.markTemp()
643                 o.exprList(n.Lhs)
644                 o.init(n.Rhs[0])
645                 o.call(n.Rhs[0])
646                 o.as2func(n)
647                 o.cleanTemp(t)
648
649         // Special: use temporary variables to hold result,
650         // so that runtime can take address of temporary.
651         // No temporary for blank assignment.
652         //
653         // OAS2MAPR: make sure key is addressable if needed,
654         //           and make sure OINDEXMAP is not copied out.
655         case ir.OAS2DOTTYPE, ir.OAS2RECV, ir.OAS2MAPR:
656                 n := n.(*ir.AssignListStmt)
657                 t := o.markTemp()
658                 o.exprList(n.Lhs)
659
660                 switch r := n.Rhs[0]; r.Op() {
661                 case ir.ODOTTYPE2:
662                         r := r.(*ir.TypeAssertExpr)
663                         r.X = o.expr(r.X, nil)
664                 case ir.ORECV:
665                         r := r.(*ir.UnaryExpr)
666                         r.X = o.expr(r.X, nil)
667                 case ir.OINDEXMAP:
668                         r := r.(*ir.IndexExpr)
669                         r.X = o.expr(r.X, nil)
670                         r.Index = o.expr(r.Index, nil)
671                         // See similar conversion for OINDEXMAP below.
672                         _ = mapKeyReplaceStrConv(r.Index)
673                         r.Index = o.mapKeyTemp(r.X.Type(), r.Index)
674                 default:
675                         base.Fatalf("order.stmt: %v", r.Op())
676                 }
677
678                 o.as2ok(n)
679                 o.cleanTemp(t)
680
681         // Special: does not save n onto out.
682         case ir.OBLOCK:
683                 n := n.(*ir.BlockStmt)
684                 o.stmtList(n.List)
685
686         // Special: n->left is not an expression; save as is.
687         case ir.OBREAK,
688                 ir.OCONTINUE,
689                 ir.ODCL,
690                 ir.ODCLCONST,
691                 ir.ODCLTYPE,
692                 ir.OFALL,
693                 ir.OGOTO,
694                 ir.OLABEL,
695                 ir.OTAILCALL:
696                 o.out = append(o.out, n)
697
698         // Special: handle call arguments.
699         case ir.OCALLFUNC, ir.OCALLINTER, ir.OCALLMETH:
700                 n := n.(*ir.CallExpr)
701                 t := o.markTemp()
702                 o.call(n)
703                 o.out = append(o.out, n)
704                 o.cleanTemp(t)
705
706         case ir.OCLOSE, ir.ORECV:
707                 n := n.(*ir.UnaryExpr)
708                 t := o.markTemp()
709                 n.X = o.expr(n.X, nil)
710                 o.out = append(o.out, n)
711                 o.cleanTemp(t)
712
713         case ir.OCOPY:
714                 n := n.(*ir.BinaryExpr)
715                 t := o.markTemp()
716                 n.X = o.expr(n.X, nil)
717                 n.Y = o.expr(n.Y, nil)
718                 o.out = append(o.out, n)
719                 o.cleanTemp(t)
720
721         case ir.OPRINT, ir.OPRINTN, ir.ORECOVER:
722                 n := n.(*ir.CallExpr)
723                 t := o.markTemp()
724                 o.exprList(n.Args)
725                 o.out = append(o.out, n)
726                 o.cleanTemp(t)
727
728         // Special: order arguments to inner call but not call itself.
729         case ir.ODEFER, ir.OGO:
730                 n := n.(*ir.GoDeferStmt)
731                 t := o.markTemp()
732                 o.init(n.Call)
733                 o.call(n.Call)
734                 o.out = append(o.out, n)
735                 o.cleanTemp(t)
736
737         case ir.ODELETE:
738                 n := n.(*ir.CallExpr)
739                 t := o.markTemp()
740                 n.Args[0] = o.expr(n.Args[0], nil)
741                 n.Args[1] = o.expr(n.Args[1], nil)
742                 n.Args[1] = o.mapKeyTemp(n.Args[0].Type(), n.Args[1])
743                 o.out = append(o.out, n)
744                 o.cleanTemp(t)
745
746         // Clean temporaries from condition evaluation at
747         // beginning of loop body and after for statement.
748         case ir.OFOR:
749                 n := n.(*ir.ForStmt)
750                 t := o.markTemp()
751                 n.Cond = o.exprInPlace(n.Cond)
752                 n.Body.Prepend(o.cleanTempNoPop(t)...)
753                 orderBlock(&n.Body, o.free)
754                 n.Post = orderStmtInPlace(n.Post, o.free)
755                 o.out = append(o.out, n)
756                 o.cleanTemp(t)
757
758         // Clean temporaries from condition at
759         // beginning of both branches.
760         case ir.OIF:
761                 n := n.(*ir.IfStmt)
762                 t := o.markTemp()
763                 n.Cond = o.exprInPlace(n.Cond)
764                 n.Body.Prepend(o.cleanTempNoPop(t)...)
765                 n.Else.Prepend(o.cleanTempNoPop(t)...)
766                 o.popTemp(t)
767                 orderBlock(&n.Body, o.free)
768                 orderBlock(&n.Else, o.free)
769                 o.out = append(o.out, n)
770
771         case ir.OPANIC:
772                 n := n.(*ir.UnaryExpr)
773                 t := o.markTemp()
774                 n.X = o.expr(n.X, nil)
775                 if !n.X.Type().IsEmptyInterface() {
776                         base.FatalfAt(n.Pos(), "bad argument to panic: %L", n.X)
777                 }
778                 o.out = append(o.out, n)
779                 o.cleanTemp(t)
780
781         case ir.ORANGE:
782                 // n.Right is the expression being ranged over.
783                 // order it, and then make a copy if we need one.
784                 // We almost always do, to ensure that we don't
785                 // see any value changes made during the loop.
786                 // Usually the copy is cheap (e.g., array pointer,
787                 // chan, slice, string are all tiny).
788                 // The exception is ranging over an array value
789                 // (not a slice, not a pointer to array),
790                 // which must make a copy to avoid seeing updates made during
791                 // the range body. Ranging over an array value is uncommon though.
792
793                 // Mark []byte(str) range expression to reuse string backing storage.
794                 // It is safe because the storage cannot be mutated.
795                 n := n.(*ir.RangeStmt)
796                 if n.X.Op() == ir.OSTR2BYTES {
797                         n.X.(*ir.ConvExpr).SetOp(ir.OSTR2BYTESTMP)
798                 }
799
800                 t := o.markTemp()
801                 n.X = o.expr(n.X, nil)
802
803                 orderBody := true
804                 xt := typecheck.RangeExprType(n.X.Type())
805                 switch xt.Kind() {
806                 default:
807                         base.Fatalf("order.stmt range %v", n.Type())
808
809                 case types.TARRAY, types.TSLICE:
810                         if n.Value == nil || ir.IsBlank(n.Value) {
811                                 // for i := range x will only use x once, to compute len(x).
812                                 // No need to copy it.
813                                 break
814                         }
815                         fallthrough
816
817                 case types.TCHAN, types.TSTRING:
818                         // chan, string, slice, array ranges use value multiple times.
819                         // make copy.
820                         r := n.X
821
822                         if r.Type().IsString() && r.Type() != types.Types[types.TSTRING] {
823                                 r = ir.NewConvExpr(base.Pos, ir.OCONV, nil, r)
824                                 r.SetType(types.Types[types.TSTRING])
825                                 r = typecheck.Expr(r)
826                         }
827
828                         n.X = o.copyExpr(r)
829
830                 case types.TMAP:
831                         if isMapClear(n) {
832                                 // Preserve the body of the map clear pattern so it can
833                                 // be detected during walk. The loop body will not be used
834                                 // when optimizing away the range loop to a runtime call.
835                                 orderBody = false
836                                 break
837                         }
838
839                         // copy the map value in case it is a map literal.
840                         // TODO(rsc): Make tmp = literal expressions reuse tmp.
841                         // For maps tmp is just one word so it hardly matters.
842                         r := n.X
843                         n.X = o.copyExpr(r)
844
845                         // n.Prealloc is the temp for the iterator.
846                         // MapIterType contains pointers and needs to be zeroed.
847                         n.Prealloc = o.newTemp(reflectdata.MapIterType(xt), true)
848                 }
849                 n.Key = o.exprInPlace(n.Key)
850                 n.Value = o.exprInPlace(n.Value)
851                 if orderBody {
852                         orderBlock(&n.Body, o.free)
853                 }
854                 o.out = append(o.out, n)
855                 o.cleanTemp(t)
856
857         case ir.ORETURN:
858                 n := n.(*ir.ReturnStmt)
859                 o.exprList(n.Results)
860                 o.out = append(o.out, n)
861
862         // Special: clean case temporaries in each block entry.
863         // Select must enter one of its blocks, so there is no
864         // need for a cleaning at the end.
865         // Doubly special: evaluation order for select is stricter
866         // than ordinary expressions. Even something like p.c
867         // has to be hoisted into a temporary, so that it cannot be
868         // reordered after the channel evaluation for a different
869         // case (if p were nil, then the timing of the fault would
870         // give this away).
871         case ir.OSELECT:
872                 n := n.(*ir.SelectStmt)
873                 t := o.markTemp()
874                 for _, ncas := range n.Cases {
875                         r := ncas.Comm
876                         ir.SetPos(ncas)
877
878                         // Append any new body prologue to ninit.
879                         // The next loop will insert ninit into nbody.
880                         if len(ncas.Init()) != 0 {
881                                 base.Fatalf("order select ninit")
882                         }
883                         if r == nil {
884                                 continue
885                         }
886                         switch r.Op() {
887                         default:
888                                 ir.Dump("select case", r)
889                                 base.Fatalf("unknown op in select %v", r.Op())
890
891                         case ir.OSELRECV2:
892                                 // case x, ok = <-c
893                                 r := r.(*ir.AssignListStmt)
894                                 recv := r.Rhs[0].(*ir.UnaryExpr)
895                                 recv.X = o.expr(recv.X, nil)
896                                 if !ir.IsAutoTmp(recv.X) {
897                                         recv.X = o.copyExpr(recv.X)
898                                 }
899                                 init := ir.TakeInit(r)
900
901                                 colas := r.Def
902                                 do := func(i int, t *types.Type) {
903                                         n := r.Lhs[i]
904                                         if ir.IsBlank(n) {
905                                                 return
906                                         }
907                                         // If this is case x := <-ch or case x, y := <-ch, the case has
908                                         // the ODCL nodes to declare x and y. We want to delay that
909                                         // declaration (and possible allocation) until inside the case body.
910                                         // Delete the ODCL nodes here and recreate them inside the body below.
911                                         if colas {
912                                                 if len(init) > 0 && init[0].Op() == ir.ODCL && init[0].(*ir.Decl).X == n {
913                                                         init = init[1:]
914                                                 }
915                                                 dcl := typecheck.Stmt(ir.NewDecl(base.Pos, ir.ODCL, n.(*ir.Name)))
916                                                 ncas.PtrInit().Append(dcl)
917                                         }
918                                         tmp := o.newTemp(t, t.HasPointers())
919                                         as := typecheck.Stmt(ir.NewAssignStmt(base.Pos, n, typecheck.Conv(tmp, n.Type())))
920                                         ncas.PtrInit().Append(as)
921                                         r.Lhs[i] = tmp
922                                 }
923                                 do(0, recv.X.Type().Elem())
924                                 do(1, types.Types[types.TBOOL])
925                                 if len(init) != 0 {
926                                         ir.DumpList("ninit", r.Init())
927                                         base.Fatalf("ninit on select recv")
928                                 }
929                                 orderBlock(ncas.PtrInit(), o.free)
930
931                         case ir.OSEND:
932                                 r := r.(*ir.SendStmt)
933                                 if len(r.Init()) != 0 {
934                                         ir.DumpList("ninit", r.Init())
935                                         base.Fatalf("ninit on select send")
936                                 }
937
938                                 // case c <- x
939                                 // r->left is c, r->right is x, both are always evaluated.
940                                 r.Chan = o.expr(r.Chan, nil)
941
942                                 if !ir.IsAutoTmp(r.Chan) {
943                                         r.Chan = o.copyExpr(r.Chan)
944                                 }
945                                 r.Value = o.expr(r.Value, nil)
946                                 if !ir.IsAutoTmp(r.Value) {
947                                         r.Value = o.copyExpr(r.Value)
948                                 }
949                         }
950                 }
951                 // Now that we have accumulated all the temporaries, clean them.
952                 // Also insert any ninit queued during the previous loop.
953                 // (The temporary cleaning must follow that ninit work.)
954                 for _, cas := range n.Cases {
955                         orderBlock(&cas.Body, o.free)
956                         cas.Body.Prepend(o.cleanTempNoPop(t)...)
957
958                         // TODO(mdempsky): Is this actually necessary?
959                         // walkSelect appears to walk Ninit.
960                         cas.Body.Prepend(ir.TakeInit(cas)...)
961                 }
962
963                 o.out = append(o.out, n)
964                 o.popTemp(t)
965
966         // Special: value being sent is passed as a pointer; make it addressable.
967         case ir.OSEND:
968                 n := n.(*ir.SendStmt)
969                 t := o.markTemp()
970                 n.Chan = o.expr(n.Chan, nil)
971                 n.Value = o.expr(n.Value, nil)
972                 if base.Flag.Cfg.Instrumenting {
973                         // Force copying to the stack so that (chan T)(nil) <- x
974                         // is still instrumented as a read of x.
975                         n.Value = o.copyExpr(n.Value)
976                 } else {
977                         n.Value = o.addrTemp(n.Value)
978                 }
979                 o.out = append(o.out, n)
980                 o.cleanTemp(t)
981
982         // TODO(rsc): Clean temporaries more aggressively.
983         // Note that because walkSwitch will rewrite some of the
984         // switch into a binary search, this is not as easy as it looks.
985         // (If we ran that code here we could invoke order.stmt on
986         // the if-else chain instead.)
987         // For now just clean all the temporaries at the end.
988         // In practice that's fine.
989         case ir.OSWITCH:
990                 n := n.(*ir.SwitchStmt)
991                 if base.Debug.Libfuzzer != 0 && !hasDefaultCase(n) {
992                         // Add empty "default:" case for instrumentation.
993                         n.Cases = append(n.Cases, ir.NewCaseStmt(base.Pos, nil, nil))
994                 }
995
996                 t := o.markTemp()
997                 n.Tag = o.expr(n.Tag, nil)
998                 for _, ncas := range n.Cases {
999                         o.exprListInPlace(ncas.List)
1000                         orderBlock(&ncas.Body, o.free)
1001                 }
1002
1003                 o.out = append(o.out, n)
1004                 o.cleanTemp(t)
1005         }
1006
1007         base.Pos = lno
1008 }
1009
1010 func hasDefaultCase(n *ir.SwitchStmt) bool {
1011         for _, ncas := range n.Cases {
1012                 if len(ncas.List) == 0 {
1013                         return true
1014                 }
1015         }
1016         return false
1017 }
1018
1019 // exprList orders the expression list l into o.
1020 func (o *orderState) exprList(l ir.Nodes) {
1021         s := l
1022         for i := range s {
1023                 s[i] = o.expr(s[i], nil)
1024         }
1025 }
1026
1027 // exprListInPlace orders the expression list l but saves
1028 // the side effects on the individual expression ninit lists.
1029 func (o *orderState) exprListInPlace(l ir.Nodes) {
1030         s := l
1031         for i := range s {
1032                 s[i] = o.exprInPlace(s[i])
1033         }
1034 }
1035
1036 func (o *orderState) exprNoLHS(n ir.Node) ir.Node {
1037         return o.expr(n, nil)
1038 }
1039
1040 // expr orders a single expression, appending side
1041 // effects to o.out as needed.
1042 // If this is part of an assignment lhs = *np, lhs is given.
1043 // Otherwise lhs == nil. (When lhs != nil it may be possible
1044 // to avoid copying the result of the expression to a temporary.)
1045 // The result of expr MUST be assigned back to n, e.g.
1046 //      n.Left = o.expr(n.Left, lhs)
1047 func (o *orderState) expr(n, lhs ir.Node) ir.Node {
1048         if n == nil {
1049                 return n
1050         }
1051         lno := ir.SetPos(n)
1052         n = o.expr1(n, lhs)
1053         base.Pos = lno
1054         return n
1055 }
1056
1057 func (o *orderState) expr1(n, lhs ir.Node) ir.Node {
1058         o.init(n)
1059
1060         switch n.Op() {
1061         default:
1062                 if o.edit == nil {
1063                         o.edit = o.exprNoLHS // create closure once
1064                 }
1065                 ir.EditChildren(n, o.edit)
1066                 return n
1067
1068         // Addition of strings turns into a function call.
1069         // Allocate a temporary to hold the strings.
1070         // Fewer than 5 strings use direct runtime helpers.
1071         case ir.OADDSTR:
1072                 n := n.(*ir.AddStringExpr)
1073                 o.exprList(n.List)
1074
1075                 if len(n.List) > 5 {
1076                         t := types.NewArray(types.Types[types.TSTRING], int64(len(n.List)))
1077                         n.Prealloc = o.newTemp(t, false)
1078                 }
1079
1080                 // Mark string(byteSlice) arguments to reuse byteSlice backing
1081                 // buffer during conversion. String concatenation does not
1082                 // memorize the strings for later use, so it is safe.
1083                 // However, we can do it only if there is at least one non-empty string literal.
1084                 // Otherwise if all other arguments are empty strings,
1085                 // concatstrings will return the reference to the temp string
1086                 // to the caller.
1087                 hasbyte := false
1088
1089                 haslit := false
1090                 for _, n1 := range n.List {
1091                         hasbyte = hasbyte || n1.Op() == ir.OBYTES2STR
1092                         haslit = haslit || n1.Op() == ir.OLITERAL && len(ir.StringVal(n1)) != 0
1093                 }
1094
1095                 if haslit && hasbyte {
1096                         for _, n2 := range n.List {
1097                                 if n2.Op() == ir.OBYTES2STR {
1098                                         n2 := n2.(*ir.ConvExpr)
1099                                         n2.SetOp(ir.OBYTES2STRTMP)
1100                                 }
1101                         }
1102                 }
1103                 return n
1104
1105         case ir.OINDEXMAP:
1106                 n := n.(*ir.IndexExpr)
1107                 n.X = o.expr(n.X, nil)
1108                 n.Index = o.expr(n.Index, nil)
1109                 needCopy := false
1110
1111                 if !n.Assigned {
1112                         // Enforce that any []byte slices we are not copying
1113                         // can not be changed before the map index by forcing
1114                         // the map index to happen immediately following the
1115                         // conversions. See copyExpr a few lines below.
1116                         needCopy = mapKeyReplaceStrConv(n.Index)
1117
1118                         if base.Flag.Cfg.Instrumenting {
1119                                 // Race detector needs the copy.
1120                                 needCopy = true
1121                         }
1122                 }
1123
1124                 // key must be addressable
1125                 n.Index = o.mapKeyTemp(n.X.Type(), n.Index)
1126                 if needCopy {
1127                         return o.copyExpr(n)
1128                 }
1129                 return n
1130
1131         // concrete type (not interface) argument might need an addressable
1132         // temporary to pass to the runtime conversion routine.
1133         case ir.OCONVIFACE:
1134                 n := n.(*ir.ConvExpr)
1135                 n.X = o.expr(n.X, nil)
1136                 if n.X.Type().IsInterface() {
1137                         return n
1138                 }
1139                 if _, needsaddr := convFuncName(n.X.Type(), n.Type()); needsaddr || isStaticCompositeLiteral(n.X) {
1140                         // Need a temp if we need to pass the address to the conversion function.
1141                         // We also process static composite literal node here, making a named static global
1142                         // whose address we can put directly in an interface (see OCONVIFACE case in walk).
1143                         n.X = o.addrTemp(n.X)
1144                 }
1145                 return n
1146
1147         case ir.OCONVNOP:
1148                 n := n.(*ir.ConvExpr)
1149                 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) {
1150                         call := n.X.(*ir.CallExpr)
1151                         // When reordering unsafe.Pointer(f()) into a separate
1152                         // statement, the conversion and function call must stay
1153                         // together. See golang.org/issue/15329.
1154                         o.init(call)
1155                         o.call(call)
1156                         if lhs == nil || lhs.Op() != ir.ONAME || base.Flag.Cfg.Instrumenting {
1157                                 return o.copyExpr(n)
1158                         }
1159                 } else {
1160                         n.X = o.expr(n.X, nil)
1161                 }
1162                 return n
1163
1164         case ir.OANDAND, ir.OOROR:
1165                 // ... = LHS && RHS
1166                 //
1167                 // var r bool
1168                 // r = LHS
1169                 // if r {       // or !r, for OROR
1170                 //     r = RHS
1171                 // }
1172                 // ... = r
1173
1174                 n := n.(*ir.LogicalExpr)
1175                 r := o.newTemp(n.Type(), false)
1176
1177                 // Evaluate left-hand side.
1178                 lhs := o.expr(n.X, nil)
1179                 o.out = append(o.out, typecheck.Stmt(ir.NewAssignStmt(base.Pos, r, lhs)))
1180
1181                 // Evaluate right-hand side, save generated code.
1182                 saveout := o.out
1183                 o.out = nil
1184                 t := o.markTemp()
1185                 o.edge()
1186                 rhs := o.expr(n.Y, nil)
1187                 o.out = append(o.out, typecheck.Stmt(ir.NewAssignStmt(base.Pos, r, rhs)))
1188                 o.cleanTemp(t)
1189                 gen := o.out
1190                 o.out = saveout
1191
1192                 // If left-hand side doesn't cause a short-circuit, issue right-hand side.
1193                 nif := ir.NewIfStmt(base.Pos, r, nil, nil)
1194                 if n.Op() == ir.OANDAND {
1195                         nif.Body = gen
1196                 } else {
1197                         nif.Else = gen
1198                 }
1199                 o.out = append(o.out, nif)
1200                 return r
1201
1202         case ir.OCALLFUNC,
1203                 ir.OCALLINTER,
1204                 ir.OCALLMETH,
1205                 ir.OCAP,
1206                 ir.OCOMPLEX,
1207                 ir.OCOPY,
1208                 ir.OIMAG,
1209                 ir.OLEN,
1210                 ir.OMAKECHAN,
1211                 ir.OMAKEMAP,
1212                 ir.OMAKESLICE,
1213                 ir.OMAKESLICECOPY,
1214                 ir.ONEW,
1215                 ir.OREAL,
1216                 ir.ORECOVER,
1217                 ir.OSTR2BYTES,
1218                 ir.OSTR2BYTESTMP,
1219                 ir.OSTR2RUNES:
1220
1221                 if isRuneCount(n) {
1222                         // len([]rune(s)) is rewritten to runtime.countrunes(s) later.
1223                         conv := n.(*ir.UnaryExpr).X.(*ir.ConvExpr)
1224                         conv.X = o.expr(conv.X, nil)
1225                 } else {
1226                         o.call(n)
1227                 }
1228
1229                 if lhs == nil || lhs.Op() != ir.ONAME || base.Flag.Cfg.Instrumenting {
1230                         return o.copyExpr(n)
1231                 }
1232                 return n
1233
1234         case ir.OAPPEND:
1235                 // Check for append(x, make([]T, y)...) .
1236                 n := n.(*ir.CallExpr)
1237                 if isAppendOfMake(n) {
1238                         n.Args[0] = o.expr(n.Args[0], nil) // order x
1239                         mk := n.Args[1].(*ir.MakeExpr)
1240                         mk.Len = o.expr(mk.Len, nil) // order y
1241                 } else {
1242                         o.exprList(n.Args)
1243                 }
1244
1245                 if lhs == nil || lhs.Op() != ir.ONAME && !ir.SameSafeExpr(lhs, n.Args[0]) {
1246                         return o.copyExpr(n)
1247                 }
1248                 return n
1249
1250         case ir.OSLICE, ir.OSLICEARR, ir.OSLICESTR, ir.OSLICE3, ir.OSLICE3ARR:
1251                 n := n.(*ir.SliceExpr)
1252                 n.X = o.expr(n.X, nil)
1253                 n.Low = o.cheapExpr(o.expr(n.Low, nil))
1254                 n.High = o.cheapExpr(o.expr(n.High, nil))
1255                 n.Max = o.cheapExpr(o.expr(n.Max, nil))
1256                 if lhs == nil || lhs.Op() != ir.ONAME && !ir.SameSafeExpr(lhs, n.X) {
1257                         return o.copyExpr(n)
1258                 }
1259                 return n
1260
1261         case ir.OCLOSURE:
1262                 n := n.(*ir.ClosureExpr)
1263                 if n.Transient() && len(n.Func.ClosureVars) > 0 {
1264                         n.Prealloc = o.newTemp(typecheck.ClosureType(n), false)
1265                 }
1266                 return n
1267
1268         case ir.OCALLPART:
1269                 n := n.(*ir.SelectorExpr)
1270                 n.X = o.expr(n.X, nil)
1271                 if n.Transient() {
1272                         t := typecheck.PartialCallType(n)
1273                         n.Prealloc = o.newTemp(t, false)
1274                 }
1275                 return n
1276
1277         case ir.OSLICELIT:
1278                 n := n.(*ir.CompLitExpr)
1279                 o.exprList(n.List)
1280                 if n.Transient() {
1281                         t := types.NewArray(n.Type().Elem(), n.Len)
1282                         n.Prealloc = o.newTemp(t, false)
1283                 }
1284                 return n
1285
1286         case ir.ODOTTYPE, ir.ODOTTYPE2:
1287                 n := n.(*ir.TypeAssertExpr)
1288                 n.X = o.expr(n.X, nil)
1289                 if !types.IsDirectIface(n.Type()) || base.Flag.Cfg.Instrumenting {
1290                         return o.copyExprClear(n)
1291                 }
1292                 return n
1293
1294         case ir.ORECV:
1295                 n := n.(*ir.UnaryExpr)
1296                 n.X = o.expr(n.X, nil)
1297                 return o.copyExprClear(n)
1298
1299         case ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE:
1300                 n := n.(*ir.BinaryExpr)
1301                 n.X = o.expr(n.X, nil)
1302                 n.Y = o.expr(n.Y, nil)
1303
1304                 t := n.X.Type()
1305                 switch {
1306                 case t.IsString():
1307                         // Mark string(byteSlice) arguments to reuse byteSlice backing
1308                         // buffer during conversion. String comparison does not
1309                         // memorize the strings for later use, so it is safe.
1310                         if n.X.Op() == ir.OBYTES2STR {
1311                                 n.X.(*ir.ConvExpr).SetOp(ir.OBYTES2STRTMP)
1312                         }
1313                         if n.Y.Op() == ir.OBYTES2STR {
1314                                 n.Y.(*ir.ConvExpr).SetOp(ir.OBYTES2STRTMP)
1315                         }
1316
1317                 case t.IsStruct() || t.IsArray():
1318                         // for complex comparisons, we need both args to be
1319                         // addressable so we can pass them to the runtime.
1320                         n.X = o.addrTemp(n.X)
1321                         n.Y = o.addrTemp(n.Y)
1322                 }
1323                 return n
1324
1325         case ir.OMAPLIT:
1326                 // Order map by converting:
1327                 //   map[int]int{
1328                 //     a(): b(),
1329                 //     c(): d(),
1330                 //     e(): f(),
1331                 //   }
1332                 // to
1333                 //   m := map[int]int{}
1334                 //   m[a()] = b()
1335                 //   m[c()] = d()
1336                 //   m[e()] = f()
1337                 // Then order the result.
1338                 // Without this special case, order would otherwise compute all
1339                 // the keys and values before storing any of them to the map.
1340                 // See issue 26552.
1341                 n := n.(*ir.CompLitExpr)
1342                 entries := n.List
1343                 statics := entries[:0]
1344                 var dynamics []*ir.KeyExpr
1345                 for _, r := range entries {
1346                         r := r.(*ir.KeyExpr)
1347
1348                         if !isStaticCompositeLiteral(r.Key) || !isStaticCompositeLiteral(r.Value) {
1349                                 dynamics = append(dynamics, r)
1350                                 continue
1351                         }
1352
1353                         // Recursively ordering some static entries can change them to dynamic;
1354                         // e.g., OCONVIFACE nodes. See #31777.
1355                         r = o.expr(r, nil).(*ir.KeyExpr)
1356                         if !isStaticCompositeLiteral(r.Key) || !isStaticCompositeLiteral(r.Value) {
1357                                 dynamics = append(dynamics, r)
1358                                 continue
1359                         }
1360
1361                         statics = append(statics, r)
1362                 }
1363                 n.List = statics
1364
1365                 if len(dynamics) == 0 {
1366                         return n
1367                 }
1368
1369                 // Emit the creation of the map (with all its static entries).
1370                 m := o.newTemp(n.Type(), false)
1371                 as := ir.NewAssignStmt(base.Pos, m, n)
1372                 typecheck.Stmt(as)
1373                 o.stmt(as)
1374
1375                 // Emit eval+insert of dynamic entries, one at a time.
1376                 for _, r := range dynamics {
1377                         as := ir.NewAssignStmt(base.Pos, ir.NewIndexExpr(base.Pos, m, r.Key), r.Value)
1378                         typecheck.Stmt(as) // Note: this converts the OINDEX to an OINDEXMAP
1379                         o.stmt(as)
1380                 }
1381                 return m
1382         }
1383
1384         // No return - type-assertions above. Each case must return for itself.
1385 }
1386
1387 // as2func orders OAS2FUNC nodes. It creates temporaries to ensure left-to-right assignment.
1388 // The caller should order the right-hand side of the assignment before calling order.as2func.
1389 // It rewrites,
1390 //      a, b, a = ...
1391 // as
1392 //      tmp1, tmp2, tmp3 = ...
1393 //      a, b, a = tmp1, tmp2, tmp3
1394 // This is necessary to ensure left to right assignment order.
1395 func (o *orderState) as2func(n *ir.AssignListStmt) {
1396         results := n.Rhs[0].Type()
1397         as := ir.NewAssignListStmt(n.Pos(), ir.OAS2, nil, nil)
1398         for i, nl := range n.Lhs {
1399                 if !ir.IsBlank(nl) {
1400                         typ := results.Field(i).Type
1401                         tmp := o.newTemp(typ, typ.HasPointers())
1402                         n.Lhs[i] = tmp
1403                         as.Lhs = append(as.Lhs, nl)
1404                         as.Rhs = append(as.Rhs, tmp)
1405                 }
1406         }
1407
1408         o.out = append(o.out, n)
1409         o.stmt(typecheck.Stmt(as))
1410 }
1411
1412 // as2ok orders OAS2XXX with ok.
1413 // Just like as2func, this also adds temporaries to ensure left-to-right assignment.
1414 func (o *orderState) as2ok(n *ir.AssignListStmt) {
1415         as := ir.NewAssignListStmt(n.Pos(), ir.OAS2, nil, nil)
1416
1417         do := func(i int, typ *types.Type) {
1418                 if nl := n.Lhs[i]; !ir.IsBlank(nl) {
1419                         var tmp ir.Node = o.newTemp(typ, typ.HasPointers())
1420                         n.Lhs[i] = tmp
1421                         as.Lhs = append(as.Lhs, nl)
1422                         if i == 1 {
1423                                 // The "ok" result is an untyped boolean according to the Go
1424                                 // spec. We need to explicitly convert it to the LHS type in
1425                                 // case the latter is a defined boolean type (#8475).
1426                                 tmp = typecheck.Conv(tmp, nl.Type())
1427                         }
1428                         as.Rhs = append(as.Rhs, tmp)
1429                 }
1430         }
1431
1432         do(0, n.Rhs[0].Type())
1433         do(1, types.Types[types.TBOOL])
1434
1435         o.out = append(o.out, n)
1436         o.stmt(typecheck.Stmt(as))
1437 }