use of org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand in project JikesRVM by JikesRVM.
the class NormalBURS method buildTrees.
/**
* Stage 1: Complete the expression trees and identify tree roots.
* Complete BURS trees by adding leaf nodes as needed, and
* creating tree edges by calling insertChild1() or insertChild2()
* This step is also where we introduce intermediate tree nodes for
* any LIR instruction that has > 2 "real" operands e.g., a CALL.
* We also mark nodes that must be tree roots.
*
* @param dg The dependence graph.
*/
private void buildTrees(DepGraph dg) {
DepGraphNode bbNodes = (DepGraphNode) dg.firstNode();
for (DepGraphNode n = bbNodes; n != null; n = (DepGraphNode) n.getNext()) {
// Initialize n.treeNode
AbstractBURS_TreeNode cur_parent = AbstractBURS_TreeNode.create(n);
castNode(n).setCurrentParent(cur_parent);
Instruction instr = n.instruction();
// loop for USES of an instruction
for (Enumeration<Operand> uses = instr.getUses(); uses.hasMoreElements(); ) {
// Create tree edge for next use.
Operand op = uses.nextElement();
if (op == null)
continue;
// Set child = AbstractBURS_TreeNode for operand op
AbstractBURS_TreeNode child;
if (op instanceof RegisterOperand) {
RegisterOperand regOp = (RegisterOperand) op;
// ignore validation registers
if (regOp.getRegister().isValidation())
continue;
DepGraphEdge e = DepGraphEdge.findInputEdge(n, op);
if (e == null) {
// operand is leaf
child = Register;
} else {
child = castNode(e.fromNode()).getCurrentParent();
}
} else if (op instanceof IntConstantOperand) {
child = new BURS_IntConstantTreeNode(((IntConstantOperand) op).value);
} else if (op instanceof LongConstantOperand) {
child = LongConstant;
} else if (op instanceof AddressConstantOperand) {
child = AddressConstant;
} else if (op instanceof BranchOperand && instr.isCall()) {
child = BranchTarget;
} else if (op instanceof InlinedOsrTypeInfoOperand && instr.isYieldPoint()) {
child = NullTreeNode;
} else {
continue;
}
// Attach child as child of cur_parent in correct position
if (cur_parent.getChild1() == null) {
cur_parent.setChild1(child);
} else if (cur_parent.getChild2() == null) {
cur_parent.setChild2(child);
} else {
// Create auxiliary node so as to represent
// a instruction with arity > 2 in a binary tree.
AbstractBURS_TreeNode child1 = cur_parent.getChild2();
AbstractBURS_TreeNode aux = AbstractBURS_TreeNode.create(OTHER_OPERAND_opcode);
cur_parent.setChild2(aux);
cur_parent = aux;
cur_parent.setChild1(child1);
cur_parent.setChild2(child);
}
}
// patch for calls & return
switch(instr.getOpcode()) {
case CALL_opcode:
case SYSCALL_opcode:
case YIELDPOINT_OSR_opcode:
if (cur_parent.getChild2() == null) {
cur_parent.setChild2(NullTreeNode);
}
// fall through
case RETURN_opcode:
if (cur_parent.getChild1() == null) {
cur_parent.setChild1(NullTreeNode);
}
}
if (mustBeTreeRoot(n)) {
makeTreeRoot(castNode(n).getCurrentParent());
}
}
}
use of org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand in project JikesRVM by JikesRVM.
the class BURS_MemOp_Helpers method augmentAddress.
protected final void augmentAddress(Operand op) {
if (VM.VerifyAssertions)
VM._assert(AddrStack != null, "No address to augment");
if (op.isRegister()) {
RegisterOperand rop = op.asRegister();
if (AddrStack.base == null) {
AddrStack.base = rop;
} else if (AddrStack.index == null) {
if (VM.VerifyAssertions)
VM._assert(AddrStack.scale == (byte) 0);
AddrStack.index = rop;
} else {
throw new OptimizingCompilerException("three base registers in address");
}
} else {
if (VM.fullyBooted) {
if (VM.BuildFor64Addr && op instanceof IntConstantOperand)
throw new OptimizingCompilerException("augmenting int to address in 64bit code");
if (VM.BuildFor32Addr && op instanceof LongConstantOperand)
throw new OptimizingCompilerException("augmenting long to address in 32bit code");
}
long dispTemp = op instanceof LongConstantOperand ? ((LongConstantOperand) op).value : ((IntConstantOperand) op).value;
if (VM.VerifyAssertions && VM.BuildFor32Addr)
opt_assert(fits(dispTemp, 32));
Offset disp = Offset.fromLong(dispTemp);
AddrStack.displacement = AddrStack.displacement.plus(disp);
}
}
use of org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand in project JikesRVM by JikesRVM.
the class DynamicTypeCheckExpansion method instanceOfNotNull.
/**
* Expand an instanceof instruction into the LIR sequence that implements
* the dynamic type check. Ref is known to never contain a null ptr at
* runtime.
*
* @param s an INSTANCEOF_NOTNULL instruction to expand
* @param ir the enclosing IR
* @return the last Instruction in the generated LIR sequence.
*/
static Instruction instanceOfNotNull(Instruction s, IR ir) {
RegisterOperand result = InstanceOf.getClearResult(s);
TypeReference LHStype = InstanceOf.getType(s).getTypeRef();
Operand ref = InstanceOf.getClearRef(s);
Operand guard = InstanceOf.getClearGuard(s);
Instruction next = s.nextInstructionInCodeOrder();
if (next.operator() == INT_IFCMP && IfCmp.getVal1(next) instanceof RegisterOperand && result.similar(IfCmp.getVal1(next))) {
// The result of instanceof is being consumed by a conditional branch.
// Optimize this case by generating a branching type
// check instead of producing a value.
Operand val2 = IfCmp.getVal2(next);
if (VM.VerifyAssertions) {
VM._assert(val2.isIntConstant());
}
int ival2 = ((IntConstantOperand) val2).value;
ConditionOperand cond = IfCmp.getCond(next);
boolean branchCondition = (((ival2 == 0) && (cond.isNOT_EQUAL() || cond.isLESS_EQUAL())) || ((ival2 == 1) && (cond.isEQUAL() || cond.isGREATER_EQUAL())));
BasicBlock branchBB = next.getBranchTarget();
RegisterOperand oldGuard = IfCmp.getGuardResult(next);
next.remove();
BasicBlock fallThroughBB = fallThroughBB(s, ir);
Operand RHStib = getTIB(s, ir, ref, guard);
if (branchCondition) {
return generateBranchingTypeCheck(s, ir, ref.copy(), LHStype, RHStib, branchBB, fallThroughBB, oldGuard.copyRO(), IfCmp.getClearBranchProfile(next).flip());
} else {
return generateBranchingTypeCheck(s, ir, ref.copy(), LHStype, RHStib, fallThroughBB, branchBB, oldGuard.copyRO(), IfCmp.getClearBranchProfile(next));
}
} else {
// Not a branching pattern
Operand RHStib = getTIB(s, ir, ref, guard);
return generateValueProducingTypeCheck(s, ir, ref.copy(), LHStype, RHStib, result);
}
}
use of org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand in project JikesRVM by JikesRVM.
the class BranchOptimizations method generateBooleanCompare.
/**
* Attempt to generate a boolean compare opcode from a conditional branch.
*
* <pre>
* 1) IF .. GOTO A replaced by BOOLEAN_CMP x=..
* x = 0
* GOTO B
* A: x = 1
* B: ...
* </pre>
*
* <p> Precondition: <code>IfCmp.conforms(<i>cb</i>)</code>
*
* @param ir governing IR
* @param bb basic block of cb
* @param cb conditional branch instruction
* @param tb target block the branch instruction
* @return {@code true} if and only if the transformation succeeds
*/
private boolean generateBooleanCompare(IR ir, BasicBlock bb, Instruction cb, BasicBlock tb) {
if ((cb.operator() != INT_IFCMP) && (cb.operator() != REF_IFCMP)) {
return false;
}
// make sure this is the last branch in the block
if (cb.nextInstructionInCodeOrder().operator() != BBEND) {
return false;
}
Operand val1 = IfCmp.getVal1(cb);
Operand val2 = IfCmp.getVal2(cb);
ConditionOperand condition = IfCmp.getCond(cb);
// "not taken" path
BasicBlock fb = cb.getBasicBlock().getNotTakenNextBlock();
// make sure it's a diamond
if (tb.getNumberOfNormalOut() != 1) {
return false;
}
if (fb.getNumberOfNormalOut() != 1) {
return false;
}
// join block
BasicBlock jb = fb.getNormalOut().nextElement();
// make sure it's a diamond
if (!tb.pointsOut(jb)) {
return false;
}
Instruction ti = tb.firstRealInstruction();
Instruction fi = fb.firstRealInstruction();
// or both returns
if (ti == null || fi == null) {
return false;
}
if (ti.operator() != fi.operator()) {
return false;
}
if (ti.operator() != RETURN && ti.operator() != INT_MOVE) {
return false;
}
//
if (ti.operator() == RETURN) {
// make sure each of the target blocks contains only one instruction
if (ti != tb.lastRealInstruction()) {
return false;
}
if (fi != fb.lastRealInstruction()) {
return false;
}
Operand tr = Return.getVal(ti);
Operand fr = Return.getVal(fi);
// make sure we're returning constants
if (!(tr instanceof IntConstantOperand) || !(fr instanceof IntConstantOperand)) {
return false;
}
int tv = ((IntConstantOperand) tr).value;
int fv = ((IntConstantOperand) fr).value;
if (!((tv == 1 && fv == 0) || (tv == 1 && fv == 0))) {
return false;
}
RegisterOperand t = ir.regpool.makeTemp(TypeReference.Boolean);
// Cases 1) and 2)
if (tv == 0) {
condition = condition.flipCode();
}
booleanCompareHelper(cb, t, val1.copy(), val2.copy(), condition);
cb.insertAfter(Return.create(RETURN, t.copyD2U()));
} else {
// make sure each of the target blocks only does the move
if (ti != tb.lastRealInstruction() && ti.nextInstructionInCodeOrder().operator() != GOTO) {
return false;
}
if (fi != fb.lastRealInstruction() && fi.nextInstructionInCodeOrder().operator() != GOTO) {
return false;
}
RegisterOperand t = Move.getResult(ti);
// make sure both moves are to the same register
if (t.getRegister() != Move.getResult(fi).getRegister()) {
return false;
}
Operand tr = Move.getVal(ti);
Operand fr = Move.getVal(fi);
// make sure we're assigning constants
if (!(tr instanceof IntConstantOperand) || !(fr instanceof IntConstantOperand)) {
return false;
}
int tv = ((IntConstantOperand) tr).value;
int fv = ((IntConstantOperand) fr).value;
if (!((tv == 1 && fv == 0) || (tv == 0 && fv == 1))) {
return false;
}
// Cases 3) and 4)
if (tv == 0) {
condition = condition.flipCode();
}
booleanCompareHelper(cb, t.copyRO(), val1.copy(), val2.copy(), condition);
Instruction next = cb.nextInstructionInCodeOrder();
if (next.operator() == GOTO) {
Goto.setTarget(next, jb.makeJumpTarget());
} else {
cb.insertAfter(jb.makeGOTO());
}
}
// fixup CFG
bb.deleteOut(tb);
bb.deleteOut(fb);
// Note: if we processed returns,
bb.insertOut(jb);
// jb is the exit node.
return true;
}
use of org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand in project JikesRVM by JikesRVM.
the class BranchOptimizations method booleanCompareHelper.
/**
* Generate a boolean operation opcode
*
* <pre>
* 1) IF br != 0 THEN x=1 ELSE x=0 replaced by INT_MOVE x=br
* IF br == 0 THEN x=0 ELSE x=1
* 2) IF br == 0 THEN x=1 ELSE x=0 replaced by BOOLEAN_NOT x=br
* IF br != 0 THEN x=0 ELSE x=1
* 3) IF v1 ~ v2 THEN x=1 ELSE x=0 replaced by BOOLEAN_CMP x=v1,v2,~
* </pre>
*
* @param cb conditional branch instruction
* @param res the operand for result
* @param val1 value being compared
* @param val2 value being compared with
* @param cond comparison condition
*/
private void booleanCompareHelper(Instruction cb, RegisterOperand res, Operand val1, Operand val2, ConditionOperand cond) {
if ((val1 instanceof RegisterOperand) && ((RegisterOperand) val1).getType().isBooleanType() && (val2 instanceof IntConstantOperand)) {
int value = ((IntConstantOperand) val2).value;
if (VM.VerifyAssertions && (value != 0) && (value != 1)) {
throw new OptimizingCompilerException("Invalid boolean value");
}
int c = cond.evaluate(value, 0);
if (c == ConditionOperand.TRUE) {
Unary.mutate(cb, BOOLEAN_NOT, res, val1);
return;
} else if (c == ConditionOperand.FALSE) {
Move.mutate(cb, INT_MOVE, res, val1);
return;
}
}
BooleanCmp.mutate(cb, (cb.operator() == REF_IFCMP) ? BOOLEAN_CMP_ADDR : BOOLEAN_CMP_INT, res, val1, val2, cond, new BranchProfileOperand());
}
Aggregations