return _callHelper(call, ir);
return callHelper(call, ir);
  static OPT_Instruction arrayStoreCheck(OPT_Instruction s, OPT_IR ir, boolean couldBeNull) {    OPT_RegisterOperand guardResult = StoreCheck.getClearGuardResult(s);    OPT_Operand arrayRef = StoreCheck.getClearRef(s);    OPT_Operand elemRef = StoreCheck.getClearVal(s);    OPT_Operand guard = StoreCheck.getClearGuard(s);    if (elemRef instanceof OPT_NullConstantOperand) {      OPT_Instruction continueAt = s.prevInstructionInCodeOrder();      s.remove();      return continueAt;    }    OPT_BasicBlock myBlock = s.getBasicBlock();    OPT_BasicBlock contBlock = myBlock.splitNodeAt(s, ir);    OPT_BasicBlock trapBlock = myBlock.createSubBlock(s.bcIndex, ir, .0001f);    OPT_BasicBlock curBlock = myBlock;    s.remove();      // Set up a block with a trap instruction that we can jump to if the       // store check fails    OPT_Instruction trap = Trap.create(TRAP, null, OPT_TrapCodeOperand.StoreCheck());    trap.copyPosition(s);    trapBlock.appendInstruction(trap);    ir.cfg.addLastInCodeOrder(trapBlock);    OPT_Operand rhsGuard = guard;    if (couldBeNull) {      // if rhs is null, then the checkcast succeeds      rhsGuard = ir.regpool.makeTempValidation();      contBlock.prependInstruction(Binary.create(GUARD_COMBINE, 						 guardResult, 						 guardResult.copyRO(), 						 rhsGuard.copy()));      curBlock.appendInstruction(IfCmp.create(REF_IFCMP, rhsGuard.asRegister(), 					      elemRef, 					      new OPT_NullConstantOperand(),					      OPT_ConditionOperand.EQUAL(), 					      contBlock.makeJumpTarget(), 					      new OPT_BranchProfileOperand()));      curBlock.insertOut(contBlock);      curBlock = advanceBlock(s.bcIndex, curBlock, ir);    }	      // Find out what we think the compile time type of the lhs is.    // Based on this, we can do one of several things:    //  (1) If the compile time element type is a final proper class, then a     //      TIB comparision of the runtime elemRef type and the     //      compile time element type is definitive.    //  (2) If the compile time type is known to be the declared type,    //      then inject a short-circuit test to see if the     //      runtime lhs type is the same as the compile-time lhs type.    //  (3) If the compile time element type is a proper class other than     //      java.lang.Object, then a subclass test of the runtime LHS elem type     //      and the runtime elemRef type is definitive.  Note: we must exclude    //      java.lang.Object because if the compile time element type is     //      java.lang.Object, then the runtime-element type might actually be     //      an interface (ie not a proper class), and we won't be testing the right thing!    // If we think the compile time type is JavaLangObjectType then    // we lost type information due to unloaded classes causing    // imprecise meets.  This should only happen once in a blue moon,    // so don't bother trying anything clever when it does.    VM_Type compType = arrayRef.getType();    if (compType != VM_Type.JavaLangObjectType) {      // optionally (1) from above      if (compType.getDimensionality() == 1) {	VM_Class et = compType.asArray().getElementType().asClass();	if (et.isResolved() && et.isFinal()) {	  if (VM.VerifyAssertions) VM._assert(!et.isInterface());	  OPT_RegisterOperand rhsTIB = getTIB(curBlock.lastInstruction(), ir, elemRef.copy(), rhsGuard.copy());	  OPT_RegisterOperand etTIB = getTIB(curBlock.lastInstruction(), ir, et);	  curBlock.appendInstruction(IfCmp.create(REF_IFCMP, guardResult.copyRO(), 						  rhsTIB, etTIB,						  OPT_ConditionOperand.NOT_EQUAL(), 						  trapBlock.makeJumpTarget(),						  OPT_BranchProfileOperand.never()));	  curBlock.insertOut(trapBlock);	  curBlock.insertOut(contBlock);	  ir.cfg.linkInCodeOrder(curBlock, contBlock);	  return curBlock.lastInstruction();	}      }      // optionally (2) from above      OPT_RegisterOperand lhsTIB = getTIB(curBlock.lastInstruction(), ir, arrayRef, guard);      if (((arrayRef instanceof OPT_RegisterOperand)&&((OPT_RegisterOperand)arrayRef).isDeclaredType()) || compType == VM_Type.JavaLangObjectArrayType) {	OPT_RegisterOperand declTIB = getTIB(curBlock.lastInstruction(), ir, compType);	curBlock.appendInstruction(IfCmp.create(REF_IFCMP, guardResult.copyRO(), 						declTIB, lhsTIB,						OPT_ConditionOperand.EQUAL(), 						contBlock.makeJumpTarget(),						new OPT_BranchProfileOperand()));	curBlock.insertOut(contBlock);	curBlock = advanceBlock(s.bcIndex, curBlock, ir);      }      // On our way to doing (3) from above attempt another short-circuit.      // If lhsElemTIB == rhsTIB, then we are done.      OPT_RegisterOperand rhsTIB = getTIB(curBlock.lastInstruction(), ir, elemRef.copy(), rhsGuard.copy());      OPT_RegisterOperand lhsElemTIB = 	InsertUnary(curBlock.lastInstruction(), ir, GET_ARRAY_ELEMENT_TIB_FROM_TIB, 		    OPT_ClassLoaderProxy.JavaLangObjectArrayType, 		    lhsTIB.copyRO());      curBlock.appendInstruction(IfCmp.create(REF_IFCMP, guardResult.copyRO(), 					      rhsTIB, lhsElemTIB,					      OPT_ConditionOperand.EQUAL(), 					      contBlock.makeJumpTarget(),					      new OPT_BranchProfileOperand()));      curBlock.insertOut(contBlock);      curBlock = advanceBlock(s.bcIndex, curBlock, ir);      // Optionally (3) from above       if (compType.getDimensionality() == 1) {	VM_Class et = compType.asArray().getElementType().asClass();	if (et.isResolved() && !et.isInterface() && !et.isJavaLangObjectType()) {	  OPT_RegisterOperand lhsElemType = 	    InsertUnary(curBlock.lastInstruction(), ir, 			GET_TYPE_FROM_TIB, OPT_ClassLoaderProxy.VM_Type_type, 			lhsElemTIB.copyU2U());	  OPT_RegisterOperand rhsSuperclassIds = 	    InsertUnary(curBlock.lastInstruction(), ir, GET_SUPERCLASS_IDS_FROM_TIB, 			OPT_ClassLoaderProxy.ShortArrayType, rhsTIB.copyD2U());	  OPT_RegisterOperand lhsElemDepth = 	    getField(curBlock.lastInstruction(), ir, lhsElemType, VM_Entrypoints.depthField, TG());	  OPT_RegisterOperand rhsSuperclassIdsLength = 	    InsertGuardedUnary(curBlock.lastInstruction(), ir, 			       ARRAYLENGTH, VM_Type.IntType,			       rhsSuperclassIds.copyD2U(), TG());	  curBlock.appendInstruction(IfCmp.create(INT_IFCMP, guardResult.copyRO(), 						  lhsElemDepth, 						  rhsSuperclassIdsLength,						  OPT_ConditionOperand.GREATER_EQUAL(), 						  trapBlock.makeJumpTarget(),						  OPT_BranchProfileOperand.never()));	  curBlock.insertOut(trapBlock);	  curBlock = advanceBlock(s.bcIndex, curBlock, ir);	  OPT_RegisterOperand lhsElemId = 	    getField(curBlock.lastInstruction(), ir, lhsElemType.copyD2U(), VM_Entrypoints.idField, TG());	  OPT_RegisterOperand refCandidate = ir.regpool.makeTemp(VM_Type.ShortType);	  OPT_LocationOperand loc = new OPT_LocationOperand(VM_Type.ShortType);	  if (LOWER_ARRAY_ACCESS) {	    OPT_RegisterOperand lhsDepthOffset = 	      InsertBinary(curBlock.lastInstruction(), ir, INT_SHL, VM_Type.IntType, 			   lhsElemDepth.copyD2U(), I(1));	    curBlock.appendInstruction(Load.create(USHORT_LOAD, refCandidate, 						   rhsSuperclassIds, 						   lhsDepthOffset, loc, TG()));	  } else {	    curBlock.appendInstruction(ALoad.create(USHORT_ALOAD, refCandidate, 						    rhsSuperclassIds, 						    lhsElemDepth, loc, TG()));	  }	  curBlock.appendInstruction(IfCmp.create(INT_IFCMP, guardResult.copyRO(),						  refCandidate.copyD2U(), 						  lhsElemId,						  OPT_ConditionOperand.NOT_EQUAL(), 						  trapBlock.makeJumpTarget(),						  OPT_BranchProfileOperand.never()));	  curBlock.insertOut(trapBlock);	  curBlock.insertOut(contBlock);	  ir.cfg.linkInCodeOrder(curBlock, contBlock);	  return curBlock.lastInstruction();	}      }    }    // Call VM_Runtime.checkstore.    OPT_Instruction call = Call.create2(CALL, null, null,					OPT_MethodOperand.STATIC(VM_Entrypoints.checkstoreMethod), 					rhsGuard.copy(), arrayRef.copy(), elemRef.copy());    call.copyPosition(s);    curBlock.appendInstruction(call);    curBlock.insertOut(contBlock);    ir.cfg.linkInCodeOrder(curBlock, contBlock);    return _callHelper(call, ir);  }