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