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:    * generated at use-site.
     */
    bool isExpression(HInstruction instruction, HBasicBlock limit) {
      if (instruction is HPhi && !logicalOperations.containsKey(instruction)) {
        return false;
      }
      while (instruction.previous != null) {
        instruction = instruction.previous;
        if (!generateAtUseSite.contains(instruction)) {
          return false;
        }
      }
      HBasicBlock block = instruction.block;
      if (!block.phis.isEmpty()) return false;
      if (instruction is HPhi && logicalOperations.containsKey(instruction)) {
        return isExpression(instruction.inputs[0], limit);
      }
      return block.predecessors.length == 1 && block.predecessors[0] == limit;
    }
  
    void replaceWithLogicalOperator(HPhi phi, String type) {
      if (canGenerateAtUseSite(phi)) generateAtUseSite.add(phi);
      logicalOperations[phi] = type;
    }
  
    bool canGenerateAtUseSite(HPhi phi) {
      if (phi.usedBy.length != 1) return false;
      assert(phi.next == null);
      HInstruction use = phi.usedBy[0];
  
      HInstruction current = phi.block.first;
      while (current != use) {
        if (!generateAtUseSite.contains(current)) return false;
        if (current.next != null) {
          current = current.next;
        } else if (current is HPhi) {
          current = current.block.first;
        } else {
          assert(current is HControlFlow);
          if (current is !HGoto) return false;
          HBasicBlock nextBlock = current.block.successors[0];
          if (!nextBlock.phis.isEmpty()) {
            current = nextBlock.phis.first;
  
negative.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! HIf) return;
      if (firstBlock.successors[1] != phi.block) return;
      HIf firstBranch = firstBlock.last;
      HInstruction condition = firstBranch.inputs[0];
      if (condition === first) {
        replaceWithLogicalOperator(phi, "&&");
      } else if (condition is HNot &&
                 condition.inputs[0] == first) {
        replaceWithLogicalOperator(phi, "||");
        // If the negation is only used by this logical operation, or only by
        // logical operators in general, it won't need to be generated.
        if (!generateAtUseSite.contains(condition)) {
          for (HInstruction user in condition.usedBy) {
            if (user is! HIf || !generateAtUseSite.contains(user)) {
              return;
            }
          }
          generateAtUseSite.add(condition);
        }
      }
      return;
    }
  
    void visitBasicBlock(HBasicBlock block) {
      if (!block.phis.isEmpty() &&
          block.phis.first === block.phis.last) {
        detectLogicControlFlow(block.phis.first);
      }
    }
  