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