VM.assert(low <= high, "broken control logic in _lookupswitchHelper");
VM._assert(low <= high, "broken control logic in _lookupswitchHelper");
  private static OPT_BasicBlock _lookupswitchHelper(OPT_Instruction switchInstr, 						    OPT_RegisterOperand reg, 						    OPT_BasicBlock defaultBB, 						    OPT_IR ir, 						    OPT_BasicBlock curBlock, 						    int low, 						    int high, 						    int min, 						    int max) {    if (VM.VerifyAssertions)      VM.assert(low <= high, "broken control logic in _lookupswitchHelper");    int middle = (low + high) >> 1;             // find middle    // The following are used below to store the computed branch    // probabilities for the branches that are created to implement    // the binary search.  Used only if basic block frequencies available    float lessProb = 0.0f;    float greaterProb = 0.0f;    float equalProb = 0.0f;    float sum=0.0f;    // Sum the probabilities for all targets < middle    for (int i=low; i < middle; i++) {      lessProb += LookupSwitch.getBranchProfile(switchInstr,i).takenProbability;    }    // Sum the probabilities for all targets > middle    for (int i=middle+1; i <= high; i++) {      greaterProb += LookupSwitch.getBranchProfile(switchInstr,i).takenProbability;    }    equalProb = LookupSwitch.getBranchProfile(switchInstr,middle).takenProbability;    // The default case is a bit of a kludge.  We know the total    // probability of executing the default case, but we have no    // idea which paths are taken to get there.  For now, we'll    // assume that all paths that went to default were because the    // value was less than the smallest switch value.  This ensures    // that all basic block appearing in the switch will have the    // correct weights (but the blocks in the binary switch    // generated may not).    if (low == 0)       lessProb += LookupSwitch.getDefaultBranchProfile(switchInstr).takenProbability;    // Now normalize them so they are relative to the sum of the    // branches being considered in this piece of the subtree    sum = lessProb + equalProb + greaterProb;    if (sum > 0) {  // check for divide by zero      lessProb /= sum;      equalProb /= sum;      greaterProb /= sum;    }    OPT_IntConstantOperand val =       LookupSwitch.getClearMatch(switchInstr, middle);    int value = val.value;    OPT_BasicBlock greaterBlock =       middle == high ? defaultBB : curBlock.createSubBlock(0, ir);    OPT_BasicBlock lesserBlock =       low == middle ? defaultBB : curBlock.createSubBlock(0, ir);    // Generate this level of tests    OPT_BranchOperand branch =       LookupSwitch.getClearTarget(switchInstr, middle);    OPT_BasicBlock branchBB = branch.target.getBasicBlock();    curBlock.insertOut(branchBB);    if (low != high) {      if (value == min) {        curBlock.appendInstruction(IfCmp.create(INT_IFCMP, null, 						reg.copy(), val,						OPT_ConditionOperand.EQUAL(), 						branchBB.makeJumpTarget(),						new OPT_BranchProfileOperand(equalProb)));      } else {		// To compute the probability of the second compare, the first	// probability must be removed since the second branch is	// considered only if the first fails.	float secondIfProb = 0.0f;	sum = equalProb + greaterProb;	if (sum > 0) // if divide by zero, leave as is	  secondIfProb = equalProb/sum;        curBlock.appendInstruction(IfCmp2.create(INT_IFCMP2, null, 						 reg.copy(), val,						 OPT_ConditionOperand.LESS(), 						 lesserBlock.makeJumpTarget(),						 new OPT_BranchProfileOperand(lessProb),						 OPT_ConditionOperand.EQUAL(), 						 branchBB.makeJumpTarget(),						 new OPT_BranchProfileOperand(secondIfProb)));        curBlock.insertOut(lesserBlock);      }    } else {      // Base case: middle was the only case left to consider      if (min == max) {        curBlock.appendInstruction(Goto.create(GOTO, branch));        curBlock.insertOut(branchBB);      } else {        curBlock.appendInstruction(IfCmp.create(INT_IFCMP, null,						reg.copy(), val, 						OPT_ConditionOperand.EQUAL(), 						branchBB.makeJumpTarget(),						new OPT_BranchProfileOperand(equalProb)));        OPT_BasicBlock newBlock = curBlock.createSubBlock(0, ir);        curBlock.insertOut(newBlock);        ir.cfg.linkInCodeOrder(curBlock, newBlock);        curBlock = newBlock;        curBlock.appendInstruction(defaultBB.makeGOTO());        curBlock.insertOut(defaultBB);      }    }    // Generate sublevels as needed and splice together instr & bblist    if (middle < high) {      curBlock.insertOut(greaterBlock);      ir.cfg.linkInCodeOrder(curBlock, greaterBlock);      curBlock = _lookupswitchHelper(switchInstr, reg, defaultBB, ir, 				     greaterBlock, middle + 1, high, 				     value + 1, max);    }    if (low < middle) {      ir.cfg.linkInCodeOrder(curBlock, lesserBlock);      curBlock = _lookupswitchHelper(switchInstr, reg, defaultBB, ir, 				     lesserBlock, low, middle - 1, min, 				     value - 1);    }    return  curBlock;  }