Search in sources :

Example 16 with OptimizingCompilerException

use of org.jikesrvm.compilers.opt.OptimizingCompilerException in project JikesRVM by JikesRVM.

the class IndexPropagationSystem method processALoad.

/**
 * Update the set of dataflow equations to account for the actions
 * of ALoad instruction s
 *
 * <p> The load is of the form x = A[k].  let A_1 be the array SSA
 * variable before the load, and A_2 the array SSA variable after
 * the load.  Then we add the dataflow equation
 * L(A_2) = updateUse(L(A_1), VALNUM(k))
 *
 * <p> Intuitively, this equation represents the fact that A[k] is available
 * after the store
 *
 * @param s the Aload instruction
 */
void processALoad(Instruction s) {
    HeapOperand<?>[] A1 = ssa.getHeapUses(s);
    HeapOperand<?>[] A2 = ssa.getHeapDefs(s);
    if ((A1.length != 1) || (A2.length != 1)) {
        throw new OptimizingCompilerException("IndexPropagation.processALoad: aload instruction defs or uses multiple heap variables?");
    }
    Operand array = ALoad.getArray(s);
    Operand index = ALoad.getIndex(s);
    if (IRTools.mayBeVolatileFieldLoad(s) || ir.options.READS_KILL) {
        // to obey JMM strictly, we must treat every load as a
        // DEF
        addUpdateArrayDefEquation(A2[0].getHeapVariable(), A1[0].getHeapVariable(), array, index);
    } else {
        // otherwise, don't have to treat every load as a DEF
        addUpdateArrayUseEquation(A2[0].getHeapVariable(), A1[0].getHeapVariable(), array, index);
    }
}
Also used : HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException)

Example 17 with OptimizingCompilerException

use of org.jikesrvm.compilers.opt.OptimizingCompilerException in project JikesRVM by JikesRVM.

the class IndexPropagationSystem method processAStore.

/**
 * Update the set of dataflow equations to account for the actions
 * of AStore instruction s
 *
 * <p> The store is of the form A[k] = val.  let A_1 be the array SSA
 * variable before the store, and A_2 the array SSA variable after
 * the store.  Then we add the dataflow equation
 * L(A_2) = update(L(A_1), VALNUM(k))
 *
 * <p> Intuitively, this equation represents the fact that A[k] is available
 * after the store
 *
 * @param s the Astore instruction
 */
void processAStore(Instruction s) {
    HeapOperand<?>[] A1 = ssa.getHeapUses(s);
    HeapOperand<?>[] A2 = ssa.getHeapDefs(s);
    if ((A1.length != 1) || (A2.length != 1)) {
        throw new OptimizingCompilerException("IndexPropagation.processAStore: astore instruction defs or uses multiple heap variables?");
    }
    Operand array = AStore.getArray(s);
    Operand index = AStore.getIndex(s);
    addUpdateArrayDefEquation(A2[0].getHeapVariable(), A1[0].getHeapVariable(), array, index);
}
Also used : HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException)

Example 18 with OptimizingCompilerException

use of org.jikesrvm.compilers.opt.OptimizingCompilerException in project JikesRVM by JikesRVM.

the class ValueGraph method findOrCreateVertex.

/**
 * Find or create an ValueGraphVertex corresponding to a
 * given constant operand
 *
 * @param op the constant operand
 * @return a value graph vertex corresponding to this variable
 */
private ValueGraphVertex findOrCreateVertex(ConstantOperand op) {
    Object name;
    if (op.isAddressConstant()) {
        name = (VM.BuildFor32Addr) ? op.asAddressConstant().value.toInt() : op.asAddressConstant().value.toLong();
    } else if (op.isIntConstant()) {
        name = op.asIntConstant().value;
    } else if (op.isFloatConstant()) {
        name = op.asFloatConstant().value;
    } else if (op.isLongConstant()) {
        name = op.asLongConstant().value;
    } else if (op.isDoubleConstant()) {
        name = op.asDoubleConstant().value;
    } else if (op instanceof ObjectConstantOperand) {
        name = op.asObjectConstant().value;
    } else if (op instanceof TIBConstantOperand) {
        name = op.asTIBConstant().value;
    } else if (op.isNullConstant()) {
        name = op;
    } else if (op instanceof TrueGuardOperand) {
        name = op;
    } else if (op instanceof UnreachableOperand) {
        name = op;
    } else {
        throw new OptimizingCompilerException("ValueGraph.findOrCreateVertex: unexpected constant operand: " + op);
    }
    ValueGraphVertex v = getVertex(name);
    if (v == null) {
        v = new ValueGraphVertex(op);
        v.setLabel(op, 0);
        graph.addGraphNode(v);
        nameMap.put(name, v);
    }
    return v;
}
Also used : ObjectConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand) TIBConstantOperand(org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand) UnreachableOperand(org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)

Example 19 with OptimizingCompilerException

use of org.jikesrvm.compilers.opt.OptimizingCompilerException in project JikesRVM by JikesRVM.

the class BURS_Helpers method LONG_SHR.

/**
 * Expansion of LONG_SHR
 * @param s the instruction to expand
 * @param result the result operand
 * @param val1 the shifted operand
 * @param val2 the shift amount operand
 * @param maskWith3f should the shift operand by masked with 0x3f? This is
 *          default behaviour on Intel but it differs from how we combine
 *          shift operands in HIR
 */
