use of org.jikesrvm.compilers.opt.ir.operand.Operand in project JikesRVM by JikesRVM.
the class ComplexLIR2MIRExpansion method fp_ifcmp.
// the fcmoi/fcmoip was generated by burs
// we do the rest of the expansion here because in some
// cases we must remove a trailing goto, and we
// can't do that in burs!
private static Instruction fp_ifcmp(Instruction s) {
Instruction nextInstr = s.nextInstructionInCodeOrder();
BranchOperand testFailed;
BasicBlock bb = s.getBasicBlock();
Instruction lastInstr = bb.lastRealInstruction();
if (lastInstr.operator() == IA32_JMP) {
// We're in trouble if there is another instruction between s and lastInstr!
if (VM.VerifyAssertions)
VM._assert(s.nextInstructionInCodeOrder() == lastInstr);
// Set testFailed to target of GOTO
testFailed = MIR_Branch.getClearTarget(lastInstr);
nextInstr = lastInstr.nextInstructionInCodeOrder();
lastInstr.remove();
} else {
// Set testFailed to label of next (fallthrough basic block)
testFailed = bb.nextBasicBlockInCodeOrder().makeJumpTarget();
}
// Translate condition operand respecting IA32 FCOMI/COMISS/COMISD
Instruction fcomi = s.prevInstructionInCodeOrder();
Operand val1 = MIR_Compare.getVal1(fcomi);
Operand val2 = MIR_Compare.getVal2(fcomi);
ConditionOperand c = IfCmp.getCond(s);
BranchOperand target = IfCmp.getTarget(s).copy().asBranch();
BranchProfileOperand branchProfile = (BranchProfileOperand) IfCmp.getBranchProfile(s).copy();
// propagate the original probability to the second condition.
switch(c.value) {
// (i.e. UNORDERED is a goto to testFailed)
case ConditionOperand.CMPL_EQUAL:
if (VM.VerifyAssertions)
VM._assert(!c.branchIfUnordered());
// Check whether val1 and val2 operands are the same
if (!val1.similar(val2)) {
s.insertBefore(MIR_CondBranch2.create(IA32_JCC2, IA32ConditionOperand.PE(), // PF == 1
testFailed, new BranchProfileOperand(0f), IA32ConditionOperand.EQ(), // ZF == 1
target, branchProfile));
s.insertBefore(MIR_Branch.create(IA32_JMP, (BranchOperand) (testFailed.copy())));
} else {
// As val1 == val2 result of compare must be == or UNORDERED
s.insertBefore(// PF == 0
MIR_CondBranch.create(// PF == 0
IA32_JCC, // PF == 0
IA32ConditionOperand.PO(), target, branchProfile));
s.insertBefore(MIR_Branch.create(IA32_JMP, testFailed));
}
break;
case ConditionOperand.CMPL_GREATER:
if (VM.VerifyAssertions)
VM._assert(!c.branchIfUnordered());
s.insertBefore(// CF == 0 and ZF == 0
MIR_CondBranch.create(// CF == 0 and ZF == 0
IA32_JCC, // CF == 0 and ZF == 0
IA32ConditionOperand.LGT(), target, branchProfile));
s.insertBefore(MIR_Branch.create(IA32_JMP, testFailed));
break;
case ConditionOperand.CMPG_LESS:
if (VM.VerifyAssertions)
VM._assert(!c.branchIfUnordered());
s.insertBefore(MIR_CondBranch2.create(IA32_JCC2, IA32ConditionOperand.PE(), // PF == 1
testFailed, new BranchProfileOperand(0f), IA32ConditionOperand.LLT(), // CF == 1
target, branchProfile));
s.insertBefore(MIR_Branch.create(IA32_JMP, (BranchOperand) (testFailed.copy())));
break;
case ConditionOperand.CMPL_GREATER_EQUAL:
if (VM.VerifyAssertions)
VM._assert(!c.branchIfUnordered());
s.insertBefore(// CF == 0
MIR_CondBranch.create(// CF == 0
IA32_JCC, // CF == 0
IA32ConditionOperand.LGE(), target, branchProfile));
s.insertBefore(MIR_Branch.create(IA32_JMP, testFailed));
break;
case ConditionOperand.CMPG_LESS_EQUAL:
s.insertBefore(MIR_CondBranch2.create(IA32_JCC2, IA32ConditionOperand.PE(), // PF == 1
testFailed, new BranchProfileOperand(0f), IA32ConditionOperand.LGT(), // ZF == 0 and CF == 0
(BranchOperand) (testFailed.copy()), branchProfile));
s.insertBefore(MIR_Branch.create(IA32_JMP, target));
break;
// (i.e. UNORDERED is a goto to target)
case ConditionOperand.CMPL_NOT_EQUAL:
if (VM.VerifyAssertions)
VM._assert(c.branchIfUnordered());
// Check whether val1 and val2 operands are the same
if (!val1.similar(val2)) {
s.insertBefore(MIR_CondBranch2.create(IA32_JCC2, IA32ConditionOperand.PE(), // PF == 1
target, new BranchProfileOperand(0f), IA32ConditionOperand.NE(), // ZF == 0
(BranchOperand) (target.copy()), branchProfile));
s.insertBefore(MIR_Branch.create(IA32_JMP, testFailed));
} else {
// As val1 == val2 result of compare must be == or UNORDERED
s.insertBefore(// PF == 1
MIR_CondBranch.create(// PF == 1
IA32_JCC, // PF == 1
IA32ConditionOperand.PE(), target, branchProfile));
s.insertBefore(MIR_Branch.create(IA32_JMP, testFailed));
}
break;
case ConditionOperand.CMPL_LESS:
if (VM.VerifyAssertions)
VM._assert(c.branchIfUnordered());
s.insertBefore(// CF == 1
MIR_CondBranch.create(// CF == 1
IA32_JCC, // CF == 1
IA32ConditionOperand.LLT(), target, branchProfile));
s.insertBefore(MIR_Branch.create(IA32_JMP, testFailed));
break;
case ConditionOperand.CMPG_GREATER_EQUAL:
if (VM.VerifyAssertions)
VM._assert(c.branchIfUnordered());
s.insertBefore(MIR_CondBranch2.create(IA32_JCC2, IA32ConditionOperand.PE(), // PF == 1
target, new BranchProfileOperand(0f), IA32ConditionOperand.LLT(), // CF == 1
testFailed, branchProfile));
s.insertBefore(MIR_Branch.create(IA32_JMP, (BranchOperand) (target.copy())));
break;
case ConditionOperand.CMPG_GREATER:
if (VM.VerifyAssertions)
VM._assert(c.branchIfUnordered());
s.insertBefore(MIR_CondBranch2.create(IA32_JCC2, IA32ConditionOperand.PE(), // PF == 1
target, new BranchProfileOperand(0f), IA32ConditionOperand.LGT(), // ZF == 0 and CF == 0
(BranchOperand) (target.copy()), branchProfile));
s.insertBefore(MIR_Branch.create(IA32_JMP, testFailed));
break;
case ConditionOperand.CMPL_LESS_EQUAL:
if (VM.VerifyAssertions)
VM._assert(c.branchIfUnordered());
s.insertBefore(// CF == 1 or ZF == 1
MIR_CondBranch.create(// CF == 1 or ZF == 1
IA32_JCC, // CF == 1 or ZF == 1
IA32ConditionOperand.LLE(), target, branchProfile));
s.insertBefore(MIR_Branch.create(IA32_JMP, testFailed));
break;
default:
OptimizingCompilerException.UNREACHABLE();
}
s.remove();
return nextInstr;
}
use of org.jikesrvm.compilers.opt.ir.operand.Operand in project JikesRVM by JikesRVM.
the class Simple method typePropagation.
/**
* Perform flow-insensitive type propagation using register list
* information. Note: register list MUST be initialized BEFORE
* calling this routine.
*
* <p> Kept separate from copyPropagation loop to enable clients
* more flexibility.
*
* @param ir the IR in question
*/
static void typePropagation(IR ir) {
// Use register list to enumerate register objects (FAST)
Register elemNext;
for (Register reg = ir.regpool.getFirstSymbolicRegister(); reg != null; reg = elemNext) {
elemNext = reg.getNext();
// Type propagation not possible if reg has no uses
if (reg.useList == null) {
continue;
}
// Type propagation not possible if reg has no defs
if (reg.defList == null) {
continue;
}
// Do not attempt type propagation if reg has multiple defs
if (!reg.isSSA()) {
continue;
}
// Now reg has exactly one definition
RegisterOperand lhs = reg.defList;
Instruction instr = lhs.instruction;
Operator op = instr.operator();
// Type propagation not possible if lhs is not in a move instr
if (!op.isMove()) {
continue;
}
Operand rhsOp = Move.getVal(instr);
// Do not attempt type propagation if RHS is not a register
if (!(rhsOp instanceof RegisterOperand)) {
continue;
}
RegisterOperand rhs = (RegisterOperand) rhsOp;
// Propagate the type in the def
lhs.copyTypeFrom(rhs);
// Now propagate lhs into all uses; substitute rhs.type for lhs.type
for (RegisterOperand use = reg.useList; use != null; use = use.getNext()) {
// because use.type has more detailed information
if (ClassLoaderProxy.includesType(rhs.getType(), use.getType()) == YES) {
continue;
}
// don't undo the effects!
if (rhs.getType().isPrimitiveType() && !use.getType().isPrimitiveType()) {
continue;
}
use.copyTypeFrom(rhs);
}
}
}
use of org.jikesrvm.compilers.opt.ir.operand.Operand in project JikesRVM by JikesRVM.
the class Simple method eliminateDeadInstructions.
/**
* Simple conservative dead code elimination.
* An instruction is eliminated if:
* <ul>
* <li> 1. it is not a PEI, store or non-pure call
* <li> 2. it DEFs only registers
* <li> 3. all registers it DEFS are dead
* </ul>
*
* <p> Note: this function incrementally maintains the register list.
*
* @param ir IR to optimize
* @param preserveImplicitSSA if this is true, do not eliminate dead
* instructions that have implicit operands for heap array SSA form
*/
public static void eliminateDeadInstructions(IR ir, boolean preserveImplicitSSA) {
// (USE BACKWARDS PASS FOR INCREASED EFFECTIVENESS)
ArrayList<Instruction> setCaughtExceptionInstructions = null;
int getCaughtExceptionInstructions = 0;
for (Instruction instr = ir.lastInstructionInCodeOrder(), prevInstr = null; instr != null; instr = prevInstr) {
// cache because
prevInstr = instr.prevInstructionInCodeOrder();
// if instr is a PEI, store, branch, or call, then it's not dead ...
if (instr.isPEI() || instr.isImplicitStore() || instr.isBranch() || instr.isNonPureCall()) {
if (instr.operator() != TRAP) {
continue;
}
// was changed to a trap)
if (codeAfterTrapIsUnreachable(instr)) {
removeCodeAfterTrapInstruction(instr);
}
continue;
}
if (preserveImplicitSSA && (instr.isImplicitLoad() || instr.isAllocation() || instr.operator() == PHI)) {
continue;
}
if (instr.operator() == SET_CAUGHT_EXCEPTION) {
if (setCaughtExceptionInstructions == null) {
setCaughtExceptionInstructions = new ArrayList<Instruction>();
}
setCaughtExceptionInstructions.add(instr);
}
// remove NOPs
if (instr.operator() == NOP) {
DefUse.removeInstructionAndUpdateDU(instr);
}
// remove UNINT_BEGIN/UNINT_END with nothing in between them
if (instr.operator() == UNINT_BEGIN) {
Instruction s = instr.nextInstructionInCodeOrder();
if (s.operator() == UNINT_END) {
DefUse.removeInstructionAndUpdateDU(s);
DefUse.removeInstructionAndUpdateDU(instr);
}
}
// remove trivial assignments
if (Move.conforms(instr)) {
Register lhs = Move.getResult(instr).asRegister().getRegister();
if (Move.getVal(instr).isRegister()) {
Register rhs = Move.getVal(instr).asRegister().getRegister();
if (lhs == rhs) {
DefUse.removeInstructionAndUpdateDU(instr);
continue;
}
}
}
if (instr.operator() == GET_CAUGHT_EXCEPTION) {
getCaughtExceptionInstructions++;
}
// check that all defs are to dead registers and that
// there is at least 1 def.
boolean isDead = true;
boolean foundRegisterDef = false;
for (Enumeration<Operand> defs = instr.getDefs(); defs.hasMoreElements(); ) {
Operand def = defs.nextElement();
if (!def.isRegister()) {
isDead = false;
break;
}
foundRegisterDef = true;
RegisterOperand r = def.asRegister();
if (r.getRegister().useList != null) {
isDead = false;
break;
}
if (r.getRegister().isPhysical()) {
isDead = false;
break;
}
}
if (!isDead) {
continue;
}
if (!foundRegisterDef) {
continue;
}
if (instr.operator() == GET_CAUGHT_EXCEPTION) {
getCaughtExceptionInstructions--;
}
// There are 1 or more register defs, but all of them are dead.
// Remove instr.
DefUse.removeInstructionAndUpdateDU(instr);
}
if (// temporarily disabled - see RVM-410
false && (getCaughtExceptionInstructions == 0) && (setCaughtExceptionInstructions != null)) {
for (Instruction instr : setCaughtExceptionInstructions) {
DefUse.removeInstructionAndUpdateDU(instr);
}
}
}
use of org.jikesrvm.compilers.opt.ir.operand.Operand in project JikesRVM by JikesRVM.
the class Simple method copyPropagation.
/**
* Perform flow-insensitive copy and constant propagation using
* register list information.
*
* <ul>
* <li> Note: register list MUST be initialized BEFORE calling this routine.
* <li> Note: this function incrementally maintains the register list.
* </ul>
*
* @param ir the IR in question
*/
public static void copyPropagation(IR ir) {
// Use register list to enumerate register objects
Register elemNext;
boolean reiterate = true;
while (reiterate) {
// /MT/ better think about proper ordering.
reiterate = false;
for (Register reg = ir.regpool.getFirstSymbolicRegister(); reg != null; reg = elemNext) {
// we may remove reg, so get elemNext up front
elemNext = reg.getNext();
if (// Copy propagation not possible if reg
reg.useList == null || // has no uses
reg.defList == // Copy propagation not possible if reg
null || // has no defs
!reg.isSSA()) {
// for SSA registers.
continue;
}
// isSSA => reg has exactly one definition, reg.defList.
RegisterOperand lhs = reg.defList;
Instruction defInstr = lhs.instruction;
Operand rhs;
// Copy/constant propagation only possible when defInstr is a move
if (defInstr.isMove()) {
rhs = Move.getVal(defInstr);
} else if (defInstr.operator() == PHI) {
Operand phiVal = equivalentValforPHI(defInstr);
if (phiVal == null)
continue;
rhs = phiVal;
} else {
continue;
}
if (rhs.isRegister()) {
Register rrhs = rhs.asRegister().getRegister();
// all uses.
if (!rrhs.isSSA())
continue;
// uses/defs of physical registers well enough to do so safely.
if (rrhs.isPhysical())
continue;
}
reiterate = ir.options.getOptLevel() > 1;
// register list as we go.
if (rhs.isRegister()) {
RegisterOperand nextUse;
RegisterOperand rhsRegOp = rhs.asRegister();
for (RegisterOperand use = reg.useList; use != null; use = nextUse) {
// get early before reg's useList is updated.
nextUse = use.getNext();
if (VM.VerifyAssertions)
VM._assert(rhsRegOp.getRegister().getType() == use.getRegister().getType());
DefUse.transferUse(use, rhsRegOp);
}
} else if (rhs.isConstant()) {
// to blow it all away as soon as this loop is done.
for (RegisterOperand use = reg.useList; use != null; use = use.getNext()) {
int index = use.getIndexInInstruction();
use.instruction.putOperand(index, rhs.copy());
}
} else {
throw new OptimizingCompilerException("Simple.copyPropagation: unexpected operand type");
}
// defInstr is now dead. Remove it.
defInstr.remove();
if (rhs.isRegister()) {
DefUse.removeUse(rhs.asRegister());
}
ir.regpool.removeRegister(lhs.getRegister());
}
}
}
use of org.jikesrvm.compilers.opt.ir.operand.Operand in project JikesRVM by JikesRVM.
the class Simplifier method refUshr.
private static DefUseEffect refUshr(Instruction s, OptOptions opts) {
if (opts.SIMPLIFY_REF_OPS) {
Operand op2 = Binary.getVal2(s);
Operand op1 = Binary.getVal1(s);
if (op2.isIntConstant()) {
int val2 = op2.asIntConstant().value;
if (op1.isConstant() && !op1.isMovableObjectConstant()) {
// BOTH CONSTANTS: FOLD
Word val1 = getAddressValue(op1).toWord();
Move.mutate(s, REF_MOVE, Binary.getClearResult(s), AC(val1.rshl(val2).toAddress()));
return DefUseEffect.MOVE_FOLDED;
} else {
// ONLY OP2 IS CONSTANT: ATTEMPT TO APPLY AXIOMS
if (val2 == 0) {
// x >>> 0 == x
Move.mutate(s, REF_MOVE, Binary.getClearResult(s), Binary.getClearVal1(s));
return DefUseEffect.MOVE_REDUCED;
}
if ((val2 >= BITS_IN_ADDRESS) || (val2 < 0)) {
// x >>> 32 == 0
Move.mutate(s, REF_MOVE, Binary.getClearResult(s), IC(0));
return DefUseEffect.MOVE_FOLDED;
}
}
} else if (op1.isConstant() && !op1.isMovableObjectConstant()) {
Word val1 = getAddressValue(op1).toWord();
// ONLY OP1 IS CONSTANT: ATTEMPT TO APPLY AXIOMS
if (val1.EQ(Word.zero())) {
// 0 >>> x == 0
Move.mutate(s, REF_MOVE, Binary.getClearResult(s), AC(Address.zero()));
return DefUseEffect.MOVE_FOLDED;
}
}
}
return DefUseEffect.UNCHANGED;
}
Aggregations