use of org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand in project JikesRVM by JikesRVM.
the class ObjectReplacer method scalarReplace.
/**
* Replace a given use of a object with its scalar equivalent
*
* @param use the use to replace
* @param scalars an array of scalar register operands to replace
* the object's fields with
* @param fields the object's fields
* @param visited the registers that were already seen
*/
private void scalarReplace(RegisterOperand use, RegisterOperand[] scalars, ArrayList<RVMField> fields, Set<Register> visited) {
Instruction inst = use.instruction;
try {
switch(inst.getOpcode()) {
case PUTFIELD_opcode:
{
FieldReference fr = PutField.getLocation(inst).getFieldRef();
if (VM.VerifyAssertions)
VM._assert(fr.isResolved());
RVMField f = fr.peekResolvedField();
int index = fields.indexOf(f);
TypeReference type = scalars[index].getType();
Operator moveOp = IRTools.getMoveOp(type);
Instruction i = Move.create(moveOp, scalars[index].copyRO(), PutField.getClearValue(inst));
inst.insertBefore(i);
DefUse.removeInstructionAndUpdateDU(inst);
DefUse.updateDUForNewInstruction(i);
}
break;
case GETFIELD_opcode:
{
FieldReference fr = GetField.getLocation(inst).getFieldRef();
if (VM.VerifyAssertions)
VM._assert(fr.isResolved());
RVMField f = fr.peekResolvedField();
int index = fields.indexOf(f);
TypeReference type = scalars[index].getType();
Operator moveOp = IRTools.getMoveOp(type);
Instruction i = Move.create(moveOp, GetField.getClearResult(inst), scalars[index].copyRO());
inst.insertBefore(i);
DefUse.removeInstructionAndUpdateDU(inst);
DefUse.updateDUForNewInstruction(i);
}
break;
case MONITORENTER_opcode:
inst.insertBefore(Empty.create(READ_CEILING));
DefUse.removeInstructionAndUpdateDU(inst);
break;
case MONITOREXIT_opcode:
inst.insertBefore(Empty.create(WRITE_FLOOR));
DefUse.removeInstructionAndUpdateDU(inst);
break;
case CALL_opcode:
case NULL_CHECK_opcode:
// (SJF) TODO: Why wasn't this caught by BC2IR for
// java.lang.Double.<init> (Ljava/lang/String;)V ?
DefUse.removeInstructionAndUpdateDU(inst);
break;
case CHECKCAST_opcode:
case CHECKCAST_NOTNULL_opcode:
case CHECKCAST_UNRESOLVED_opcode:
{
// We cannot handle removing the checkcast if the result of the
// checkcast test is unknown
TypeReference lhsType = TypeCheck.getType(inst).getTypeRef();
if (ClassLoaderProxy.includesType(lhsType, klass.getTypeRef()) == YES) {
if (visited == null) {
visited = new HashSet<Register>();
}
Register copy = TypeCheck.getResult(inst).getRegister();
if (!visited.contains(copy)) {
visited.add(copy);
transform2(copy, inst, scalars, fields, visited);
// NB will remove inst
} else {
DefUse.removeInstructionAndUpdateDU(inst);
}
} else {
Instruction i2 = Trap.create(TRAP, null, TrapCodeOperand.CheckCast());
DefUse.replaceInstructionAndUpdateDU(inst, i2);
}
}
break;
case INSTANCEOF_opcode:
case INSTANCEOF_NOTNULL_opcode:
case INSTANCEOF_UNRESOLVED_opcode:
{
// We cannot handle removing the instanceof if the result of the
// instanceof test is unknown
TypeReference lhsType = InstanceOf.getType(inst).getTypeRef();
Instruction i2;
if (ClassLoaderProxy.includesType(lhsType, klass.getTypeRef()) == YES) {
i2 = Move.create(INT_MOVE, InstanceOf.getClearResult(inst), IC(1));
} else {
i2 = Move.create(INT_MOVE, InstanceOf.getClearResult(inst), IC(0));
}
DefUse.replaceInstructionAndUpdateDU(inst, i2);
}
break;
case GET_OBJ_TIB_opcode:
{
Instruction i2 = Move.create(REF_MOVE, GuardedUnary.getClearResult(inst), new TIBConstantOperand(klass));
DefUse.replaceInstructionAndUpdateDU(inst, i2);
}
break;
case REF_MOVE_opcode:
{
if (visited == null) {
visited = new HashSet<Register>();
}
Register copy = Move.getResult(use.instruction).getRegister();
if (!visited.contains(copy)) {
visited.add(copy);
transform2(copy, inst, scalars, fields, visited);
// NB will remove inst
} else {
DefUse.removeInstructionAndUpdateDU(inst);
}
}
break;
default:
throw new OptimizingCompilerException("ObjectReplacer: unexpected use " + inst);
}
} catch (Exception e) {
OptimizingCompilerException oe = new OptimizingCompilerException("Error handling use (" + use + ") of: " + inst);
oe.initCause(e);
throw oe;
}
}
use of org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand in project JikesRVM by JikesRVM.
the class ShortArrayReplacer method scalarReplace.
/**
* Replace a given use of an array with its scalar equivalent.
*
* @param use the use to replace
* @param scalars an array of scalar register operands to replace
* the array with
* @param visited TODO currently useless. Is this parameter
* necessary or should it be removed?
*/
private void scalarReplace(RegisterOperand use, RegisterOperand[] scalars, Set<Register> visited) {
Instruction inst = use.instruction;
RVMType type = vmArray.getElementType();
switch(inst.getOpcode()) {
case INT_ALOAD_opcode:
case LONG_ALOAD_opcode:
case FLOAT_ALOAD_opcode:
case DOUBLE_ALOAD_opcode:
case BYTE_ALOAD_opcode:
case UBYTE_ALOAD_opcode:
case USHORT_ALOAD_opcode:
case SHORT_ALOAD_opcode:
case REF_ALOAD_opcode:
{
// of a trap
if (ALoad.getIndex(inst).isIntConstant()) {
Operator moveOp = IRTools.getMoveOp(type.getTypeRef());
int index = ALoad.getIndex(inst).asIntConstant().value;
if (index >= 0 && index < size) {
Instruction i2 = Move.create(moveOp, ALoad.getClearResult(inst), scalars[index].copyRO());
DefUse.replaceInstructionAndUpdateDU(inst, i2);
} else {
DefUse.removeInstructionAndUpdateDU(inst);
}
} else {
if (VM.BuildForIA32) {
if (size == 0) {
DefUse.removeInstructionAndUpdateDU(inst);
} else if (size == 1) {
int index = 0;
Operator moveOp = IRTools.getMoveOp(type.getTypeRef());
Instruction i2 = Move.create(moveOp, ALoad.getClearResult(inst), scalars[index].copyRO());
DefUse.replaceInstructionAndUpdateDU(inst, i2);
} else {
Operator moveOp = IRTools.getCondMoveOp(type.getTypeRef());
Instruction i2 = CondMove.create(moveOp, ALoad.getClearResult(inst), ALoad.getClearIndex(inst), IC(0), ConditionOperand.EQUAL(), scalars[0].copyRO(), scalars[1].copyRO());
DefUse.replaceInstructionAndUpdateDU(inst, i2);
}
} else {
if (size == 1) {
int index = 0;
Operator moveOp = IRTools.getMoveOp(type.getTypeRef());
Instruction i2 = Move.create(moveOp, ALoad.getClearResult(inst), scalars[index].copyRO());
DefUse.replaceInstructionAndUpdateDU(inst, i2);
} else {
DefUse.removeInstructionAndUpdateDU(inst);
}
}
}
}
break;
case INT_ASTORE_opcode:
case LONG_ASTORE_opcode:
case FLOAT_ASTORE_opcode:
case DOUBLE_ASTORE_opcode:
case BYTE_ASTORE_opcode:
case SHORT_ASTORE_opcode:
case REF_ASTORE_opcode:
{
// of a trap
if (AStore.getIndex(inst).isIntConstant()) {
int index = AStore.getIndex(inst).asIntConstant().value;
if (index >= 0 && index < size) {
Operator moveOp = IRTools.getMoveOp(type.getTypeRef());
Instruction i2 = Move.create(moveOp, scalars[index].copyRO(), AStore.getClearValue(inst));
DefUse.replaceInstructionAndUpdateDU(inst, i2);
} else {
DefUse.removeInstructionAndUpdateDU(inst);
}
} else {
if (VM.BuildForIA32) {
if (size == 0) {
DefUse.removeInstructionAndUpdateDU(inst);
} else if (size == 1) {
int index = 0;
Operator moveOp = IRTools.getMoveOp(type.getTypeRef());
Instruction i2 = Move.create(moveOp, scalars[index].copyRO(), AStore.getClearValue(inst));
DefUse.replaceInstructionAndUpdateDU(inst, i2);
} else {
Operator moveOp = IRTools.getCondMoveOp(type.getTypeRef());
Operand value = AStore.getClearValue(inst);
Instruction i2 = CondMove.create(moveOp, scalars[0].copyRO(), AStore.getIndex(inst), IC(0), ConditionOperand.EQUAL(), value, scalars[0].copyRO());
DefUse.replaceInstructionAndUpdateDU(inst, i2);
Instruction i3 = CondMove.create(moveOp, scalars[1].copyRO(), AStore.getIndex(inst), IC(0), ConditionOperand.NOT_EQUAL(), value, scalars[1].copyRO());
i2.insertAfter(i3);
DefUse.updateDUForNewInstruction(i3);
}
} else {
if (size == 1) {
int index = 0;
Operator moveOp = IRTools.getMoveOp(type.getTypeRef());
Instruction i2 = Move.create(moveOp, scalars[index].copyRO(), AStore.getClearValue(inst));
DefUse.replaceInstructionAndUpdateDU(inst, i2);
} else {
DefUse.removeInstructionAndUpdateDU(inst);
}
}
}
}
break;
case NULL_CHECK_opcode:
{
// Null check on result of new array must succeed
Instruction i2 = Move.create(GUARD_MOVE, NullCheck.getClearGuardResult(inst), new TrueGuardOperand());
DefUse.replaceInstructionAndUpdateDU(inst, i2);
}
break;
case BOUNDS_CHECK_opcode:
{
// Remove or create trap as appropriate
Instruction i2 = TrapIf.create(TRAP_IF, BoundsCheck.getClearGuardResult(inst), IC(size), BoundsCheck.getClearIndex(inst), ConditionOperand.LOWER_EQUAL(), TrapCodeOperand.ArrayBounds());
DefUse.replaceInstructionAndUpdateDU(inst, i2);
}
break;
case CHECKCAST_opcode:
case CHECKCAST_NOTNULL_opcode:
case CHECKCAST_UNRESOLVED_opcode:
{
// We cannot handle removing the checkcast if the result of the
// checkcast test is unknown
TypeReference lhsType = TypeCheck.getType(inst).getTypeRef();
if (ClassLoaderProxy.includesType(lhsType, vmArray.getTypeRef()) == YES) {
if (visited == null) {
visited = new HashSet<Register>();
}
Register copy = TypeCheck.getResult(inst).getRegister();
if (!visited.contains(copy)) {
visited.add(copy);
transform2(copy, inst, scalars);
// NB will remove inst
} else {
DefUse.removeInstructionAndUpdateDU(inst);
}
} else {
Instruction i2 = Trap.create(TRAP, null, TrapCodeOperand.CheckCast());
DefUse.replaceInstructionAndUpdateDU(inst, i2);
}
}
break;
case INSTANCEOF_opcode:
case INSTANCEOF_NOTNULL_opcode:
case INSTANCEOF_UNRESOLVED_opcode:
{
// We cannot handle removing the instanceof if the result of the
// instanceof test is unknown
TypeReference lhsType = InstanceOf.getType(inst).getTypeRef();
Instruction i2;
if (ClassLoaderProxy.includesType(lhsType, vmArray.getTypeRef()) == YES) {
i2 = Move.create(INT_MOVE, InstanceOf.getClearResult(inst), IC(1));
} else {
i2 = Move.create(INT_MOVE, InstanceOf.getClearResult(inst), IC(0));
}
DefUse.replaceInstructionAndUpdateDU(inst, i2);
}
break;
case GET_OBJ_TIB_opcode:
{
Instruction i2 = Move.create(REF_MOVE, GuardedUnary.getClearResult(inst), new TIBConstantOperand(vmArray));
DefUse.replaceInstructionAndUpdateDU(inst, i2);
}
break;
case REF_MOVE_opcode:
{
if (visited == null) {
visited = new HashSet<Register>();
}
Register copy = Move.getResult(inst).getRegister();
if (!visited.contains(copy)) {
visited.add(copy);
transform2(copy, inst, scalars);
// NB will remove inst
} else {
DefUse.removeInstructionAndUpdateDU(inst);
}
}
break;
default:
throw new OptimizingCompilerException("Unexpected instruction: " + inst);
}
}
use of org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand in project JikesRVM by JikesRVM.
the class NormalizeConstants method perform.
/**
* Doit.
*
* @param ir IR to normalize
*/
public static void perform(IR ir) {
// This greatly reduces the number of cases we have to worry about below.
if (VM.VerifyAssertions)
VM._assert(ir.options.SIMPLIFY_INTEGER_OPS && ir.options.SIMPLIFY_LONG_OPS && ir.options.SIMPLIFY_REF_OPS);
for (Instruction s = ir.firstInstructionInCodeOrder(); s != null; s = s.nextInstructionInCodeOrder()) {
// STEP ONE: Get 'large' constants into a form that the PPC BURS rules
// are prepared to deal with.
// Constants can't appear as defs, so only scan the uses.
//
int numUses = s.getNumberOfUses();
if (numUses > 0) {
int numDefs = s.getNumberOfDefs();
for (int idx = numDefs; idx < numUses + numDefs; idx++) {
Operand use = s.getOperand(idx);
if (use != null) {
if (use instanceof ObjectConstantOperand) {
RegisterOperand rop = ir.regpool.makeTemp(use.getType());
RegisterOperand jtoc = (RegisterOperand) ir.regpool.makeJTOCOp();
ObjectConstantOperand oc = (ObjectConstantOperand) use;
Offset offset = oc.offset;
if (offset.isZero()) {
if (use instanceof StringConstantOperand) {
throw new OptimizingCompilerException("String constant w/o valid JTOC offset");
} else if (use instanceof ClassConstantOperand) {
throw new OptimizingCompilerException("Class constant w/o valid JTOC offset");
}
offset = Offset.fromIntSignExtend(Statics.findOrCreateObjectLiteral(oc.value));
}
LocationOperand loc = new LocationOperand(offset);
s.insertBefore(Load.create(VM.BuildFor32Addr ? INT_LOAD : LONG_LOAD, rop, jtoc, asImmediateOrRegOffset(AC(offset), s, ir, true), loc));
s.putOperand(idx, rop.copyD2U());
} else if (use instanceof DoubleConstantOperand) {
RegisterOperand rop = ir.regpool.makeTemp(TypeReference.Double);
RegisterOperand jtoc = (RegisterOperand) ir.regpool.makeJTOCOp();
DoubleConstantOperand dc = (DoubleConstantOperand) use;
Offset offset = dc.offset;
if (offset.isZero()) {
offset = Offset.fromIntSignExtend(Statics.findOrCreateLongSizeLiteral(Double.doubleToLongBits(dc.value)));
}
LocationOperand loc = new LocationOperand(offset);
s.insertBefore(Load.create(DOUBLE_LOAD, rop, jtoc, asImmediateOrRegOffset(AC(offset), s, ir, true), loc));
s.putOperand(idx, rop.copyD2U());
} else if (use instanceof FloatConstantOperand) {
RegisterOperand rop = ir.regpool.makeTemp(TypeReference.Float);
RegisterOperand jtoc = (RegisterOperand) ir.regpool.makeJTOCOp();
FloatConstantOperand fc = (FloatConstantOperand) use;
Offset offset = fc.offset;
if (offset.isZero()) {
offset = Offset.fromIntSignExtend(Statics.findOrCreateIntSizeLiteral(Float.floatToIntBits(fc.value)));
}
LocationOperand loc = new LocationOperand(offset);
s.insertBefore(Load.create(FLOAT_LOAD, rop, jtoc, asImmediateOrRegOffset(AC(offset), s, ir, true), loc));
s.putOperand(idx, rop.copyD2U());
} else if (use instanceof LongConstantOperand) {
if (!VM.BuildFor64Addr) {
if (s.getOpcode() != TRAP_IF_opcode) {
RegisterOperand rop = ir.regpool.makeTemp(TypeReference.Long);
s.insertBefore(Move.create(LONG_MOVE, rop, use.copy()));
s.putOperand(idx, rop.copyD2U());
}
}
} else if (use instanceof NullConstantOperand) {
s.putOperand(idx, AC(Address.zero()));
} else if (use instanceof TIBConstantOperand) {
RegisterOperand rop = ir.regpool.makeTemp(TypeReference.JavaLangObjectArray);
Operand jtoc = ir.regpool.makeJTOCOp();
Offset offset = ((TIBConstantOperand) use).value.getTibOffset();
LocationOperand loc = new LocationOperand(offset);
s.insertBefore(Load.create(VM.BuildFor32Addr ? INT_LOAD : LONG_LOAD, rop, jtoc, asImmediateOrRegOffset(AC(offset), s, ir, true), loc));
s.putOperand(idx, rop.copyD2U());
} else if (use instanceof CodeConstantOperand) {
RegisterOperand rop = ir.regpool.makeTemp(TypeReference.CodeArray);
Operand jtoc = ir.regpool.makeJTOCOp();
Offset offset = ((CodeConstantOperand) use).value.findOrCreateJtocOffset();
LocationOperand loc = new LocationOperand(offset);
s.insertBefore(Load.create(VM.BuildFor32Addr ? INT_LOAD : LONG_LOAD, rop, jtoc, asImmediateOrRegOffset(AC(offset), s, ir, true), loc));
s.putOperand(idx, rop.copyD2U());
}
}
}
}
// Calling Simplifier.simplify ensures that the instruction is
// in normalized form. This reduces the number of cases we have to
// worry about (and does last minute constant folding on the off chance
// we've missed an opportunity...)
Simplifier.simplify(false, ir.regpool, ir.options, s);
switch(s.getOpcode()) {
// ////////
case REF_STORE_opcode:
s.changeOperatorTo(VM.BuildFor32Addr ? INT_STORE : LONG_STORE);
// On PowerPC, the value being stored must be in a register
Store.setValue(s, asRegPolymorphic(Store.getClearValue(s), s, ir));
// Supported addressing modes are quite limited.
Store.setAddress(s, asRegAddress(Store.getClearAddress(s), s, ir));
Store.setOffset(s, asImmediateOrRegOffset(Store.getClearOffset(s), s, ir, true));
break;
case BYTE_STORE_opcode:
case SHORT_STORE_opcode:
case INT_STORE_opcode:
case LONG_STORE_opcode:
// On PowerPC, the value being stored must be in a register
Store.setValue(s, asRegPolymorphic(Store.getClearValue(s), s, ir));
// Supported addressing modes are quite limited.
Store.setAddress(s, asRegAddress(Store.getClearAddress(s), s, ir));
Store.setOffset(s, asImmediateOrRegOffset(Store.getClearOffset(s), s, ir, true));
break;
case FLOAT_STORE_opcode:
case DOUBLE_STORE_opcode:
// Supported addressing modes are quite limited.
Store.setAddress(s, asRegAddress(Store.getClearAddress(s), s, ir));
Store.setOffset(s, asImmediateOrRegOffset(Store.getClearOffset(s), s, ir, true));
break;
case REF_LOAD_opcode:
s.changeOperatorTo(VM.BuildFor32Addr ? INT_LOAD : LONG_LOAD);
// Supported addressing modes are quite limited.
Load.setAddress(s, asRegAddress(Load.getClearAddress(s), s, ir));
Load.setOffset(s, asImmediateOrRegOffset(Load.getClearOffset(s), s, ir, true));
break;
case BYTE_LOAD_opcode:
case UBYTE_LOAD_opcode:
case SHORT_LOAD_opcode:
case USHORT_LOAD_opcode:
case INT_LOAD_opcode:
case LONG_LOAD_opcode:
case FLOAT_LOAD_opcode:
case DOUBLE_LOAD_opcode:
// Supported addressing modes are quite limited.
Load.setAddress(s, asRegAddress(Load.getClearAddress(s), s, ir));
Load.setOffset(s, asImmediateOrRegOffset(Load.getClearOffset(s), s, ir, true));
break;
case ATTEMPT_INT_opcode:
case ATTEMPT_LONG_opcode:
case ATTEMPT_ADDR_opcode:
// On PowerPC, the value being stored must be in a register
Attempt.setNewValue(s, asRegPolymorphic(Attempt.getClearNewValue(s), s, ir));
// not used on powerpc.
Attempt.setOldValue(s, null);
// Supported addressing modes are quite limited.
Attempt.setAddress(s, asRegAddress(Attempt.getClearAddress(s), s, ir));
Attempt.setOffset(s, asRegOffset(Attempt.getClearOffset(s), s, ir));
break;
case PREPARE_INT_opcode:
case PREPARE_LONG_opcode:
case PREPARE_ADDR_opcode:
// Supported addressing modes are quite limited.
Prepare.setAddress(s, asRegAddress(Prepare.getClearAddress(s), s, ir));
Prepare.setOffset(s, asRegOffset(Prepare.getClearOffset(s), s, ir));
break;
case LONG_MOVE_opcode:
if (VM.BuildFor64Addr) {
s.changeOperatorTo(REF_MOVE);
}
break;
case INT_MOVE_opcode:
s.changeOperatorTo(REF_MOVE);
break;
case REF_COND_MOVE_opcode:
s.changeOperatorTo(VM.BuildFor32Addr ? INT_COND_MOVE : LONG_COND_MOVE);
break;
case REF_IFCMP_opcode:
s.changeOperatorTo(VM.BuildFor32Addr ? INT_IFCMP : LONG_IFCMP);
// val1 can't be a constant, val2 must be small enough.
IfCmp.setVal1(s, asRegPolymorphic(IfCmp.getClearVal1(s), s, ir));
IfCmp.setVal2(s, asImmediateOrRegPolymorphic(IfCmp.getClearVal2(s), s, ir, true));
case LONG_IFCMP_opcode:
if (VM.BuildFor64Addr) {
// val1 can't be a constant, val2 must be small enough.
IfCmp.setVal1(s, asRegPolymorphic(IfCmp.getClearVal1(s), s, ir));
IfCmp.setVal2(s, asImmediateOrRegPolymorphic(IfCmp.getClearVal2(s), s, ir, true));
}
break;
case INT_IFCMP_opcode:
// val1 can't be a constant, val2 must be small enough.
IfCmp.setVal1(s, asRegPolymorphic(IfCmp.getClearVal1(s), s, ir));
IfCmp.setVal2(s, asImmediateOrRegPolymorphic(IfCmp.getClearVal2(s), s, ir, true));
break;
case INT_IFCMP2_opcode:
// val1 can't be a constant, val2 must be small enough.
IfCmp2.setVal1(s, asRegInt(IfCmp2.getClearVal1(s), s, ir));
IfCmp2.setVal2(s, asImmediateOrRegInt(IfCmp2.getClearVal2(s), s, ir, true));
break;
case BOOLEAN_CMP_INT_opcode:
case BOOLEAN_CMP_ADDR_opcode:
// val2 must be small enough.
BooleanCmp.setVal2(s, asImmediateOrRegPolymorphic(BooleanCmp.getClearVal2(s), s, ir, !BooleanCmp.getCond(s).isUNSIGNED()));
break;
case LONG_CMP_opcode:
Binary.setVal1(s, asRegPolymorphic(Binary.getVal1(s), s, ir));
Binary.setVal2(s, asRegPolymorphic(Binary.getVal2(s), s, ir));
break;
case LONG_ADD_opcode:
if (VM.BuildFor64Addr) {
s.changeOperatorTo(REF_ADD);
Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, true));
}
break;
case INT_ADD_opcode:
s.changeOperatorTo(REF_ADD);
Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, true));
break;
case REF_ADD_opcode:
Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, true));
break;
case LONG_SUB_opcode:
if (VM.BuildFor64Addr) {
s.changeOperatorTo(REF_SUB);
Binary.setVal1(s, asImmediateOrRegPolymorphic(Binary.getClearVal1(s), s, ir, true));
// val2 isn't be constant (if it were, Simplifier would have
// converted this into an ADD of -Val2).
}
break;
case INT_SUB_opcode:
s.changeOperatorTo(REF_SUB);
Binary.setVal1(s, asImmediateOrRegPolymorphic(Binary.getClearVal1(s), s, ir, true));
// converted this into an ADD of -Val2).
break;
case REF_SUB_opcode:
Binary.setVal1(s, asImmediateOrRegPolymorphic(Binary.getClearVal1(s), s, ir, true));
// converted this into an ADD of -Val2).
break;
case INT_MUL_opcode:
Binary.setVal2(s, asImmediateOrRegInt(Binary.getClearVal2(s), s, ir, true));
break;
case LONG_MUL_opcode:
if (VM.BuildFor64Addr) {
Binary.setVal2(s, asImmediateOrRegLong(Binary.getClearVal2(s), s, ir, true));
}
break;
// seem to expect constant operands at all.
case INT_REM_opcode:
case INT_DIV_opcode:
GuardedBinary.setVal1(s, asRegInt(GuardedBinary.getClearVal1(s), s, ir));
GuardedBinary.setVal2(s, asRegInt(GuardedBinary.getClearVal2(s), s, ir));
break;
case LONG_REM_opcode:
case LONG_DIV_opcode:
if (VM.BuildFor64Addr) {
GuardedBinary.setVal1(s, asRegLong(GuardedBinary.getClearVal1(s), s, ir));
GuardedBinary.setVal2(s, asRegLong(GuardedBinary.getClearVal2(s), s, ir));
}
break;
case LONG_NEG_opcode:
if (VM.BuildFor64Addr) {
s.changeOperatorTo(REF_NEG);
}
break;
case INT_NEG_opcode:
s.changeOperatorTo(REF_NEG);
break;
case LONG_NOT_opcode:
if (VM.BuildFor64Addr) {
s.changeOperatorTo(REF_NOT);
}
break;
case INT_NOT_opcode:
s.changeOperatorTo(REF_NOT);
break;
case LONG_AND_opcode:
if (VM.BuildFor64Addr) {
s.changeOperatorTo(REF_AND);
// unsigned immediate
Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
}
break;
case INT_AND_opcode:
s.changeOperatorTo(REF_AND);
// unsigned immediate
Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
break;
case REF_AND_opcode:
// unsigned immediate
Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
break;
case LONG_OR_opcode:
if (VM.BuildFor64Addr) {
s.changeOperatorTo(REF_OR);
// unsigned immediate
Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
}
break;
case INT_OR_opcode:
s.changeOperatorTo(REF_OR);
// unsigned immediate
Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
break;
case REF_OR_opcode:
// unsigned immediate
Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
break;
case LONG_XOR_opcode:
if (VM.BuildFor64Addr) {
s.changeOperatorTo(REF_XOR);
// unsigned immediate
Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
}
break;
case INT_XOR_opcode:
s.changeOperatorTo(REF_XOR);
// unsigned immediate
Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
break;
case REF_XOR_opcode:
// unsigned immediate
Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
break;
case REF_SHL_opcode:
s.changeOperatorTo(VM.BuildFor32Addr ? INT_SHL : LONG_SHL);
// Val2 could be a constant, but Val1 apparently can't be.
Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
break;
case LONG_SHL_opcode:
if (VM.BuildFor64Addr) {
// Val2 could be a constant, but Val1 apparently can't be.
Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
}
break;
case INT_SHL_opcode:
// Val2 could be a constant, but Val1 apparently can't be.
Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
break;
case REF_SHR_opcode:
s.changeOperatorTo(VM.BuildFor32Addr ? INT_SHR : LONG_SHR);
// Val2 could be a constant, but Val1 apparently can't be.
Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
break;
case LONG_SHR_opcode:
if (VM.BuildFor64Addr) {
// Val2 could be a constant, but Val1 apparently can't be.
Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
}
break;
case INT_SHR_opcode:
// Val2 could be a constant, but Val1 apparently can't be.
Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
break;
case REF_USHR_opcode:
s.changeOperatorTo(VM.BuildFor32Addr ? INT_USHR : LONG_USHR);
// Val2 could be a constant, but Val1 apparently can't be.
Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
break;
case LONG_USHR_opcode:
if (VM.BuildFor64Addr) {
// Val2 could be a constant, but Val1 apparently can't be.
Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
}
break;
case INT_USHR_opcode:
// Val2 could be a constant, but Val1 apparently can't be.
Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
break;
// Deal with Simplifier.CF_FLOAT or Simplifier.CF_DOUBLE being false
case INT_2DOUBLE_opcode:
case INT_2FLOAT_opcode:
case INT_BITS_AS_FLOAT_opcode:
Unary.setVal(s, asRegInt(Unary.getVal(s), s, ir));
break;
case ADDR_2INT_opcode:
s.changeOperatorTo(VM.BuildFor32Addr ? REF_MOVE : LONG_2INT);
break;
case ADDR_2LONG_opcode:
s.changeOperatorTo(VM.BuildFor32Addr ? INT_2LONG : REF_MOVE);
break;
case INT_2ADDRSigExt_opcode:
s.changeOperatorTo(VM.BuildFor32Addr ? REF_MOVE : INT_2LONG);
break;
case INT_2ADDRZerExt_opcode:
if (VM.BuildFor32Addr) {
s.changeOperatorTo(REF_MOVE);
}
break;
case LONG_2ADDR_opcode:
s.changeOperatorTo(VM.BuildFor64Addr ? REF_MOVE : LONG_2INT);
break;
case NULL_CHECK_opcode:
NullCheck.setRef(s, asRegAddress(NullCheck.getClearRef(s), s, ir));
break;
// Force all call parameters to be in registers
case SYSCALL_opcode:
case CALL_opcode:
{
int numArgs = Call.getNumberOfParams(s);
for (int i = 0; i < numArgs; i++) {
Call.setParam(s, i, asRegPolymorphic(Call.getClearParam(s, i), s, ir));
}
}
break;
case RETURN_opcode:
if (Return.hasVal(s)) {
Return.setVal(s, asRegPolymorphic(Return.getClearVal(s), s, ir));
}
break;
}
}
}
use of org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand in project JikesRVM by JikesRVM.
the class ValueGraph method findOrCreateVertex.
/**
* Find or create an ValueGraphVertex corresponding to a
* given constant operand
*
* @param op the constant operand
* @return a value graph vertex corresponding to this variable
*/
private ValueGraphVertex findOrCreateVertex(ConstantOperand op) {
Object name;
if (op.isAddressConstant()) {
name = (VM.BuildFor32Addr) ? op.asAddressConstant().value.toInt() : op.asAddressConstant().value.toLong();
} else if (op.isIntConstant()) {
name = op.asIntConstant().value;
} else if (op.isFloatConstant()) {
name = op.asFloatConstant().value;
} else if (op.isLongConstant()) {
name = op.asLongConstant().value;
} else if (op.isDoubleConstant()) {
name = op.asDoubleConstant().value;
} else if (op instanceof ObjectConstantOperand) {
name = op.asObjectConstant().value;
} else if (op instanceof TIBConstantOperand) {
name = op.asTIBConstant().value;
} else if (op.isNullConstant()) {
name = op;
} else if (op instanceof TrueGuardOperand) {
name = op;
} else if (op instanceof UnreachableOperand) {
name = op;
} else {
throw new OptimizingCompilerException("ValueGraph.findOrCreateVertex: unexpected constant operand: " + op);
}
ValueGraphVertex v = getVertex(name);
if (v == null) {
v = new ValueGraphVertex(op);
v.setLabel(op, 0);
graph.addGraphNode(v);
nameMap.put(name, v);
}
return v;
}
use of org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand in project JikesRVM by JikesRVM.
the class Simplifier method refLoad.
private static DefUseEffect refLoad(Instruction s, OptOptions opts) {
if (opts.SIMPLIFY_TIB_OPS) {
Operand base = Load.getAddress(s);
if (base.isTIBConstant()) {
TIBConstantOperand tib = base.asTIBConstant();
Operand offset = Load.getOffset(s);
if (tib.value.isInstantiated() && offset.isConstant()) {
// Reading from a fixed offset from an effectively
// constant array
int intOffset;
if (offset.isIntConstant()) {
intOffset = offset.asIntConstant().value;
} else {
intOffset = offset.asAddressConstant().value.toInt();
}
int intSlot = intOffset >> LOG_BYTES_IN_ADDRESS;
// Create appropriate constant operand for TIB slot
ConstantOperand result;
TIB tibArray = tib.value.getTypeInformationBlock();
if (tibArray.slotContainsTib(intSlot)) {
RVMType typeOfTIB = ((TIB) tibArray.get(intSlot)).getType();
result = new TIBConstantOperand(typeOfTIB);
} else if (tibArray.slotContainsCode(intSlot)) {
// some virtual calls go via the JTOC
if (opts.H2L_CALL_VIA_JTOC) {
RVMMethod method = tib.value.getTIBMethodAtSlot(intSlot);
result = new CodeConstantOperand(method);
} else {
return DefUseEffect.UNCHANGED;
}
} else {
if (tibArray.get(intSlot) == null) {
result = new NullConstantOperand();
} else {
result = new ObjectConstantOperand(tibArray.get(intSlot), Offset.zero());
}
}
Move.mutate(s, REF_MOVE, Load.getClearResult(s), result);
return DefUseEffect.MOVE_FOLDED;
}
}
}
return DefUseEffect.UNCHANGED;
}
Aggregations