use of org.jikesrvm.compilers.opt.ir.Operator in project JikesRVM by JikesRVM.
the class NullCheckCombining method perform.
/**
* Perform nullcheck combining and validation register removal.
*
* @param ir the IR to transform
*/
@Override
public void perform(IR ir) {
for (BasicBlock bb = ir.firstBasicBlockInCodeOrder(); bb != null; bb = bb.nextBasicBlockInCodeOrder()) {
if (!bb.isEmpty()) {
Instruction lastInstr = bb.lastInstruction();
boolean combined;
boolean remaining;
// handler-visible state.
do {
combined = remaining = false;
Instruction activeNullCheck = null;
Operand activeGuard = null;
for (Instruction instr = bb.firstRealInstruction(), nextInstr = null; instr != lastInstr; instr = nextInstr) {
nextInstr = instr.nextInstructionInCodeOrder();
Operator op = instr.operator();
if (op == GUARD_MOVE) {
if (activeGuard != null && Move.getVal(instr).similar(activeGuard)) {
activeGuard = Move.getResult(instr);
}
} else if (op == GUARD_COMBINE) {
if (activeGuard != null && (Binary.getVal1(instr) == activeGuard || Binary.getVal2(instr) == activeGuard)) {
activeGuard = null;
}
} else if (op == NULL_CHECK) {
remaining |= (activeGuard == null);
activeGuard = NullCheck.getGuardResult(instr);
activeNullCheck = instr;
} else if (isExplicitStore(instr, op)) {
if (instr.isPEI()) {
// can't reorder PEI's
// NOTE: don't mark remaining, since we'd hit the same problem instr again.
activeGuard = null;
} else {
if (activeGuard != null && canFold(instr, activeGuard, true)) {
instr.markAsPEI();
activeNullCheck.remove();
activeGuard = null;
combined = true;
}
remaining |= (activeGuard == null);
// don't attempt to move PEI past a store; could do better.
activeGuard = null;
}
} else if (isExplicitLoad(instr, op)) {
if (activeGuard != null && canFold(instr, activeGuard, false)) {
instr.markAsPEI();
activeNullCheck.remove();
activeGuard = null;
combined = true;
} else if (instr.isPEI()) {
// can't reorder PEI's
// NOTE: don't mark remaining, since we'd hit the same problem instr again.
activeGuard = null;
}
} else {
if (op.isImplicitStore() || op.isPEI()) {
// NOTE: don't mark remaining, since we'd hit the same problem instr again.
// don't reorder PEI's; be conservative about stores.
activeGuard = null;
}
}
}
} while (combined & remaining);
// (2) Blow away all validation registers in bb.
for (Instruction instr = bb.firstRealInstruction(), nextInstr = null; instr != lastInstr; instr = nextInstr) {
nextInstr = instr.nextInstructionInCodeOrder();
Operator op = instr.operator();
if (op == GUARD_MOVE || op == GUARD_COMBINE) {
instr.remove();
} else {
if (GuardResultCarrier.conforms(op)) {
GuardResultCarrier.setGuardResult(instr, null);
}
if (GuardCarrier.conforms(op)) {
GuardCarrier.setGuard(instr, null);
}
}
}
}
}
}
use of org.jikesrvm.compilers.opt.ir.Operator in project JikesRVM by JikesRVM.
the class BURS_Helpers method CMP64.
/**
* emit basic code to handle an INT_IFCMP when no folding
* of the compare into some other computation is possible.
*/
protected final void CMP64(Instruction s, RegisterOperand val1, Operand val2, ConditionOperand cond, boolean immediate) {
if (VM.VerifyAssertions)
VM._assert(VM.BuildFor64Addr);
RegisterOperand cr = regpool.makeTempCondition();
Operator op;
if (immediate) {
op = cond.isUNSIGNED() ? PPC64_CMPLI : PPC64_CMPI;
} else {
op = cond.isUNSIGNED() ? PPC64_CMPL : PPC64_CMP;
}
EMIT(MIR_Binary.create(op, cr, val1, val2));
EMIT(MIR_CondBranch.mutate(s, PPC_BCOND, cr.copyD2U(), new PowerPCConditionOperand(cond), IfCmp.getTarget(s), IfCmp.getBranchProfile(s)));
}
use of org.jikesrvm.compilers.opt.ir.Operator 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.Operator in project JikesRVM by JikesRVM.
the class BURS_Helpers method EMIT_BOOLCMP_BRANCH.
protected final void EMIT_BOOLCMP_BRANCH(BranchOperand target, BranchProfileOperand bp) {
if (VM.VerifyAssertions)
VM._assert(cc != null);
RegisterOperand cr = regpool.makeTempCondition();
Operator op;
if (VM.BuildFor64Addr && isAddress) {
if (val2 instanceof IntConstantOperand) {
op = cc.isUNSIGNED() ? PPC64_CMPLI : PPC64_CMPI;
} else {
op = cc.isUNSIGNED() ? PPC64_CMPL : PPC64_CMP;
}
} else if (val2 instanceof IntConstantOperand) {
op = cc.isUNSIGNED() ? PPC_CMPLI : PPC_CMPI;
} else {
op = cc.isUNSIGNED() ? PPC_CMPL : PPC_CMP;
}
EMIT(MIR_Binary.create(op, cr, R(val1), val2));
EMIT(MIR_CondBranch.create(PPC_BCOND, cr.copyD2U(), new PowerPCConditionOperand(cc), target, bp));
if (VM.VerifyAssertions) {
cc = null;
val1 = null;
val2 = null;
}
}
use of org.jikesrvm.compilers.opt.ir.Operator 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