// combine copyelim and phielim into a single pass. // copyelim removes all uses of OpCopy values from f. // A subsequent deadcode pass is needed to actually remove the copies. func copyelim(f *Func) { … } // copySource returns the (non-copy) op which is the // ultimate source of v. v must be a copy op. func copySource(v *Value) *Value { … } // copyelimValue ensures that no args of v are copies. func copyelimValue(v *Value) { … } // phielim eliminates redundant phi values from f. // A phi is redundant if its arguments are all equal. For // purposes of counting, ignore the phi itself. Both of // these phis are redundant: // // v = phi(x,x,x) // v = phi(x,v,x,v) // // We repeat this process to also catch situations like: // // v = phi(x, phi(x, x), phi(x, v)) // // TODO: Can we also simplify cases like: // // v = phi(v, w, x) // w = phi(v, w, x) // // and would that be useful? func phielim(f *Func) { … } // phielimValue tries to convert the phi v to a copy. func phielimValue(v *Value) bool { … }