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