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