anchor.diff:        // `block.predecessors[0]` again, we can just re-use its
         // [memorySet].
         memorySet = memories[block.predecessors[0].id];
  -    } else if (block.isLoopHeader()) {
  -      // We currently do not handle loops.
  -      memorySet = new MemorySet(compiler);
       } else if (block.predecessors.length == 1) {
         // Clone the memorySet of the predecessor, because it is also used
         // by other successors of it.
  
positive.code:                             HBasicBlock block,
                              int predecessorIndex) {
      MemorySet result = new MemorySet(compiler);
      fieldValues.forEach((element, values) {
        var otherValues = other.fieldValues[element];
        if (otherValues == null) return;
  
negative.code: 
    SsaLoadElimination(this.compiler);
  
    void visitGraph(HGraph graph) {
      memories = new List<MemorySet>(graph.blocks.length);
      List<HBasicBlock> blocks = graph.blocks;
      for (int i = 0; i < blocks.length; i++) {
        HBasicBlock block = blocks[i];
        visitBasicBlock(block);
        if (block.successors.isNotEmpty && block.successors[0].isLoopHeader()) {
          // We've reached the ending block of a loop. Iterate over the
          // blocks of the loop again to take values that flow from that
          // ending block into account.
          for (int j = block.successors[0].id; j <= block.id; j++) {
            visitBasicBlock(blocks[j]);
          }
        }
      }
    }
  
    void visitBasicBlock(HBasicBlock block) {
      if (block.predecessors.length == 0) {
        // Entry block.
        memorySet = new MemorySet(compiler);
  