use of org.jikesrvm.compilers.opt.ir.operand.BranchOperand 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.BranchOperand in project JikesRVM by JikesRVM.
the class BC2IR method _jsrHelper.
// // SUBROUTINES.
private Instruction _jsrHelper(int offset) {
// (1) notify the BBSet that we have reached a JSR bytecode.
// This enables the more complex JSR-aware implementation of
// BBSet.getOrCreateBlock.
blocks.seenJSR();
// (2) push return address on expression stack
push(new ReturnAddressOperand(bcodes.index()));
// (3) generate GOTO to subroutine body.
BranchOperand branch = generateTarget(offset);
return Goto.create(GOTO, branch);
}
use of org.jikesrvm.compilers.opt.ir.operand.BranchOperand in project JikesRVM by JikesRVM.
the class BURS_Helpers method CALL.
/**
* Expand a call instruction.
*/
protected final void CALL(Instruction s) {
Operand target = Call.getClearAddress(s);
MethodOperand meth = Call.getClearMethod(s);
// Step 1: Find out how many parameters we're going to have.
int numParams = Call.getNumberOfParams(s);
int longParams = 0;
if (VM.BuildFor32Addr) {
for (int pNum = 0; pNum < numParams; pNum++) {
if (Call.getParam(s, pNum).getType().isLongType()) {
longParams++;
}
}
}
// Step 2: Figure out what the result and result2 values will be
RegisterOperand result = Call.getClearResult(s);
RegisterOperand result2 = null;
if (VM.BuildFor32Addr) {
if (result != null && result.getType().isLongType()) {
result2 = I(regpool.getSecondReg(result.getRegister()));
}
}
// Step 3: Figure out what the operator is going to be
Operator callOp;
if (target instanceof RegisterOperand) {
// indirect call through target (contains code addr)
Register ctr = regpool.getPhysicalRegisterSet().asPPC().getCTR();
EMIT(MIR_Move.create(PPC_MTSPR, A(ctr), (RegisterOperand) target));
target = null;
callOp = PPC_BCTRL;
} else if (target instanceof BranchOperand) {
// Earlier analysis has tagged this call as recursive,
// set up for a direct call.
callOp = PPC_BL;
} else {
throw new OptimizingCompilerException("Unexpected target operand " + target + " to call " + s);
}
// Step 4: Mutate the Call to an MIR_Call.
// Note MIR_Call and Call have a different number of fixed
// arguments, so some amount of copying is required. We'll hope the
// opt compiler can manage to make this more efficient than it looks.
Operand[] params = new Operand[numParams];
for (int i = 0; i < numParams; i++) {
params[i] = Call.getClearParam(s, i);
}
// see step 3: callTarget is either null or already a BranchOperand
BranchOperand callTarget = (BranchOperand) target;
EMIT(MIR_Call.mutate(s, callOp, result, result2, callTarget, meth, numParams + longParams));
for (int paramIdx = 0, mirCallIdx = 0; paramIdx < numParams; ) {
Operand param = params[paramIdx++];
MIR_Call.setParam(s, mirCallIdx++, param);
if (VM.BuildFor32Addr) {
if (param instanceof RegisterOperand) {
RegisterOperand rparam = (RegisterOperand) param;
if (rparam.getType().isLongType()) {
MIR_Call.setParam(s, mirCallIdx++, L(regpool.getSecondReg(rparam.getRegister())));
}
}
}
}
}
use of org.jikesrvm.compilers.opt.ir.operand.BranchOperand 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.BranchOperand in project JikesRVM by JikesRVM.
the class BURS_Helpers method SYSCALL.
/**
* Expand a syscall instruction.
*/
protected final void SYSCALL(Instruction s) {
burs.ir.setHasSysCall(true);
Operand target = Call.getClearAddress(s);
MethodOperand meth = Call.getClearMethod(s);
// Step 1: Find out how many parameters we're going to have.
int numParams = Call.getNumberOfParams(s);
int longParams = 0;
if (VM.BuildFor32Addr) {
for (int pNum = 0; pNum < numParams; pNum++) {
if (Call.getParam(s, pNum).getType().isLongType()) {
longParams++;
}
}
}
// Step 2: Figure out what the result and result2 values will be
RegisterOperand result = Call.getClearResult(s);
RegisterOperand result2 = null;
if (VM.BuildFor32Addr) {
if (result != null && result.getType().isLongType()) {
result2 = I(regpool.getSecondReg(result.getRegister()));
}
}
// Step 3: Figure out what the operator is going to be
Operator callOp;
if (target instanceof RegisterOperand) {
// indirect call through target (contains code addr)
Register ctr = regpool.getPhysicalRegisterSet().asPPC().getCTR();
EMIT(MIR_Move.create(PPC_MTSPR, A(ctr), (RegisterOperand) target));
target = null;
callOp = PPC_BCTRL_SYS;
} else if (target instanceof BranchOperand) {
// Earlier analysis has tagged this call as recursive,
// set up for a direct call.
callOp = PPC_BL_SYS;
} else {
throw new OptimizingCompilerException("Unexpected target operand " + target + " to call " + s);
}
// Step 4: Mutate the SysCall to an MIR_Call.
// Note MIR_Call and Call have a different number of fixed
// arguments, so some amount of copying is required. We'll hope the
// opt compiler can manage to make this more efficient than it looks.
Operand[] params = new Operand[numParams];
for (int i = 0; i < numParams; i++) {
params[i] = Call.getClearParam(s, i);
}
// see step 3: callTarget is either null or already a BranchOperand
BranchOperand callTarget = (BranchOperand) target;
EMIT(MIR_Call.mutate(s, callOp, result, result2, callTarget, meth, numParams + longParams));
for (int paramIdx = 0, mirCallIdx = 0; paramIdx < numParams; ) {
Operand param = params[paramIdx++];
MIR_Call.setParam(s, mirCallIdx++, param);
if (VM.BuildFor32Addr) {
if (param instanceof RegisterOperand) {
RegisterOperand rparam = (RegisterOperand) param;
if (rparam.getType().isLongType()) {
MIR_Call.setParam(s, mirCallIdx++, L(regpool.getSecondReg(rparam.getRegister())));
}
}
}
}
}
Aggregations