]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/compile/internal/walk/order.go
cmd/compile/internal/ir: remove ODCLCONST and ODCLTYPE
[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(base.Pos, 0xff)),
437                 []ir.Node{ir.NewAssignStmt(base.Pos, counter, ir.NewInt(base.Pos, 1))},
438                 []ir.Node{ir.NewAssignOpStmt(base.Pos, ir.OADD, counter, ir.NewInt(base.Pos, 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.OFALL,
717                 ir.OGOTO,
718                 ir.OLABEL,
719                 ir.OTAILCALL:
720                 o.out = append(o.out, n)
721
722         // Special: handle call arguments.
723         case ir.OCALLFUNC, ir.OCALLINTER:
724                 n := n.(*ir.CallExpr)
725                 t := o.markTemp()
726                 o.call(n)
727                 o.out = append(o.out, n)
728                 o.popTemp(t)
729
730         case ir.OINLCALL:
731                 n := n.(*ir.InlinedCallExpr)
732                 o.stmtList(n.Body)
733
734                 // discard results; double-check for no side effects
735                 for _, result := range n.ReturnVars {
736                         if staticinit.AnySideEffects(result) {
737                                 base.FatalfAt(result.Pos(), "inlined call result has side effects: %v", result)
738                         }
739                 }
740
741         case ir.OCHECKNIL, ir.OCLEAR, ir.OCLOSE, ir.OPANIC, ir.ORECV:
742                 n := n.(*ir.UnaryExpr)
743                 t := o.markTemp()
744                 n.X = o.expr(n.X, nil)
745                 o.out = append(o.out, n)
746                 o.popTemp(t)
747
748         case ir.OCOPY:
749                 n := n.(*ir.BinaryExpr)
750                 t := o.markTemp()
751                 n.X = o.expr(n.X, nil)
752                 n.Y = o.expr(n.Y, nil)
753                 o.out = append(o.out, n)
754                 o.popTemp(t)
755
756         case ir.OPRINT, ir.OPRINTN, ir.ORECOVERFP:
757                 n := n.(*ir.CallExpr)
758                 t := o.markTemp()
759                 o.call(n)
760                 o.out = append(o.out, n)
761                 o.popTemp(t)
762
763         // Special: order arguments to inner call but not call itself.
764         case ir.ODEFER, ir.OGO:
765                 n := n.(*ir.GoDeferStmt)
766                 t := o.markTemp()
767                 o.init(n.Call)
768                 o.call(n.Call)
769                 o.out = append(o.out, n)
770                 o.popTemp(t)
771
772         case ir.ODELETE:
773                 n := n.(*ir.CallExpr)
774                 t := o.markTemp()
775                 n.Args[0] = o.expr(n.Args[0], nil)
776                 n.Args[1] = o.expr(n.Args[1], nil)
777                 n.Args[1] = o.mapKeyTemp(n.Pos(), n.Args[0].Type(), n.Args[1])
778                 o.out = append(o.out, n)
779                 o.popTemp(t)
780
781         // Clean temporaries from condition evaluation at
782         // beginning of loop body and after for statement.
783         case ir.OFOR:
784                 n := n.(*ir.ForStmt)
785                 t := o.markTemp()
786                 n.Cond = o.exprInPlace(n.Cond)
787                 orderBlock(&n.Body, o.free)
788                 n.Post = orderStmtInPlace(n.Post, o.free)
789                 o.out = append(o.out, n)
790                 o.popTemp(t)
791
792         // Clean temporaries from condition at
793         // beginning of both branches.
794         case ir.OIF:
795                 n := n.(*ir.IfStmt)
796                 t := o.markTemp()
797                 n.Cond = o.exprInPlace(n.Cond)
798                 o.popTemp(t)
799                 orderBlock(&n.Body, o.free)
800                 orderBlock(&n.Else, o.free)
801                 o.out = append(o.out, n)
802
803         case ir.ORANGE:
804                 // n.Right is the expression being ranged over.
805                 // order it, and then make a copy if we need one.
806                 // We almost always do, to ensure that we don't
807                 // see any value changes made during the loop.
808                 // Usually the copy is cheap (e.g., array pointer,
809                 // chan, slice, string are all tiny).
810                 // The exception is ranging over an array value
811                 // (not a slice, not a pointer to array),
812                 // which must make a copy to avoid seeing updates made during
813                 // the range body. Ranging over an array value is uncommon though.
814
815                 // Mark []byte(str) range expression to reuse string backing storage.
816                 // It is safe because the storage cannot be mutated.
817                 n := n.(*ir.RangeStmt)
818                 if n.X.Op() == ir.OSTR2BYTES {
819                         n.X.(*ir.ConvExpr).SetOp(ir.OSTR2BYTESTMP)
820                 }
821
822                 t := o.markTemp()
823                 n.X = o.expr(n.X, nil)
824
825                 orderBody := true
826                 xt := typecheck.RangeExprType(n.X.Type())
827                 switch xt.Kind() {
828                 default:
829                         base.Fatalf("order.stmt range %v", n.Type())
830
831                 case types.TARRAY, types.TSLICE:
832                         if n.Value == nil || ir.IsBlank(n.Value) {
833                                 // for i := range x will only use x once, to compute len(x).
834                                 // No need to copy it.
835                                 break
836                         }
837                         fallthrough
838
839                 case types.TCHAN, types.TSTRING:
840                         // chan, string, slice, array ranges use value multiple times.
841                         // make copy.
842                         r := n.X
843
844                         if r.Type().IsString() && r.Type() != types.Types[types.TSTRING] {
845                                 r = ir.NewConvExpr(base.Pos, ir.OCONV, nil, r)
846                                 r.SetType(types.Types[types.TSTRING])
847                                 r = typecheck.Expr(r)
848                         }
849
850                         n.X = o.copyExpr(r)
851
852                 case types.TMAP:
853                         if isMapClear(n) {
854                                 // Preserve the body of the map clear pattern so it can
855                                 // be detected during walk. The loop body will not be used
856                                 // when optimizing away the range loop to a runtime call.
857                                 orderBody = false
858                                 break
859                         }
860
861                         // copy the map value in case it is a map literal.
862                         // TODO(rsc): Make tmp = literal expressions reuse tmp.
863                         // For maps tmp is just one word so it hardly matters.
864                         r := n.X
865                         n.X = o.copyExpr(r)
866
867                         // n.Prealloc is the temp for the iterator.
868                         // MapIterType contains pointers and needs to be zeroed.
869                         n.Prealloc = o.newTemp(reflectdata.MapIterType(xt), true)
870                 }
871                 n.Key = o.exprInPlace(n.Key)
872                 n.Value = o.exprInPlace(n.Value)
873                 if orderBody {
874                         orderBlock(&n.Body, o.free)
875                 }
876                 o.out = append(o.out, n)
877                 o.popTemp(t)
878
879         case ir.ORETURN:
880                 n := n.(*ir.ReturnStmt)
881                 o.exprList(n.Results)
882                 o.out = append(o.out, n)
883
884         // Special: clean case temporaries in each block entry.
885         // Select must enter one of its blocks, so there is no
886         // need for a cleaning at the end.
887         // Doubly special: evaluation order for select is stricter
888         // than ordinary expressions. Even something like p.c
889         // has to be hoisted into a temporary, so that it cannot be
890         // reordered after the channel evaluation for a different
891         // case (if p were nil, then the timing of the fault would
892         // give this away).
893         case ir.OSELECT:
894                 n := n.(*ir.SelectStmt)
895                 t := o.markTemp()
896                 for _, ncas := range n.Cases {
897                         r := ncas.Comm
898                         ir.SetPos(ncas)
899
900                         // Append any new body prologue to ninit.
901                         // The next loop will insert ninit into nbody.
902                         if len(ncas.Init()) != 0 {
903                                 base.Fatalf("order select ninit")
904                         }
905                         if r == nil {
906                                 continue
907                         }
908                         switch r.Op() {
909                         default:
910                                 ir.Dump("select case", r)
911                                 base.Fatalf("unknown op in select %v", r.Op())
912
913                         case ir.OSELRECV2:
914                                 // case x, ok = <-c
915                                 r := r.(*ir.AssignListStmt)
916                                 recv := r.Rhs[0].(*ir.UnaryExpr)
917                                 recv.X = o.expr(recv.X, nil)
918                                 if !ir.IsAutoTmp(recv.X) {
919                                         recv.X = o.copyExpr(recv.X)
920                                 }
921                                 init := ir.TakeInit(r)
922
923                                 colas := r.Def
924                                 do := func(i int, t *types.Type) {
925                                         n := r.Lhs[i]
926                                         if ir.IsBlank(n) {
927                                                 return
928                                         }
929                                         // If this is case x := <-ch or case x, y := <-ch, the case has
930                                         // the ODCL nodes to declare x and y. We want to delay that
931                                         // declaration (and possible allocation) until inside the case body.
932                                         // Delete the ODCL nodes here and recreate them inside the body below.
933                                         if colas {
934                                                 if len(init) > 0 && init[0].Op() == ir.ODCL && init[0].(*ir.Decl).X == n {
935                                                         init = init[1:]
936
937                                                         // iimport may have added a default initialization assignment,
938                                                         // due to how it handles ODCL statements.
939                                                         if len(init) > 0 && init[0].Op() == ir.OAS && init[0].(*ir.AssignStmt).X == n {
940                                                                 init = init[1:]
941                                                         }
942                                                 }
943                                                 dcl := typecheck.Stmt(ir.NewDecl(base.Pos, ir.ODCL, n.(*ir.Name)))
944                                                 ncas.PtrInit().Append(dcl)
945                                         }
946                                         tmp := o.newTemp(t, t.HasPointers())
947                                         as := typecheck.Stmt(ir.NewAssignStmt(base.Pos, n, typecheck.Conv(tmp, n.Type())))
948                                         ncas.PtrInit().Append(as)
949                                         r.Lhs[i] = tmp
950                                 }
951                                 do(0, recv.X.Type().Elem())
952                                 do(1, types.Types[types.TBOOL])
953                                 if len(init) != 0 {
954                                         ir.DumpList("ninit", init)
955                                         base.Fatalf("ninit on select recv")
956                                 }
957                                 orderBlock(ncas.PtrInit(), o.free)
958
959                         case ir.OSEND:
960                                 r := r.(*ir.SendStmt)
961                                 if len(r.Init()) != 0 {
962                                         ir.DumpList("ninit", r.Init())
963                                         base.Fatalf("ninit on select send")
964                                 }
965
966                                 // case c <- x
967                                 // r->left is c, r->right is x, both are always evaluated.
968                                 r.Chan = o.expr(r.Chan, nil)
969
970                                 if !ir.IsAutoTmp(r.Chan) {
971                                         r.Chan = o.copyExpr(r.Chan)
972                                 }
973                                 r.Value = o.expr(r.Value, nil)
974                                 if !ir.IsAutoTmp(r.Value) {
975                                         r.Value = o.copyExpr(r.Value)
976                                 }
977                         }
978                 }
979                 // Now that we have accumulated all the temporaries, clean them.
980                 // Also insert any ninit queued during the previous loop.
981                 // (The temporary cleaning must follow that ninit work.)
982                 for _, cas := range n.Cases {
983                         orderBlock(&cas.Body, o.free)
984
985                         // TODO(mdempsky): Is this actually necessary?
986                         // walkSelect appears to walk Ninit.
987                         cas.Body.Prepend(ir.TakeInit(cas)...)
988                 }
989
990                 o.out = append(o.out, n)
991                 o.popTemp(t)
992
993         // Special: value being sent is passed as a pointer; make it addressable.
994         case ir.OSEND:
995                 n := n.(*ir.SendStmt)
996                 t := o.markTemp()
997                 n.Chan = o.expr(n.Chan, nil)
998                 n.Value = o.expr(n.Value, nil)
999                 if base.Flag.Cfg.Instrumenting {
1000                         // Force copying to the stack so that (chan T)(nil) <- x
1001                         // is still instrumented as a read of x.
1002                         n.Value = o.copyExpr(n.Value)
1003                 } else {
1004                         n.Value = o.addrTemp(n.Value)
1005                 }
1006                 o.out = append(o.out, n)
1007                 o.popTemp(t)
1008
1009         // TODO(rsc): Clean temporaries more aggressively.
1010         // Note that because walkSwitch will rewrite some of the
1011         // switch into a binary search, this is not as easy as it looks.
1012         // (If we ran that code here we could invoke order.stmt on
1013         // the if-else chain instead.)
1014         // For now just clean all the temporaries at the end.
1015         // In practice that's fine.
1016         case ir.OSWITCH:
1017                 n := n.(*ir.SwitchStmt)
1018                 if base.Debug.Libfuzzer != 0 && !hasDefaultCase(n) {
1019                         // Add empty "default:" case for instrumentation.
1020                         n.Cases = append(n.Cases, ir.NewCaseStmt(base.Pos, nil, nil))
1021                 }
1022
1023                 t := o.markTemp()
1024                 n.Tag = o.expr(n.Tag, nil)
1025                 for _, ncas := range n.Cases {
1026                         o.exprListInPlace(ncas.List)
1027                         orderBlock(&ncas.Body, o.free)
1028                 }
1029
1030                 o.out = append(o.out, n)
1031                 o.popTemp(t)
1032         }
1033
1034         base.Pos = lno
1035 }
1036
1037 func hasDefaultCase(n *ir.SwitchStmt) bool {
1038         for _, ncas := range n.Cases {
1039                 if len(ncas.List) == 0 {
1040                         return true
1041                 }
1042         }
1043         return false
1044 }
1045
1046 // exprList orders the expression list l into o.
1047 func (o *orderState) exprList(l ir.Nodes) {
1048         s := l
1049         for i := range s {
1050                 s[i] = o.expr(s[i], nil)
1051         }
1052 }
1053
1054 // exprListInPlace orders the expression list l but saves
1055 // the side effects on the individual expression ninit lists.
1056 func (o *orderState) exprListInPlace(l ir.Nodes) {
1057         s := l
1058         for i := range s {
1059                 s[i] = o.exprInPlace(s[i])
1060         }
1061 }
1062
1063 func (o *orderState) exprNoLHS(n ir.Node) ir.Node {
1064         return o.expr(n, nil)
1065 }
1066
1067 // expr orders a single expression, appending side
1068 // effects to o.out as needed.
1069 // If this is part of an assignment lhs = *np, lhs is given.
1070 // Otherwise lhs == nil. (When lhs != nil it may be possible
1071 // to avoid copying the result of the expression to a temporary.)
1072 // The result of expr MUST be assigned back to n, e.g.
1073 //
1074 //      n.Left = o.expr(n.Left, lhs)
1075 func (o *orderState) expr(n, lhs ir.Node) ir.Node {
1076         if n == nil {
1077                 return n
1078         }
1079         lno := ir.SetPos(n)
1080         n = o.expr1(n, lhs)
1081         base.Pos = lno
1082         return n
1083 }
1084
1085 func (o *orderState) expr1(n, lhs ir.Node) ir.Node {
1086         o.init(n)
1087
1088         switch n.Op() {
1089         default:
1090                 if o.edit == nil {
1091                         o.edit = o.exprNoLHS // create closure once
1092                 }
1093                 ir.EditChildren(n, o.edit)
1094                 return n
1095
1096         // Addition of strings turns into a function call.
1097         // Allocate a temporary to hold the strings.
1098         // Fewer than 5 strings use direct runtime helpers.
1099         case ir.OADDSTR:
1100                 n := n.(*ir.AddStringExpr)
1101                 o.exprList(n.List)
1102
1103                 if len(n.List) > 5 {
1104                         t := types.NewArray(types.Types[types.TSTRING], int64(len(n.List)))
1105                         n.Prealloc = o.newTemp(t, false)
1106                 }
1107
1108                 // Mark string(byteSlice) arguments to reuse byteSlice backing
1109                 // buffer during conversion. String concatenation does not
1110                 // memorize the strings for later use, so it is safe.
1111                 // However, we can do it only if there is at least one non-empty string literal.
1112                 // Otherwise if all other arguments are empty strings,
1113                 // concatstrings will return the reference to the temp string
1114                 // to the caller.
1115                 hasbyte := false
1116
1117                 haslit := false
1118                 for _, n1 := range n.List {
1119                         hasbyte = hasbyte || n1.Op() == ir.OBYTES2STR
1120                         haslit = haslit || n1.Op() == ir.OLITERAL && len(ir.StringVal(n1)) != 0
1121                 }
1122
1123                 if haslit && hasbyte {
1124                         for _, n2 := range n.List {
1125                                 if n2.Op() == ir.OBYTES2STR {
1126                                         n2 := n2.(*ir.ConvExpr)
1127                                         n2.SetOp(ir.OBYTES2STRTMP)
1128                                 }
1129                         }
1130                 }
1131                 return n
1132
1133         case ir.OINDEXMAP:
1134                 n := n.(*ir.IndexExpr)
1135                 n.X = o.expr(n.X, nil)
1136                 n.Index = o.expr(n.Index, nil)
1137                 needCopy := false
1138
1139                 if !n.Assigned {
1140                         // Enforce that any []byte slices we are not copying
1141                         // can not be changed before the map index by forcing
1142                         // the map index to happen immediately following the
1143                         // conversions. See copyExpr a few lines below.
1144                         needCopy = mapKeyReplaceStrConv(n.Index)
1145
1146                         if base.Flag.Cfg.Instrumenting {
1147                                 // Race detector needs the copy.
1148                                 needCopy = true
1149                         }
1150                 }
1151
1152                 // key must be addressable
1153                 n.Index = o.mapKeyTemp(n.Pos(), n.X.Type(), n.Index)
1154                 if needCopy {
1155                         return o.copyExpr(n)
1156                 }
1157                 return n
1158
1159         // concrete type (not interface) argument might need an addressable
1160         // temporary to pass to the runtime conversion routine.
1161         case ir.OCONVIFACE, ir.OCONVIDATA:
1162                 n := n.(*ir.ConvExpr)
1163                 n.X = o.expr(n.X, nil)
1164                 if n.X.Type().IsInterface() {
1165                         return n
1166                 }
1167                 if _, _, needsaddr := dataWordFuncName(n.X.Type()); needsaddr || isStaticCompositeLiteral(n.X) {
1168                         // Need a temp if we need to pass the address to the conversion function.
1169                         // We also process static composite literal node here, making a named static global
1170                         // whose address we can put directly in an interface (see OCONVIFACE/OCONVIDATA case in walk).
1171                         n.X = o.addrTemp(n.X)
1172                 }
1173                 return n
1174
1175         case ir.OCONVNOP:
1176                 n := n.(*ir.ConvExpr)
1177                 if n.X.Op() == ir.OCALLMETH {
1178                         base.FatalfAt(n.X.Pos(), "OCALLMETH missed by typecheck")
1179                 }
1180                 if n.Type().IsKind(types.TUNSAFEPTR) && n.X.Type().IsKind(types.TUINTPTR) && (n.X.Op() == ir.OCALLFUNC || n.X.Op() == ir.OCALLINTER) {
1181                         call := n.X.(*ir.CallExpr)
1182                         // When reordering unsafe.Pointer(f()) into a separate
1183                         // statement, the conversion and function call must stay
1184                         // together. See golang.org/issue/15329.
1185                         o.init(call)
1186                         o.call(call)
1187                         if lhs == nil || lhs.Op() != ir.ONAME || base.Flag.Cfg.Instrumenting {
1188                                 return o.copyExpr(n)
1189                         }
1190                 } else {
1191                         n.X = o.expr(n.X, nil)
1192                 }
1193                 return n
1194
1195         case ir.OANDAND, ir.OOROR:
1196                 // ... = LHS && RHS
1197                 //
1198                 // var r bool
1199                 // r = LHS
1200                 // if r {       // or !r, for OROR
1201                 //     r = RHS
1202                 // }
1203                 // ... = r
1204
1205                 n := n.(*ir.LogicalExpr)
1206                 r := o.newTemp(n.Type(), false)
1207
1208                 // Evaluate left-hand side.
1209                 lhs := o.expr(n.X, nil)
1210                 o.out = append(o.out, typecheck.Stmt(ir.NewAssignStmt(base.Pos, r, lhs)))
1211
1212                 // Evaluate right-hand side, save generated code.
1213                 saveout := o.out
1214                 o.out = nil
1215                 t := o.markTemp()
1216                 o.edge()
1217                 rhs := o.expr(n.Y, nil)
1218                 o.out = append(o.out, typecheck.Stmt(ir.NewAssignStmt(base.Pos, r, rhs)))
1219                 o.popTemp(t)
1220                 gen := o.out
1221                 o.out = saveout
1222
1223                 // If left-hand side doesn't cause a short-circuit, issue right-hand side.
1224                 nif := ir.NewIfStmt(base.Pos, r, nil, nil)
1225                 if n.Op() == ir.OANDAND {
1226                         nif.Body = gen
1227                 } else {
1228                         nif.Else = gen
1229                 }
1230                 o.out = append(o.out, nif)
1231                 return r
1232
1233         case ir.OCALLMETH:
1234                 base.FatalfAt(n.Pos(), "OCALLMETH missed by typecheck")
1235                 panic("unreachable")
1236
1237         case ir.OCALLFUNC,
1238                 ir.OCALLINTER,
1239                 ir.OCAP,
1240                 ir.OCOMPLEX,
1241                 ir.OCOPY,
1242                 ir.OIMAG,
1243                 ir.OLEN,
1244                 ir.OMAKECHAN,
1245                 ir.OMAKEMAP,
1246                 ir.OMAKESLICE,
1247                 ir.OMAKESLICECOPY,
1248                 ir.OMAX,
1249                 ir.OMIN,
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 }