use of org.jikesrvm.compilers.opt.ir.operand.ConditionOperand in project JikesRVM by JikesRVM.
the class BC2IR method _intIfHelper.
// helper function for if?? bytecodes
private Instruction _intIfHelper(ConditionOperand cond) {
int offset = bcodes.getBranchOffset();
Operand op0 = popInt();
if (offset == 3) {
// remove frivolous IFs
return null;
}
if (CF_INTIF && op0 instanceof IntConstantOperand) {
int c = cond.evaluate(((IntConstantOperand) op0).value, 0);
if (c == ConditionOperand.TRUE) {
if (DBG_CF) {
db(cond + ": changed branch to goto because predicate (" + op0 + ") is constant true");
}
return _gotoHelper(offset);
} else if (c == ConditionOperand.FALSE) {
if (DBG_CF) {
db(cond + ": eliminated branch because predicate (" + op0 + ") is constant false");
}
return null;
}
}
fallThrough = true;
if (!(op0 instanceof RegisterOperand)) {
if (DBG_CF)
db("generated int_ifcmp of " + op0 + " with 0");
RegisterOperand guard = gc.getTemps().makeTempValidation();
return IfCmp.create(INT_IFCMP, guard, op0, new IntConstantOperand(0), cond, generateTarget(offset), gc.getConditionalBranchProfileOperand(instrIndex - bciAdjustment, offset < 0));
}
RegisterOperand val = (RegisterOperand) op0;
BranchOperand branch = null;
if (lastInstr != null) {
switch(lastInstr.getOpcode()) {
case INSTANCEOF_opcode:
case INSTANCEOF_UNRESOLVED_opcode:
{
if (DBG_TYPE)
db("last instruction was instanceof");
RegisterOperand res = InstanceOf.getResult(lastInstr);
if (DBG_TYPE)
db("result was in " + res + ", we are checking " + val);
if (val.getRegister() != res.getRegister()) {
// not our value
break;
}
Operand ref = InstanceOf.getRef(lastInstr);
// should've been constant folded anyway
if (!(ref instanceof RegisterOperand)) {
break;
}
RegisterOperand guard = null;
// Propagate types and non-nullness along the CFG edge where we
// know that refReg is an instanceof type2
RegisterOperand refReg = (RegisterOperand) ref;
TypeReference type2 = InstanceOf.getType(lastInstr).getTypeRef();
if (cond.isNOT_EQUAL()) {
// IS an instance of on the branch-taken edge
boolean generated = false;
if (refReg.getRegister().isLocal()) {
int locNum = gc.getLocalNumberFor(refReg.getRegister(), refReg.getType());
if (locNum != -1) {
Operand loc = getLocal(locNum);
if (loc instanceof RegisterOperand) {
if (DBG_TYPE) {
db(val + " is from instanceof test, propagating new type of " + refReg + " (" + type2 + ") to basic block at " + offset);
}
RegisterOperand locr = (RegisterOperand) loc;
RegisterOperand tlocr = locr.copyU2U();
guard = gc.makeNullCheckGuard(tlocr.getRegister());
setGuardForRegOp(tlocr, guard.copyD2U());
tlocr.clearDeclaredType();
tlocr.clearPreciseType();
tlocr.setType(type2);
setLocal(locNum, tlocr);
branch = generateTarget(offset);
generated = true;
setLocal(locNum, locr);
}
}
}
if (!generated) {
branch = generateTarget(offset);
}
} else if (cond.isEQUAL()) {
// IS an instance of on the fallthrough edge.
branch = generateTarget(offset);
if (refReg.getRegister().isLocal()) {
int locNum = gc.getLocalNumberFor(refReg.getRegister(), refReg.getType());
if (locNum != -1) {
Operand loc = getLocal(locNum);
if (loc instanceof RegisterOperand) {
if (DBG_TYPE) {
db(val + " is from instanceof test, propagating new type of " + refReg + " (" + type2 + ") along fallthrough edge");
}
RegisterOperand locr = (RegisterOperand) loc;
guard = gc.makeNullCheckGuard(locr.getRegister());
setGuardForRegOp(locr, guard.copyD2U());
locr.clearDeclaredType();
locr.clearPreciseType();
locr.setType(type2);
setLocal(locNum, loc);
}
}
}
}
if (guard == null) {
guard = gc.getTemps().makeTempValidation();
}
return IfCmp.create(INT_IFCMP, guard, val, new IntConstantOperand(0), cond, branch, gc.getConditionalBranchProfileOperand(instrIndex - bciAdjustment, offset < 0));
}
case INSTANCEOF_NOTNULL_opcode:
{
if (DBG_TYPE)
db("last instruction was instanceof");
RegisterOperand res = InstanceOf.getResult(lastInstr);
if (DBG_TYPE) {
db("result was in " + res + ", we are checking " + val);
}
if (val.getRegister() != res.getRegister()) {
// not our value
break;
}
Operand ref = InstanceOf.getRef(lastInstr);
// should've been constant folded anyway
if (!(ref instanceof RegisterOperand)) {
break;
}
// Propagate types along the CFG edge where we know that
// refReg is an instanceof type2
RegisterOperand refReg = (RegisterOperand) ref;
TypeReference type2 = InstanceOf.getType(lastInstr).getTypeRef();
if (cond.isNOT_EQUAL()) {
// IS an instance of on the branch-taken edge
boolean generated = false;
if (refReg.getRegister().isLocal()) {
int locNum = gc.getLocalNumberFor(refReg.getRegister(), refReg.getType());
if (locNum != -1) {
Operand loc = getLocal(locNum);
if (loc instanceof RegisterOperand) {
if (DBG_TYPE) {
db(val + " is from instanceof test, propagating new type of " + refReg + " (" + type2 + ") to basic block at " + offset);
}
RegisterOperand locr = (RegisterOperand) loc;
RegisterOperand tlocr = locr.copyU2U();
tlocr.clearDeclaredType();
tlocr.clearPreciseType();
tlocr.setType(type2);
setLocal(locNum, tlocr);
branch = generateTarget(offset);
generated = true;
setLocal(locNum, locr);
}
}
}
if (!generated) {
branch = generateTarget(offset);
}
} else if (cond.isEQUAL()) {
// IS an instance of on the fallthrough edge.
branch = generateTarget(offset);
if (refReg.getRegister().isLocal()) {
int locNum = gc.getLocalNumberFor(refReg.getRegister(), refReg.getType());
if (locNum != -1) {
Operand loc = getLocal(locNum);
if (loc instanceof RegisterOperand) {
if (DBG_TYPE) {
db(val + " is from instanceof test, propagating new type of " + refReg + " (" + type2 + ") along fallthrough edge");
}
RegisterOperand locr = (RegisterOperand) loc;
locr.setType(type2);
locr.clearDeclaredType();
setLocal(locNum, loc);
}
}
}
}
RegisterOperand guard = gc.getTemps().makeTempValidation();
return IfCmp.create(INT_IFCMP, guard, val, new IntConstantOperand(0), cond, branch, gc.getConditionalBranchProfileOperand(instrIndex - bciAdjustment, offset < 0));
}
case DOUBLE_CMPG_opcode:
case DOUBLE_CMPL_opcode:
case FLOAT_CMPG_opcode:
case FLOAT_CMPL_opcode:
case LONG_CMP_opcode:
{
RegisterOperand res = Binary.getResult(lastInstr);
if (val.getRegister() != res.getRegister()) {
// not our value
break;
}
Operator operator = null;
switch(lastInstr.getOpcode()) {
case DOUBLE_CMPG_opcode:
cond.translateCMPG();
operator = DOUBLE_IFCMP;
break;
case DOUBLE_CMPL_opcode:
cond.translateCMPL();
operator = DOUBLE_IFCMP;
break;
case FLOAT_CMPG_opcode:
cond.translateCMPG();
operator = FLOAT_IFCMP;
break;
case FLOAT_CMPL_opcode:
cond.translateCMPL();
operator = FLOAT_IFCMP;
break;
case LONG_CMP_opcode:
operator = LONG_IFCMP;
break;
default:
OptimizingCompilerException.UNREACHABLE();
break;
}
Operand val1 = Binary.getClearVal1(lastInstr);
Operand val2 = Binary.getClearVal2(lastInstr);
if (!(val1 instanceof RegisterOperand)) {
// swap operands
Operand temp = val1;
val1 = val2;
val2 = temp;
cond = cond.flipOperands();
}
lastInstr.remove();
lastInstr = null;
branch = generateTarget(offset);
RegisterOperand guard = gc.getTemps().makeTempValidation();
return IfCmp.create(operator, guard, val1, val2, cond, branch, gc.getConditionalBranchProfileOperand(instrIndex - bciAdjustment, offset < 0));
}
default:
// Fall through and Insert INT_IFCMP
break;
}
}
branch = generateTarget(offset);
RegisterOperand guard = gc.getTemps().makeTempValidation();
return IfCmp.create(INT_IFCMP, guard, val, new IntConstantOperand(0), cond, branch, gc.getConditionalBranchProfileOperand(instrIndex - bciAdjustment, offset < 0));
}
use of org.jikesrvm.compilers.opt.ir.operand.ConditionOperand in project JikesRVM by JikesRVM.
the class BC2IR method _intIfCmpHelper.
// helper function for if_icmp?? bytecodes
private Instruction _intIfCmpHelper(ConditionOperand cond) {
int offset = bcodes.getBranchOffset();
Operand op1 = popInt();
Operand op0 = popInt();
if (offset == 3) {
// remove frivolous INF_IFCMPs
return null;
}
if (!(op0 instanceof RegisterOperand)) {
// swap operands
Operand temp = op0;
op0 = op1;
op1 = temp;
cond = cond.flipOperands();
}
if (CF_INTIFCMP && (op0 instanceof IntConstantOperand) && (op1 instanceof IntConstantOperand)) {
int c = cond.evaluate(((IntConstantOperand) op0).value, ((IntConstantOperand) op1).value);
if (c == ConditionOperand.TRUE) {
if (DBG_CF) {
db(cond + ": changed branch to goto because predicate (" + op0 + ", " + op1 + ") is constant true");
}
return _gotoHelper(offset);
} else if (c == ConditionOperand.FALSE) {
if (DBG_CF) {
db(cond + ": eliminated branch because predicate (" + op0 + "," + op1 + ") is constant false");
}
return null;
}
}
fallThrough = true;
RegisterOperand guard = gc.getTemps().makeTempValidation();
return IfCmp.create(INT_IFCMP, guard, op0, op1, cond, generateTarget(offset), gc.getConditionalBranchProfileOperand(instrIndex - bciAdjustment, offset < 0));
}
use of org.jikesrvm.compilers.opt.ir.operand.ConditionOperand in project JikesRVM by JikesRVM.
the class BURS_Helpers method DOUBLE_IFCMP.
protected final void DOUBLE_IFCMP(Instruction s, RegisterOperand left, Operand right) {
// Create compare
RegisterOperand cr = regpool.makeTempCondition();
EMIT(MIR_Binary.create(PPC_FCMPU, cr, left, right));
// Branch depends on condition
ConditionOperand c = IfCmp.getCond(s);
BranchOperand target = IfCmp.getClearTarget(s);
if (!c.branchIfUnordered()) {
// If branch doesn't branch when unordered then we need just one
// branch destination
EMIT(MIR_CondBranch.create(PPC_BCOND, cr.copyD2U(), new PowerPCConditionOperand(c), target, IfCmp.getClearBranchProfile(s)));
} else {
if ((c.value != ConditionOperand.NOT_EQUAL) || (!left.similar(right))) {
// Propagate branch probabilities as follows: assume the
// probability of unordered (first condition) is zero, and
// propagate the original probability to the second condition.
EMIT(MIR_CondBranch2.create(PPC_BCOND2, cr.copyD2U(), PowerPCConditionOperand.UNORDERED(), target, new BranchProfileOperand(0f), new PowerPCConditionOperand(c), (BranchOperand) target.copy(), IfCmp.getClearBranchProfile(s)));
} else {
// If branch is effectively a NaN test we just need 1 branch
EMIT(MIR_CondBranch.create(PPC_BCOND, cr.copyD2U(), new PowerPCConditionOperand(c), target, IfCmp.getClearBranchProfile(s)));
}
}
}
use of org.jikesrvm.compilers.opt.ir.operand.ConditionOperand in project JikesRVM by JikesRVM.
the class BURS_Helpers method BOOLEAN_CMP_LONG.
/**
* Expansion of BOOLEAN_CMP_LONG
*
* @param s the instruction to copy position info from
* @param res the result operand
* @param val1 the first value
* @param val2 the second value
* @param cond the condition operand
*/
protected final void BOOLEAN_CMP_LONG(Instruction s, RegisterOperand res, Operand val1, Operand val2, ConditionOperand cond) {
// Can we simplify to a shift?
if (cond.isLESS() && val2.isLongConstant() && val2.asLongConstant().value == 0 && val1.isRegister()) {
// Put the most significant bit of val1 into res
Register val1_reg = val1.asRegister().getRegister();
EMIT(MIR_Move.create(IA32_MOV, res.copyRO(), new RegisterOperand(val1_reg, TypeReference.Int)));
EMIT(MIR_BinaryAcc.mutate(s, IA32_SHR, res, IC(31)));
} else if (cond.isGREATER_EQUAL() && val2.isLongConstant() && val2.asLongConstant().value == 0 && val1.isRegister()) {
// Put the most significant bit of val1 into res and invert
Register val1_reg = val1.asRegister().getRegister();
EMIT(MIR_Move.create(IA32_MOV, res.copyRO(), new RegisterOperand(val1_reg, TypeReference.Int)));
EMIT(MIR_BinaryAcc.mutate(s, IA32_SHR, res, IC(31)));
EMIT(MIR_BinaryAcc.create(IA32_XOR, res.copyRO(), IC(1)));
} else {
// ==/!= : do subtract then OR 2 32-bit quantities test for zero/non-zero
if (cond.isGREATER() || cond.isLESS_EQUAL()) {
Operand swap_temp;
cond.flipOperands();
swap_temp = val1;
val1 = val2;
val2 = swap_temp;
}
if (VM.VerifyAssertions) {
opt_assert(cond.isEQUAL() || cond.isNOT_EQUAL() || cond.isLESS() || cond.isGREATER_EQUAL());
}
RegisterOperand one = regpool.makeTempInt();
RegisterOperand lone = regpool.makeTempInt();
Operand two, ltwo;
if (val1 instanceof RegisterOperand) {
Register val1_reg = val1.asRegister().getRegister();
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, one, new RegisterOperand(val1_reg, TypeReference.Int))));
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, lone, new RegisterOperand(regpool.getSecondReg(val1_reg), TypeReference.Int))));
} else {
LongConstantOperand tmp = (LongConstantOperand) val1;
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, one, IC(tmp.upper32()))));
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, lone, IC(tmp.lower32()))));
}
if (val2 instanceof RegisterOperand) {
two = val2;
((RegisterOperand) two).setType(TypeReference.Int);
ltwo = new RegisterOperand(burs.ir.regpool.getSecondReg(val2.asRegister().getRegister()), TypeReference.Int);
} else {
LongConstantOperand tmp = (LongConstantOperand) val2;
two = IC(tmp.upper32());
ltwo = IC(tmp.lower32());
}
if (cond.isEQUAL() || cond.isNOT_EQUAL()) {
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SUB, lone.copyRO(), ltwo)));
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SBB, one.copyRO(), two)));
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_OR, one.copyRO(), lone.copyRO())));
} else {
EMIT(CPOS(s, MIR_Compare.create(IA32_CMP, lone.copyRO(), ltwo)));
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SBB, one.copyRO(), two)));
}
RegisterOperand temp = regpool.makeTemp(TypeReference.Boolean);
EMIT(CPOS(s, MIR_Set.create(IA32_SET__B, temp, COND(cond))));
EMIT(MIR_Unary.mutate(s, IA32_MOVZX__B, res, temp.copyRO()));
}
}
use of org.jikesrvm.compilers.opt.ir.operand.ConditionOperand in project JikesRVM by JikesRVM.
the class BURS_Helpers method EMIT_Compare.
/**
* Gives the MIR condition operator appropriate for the given condition
* @param s the comparison instruction
* @param cond the condition
* @param val1 first operand for the compare
* @param val2 second operand for the compare
*/
protected void EMIT_Compare(Instruction s, ConditionOperand cond, Operand val1, Operand val2) {
// Swap operands for non-commutative operators
if (getCMP_needsSwap(cond)) {
Operand temp = val1;
val2 = val1;
val1 = temp;
}
switch(cond.value) {
case ConditionOperand.CARRY_FROM_ADD:
case ConditionOperand.NO_CARRY_FROM_ADD:
case ConditionOperand.OVERFLOW_FROM_ADD:
case ConditionOperand.NO_OVERFLOW_FROM_ADD:
{
RegisterOperand temp = regpool.makeTempInt();
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, temp, val1.copy())));
EMIT(MIR_BinaryAcc.mutate(s, IA32_ADD, temp.copyRO(), val2));
break;
}
case ConditionOperand.BIT_TEST:
case ConditionOperand.NO_BIT_TEST:
case ConditionOperand.RBIT_TEST:
case ConditionOperand.NO_RBIT_TEST:
if (val2 instanceof MemoryOperand) {
RegisterOperand temp = regpool.makeTempInt();
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, temp, val2.copy())));
val2 = temp;
}
EMIT(MIR_Compare.mutate(s, IA32_BT, val1.copy(), val2.copy()));
break;
case ConditionOperand.OVERFLOW_FROM_MUL:
case ConditionOperand.NO_OVERFLOW_FROM_MUL:
{
RegisterOperand temp = regpool.makeTempInt();
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, temp, val1.copy())));
EMIT(MIR_BinaryAcc.mutate(s, IA32_IMUL2, temp.copyRO(), val2));
break;
}
default:
EMIT(MIR_Compare.mutate(s, IA32_CMP, val1.copy(), val2.copy()));
break;
}
}
Aggregations