Search in sources :

Example 41 with IntConstantOperand

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());
        }
    }
}
Also used : LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) InlinedOsrTypeInfoOperand(org.jikesrvm.compilers.opt.ir.operand.InlinedOsrTypeInfoOperand) LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) DepGraphNode(org.jikesrvm.compilers.opt.depgraph.DepGraphNode) InlinedOsrTypeInfoOperand(org.jikesrvm.compilers.opt.ir.operand.InlinedOsrTypeInfoOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand) DepGraphEdge(org.jikesrvm.compilers.opt.depgraph.DepGraphEdge)

Example 42 with IntConstantOperand

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);
    }
}
Also used : LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException) Offset(org.vmmagic.unboxed.Offset)

Example 43 with IntConstantOperand

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);
    }
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) NullConstantOperand(org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) TrapCodeOperand(org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) TypeReference(org.jikesrvm.classloader.TypeReference) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 44 with IntConstantOperand

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;
}
Also used : IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 45 with IntConstantOperand

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());
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException)

Aggregations

IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)49 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)41 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)28 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)23 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)21 LongConstantOperand (org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand)21 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)19 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)18 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)17 BranchOperand (org.jikesrvm.compilers.opt.ir.operand.BranchOperand)16 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)16 DoubleConstantOperand (org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand)15 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)15 NullConstantOperand (org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand)15 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)14 FloatConstantOperand (org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand)13 ConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ConstantOperand)12 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)11 TypeReference (org.jikesrvm.classloader.TypeReference)10 TypeOperand (org.jikesrvm.compilers.opt.ir.operand.TypeOperand)9