]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/compile/internal/walk/order.go
[dev.typeparams] all: merge master (37f9a8f) into dev.typeparams
[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
557 // mapAssign appends n to o.out.
558 func (o *orderState) mapAssign(n ir.Node) {
559         switch n.Op() {
560         default:
561                 base.Fatalf("order.mapAssign %v", n.Op())
562
563         case ir.OAS:
564                 n := n.(*ir.AssignStmt)
565                 if n.X.Op() == ir.OINDEXMAP {
566                         n.Y = o.safeMapRHS(n.Y)
567                 }
568                 o.out = append(o.out, n)
569         case ir.OASOP:
570                 n := n.(*ir.AssignOpStmt)
571                 if n.X.Op() == ir.OINDEXMAP {
572                         n.Y = o.safeMapRHS(n.Y)
573                 }
574                 o.out = append(o.out, n)
575         }
576 }
577
578 func (o *orderState) safeMapRHS(r ir.Node) ir.Node {
579         // Make sure we evaluate the RHS before starting the map insert.
580         // We need to make sure the RHS won't panic.  See issue 22881.
581         if r.Op() == ir.OAPPEND {
582                 r := r.(*ir.CallExpr)
583                 s := r.Args[1:]
584                 for i, n := range s {
585                         s[i] = o.cheapExpr(n)
586                 }
587                 return r
588         }
589         return o.cheapExpr(r)
590 }
591
592 // stmt orders the statement n, appending to o.out.
593 // Temporaries created during the statement are cleaned
594 // up using VARKILL instructions as possible.
595 func (o *orderState) stmt(n ir.Node) {
596         if n == nil {
597                 return
598         }
599
600         lno := ir.SetPos(n)
601         o.init(n)
602
603         switch n.Op() {
604         default:
605                 base.Fatalf("order.stmt %v", n.Op())
606
607         case ir.OVARKILL, ir.OVARLIVE, ir.OINLMARK:
608                 o.out = append(o.out, n)
609
610         case ir.OAS:
611                 n := n.(*ir.AssignStmt)
612                 t := o.markTemp()
613                 n.X = o.expr(n.X, nil)
614                 n.Y = o.expr(n.Y, n.X)
615                 o.mapAssign(n)
616                 o.cleanTemp(t)
617
618         case ir.OASOP:
619                 n := n.(*ir.AssignOpStmt)
620                 t := o.markTemp()
621                 n.X = o.expr(n.X, nil)
622                 n.Y = o.expr(n.Y, nil)
623
624                 if base.Flag.Cfg.Instrumenting || n.X.Op() == ir.OINDEXMAP && (n.AsOp == ir.ODIV || n.AsOp == ir.OMOD) {
625                         // Rewrite m[k] op= r into m[k] = m[k] op r so
626                         // that we can ensure that if op panics
627                         // because r is zero, the panic happens before
628                         // the map assignment.
629                         // DeepCopy is a big hammer here, but safeExpr
630                         // makes sure there is nothing too deep being copied.
631                         l1 := o.safeExpr(n.X)
632                         l2 := ir.DeepCopy(src.NoXPos, l1)
633                         if l2.Op() == ir.OINDEXMAP {
634                                 l2 := l2.(*ir.IndexExpr)
635                                 l2.Assigned = false
636                         }
637                         l2 = o.copyExpr(l2)
638                         r := o.expr(typecheck.Expr(ir.NewBinaryExpr(n.Pos(), n.AsOp, l2, n.Y)), nil)
639                         as := typecheck.Stmt(ir.NewAssignStmt(n.Pos(), l1, r))
640                         o.mapAssign(as)
641                         o.cleanTemp(t)
642                         return
643                 }
644
645                 o.mapAssign(n)
646                 o.cleanTemp(t)
647
648         case ir.OAS2:
649                 n := n.(*ir.AssignListStmt)
650                 t := o.markTemp()
651                 o.exprList(n.Lhs)
652                 o.exprList(n.Rhs)
653                 o.out = append(o.out, n)
654                 o.cleanTemp(t)
655
656         // Special: avoid copy of func call n.Right
657         case ir.OAS2FUNC:
658                 n := n.(*ir.AssignListStmt)
659                 t := o.markTemp()
660                 o.exprList(n.Lhs)
661                 o.init(n.Rhs[0])
662                 o.call(n.Rhs[0])
663                 o.as2func(n)
664                 o.cleanTemp(t)
665
666         // Special: use temporary variables to hold result,
667         // so that runtime can take address of temporary.
668         // No temporary for blank assignment.
669         //
670         // OAS2MAPR: make sure key is addressable if needed,
671         //           and make sure OINDEXMAP is not copied out.
672         case ir.OAS2DOTTYPE, ir.OAS2RECV, ir.OAS2MAPR:
673                 n := n.(*ir.AssignListStmt)
674                 t := o.markTemp()
675                 o.exprList(n.Lhs)
676
677                 switch r := n.Rhs[0]; r.Op() {
678                 case ir.ODOTTYPE2:
679                         r := r.(*ir.TypeAssertExpr)
680                         r.X = o.expr(r.X, nil)
681                 case ir.ORECV:
682                         r := r.(*ir.UnaryExpr)
683                         r.X = o.expr(r.X, nil)
684                 case ir.OINDEXMAP:
685                         r := r.(*ir.IndexExpr)
686                         r.X = o.expr(r.X, nil)
687                         r.Index = o.expr(r.Index, nil)
688                         // See similar conversion for OINDEXMAP below.
689                         _ = mapKeyReplaceStrConv(r.Index)
690                         r.Index = o.mapKeyTemp(r.X.Type(), r.Index)
691                 default:
692                         base.Fatalf("order.stmt: %v", r.Op())
693                 }
694
695                 o.as2ok(n)
696                 o.cleanTemp(t)
697
698         // Special: does not save n onto out.
699         case ir.OBLOCK:
700                 n := n.(*ir.BlockStmt)
701                 o.stmtList(n.List)
702
703         // Special: n->left is not an expression; save as is.
704         case ir.OBREAK,
705                 ir.OCONTINUE,
706                 ir.ODCL,
707                 ir.ODCLCONST,
708                 ir.ODCLTYPE,
709                 ir.OFALL,
710                 ir.OGOTO,
711                 ir.OLABEL,
712                 ir.OTAILCALL:
713                 o.out = append(o.out, n)
714
715         // Special: handle call arguments.
716         case ir.OCALLFUNC, ir.OCALLINTER, ir.OCALLMETH:
717                 n := n.(*ir.CallExpr)
718                 t := o.markTemp()
719                 o.call(n)
720                 o.out = append(o.out, n)
721                 o.cleanTemp(t)
722
723         case ir.OCHECKNIL, ir.OCLOSE, ir.OPANIC, ir.ORECV:
724                 n := n.(*ir.UnaryExpr)
725                 t := o.markTemp()
726                 n.X = o.expr(n.X, nil)
727                 o.out = append(o.out, n)
728                 o.cleanTemp(t)
729
730         case ir.OCOPY:
731                 n := n.(*ir.BinaryExpr)
732                 t := o.markTemp()
733                 n.X = o.expr(n.X, nil)
734                 n.Y = o.expr(n.Y, nil)
735                 o.out = append(o.out, n)
736                 o.cleanTemp(t)
737
738         case ir.OPRINT, ir.OPRINTN, ir.ORECOVERFP:
739                 n := n.(*ir.CallExpr)
740                 t := o.markTemp()
741                 o.call(n)
742                 o.out = append(o.out, n)
743                 o.cleanTemp(t)
744
745         // Special: order arguments to inner call but not call itself.
746         case ir.ODEFER, ir.OGO:
747                 n := n.(*ir.GoDeferStmt)
748                 t := o.markTemp()
749                 o.init(n.Call)
750                 o.call(n.Call)
751                 o.out = append(o.out, n)
752                 o.cleanTemp(t)
753
754         case ir.ODELETE:
755                 n := n.(*ir.CallExpr)
756                 t := o.markTemp()
757                 n.Args[0] = o.expr(n.Args[0], nil)
758                 n.Args[1] = o.expr(n.Args[1], nil)
759                 n.Args[1] = o.mapKeyTemp(n.Args[0].Type(), n.Args[1])
760                 o.out = append(o.out, n)
761                 o.cleanTemp(t)
762
763         // Clean temporaries from condition evaluation at
764         // beginning of loop body and after for statement.
765         case ir.OFOR:
766                 n := n.(*ir.ForStmt)
767                 t := o.markTemp()
768                 n.Cond = o.exprInPlace(n.Cond)
769                 n.Body.Prepend(o.cleanTempNoPop(t)...)
770                 orderBlock(&n.Body, o.free)
771                 n.Post = orderStmtInPlace(n.Post, o.free)
772                 o.out = append(o.out, n)
773                 o.cleanTemp(t)
774
775         // Clean temporaries from condition at
776         // beginning of both branches.
777         case ir.OIF:
778                 n := n.(*ir.IfStmt)
779                 t := o.markTemp()
780                 n.Cond = o.exprInPlace(n.Cond)
781                 n.Body.Prepend(o.cleanTempNoPop(t)...)
782                 n.Else.Prepend(o.cleanTempNoPop(t)...)
783                 o.popTemp(t)
784                 orderBlock(&n.Body, o.free)
785                 orderBlock(&n.Else, o.free)
786                 o.out = append(o.out, n)
787
788         case ir.ORANGE:
789                 // n.Right is the expression being ranged over.
790                 // order it, and then make a copy if we need one.
791                 // We almost always do, to ensure that we don't
792                 // see any value changes made during the loop.
793                 // Usually the copy is cheap (e.g., array pointer,
794                 // chan, slice, string are all tiny).
795                 // The exception is ranging over an array value
796                 // (not a slice, not a pointer to array),
797                 // which must make a copy to avoid seeing updates made during
798                 // the range body. Ranging over an array value is uncommon though.
799
800                 // Mark []byte(str) range expression to reuse string backing storage.
801                 // It is safe because the storage cannot be mutated.
802                 n := n.(*ir.RangeStmt)
803                 if n.X.Op() == ir.OSTR2BYTES {
804                         n.X.(*ir.ConvExpr).SetOp(ir.OSTR2BYTESTMP)
805                 }
806
807                 t := o.markTemp()
808                 n.X = o.expr(n.X, nil)
809
810                 orderBody := true
811                 xt := typecheck.RangeExprType(n.X.Type())
812                 switch xt.Kind() {
813                 default:
814                         base.Fatalf("order.stmt range %v", n.Type())
815
816                 case types.TARRAY, types.TSLICE:
817                         if n.Value == nil || ir.IsBlank(n.Value) {
818                                 // for i := range x will only use x once, to compute len(x).
819                                 // No need to copy it.
820                                 break
821                         }
822                         fallthrough
823
824                 case types.TCHAN, types.TSTRING:
825                         // chan, string, slice, array ranges use value multiple times.
826                         // make copy.
827                         r := n.X
828
829                         if r.Type().IsString() && r.Type() != types.Types[types.TSTRING] {
830                                 r = ir.NewConvExpr(base.Pos, ir.OCONV, nil, r)
831                                 r.SetType(types.Types[types.TSTRING])
832                                 r = typecheck.Expr(r)
833                         }
834
835                         n.X = o.copyExpr(r)
836
837                 case types.TMAP:
838                         if isMapClear(n) {
839                                 // Preserve the body of the map clear pattern so it can
840                                 // be detected during walk. The loop body will not be used
841                                 // when optimizing away the range loop to a runtime call.
842                                 orderBody = false
843                                 break
844                         }
845
846                         // copy the map value in case it is a map literal.
847                         // TODO(rsc): Make tmp = literal expressions reuse tmp.
848                         // For maps tmp is just one word so it hardly matters.
849                         r := n.X
850                         n.X = o.copyExpr(r)
851
852                         // n.Prealloc is the temp for the iterator.
853                         // MapIterType contains pointers and needs to be zeroed.
854                         n.Prealloc = o.newTemp(reflectdata.MapIterType(xt), true)
855                 }
856                 n.Key = o.exprInPlace(n.Key)
857                 n.Value = o.exprInPlace(n.Value)
858                 if orderBody {
859                         orderBlock(&n.Body, o.free)
860                 }
861                 o.out = append(o.out, n)
862                 o.cleanTemp(t)
863
864         case ir.ORETURN:
865                 n := n.(*ir.ReturnStmt)
866                 o.exprList(n.Results)
867                 o.out = append(o.out, n)
868
869         // Special: clean case temporaries in each block entry.
870         // Select must enter one of its blocks, so there is no
871         // need for a cleaning at the end.
872         // Doubly special: evaluation order for select is stricter
873         // than ordinary expressions. Even something like p.c
874         // has to be hoisted into a temporary, so that it cannot be
875         // reordered after the channel evaluation for a different
876         // case (if p were nil, then the timing of the fault would
877         // give this away).
878         case ir.OSELECT:
879                 n := n.(*ir.SelectStmt)
880                 t := o.markTemp()
881                 for _, ncas := range n.Cases {
882                         r := ncas.Comm
883                         ir.SetPos(ncas)
884
885                         // Append any new body prologue to ninit.
886                         // The next loop will insert ninit into nbody.
887                         if len(ncas.Init()) != 0 {
888                                 base.Fatalf("order select ninit")
889                         }
890                         if r == nil {
891                                 continue
892                         }
893                         switch r.Op() {
894                         default:
895                                 ir.Dump("select case", r)
896                                 base.Fatalf("unknown op in select %v", r.Op())
897
898                         case ir.OSELRECV2:
899                                 // case x, ok = <-c
900                                 r := r.(*ir.AssignListStmt)
901                                 recv := r.Rhs[0].(*ir.UnaryExpr)
902                                 recv.X = o.expr(recv.X, nil)
903                                 if !ir.IsAutoTmp(recv.X) {
904                                         recv.X = o.copyExpr(recv.X)
905                                 }
906                                 init := ir.TakeInit(r)
907
908                                 colas := r.Def
909                                 do := func(i int, t *types.Type) {
910                                         n := r.Lhs[i]
911                                         if ir.IsBlank(n) {
912                                                 return
913                                         }
914                                         // If this is case x := <-ch or case x, y := <-ch, the case has
915                                         // the ODCL nodes to declare x and y. We want to delay that
916                                         // declaration (and possible allocation) until inside the case body.
917                                         // Delete the ODCL nodes here and recreate them inside the body below.
918                                         if colas {
919                                                 if len(init) > 0 && init[0].Op() == ir.ODCL && init[0].(*ir.Decl).X == n {
920                                                         init = init[1:]
921                                                 }
922                                                 dcl := typecheck.Stmt(ir.NewDecl(base.Pos, ir.ODCL, n.(*ir.Name)))
923                                                 ncas.PtrInit().Append(dcl)
924                                         }
925                                         tmp := o.newTemp(t, t.HasPointers())
926                                         as := typecheck.Stmt(ir.NewAssignStmt(base.Pos, n, typecheck.Conv(tmp, n.Type())))
927                                         ncas.PtrInit().Append(as)
928                                         r.Lhs[i] = tmp
929                                 }
930                                 do(0, recv.X.Type().Elem())
931                                 do(1, types.Types[types.TBOOL])
932                                 if len(init) != 0 {
933                                         ir.DumpList("ninit", r.Init())
934                                         base.Fatalf("ninit on select recv")
935                                 }
936                                 orderBlock(ncas.PtrInit(), o.free)
937
938                         case ir.OSEND:
939                                 r := r.(*ir.SendStmt)
940                                 if len(r.Init()) != 0 {
941                                         ir.DumpList("ninit", r.Init())
942                                         base.Fatalf("ninit on select send")
943                                 }
944
945                                 // case c <- x
946                                 // r->left is c, r->right is x, both are always evaluated.
947                                 r.Chan = o.expr(r.Chan, nil)
948
949                                 if !ir.IsAutoTmp(r.Chan) {
950                                         r.Chan = o.copyExpr(r.Chan)
951                                 }
952                                 r.Value = o.expr(r.Value, nil)
953                                 if !ir.IsAutoTmp(r.Value) {
954                                         r.Value = o.copyExpr(r.Value)
955                                 }
956                         }
957                 }
958                 // Now that we have accumulated all the temporaries, clean them.
959                 // Also insert any ninit queued during the previous loop.
960                 // (The temporary cleaning must follow that ninit work.)
961                 for _, cas := range n.Cases {
962                         orderBlock(&cas.Body, o.free)
963                         cas.Body.Prepend(o.cleanTempNoPop(t)...)
964
965                         // TODO(mdempsky): Is this actually necessary?
966                         // walkSelect appears to walk Ninit.
967                         cas.Body.Prepend(ir.TakeInit(cas)...)
968                 }
969
970                 o.out = append(o.out, n)
971                 o.popTemp(t)
972
973         // Special: value being sent is passed as a pointer; make it addressable.
974         case ir.OSEND:
975                 n := n.(*ir.SendStmt)
976                 t := o.markTemp()
977                 n.Chan = o.expr(n.Chan, nil)
978                 n.Value = o.expr(n.Value, nil)
979                 if base.Flag.Cfg.Instrumenting {
980                         // Force copying to the stack so that (chan T)(nil) <- x
981                         // is still instrumented as a read of x.
982                         n.Value = o.copyExpr(n.Value)
983                 } else {
984                         n.Value = o.addrTemp(n.Value)
985                 }
986                 o.out = append(o.out, n)
987                 o.cleanTemp(t)
988
989         // TODO(rsc): Clean temporaries more aggressively.
990         // Note that because walkSwitch will rewrite some of the
991         // switch into a binary search, this is not as easy as it looks.
992         // (If we ran that code here we could invoke order.stmt on
993         // the if-else chain instead.)
994         // For now just clean all the temporaries at the end.
995         // In practice that's fine.
996         case ir.OSWITCH:
997                 n := n.(*ir.SwitchStmt)
998                 if base.Debug.Libfuzzer != 0 && !hasDefaultCase(n) {
999                         // Add empty "default:" case for instrumentation.
1000                         n.Cases = append(n.Cases, ir.NewCaseStmt(base.Pos, nil, nil))
1001                 }
1002
1003                 t := o.markTemp()
1004                 n.Tag = o.expr(n.Tag, nil)
1005                 for _, ncas := range n.Cases {
1006                         o.exprListInPlace(ncas.List)
1007                         orderBlock(&ncas.Body, o.free)
1008                 }
1009
1010                 o.out = append(o.out, n)
1011                 o.cleanTemp(t)
1012         }
1013
1014         base.Pos = lno
1015 }
1016
1017 func hasDefaultCase(n *ir.SwitchStmt) bool {
1018         for _, ncas := range n.Cases {
1019                 if len(ncas.List) == 0 {
1020                         return true
1021                 }
1022         }
1023         return false
1024 }
1025
1026 // exprList orders the expression list l into o.
1027 func (o *orderState) exprList(l ir.Nodes) {
1028         s := l
1029         for i := range s {
1030                 s[i] = o.expr(s[i], nil)
1031         }
1032 }
1033
1034 // exprListInPlace orders the expression list l but saves
1035 // the side effects on the individual expression ninit lists.
1036 func (o *orderState) exprListInPlace(l ir.Nodes) {
1037         s := l
1038         for i := range s {
1039                 s[i] = o.exprInPlace(s[i])
1040         }
1041 }
1042
1043 func (o *orderState) exprNoLHS(n ir.Node) ir.Node {
1044         return o.expr(n, nil)
1045 }
1046
1047 // expr orders a single expression, appending side
1048 // effects to o.out as needed.
1049 // If this is part of an assignment lhs = *np, lhs is given.
1050 // Otherwise lhs == nil. (When lhs != nil it may be possible
1051 // to avoid copying the result of the expression to a temporary.)
1052 // The result of expr MUST be assigned back to n, e.g.
1053 //      n.Left = o.expr(n.Left, lhs)
1054 func (o *orderState) expr(n, lhs ir.Node) ir.Node {
1055         if n == nil {
1056                 return n
1057         }
1058         lno := ir.SetPos(n)
1059         n = o.expr1(n, lhs)
1060         base.Pos = lno
1061         return n
1062 }
1063
1064 func (o *orderState) expr1(n, lhs ir.Node) ir.Node {
1065         o.init(n)
1066
1067         switch n.Op() {
1068         default:
1069                 if o.edit == nil {
1070                         o.edit = o.exprNoLHS // create closure once
1071                 }
1072                 ir.EditChildren(n, o.edit)
1073                 return n
1074
1075         // Addition of strings turns into a function call.
1076         // Allocate a temporary to hold the strings.
1077         // Fewer than 5 strings use direct runtime helpers.
1078         case ir.OADDSTR:
1079                 n := n.(*ir.AddStringExpr)
1080                 o.exprList(n.List)
1081
1082                 if len(n.List) > 5 {
1083                         t := types.NewArray(types.Types[types.TSTRING], int64(len(n.List)))
1084                         n.Prealloc = o.newTemp(t, false)
1085                 }
1086
1087                 // Mark string(byteSlice) arguments to reuse byteSlice backing
1088                 // buffer during conversion. String concatenation does not
1089                 // memorize the strings for later use, so it is safe.
1090                 // However, we can do it only if there is at least one non-empty string literal.
1091                 // Otherwise if all other arguments are empty strings,
1092                 // concatstrings will return the reference to the temp string
1093                 // to the caller.
1094                 hasbyte := false
1095
1096                 haslit := false
1097                 for _, n1 := range n.List {
1098                         hasbyte = hasbyte || n1.Op() == ir.OBYTES2STR
1099                         haslit = haslit || n1.Op() == ir.OLITERAL && len(ir.StringVal(n1)) != 0
1100                 }
1101
1102                 if haslit && hasbyte {
1103                         for _, n2 := range n.List {
1104                                 if n2.Op() == ir.OBYTES2STR {
1105                                         n2 := n2.(*ir.ConvExpr)
1106                                         n2.SetOp(ir.OBYTES2STRTMP)
1107                                 }
1108                         }
1109                 }
1110                 return n
1111
1112         case ir.OINDEXMAP:
1113                 n := n.(*ir.IndexExpr)
1114                 n.X = o.expr(n.X, nil)
1115                 n.Index = o.expr(n.Index, nil)
1116                 needCopy := false
1117
1118                 if !n.Assigned {
1119                         // Enforce that any []byte slices we are not copying
1120                         // can not be changed before the map index by forcing
1121                         // the map index to happen immediately following the
1122                         // conversions. See copyExpr a few lines below.
1123                         needCopy = mapKeyReplaceStrConv(n.Index)
1124
1125                         if base.Flag.Cfg.Instrumenting {
1126                                 // Race detector needs the copy.
1127                                 needCopy = true
1128                         }
1129                 }
1130
1131                 // key must be addressable
1132                 n.Index = o.mapKeyTemp(n.X.Type(), n.Index)
1133                 if needCopy {
1134                         return o.copyExpr(n)
1135                 }
1136                 return n
1137
1138         // concrete type (not interface) argument might need an addressable
1139         // temporary to pass to the runtime conversion routine.
1140         case ir.OCONVIFACE:
1141                 n := n.(*ir.ConvExpr)
1142                 n.X = o.expr(n.X, nil)
1143                 if n.X.Type().IsInterface() {
1144                         return n
1145                 }
1146                 if _, _, needsaddr := convFuncName(n.X.Type(), n.Type()); needsaddr || isStaticCompositeLiteral(n.X) {
1147                         // Need a temp if we need to pass the address to the conversion function.
1148                         // We also process static composite literal node here, making a named static global
1149                         // whose address we can put directly in an interface (see OCONVIFACE case in walk).
1150                         n.X = o.addrTemp(n.X)
1151                 }
1152                 return n
1153
1154         case ir.OCONVNOP:
1155                 n := n.(*ir.ConvExpr)
1156                 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) {
1157                         call := n.X.(*ir.CallExpr)
1158                         // When reordering unsafe.Pointer(f()) into a separate
1159                         // statement, the conversion and function call must stay
1160                         // together. See golang.org/issue/15329.
1161                         o.init(call)
1162                         o.call(call)
1163                         if lhs == nil || lhs.Op() != ir.ONAME || base.Flag.Cfg.Instrumenting {
1164                                 return o.copyExpr(n)
1165                         }
1166                 } else {
1167                         n.X = o.expr(n.X, nil)
1168                 }
1169                 return n
1170
1171         case ir.OANDAND, ir.OOROR:
1172                 // ... = LHS && RHS
1173                 //
1174                 // var r bool
1175                 // r = LHS
1176                 // if r {       // or !r, for OROR
1177                 //     r = RHS
1178                 // }
1179                 // ... = r
1180
1181                 n := n.(*ir.LogicalExpr)
1182                 r := o.newTemp(n.Type(), false)
1183
1184                 // Evaluate left-hand side.
1185                 lhs := o.expr(n.X, nil)
1186                 o.out = append(o.out, typecheck.Stmt(ir.NewAssignStmt(base.Pos, r, lhs)))
1187
1188                 // Evaluate right-hand side, save generated code.
1189                 saveout := o.out
1190                 o.out = nil
1191                 t := o.markTemp()
1192                 o.edge()
1193                 rhs := o.expr(n.Y, nil)
1194                 o.out = append(o.out, typecheck.Stmt(ir.NewAssignStmt(base.Pos, r, rhs)))
1195                 o.cleanTemp(t)
1196                 gen := o.out
1197                 o.out = saveout
1198
1199                 // If left-hand side doesn't cause a short-circuit, issue right-hand side.
1200                 nif := ir.NewIfStmt(base.Pos, r, nil, nil)
1201                 if n.Op() == ir.OANDAND {
1202                         nif.Body = gen
1203                 } else {
1204                         nif.Else = gen
1205                 }
1206                 o.out = append(o.out, nif)
1207                 return r
1208
1209         case ir.OCALLFUNC,
1210                 ir.OCALLINTER,
1211                 ir.OCALLMETH,
1212                 ir.OCAP,
1213                 ir.OCOMPLEX,
1214                 ir.OCOPY,
1215                 ir.OIMAG,
1216                 ir.OLEN,
1217                 ir.OMAKECHAN,
1218                 ir.OMAKEMAP,
1219                 ir.OMAKESLICE,
1220                 ir.OMAKESLICECOPY,
1221                 ir.ONEW,
1222                 ir.OREAL,
1223                 ir.ORECOVERFP,
1224                 ir.OSTR2BYTES,
1225                 ir.OSTR2BYTESTMP,
1226                 ir.OSTR2RUNES:
1227
1228                 if isRuneCount(n) {
1229                         // len([]rune(s)) is rewritten to runtime.countrunes(s) later.
1230                         conv := n.(*ir.UnaryExpr).X.(*ir.ConvExpr)
1231                         conv.X = o.expr(conv.X, nil)
1232                 } else {
1233                         o.call(n)
1234                 }
1235
1236                 if lhs == nil || lhs.Op() != ir.ONAME || base.Flag.Cfg.Instrumenting {
1237                         return o.copyExpr(n)
1238                 }
1239                 return n
1240
1241         case ir.OAPPEND:
1242                 // Check for append(x, make([]T, y)...) .
1243                 n := n.(*ir.CallExpr)
1244                 if isAppendOfMake(n) {
1245                         n.Args[0] = o.expr(n.Args[0], nil) // order x
1246                         mk := n.Args[1].(*ir.MakeExpr)
1247                         mk.Len = o.expr(mk.Len, nil) // order y
1248                 } else {
1249                         o.exprList(n.Args)
1250                 }
1251
1252                 if lhs == nil || lhs.Op() != ir.ONAME && !ir.SameSafeExpr(lhs, n.Args[0]) {
1253                         return o.copyExpr(n)
1254                 }
1255                 return n
1256
1257         case ir.OSLICE, ir.OSLICEARR, ir.OSLICESTR, ir.OSLICE3, ir.OSLICE3ARR:
1258                 n := n.(*ir.SliceExpr)
1259                 n.X = o.expr(n.X, nil)
1260                 n.Low = o.cheapExpr(o.expr(n.Low, nil))
1261                 n.High = o.cheapExpr(o.expr(n.High, nil))
1262                 n.Max = o.cheapExpr(o.expr(n.Max, nil))
1263                 if lhs == nil || lhs.Op() != ir.ONAME && !ir.SameSafeExpr(lhs, n.X) {
1264                         return o.copyExpr(n)
1265                 }
1266                 return n
1267
1268         case ir.OCLOSURE:
1269                 n := n.(*ir.ClosureExpr)
1270                 if n.Transient() && len(n.Func.ClosureVars) > 0 {
1271                         n.Prealloc = o.newTemp(typecheck.ClosureType(n), false)
1272                 }
1273                 return n
1274
1275         case ir.OCALLPART:
1276                 n := n.(*ir.SelectorExpr)
1277                 n.X = o.expr(n.X, nil)
1278                 if n.Transient() {
1279                         t := typecheck.PartialCallType(n)
1280                         n.Prealloc = o.newTemp(t, false)
1281                 }
1282                 return n
1283
1284         case ir.OSLICELIT:
1285                 n := n.(*ir.CompLitExpr)
1286                 o.exprList(n.List)
1287                 if n.Transient() {
1288                         t := types.NewArray(n.Type().Elem(), n.Len)
1289                         n.Prealloc = o.newTemp(t, false)
1290                 }
1291                 return n
1292
1293         case ir.ODOTTYPE, ir.ODOTTYPE2:
1294                 n := n.(*ir.TypeAssertExpr)
1295                 n.X = o.expr(n.X, nil)
1296                 if !types.IsDirectIface(n.Type()) || base.Flag.Cfg.Instrumenting {
1297                         return o.copyExprClear(n)
1298                 }
1299                 return n
1300
1301         case ir.ORECV:
1302                 n := n.(*ir.UnaryExpr)
1303                 n.X = o.expr(n.X, nil)
1304                 return o.copyExprClear(n)
1305
1306         case ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE:
1307                 n := n.(*ir.BinaryExpr)
1308                 n.X = o.expr(n.X, nil)
1309                 n.Y = o.expr(n.Y, nil)
1310
1311                 t := n.X.Type()
1312                 switch {
1313                 case t.IsString():
1314                         // Mark string(byteSlice) arguments to reuse byteSlice backing
1315                         // buffer during conversion. String comparison does not
1316                         // memorize the strings for later use, so it is safe.
1317                         if n.X.Op() == ir.OBYTES2STR {
1318                                 n.X.(*ir.ConvExpr).SetOp(ir.OBYTES2STRTMP)
1319                         }
1320                         if n.Y.Op() == ir.OBYTES2STR {
1321                                 n.Y.(*ir.ConvExpr).SetOp(ir.OBYTES2STRTMP)
1322                         }
1323
1324                 case t.IsStruct() || t.IsArray():
1325                         // for complex comparisons, we need both args to be
1326                         // addressable so we can pass them to the runtime.
1327                         n.X = o.addrTemp(n.X)
1328                         n.Y = o.addrTemp(n.Y)
1329                 }
1330                 return n
1331
1332         case ir.OMAPLIT:
1333                 // Order map by converting:
1334                 //   map[int]int{
1335                 //     a(): b(),
1336                 //     c(): d(),
1337                 //     e(): f(),
1338                 //   }
1339                 // to
1340                 //   m := map[int]int{}
1341                 //   m[a()] = b()
1342                 //   m[c()] = d()
1343                 //   m[e()] = f()
1344                 // Then order the result.
1345                 // Without this special case, order would otherwise compute all
1346                 // the keys and values before storing any of them to the map.
1347                 // See issue 26552.
1348                 n := n.(*ir.CompLitExpr)
1349                 entries := n.List
1350                 statics := entries[:0]
1351                 var dynamics []*ir.KeyExpr
1352                 for _, r := range entries {
1353                         r := r.(*ir.KeyExpr)
1354
1355                         if !isStaticCompositeLiteral(r.Key) || !isStaticCompositeLiteral(r.Value) {
1356                                 dynamics = append(dynamics, r)
1357                                 continue
1358                         }
1359
1360                         // Recursively ordering some static entries can change them to dynamic;
1361                         // e.g., OCONVIFACE nodes. See #31777.
1362                         r = o.expr(r, nil).(*ir.KeyExpr)
1363                         if !isStaticCompositeLiteral(r.Key) || !isStaticCompositeLiteral(r.Value) {
1364                                 dynamics = append(dynamics, r)
1365                                 continue
1366                         }
1367
1368                         statics = append(statics, r)
1369                 }
1370                 n.List = statics
1371
1372                 if len(dynamics) == 0 {
1373                         return n
1374                 }
1375
1376                 // Emit the creation of the map (with all its static entries).
1377                 m := o.newTemp(n.Type(), false)
1378                 as := ir.NewAssignStmt(base.Pos, m, n)
1379                 typecheck.Stmt(as)
1380                 o.stmt(as)
1381
1382                 // Emit eval+insert of dynamic entries, one at a time.
1383                 for _, r := range dynamics {
1384                         as := ir.NewAssignStmt(base.Pos, ir.NewIndexExpr(base.Pos, m, r.Key), r.Value)
1385                         typecheck.Stmt(as) // Note: this converts the OINDEX to an OINDEXMAP
1386                         o.stmt(as)
1387                 }
1388                 return m
1389         }
1390
1391         // No return - type-assertions above. Each case must return for itself.
1392 }
1393
1394 // as2func orders OAS2FUNC nodes. It creates temporaries to ensure left-to-right assignment.
1395 // The caller should order the right-hand side of the assignment before calling order.as2func.
1396 // It rewrites,
1397 //      a, b, a = ...
1398 // as
1399 //      tmp1, tmp2, tmp3 = ...
1400 //      a, b, a = tmp1, tmp2, tmp3
1401 // This is necessary to ensure left to right assignment order.
1402 func (o *orderState) as2func(n *ir.AssignListStmt) {
1403         results := n.Rhs[0].Type()
1404         as := ir.NewAssignListStmt(n.Pos(), ir.OAS2, nil, nil)
1405         for i, nl := range n.Lhs {
1406                 if !ir.IsBlank(nl) {
1407                         typ := results.Field(i).Type
1408                         tmp := o.newTemp(typ, typ.HasPointers())
1409                         n.Lhs[i] = tmp
1410                         as.Lhs = append(as.Lhs, nl)
1411                         as.Rhs = append(as.Rhs, tmp)
1412                 }
1413         }
1414
1415         o.out = append(o.out, n)
1416         o.stmt(typecheck.Stmt(as))
1417 }
1418
1419 // as2ok orders OAS2XXX with ok.
1420 // Just like as2func, this also adds temporaries to ensure left-to-right assignment.
1421 func (o *orderState) as2ok(n *ir.AssignListStmt) {
1422         as := ir.NewAssignListStmt(n.Pos(), ir.OAS2, nil, nil)
1423
1424         do := func(i int, typ *types.Type) {
1425                 if nl := n.Lhs[i]; !ir.IsBlank(nl) {
1426                         var tmp ir.Node = o.newTemp(typ, typ.HasPointers())
1427                         n.Lhs[i] = tmp
1428                         as.Lhs = append(as.Lhs, nl)
1429                         if i == 1 {
1430                                 // The "ok" result is an untyped boolean according to the Go
1431                                 // spec. We need to explicitly convert it to the LHS type in
1432                                 // case the latter is a defined boolean type (#8475).
1433                                 tmp = typecheck.Conv(tmp, nl.Type())
1434                         }
1435                         as.Rhs = append(as.Rhs, tmp)
1436                 }
1437         }
1438
1439         do(0, n.Rhs[0].Type())
1440         do(1, types.Types[types.TBOOL])
1441
1442         o.out = append(o.out, n)
1443         o.stmt(typecheck.Stmt(as))
1444 }
1445
1446 // isFuncPCIntrinsic returns whether n is a direct call of internal/abi.FuncPCABIxxx functions.
1447 func isFuncPCIntrinsic(n *ir.CallExpr) bool {
1448         if n.Op() != ir.OCALLFUNC || n.X.Op() != ir.ONAME {
1449                 return false
1450         }
1451         fn := n.X.(*ir.Name).Sym()
1452         return (fn.Name == "FuncPCABI0" || fn.Name == "FuncPCABIInternal") &&
1453                 (fn.Pkg.Path == "internal/abi" || fn.Pkg == types.LocalPkg && base.Ctxt.Pkgpath == "internal/abi")
1454 }
1455
1456 // isIfaceOfFunc returns whether n is an interface conversion from a direct reference of a func.
1457 func isIfaceOfFunc(n ir.Node) bool {
1458         return n.Op() == ir.OCONVIFACE && n.(*ir.ConvExpr).X.Op() == ir.ONAME && n.(*ir.ConvExpr).X.(*ir.Name).Class == ir.PFUNC
1459 }