void cp(Deque<Block> code){
  EdgeMap<Expr> uses=findUses(code);
  Map<Expr,Expr> map=new HashMap<Expr,Expr>();
  Set<Expr> work=new TreeSet<Expr>();
  for (  Block b : code) {
    if (!b.must_isolate_block) {
      for (      Expr e : b)       if (e.op == OP_phi || e.op == OP_dup)       work.add(e);
    }
  }
  while (!work.isEmpty()) {
    Expr e=getExpr(work);
    rename(e,e.args,map,uses);
    rename(e,e.scopes,map,uses);
    rename(e,e.locals,map,uses);
    if (e.op == OP_dup) {
      map.put(e,e.locals[0]);
      work.addAll(uses.get(e));
    }
 else     if (e.op == OP_phi) {
      assert (e.args.length == e.pred.length);
      for (int j=e.pred.length - 1; j >= 0; j--)       if (!code.contains(e.pred[j].from))       e.removePhiInput(j);
      Expr a=null;
      for (int j=e.pred.length - 1; j >= 0; j--) {
        if (e.args[j] != e && e.args[j] != a)         if (a == null)         a=e.args[j];
 else {
          a=null;
          break;
        }
      }
      if (a != null && map.get(e) != a) {
        map.put(e,a);
        work.addAll(uses.get(e));
        e.clearEffect();
      }
    }
  }
  for (  Block b : code) {
    for (    Expr e : b.exprs) {
      if (e.is_live_out) {
        b.addLiveOut(e);
      }
    }
  }
}

void cp ( Deque < Block > code ) { EdgeMap < Expr > uses = findUses ( code ) ; Map < Expr , Expr > map = new HashMap < Expr , Expr > ( ) ; Set < Expr > work = new TreeSet < Expr > ( ) ; for ( Block b : code ) { if ( ! b . must_isolate_block ) { for ( Expr e : b ) if ( e . op == OP_phi || e . op == OP_dup ) work . add ( e ) ; } } while ( ! work . isEmpty ( ) ) { Expr e = getExpr ( work ) ; rename ( e , e . args , map , uses ) ; rename ( e , e . scopes , map , uses ) ; rename ( e , e . locals , map , uses ) ; if ( e . op == OP_dup ) { map . put ( e , e . locals [ 0 ] ) ; work . addAll ( uses . get ( e ) ) ; } else if ( e . op == OP_phi ) { assert ( e . args . length == e . pred . length ) ; for ( int j = e . pred . length - 1 ; j >= 0 ; j -- ) if ( ! code . contains ( e . pred [ j ] . from ) ) e . removePhiInput ( j ) ; Expr a = null ; for ( int j = e . pred . length - 1 ; j >= 0 ; j -- ) { if ( e . args [ j ] != e && e . args [ j ] != a ) if ( a == null ) a = e . args [ j ] ; else { a = null ; break ; } } if ( a != null && map . get ( e ) != a ) { map . put ( e , a ) ; work . addAll ( uses . get ( e ) ) ; e . clearEffect ( ) ; } } } for ( Block b : code ) { for ( Expr e : b . exprs ) { if ( e . is_live_out ) { b . addLiveOut ( e ) ; } } } }
copy propagation . phi nodes that only choose themselves or one other variable are replaced by references to that other variable :
