anchor.diff:            joinedLocals[element] = instruction;
           } else {
             HInstruction phi =
  -              new HPhi.manyInputs(element, <HInstruction>[instruction, mine]);
  +              new HPhi.manyInputs(element, <HInstruction>[mine, instruction]);
             joinBlock.addPhi(phi);
             joinedLocals[element] = phi;
           }
  
positive.code:     }
    }
  
    SubGraph buildCondition(void doCondition()) {
      HBasicBlock conditionStartBlock = builder.openNewBlock();
      doCondition();
      checkNotAborted();
      assert(builder.current === builder.lastOpenedBlock);
      HInstruction condition = builder.popBoolified();
      HIf branch = new HIf(condition);
      builder.close(branch);
  
      conditionGraph =
          new SubExpression(conditionStartBlock, builder.lastOpenedBlock);
      conditionLocals = builder.localsHandler;
      return conditionGraph;
    }
  
    SubGraph buildThen(void visitThen(), LocalsHandler locals) {
      builder.localsHandler = locals;
      HBasicBlock thenBlock = builder.addNewBlock();
      conditionGraph.end.addSuccessor(thenBlock);
      builder.open(thenBlock);
      visitThen();
      if (branchesHaveValues) {
        checkNotAborted();
        thenValue = builder.pop();
      }
      thenGraph = new SubGraph(thenBlock, builder.lastOpenedBlock);
      thenLocals = builder.localsHandler;
      return thenGraph;
    }
  
    SubGraph buildElse(void visitElse(), LocalsHandler locals) {
      builder.localsHandler = locals;
      HBasicBlock elseBlock = builder.addNewBlock();
      conditionGraph.end.addSuccessor(elseBlock);
      builder.open(elseBlock);
      visitElse();
      if (branchesHaveValues) {
        checkNotAborted();
        elseValue = builder.pop();
      }
      elseGraph = new SubGraph(elseBlock, builder.lastOpenedBlock);
      elseLocals = builder.localsHandler;
      return elseGraph;
    }
  
    HBasicBlock join() {
      HBasicBlock joinBlock = null;
      HBasicBlock thenBlock = thenGraph.end;
      HBasicBlock elseBlock = elseGraph.end;
      // If the last instruction is already a control-flow instruction then the
      // block has been aborted.
      if (thenBlock.last is HControlFlow) thenBlock = null;
      if (elseBlock.last is HControlFlow) elseBlock = null;
  
      if (thenBlock !== null || elseBlock !== null) {
        joinBlock = builder.addNewBlock();
        if (thenBlock !== null) builder.goto(thenBlock, joinBlock);
        if (elseBlock !== null) builder.goto(elseBlock, joinBlock);
        // If the join block has two predecessors we have to merge the
        // locals. The current locals is what either the
        // condition or the else block left us with, so we merge that
        // with the set of locals we got after visiting the then
        // part of the if.
        builder.open(joinBlock);
        if (joinBlock.predecessors.length == 2) {
          builder.localsHandler.mergeWith(thenLocals, joinBlock);
          if (branchesHaveValues) {
            assert(thenValue !== null);
            assert(elseValue !== null);
            HPhi phi = new HPhi.manyInputs(null,
                <HInstruction>[thenValue, elseValue]);
            joinBlock.addPhi(phi);
            builder.stack.add(phi);
          }
        } else if (thenBlock !== null) {
          // The only predecessor is the then branch.
          builder.localsHandler = thenLocals;
        } else {
          assert(builder.localsHandler == elseLocals);
        }
      }
      return builder.current;
    }
  
    handleIf(void visitCondition(), void visitThen(), void visitElse()) {
      _handleDiamondBranch(visitCondition, visitThen, visitElse, false);
    }
  
    handleConditional(void visitCondition(), void visitThen(), void visitElse()) {
      _handleDiamondBranch(visitCondition, visitThen, visitElse, true);
    }
  
    void _handleDiamondBranch(void visitCondition(),
                              void visitThen(),
                              void visitElse(),
                              bool isExpression) {
      branchesHaveValues = isExpression;
      if (visitElse == null) {
        if (isExpression) {
          compiler.internalError("Diamond branch with values but without else.",
                                 node: diagnosticNode);
        }
        // Make sure to have an else part to avoid a critical edge. A
        // critical edge is an edge that connects a block with multiple
        // successors to a block with multiple predecessors. We avoid
  
negative.code:   }
  }
  
  class SsaBranch {
    final SsaBranchBuilder branchBuilder;
    final HBasicBlock block;
    LocalsHandler startLocals;
    LocalsHandler exitLocals;
    SubGraph graph;
  
    SsaBranch(this.branchBuilder) : block = new HBasicBlock();
  }
  
  class SsaBranchBuilder {
    final SsaBuilder builder;
    final Node diagnosticNode;
  
    SsaBranchBuilder(this.builder, [this.diagnosticNode]);
  
    Compiler get compiler() => builder.compiler;
  