anchor.diff:        }
       }
       return true;
  +  }
  +
  +  HInstruction previousInstruction(HInstruction instruction) {
  +    if (instruction.previous != null) return instruction.previous;
  +    HBasicBlock block = instruction.block;
  +    if (instruction is! HPhi) {
  +      if (block.phis.last != null) return block.phis.last;
  +    }
  +    if (block.predecessors.length == 1) {
  +      HBasicBlock previousBlock = block.predecessors[0];
  +      if (previousBlock.last is HGoto) {
  +        assert(previousBlock.successors.length == 1);
  +        assert(previousBlock.successors[0] === block);
  +        return previousInstruction(previousBlock.last);
  +      }
  +    }
  +    return null;
     }
   
     void detectLogicControlFlow(HPhi phi) {
  
positive.code:     // Check first input of phi being followed by a (possibly negated)
      // conditional branch based on the same value.
      if (firstBlock != phi.block.dominator) return;
      if (firstBlock.last is !HConditionalBranch) return;
      HConditionalBranch firstBranch = firstBlock.last;
      // Must be used both for value and for control to avoid the second branch.
      if (first.usedBy.length != 2) return;
      if (firstBlock.successors[1] != phi.block) return;
      HInstruction firstNext = (first is HPhi) ? firstBlock.first : first.next;
      if (firstNext == firstBranch &&
          firstBranch.condition == first) {
        replaceWithLogicalOperator(phi, "&&");
      } else if (firstNext is HNot &&
                 firstNext.inputs[0] == first &&
                 generateAtUseSite.contains(firstNext) &&
                 firstNext.next == firstBlock.last &&
                 firstBranch.condition == firstNext) {
        replaceWithLogicalOperator(phi, "||");
      } else {
        return;
      }
      // Detected as logic control flow. Mark the corresponding
      // inputs as generated at use site. These will now be generated
      // as part of an expression.
      generateAtUseSite.add(first);
      generateAtUseSite.add(firstBlock.last);
      generateAtUseSite.add(second);
      generateAtUseSite.add(secondBlock.last);
    }
  
    void visitBasicBlock(HBasicBlock block) {
      if (!block.phis.isEmpty() &&
          block.phis.first == block.phis.last) {
        detectLogicControlFlow(block.phis.first);
      }
    }
  
negative.code:     //   |/
      //   B2 b2 = phi(b0,b1); if(b2) ...
      // TODO(lrn): Also recognize ?:-flow?
      if (phi.inputs.length != 2) return;
      HInstruction first = phi.inputs[0];
      HBasicBlock firstBlock = phi.block.predecessors[0];
      HInstruction second = phi.inputs[1];
      HBasicBlock secondBlock = phi.block.predecessors[1];
      // Check second input of phi being an expression followed by a goto.
      if (second.usedBy.length != 1) return;
      HInstruction secondNext =
  