protected final void LONG_SHR(Instruction s, Operand result, Operand val1, Operand val2, boolean maskWith3f) {
    if (!val2.isIntConstant()) {
        // the most efficient form of expanding a shift by a variable amount
        // requires a branch so leave for complex operators
        // NB if !maskWith3f - we assume that a mask with 0x3F was required as
        // no optimizations currently exploits shift by registers of > 63
        // returning 0
        Binary.mutate(s, LONG_SHR, result.asRegister(), val1, val2);
        EMIT(s);
    } else if (result.isRegister()) {
        int shift = val2.asIntConstant().value;
        if (maskWith3f) {
            shift = shift & 0x3F;
        }
        Register lhsReg = result.asRegister().getRegister();
        Register lowlhsReg = burs.ir.regpool.getSecondReg(lhsReg);
        Register rhsReg1 = val1.asRegister().getRegister();
        Register lowrhsReg1 = burs.ir.regpool.getSecondReg(rhsReg1);
        if (shift == 0) {
            // operation is a nop.
            if (!result.similar(val1)) {
                EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
                EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
            }
        } else if (shift == 1) {
            if (!result.similar(val1)) {
                EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
                EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
            }
            // lhsReg = lhsReg >> 1
            EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SAR, new RegisterOperand(lhsReg, TypeReference.Int), IC(1))));
            // lowlhsReg = (lhsReg << 31) | (lowlhsReg >>> 1)
            EMIT(MIR_BinaryAcc.mutate(s, IA32_RCR, new RegisterOperand(lowlhsReg, TypeReference.Int), IC(1)));
        } else if (shift < 32) {
            // bits to shift in: tmp = rhsReg << (32 - shift)
            // TODO: use of LEA for SHL
            Register tmp = regpool.getInteger();
            EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(tmp, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
            EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SHL, new RegisterOperand(tmp, TypeReference.Int), IC(32 - shift))));
            // compute bottom half: lowlhsReg = (lowlhsReg1 >>> shift) | tmp
            if (!result.similar(val1)) {
                EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
            }
            EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SHR, new RegisterOperand(lowlhsReg, TypeReference.Int), IC(shift))));
            EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_OR, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(tmp, TypeReference.Int))));
            // compute top half: lhsReg = lhsReg >> shift
            if (!result.similar(val1)) {
                EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
            }
            EMIT(MIR_BinaryAcc.mutate(s, IA32_SAR, new RegisterOperand(lhsReg, TypeReference.Int), IC(shift)));
        } else if (shift == 32) {
            // lowlhsReg = rhsReg1
            EMIT(MIR_Move.mutate(s, IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int)));
            // lhsReg = rhsReg1 >> 31
            if (!result.similar(val1)) {
                EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
            }
            EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SAR, new RegisterOperand(lhsReg, TypeReference.Int), IC(31))));
        } else {
            if ((!maskWith3f && (shift >= 0x3F)) || (maskWith3f && ((shift & 0x3F) == 0x3F))) {
                // lhsReg = rhsReg1 >> 31
                if (!result.similar(val1)) {
                    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
                }
                EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SAR, new RegisterOperand(lhsReg, TypeReference.Int), IC(31))));
                // lowlhsReg = lhsReg
                EMIT(MIR_Move.mutate(s, IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(lhsReg, TypeReference.Int)));
            } else {
                // lhsReg = rhsReg1 >> 31
                if (!result.similar(val1)) {
                    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
                }
                EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SAR, new RegisterOperand(lhsReg, TypeReference.Int), IC(31))));
                // lowlhsReg = rhsReg1 >> shift
                EMIT(MIR_Move.mutate(s, IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int)));
                EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SAR, new RegisterOperand(lowlhsReg, TypeReference.Int), IC((shift - 32) & 0x3F))));
            }
        }
    } else {
        throw new OptimizingCompilerException("BURS_Helpers", "unexpected parameters: " + result + "=" + val1 + ">>" + val2);
    }
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException)

Example 20 with OptimizingCompilerException

use of org.jikesrvm.compilers.opt.OptimizingCompilerException in project JikesRVM by JikesRVM.

the class SplitBasicBlock method splitEachBlock.

/**
 * Splits a basic block.
 *
 * @param bb the block to process
 * @param ir the IR that contains the block
 *
 * @return {@code null} if no splitting is done, returns the second block
 *  if splitting is done.
 */
BasicBlock splitEachBlock(BasicBlock bb, IR ir) {
    if (ir.options.L2M_MAX_BLOCK_SIZE <= 0) {
        throw new OptimizingCompilerException("Maximum block size must be a" + " positive number but was " + ir.options.L2M_MAX_BLOCK_SIZE + "!", true);
    }
    int remainingInstCount = ir.options.L2M_MAX_BLOCK_SIZE;
    Enumeration<Instruction> instructions = bb.forwardRealInstrEnumerator();
    while (instructions.hasMoreElements()) {
        Instruction inst = instructions.nextElement();
        remainingInstCount--;
        if (remainingInstCount <= 0) {
            // no need to split because all the rests are just branches
            if (inst.isBranch()) {
                return null;
            }
            // no need to split because the basic block does not contain any more instructions
            if (!instructions.hasMoreElements()) {
                return null;
            }
            return bb.splitNodeWithLinksAt(inst, ir);
        }
    }
    return null;
}
Also used : OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Aggregations

OptimizingCompilerException (org.jikesrvm.compilers.opt.OptimizingCompilerException)47 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)25 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)18 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)17 Register (org.jikesrvm.compilers.opt.ir.Register)16 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)14 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)11 LongConstantOperand (org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand)11 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)11 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)10 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)10 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)9 ConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ConstantOperand)9 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)9 TypeReference (org.jikesrvm.classloader.TypeReference)8 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)8 BranchOperand (org.jikesrvm.compilers.opt.ir.operand.BranchOperand)8 DoubleConstantOperand (org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand)6 FloatConstantOperand (org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand)6 Offset (org.vmmagic.unboxed.Offset)6