github.com/miolini/go@v0.0.0-20160405192216-fca68c8cb408/src/cmd/compile/internal/ssa/copyelim.go (about) 1 // Copyright 2015 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 ssa 6 7 // copyelim removes all copies from f. 8 func copyelim(f *Func) { 9 for _, b := range f.Blocks { 10 for _, v := range b.Values { 11 copyelimValue(v) 12 } 13 v := b.Control 14 if v != nil && v.Op == OpCopy { 15 for v.Op == OpCopy { 16 v = v.Args[0] 17 } 18 b.SetControl(v) 19 } 20 } 21 22 // Update named values. 23 for _, name := range f.Names { 24 values := f.NamedValues[name] 25 for i, v := range values { 26 x := v 27 for x.Op == OpCopy { 28 x = x.Args[0] 29 } 30 if x != v { 31 values[i] = x 32 } 33 } 34 } 35 } 36 37 func copyelimValue(v *Value) bool { 38 // elide any copies generated during rewriting 39 changed := false 40 for i, a := range v.Args { 41 if a.Op != OpCopy { 42 continue 43 } 44 // Rewriting can generate OpCopy loops. 45 // They are harmless (see removePredecessor), 46 // but take care to stop if we find a cycle. 47 slow := a // advances every other iteration 48 var advance bool 49 for a.Op == OpCopy { 50 a = a.Args[0] 51 if slow == a { 52 break 53 } 54 if advance { 55 slow = slow.Args[0] 56 } 57 advance = !advance 58 } 59 v.SetArg(i, a) 60 changed = true 61 } 62 return changed 63 }