Search in sources :

Example 1 with DUP

use of org.apache.bcel.generic.DUP in project jop by jop-devel.

the class InlineOptimizer method initialize.

@Override
public void initialize(AnalysisManager analyses, Collection<MethodInfo> roots) {
    if (!preciseCycleEstimate) {
        ExecutionContext dummy = new ExecutionContext(roots.iterator().next());
        WCETProcessorModel pm = analyses.getJCopter().getWCETProcessorModel();
        InstructionList il = new InstructionList();
        // TODO very messy approximation of exec time
        storeCycles = (int) pm.getExecutionTime(dummy, il.append(new ASTORE(10)));
        checkNPCycles = 0;
        checkNPCycles += (int) pm.getExecutionTime(dummy, il.append(new DUP()));
        checkNPCycles += (int) pm.getExecutionTime(dummy, il.append(new IFNONNULL(il.append(new ATHROW()))));
        deltaReturnCycles = (int) pm.getExecutionTime(dummy, il.append(new RETURN()));
        deltaReturnCycles -= (int) pm.getExecutionTime(dummy, il.append(new GOTO(il.getEnd())));
    }
    countInvokeSites = 0;
    countDevirtualized = 0;
}
Also used : RETURN(org.apache.bcel.generic.RETURN) GOTO(org.apache.bcel.generic.GOTO) ExecutionContext(com.jopdesign.common.code.ExecutionContext) ASTORE(org.apache.bcel.generic.ASTORE) WCETProcessorModel(com.jopdesign.wcet.WCETProcessorModel) InstructionList(org.apache.bcel.generic.InstructionList) ATHROW(org.apache.bcel.generic.ATHROW) IFNONNULL(org.apache.bcel.generic.IFNONNULL) DUP(org.apache.bcel.generic.DUP)

Example 2 with DUP

use of org.apache.bcel.generic.DUP in project jop by jop-devel.

the class SimpleInliner method analyzeInvokeSite.

/**
 * Check if the invokesite can be modified in a way so that the parameters are passed in the correct order
 * @param invokeSite the invokesite to inline.
 * @param invokee the invoked method.
 * @param inlineData the map to store the analyzer results
 * @return true if the prologue can be changed to match the expected behaviour
 */
private boolean analyzeInvokeSite(InvokeSite invokeSite, MethodInfo invokee, InlineData inlineData) {
    MethodInfo invoker = invokeSite.getInvoker();
    ConstantPoolGen invokerCpg = invoker.getConstantPoolGen();
    InstructionHandle invoke = invokeSite.getInstructionHandle();
    // Check epilogue
    Type[] ret = StackHelper.produceStack(invokerCpg, invoke.getInstruction());
    // works if the invoked method returns the same (single) type as the replaced instruction..
    boolean match = (ret.length == 1 && TypeHelper.canAssign(invokee.getType(), ret[0]));
    // return something but doesn't then it is a JVM call and throws an exception.
    if (!match && !invokee.getType().equals(Type.VOID)) {
        return false;
    }
    // Check and build prologue
    Type[] args = StackHelper.consumeStack(invokerCpg, invoke.getInstruction());
    List<Instruction> oldPrologue = new LinkedList<Instruction>();
    int cnt = 0;
    InstructionHandle current = invoke;
    while (cnt < args.length) {
        if (current.hasTargeters()) {
            // stay within the basic block
            break;
        }
        current = current.getPrev();
        Instruction instr = current.getInstruction();
        // we only rearrange push-instructions
        if (!(instr instanceof PushInstruction) || (instr instanceof DUP) || (instr instanceof DUP2)) {
            break;
        }
        // we add this instruction to the old prologue to replace
        cnt++;
        oldPrologue.add(0, instr);
    }
    inlineData.setOldPrologueLength(cnt);
    List<ValueInfo> params = inlineData.getParams();
    // other parameters must be used in the order they are pushed on the stack, we do not rearrange them
    int offset = args.length - cnt;
    for (int i = 0; i < offset; i++) {
        if (i >= params.size()) {
            Type t = args[i];
            // unused argument, we cannot remove the push instruction so we pop it
            inlineData.addPrologue(t.getSize() == 2 ? new POP2() : new POP());
        } else {
            ValueInfo value = params.get(i);
            int argNum = value.getParamNr();
            if (!invokee.isStatic()) {
                argNum++;
            }
            if (argNum != i) {
                return false;
            }
        }
    }
    // Now, we create a new prologue using the expected argument values and the old push instructions
    for (int i = offset; i < params.size(); i++) {
        ValueInfo value = params.get(i);
        if (value.isThisReference() || value.isParamReference()) {
            int argNum = value.getParamNr();
            if (!invokee.isStatic()) {
                argNum++;
            }
            if (argNum < offset) {
                // loading a param a second time which we do not duplicate, cannot inline this
                return false;
            }
            // To be on the safe side, copy the instruction in case a param is used more than once
            Instruction instr = oldPrologue.get(argNum - offset).copy();
            inlineData.addPrologue(instr);
        } else if (value.isNullReference()) {
            inlineData.addPrologue(InstructionConstants.ACONST_NULL);
        } else if (value.isConstantValue() || value.isStaticFieldReference()) {
            // We need to push a constant on the stack
            Instruction instr = value.getConstantValue().createPushInstruction(invoker.getConstantPoolGen());
            inlineData.addPrologue(instr);
        } else if (!value.isContinued()) {
            throw new AssertionError("Unhandled value type");
        }
    }
    return true;
}
Also used : POP2(org.apache.bcel.generic.POP2) InvokeInstruction(org.apache.bcel.generic.InvokeInstruction) StackInstruction(org.apache.bcel.generic.StackInstruction) Instruction(org.apache.bcel.generic.Instruction) FieldInstruction(org.apache.bcel.generic.FieldInstruction) ArithmeticInstruction(org.apache.bcel.generic.ArithmeticInstruction) ConversionInstruction(org.apache.bcel.generic.ConversionInstruction) ReturnInstruction(org.apache.bcel.generic.ReturnInstruction) PushInstruction(org.apache.bcel.generic.PushInstruction) PushInstruction(org.apache.bcel.generic.PushInstruction) InstructionHandle(org.apache.bcel.generic.InstructionHandle) LinkedList(java.util.LinkedList) POP(org.apache.bcel.generic.POP) ConstantPoolGen(org.apache.bcel.generic.ConstantPoolGen) Type(org.apache.bcel.generic.Type) DUP2(org.apache.bcel.generic.DUP2) ValueInfo(com.jopdesign.common.type.ValueInfo) MethodInfo(com.jopdesign.common.MethodInfo) DUP(org.apache.bcel.generic.DUP)

Aggregations

DUP (org.apache.bcel.generic.DUP)2 MethodInfo (com.jopdesign.common.MethodInfo)1 ExecutionContext (com.jopdesign.common.code.ExecutionContext)1 ValueInfo (com.jopdesign.common.type.ValueInfo)1 WCETProcessorModel (com.jopdesign.wcet.WCETProcessorModel)1 LinkedList (java.util.LinkedList)1 ASTORE (org.apache.bcel.generic.ASTORE)1 ATHROW (org.apache.bcel.generic.ATHROW)1 ArithmeticInstruction (org.apache.bcel.generic.ArithmeticInstruction)1 ConstantPoolGen (org.apache.bcel.generic.ConstantPoolGen)1 ConversionInstruction (org.apache.bcel.generic.ConversionInstruction)1 DUP2 (org.apache.bcel.generic.DUP2)1 FieldInstruction (org.apache.bcel.generic.FieldInstruction)1 GOTO (org.apache.bcel.generic.GOTO)1 IFNONNULL (org.apache.bcel.generic.IFNONNULL)1 Instruction (org.apache.bcel.generic.Instruction)1 InstructionHandle (org.apache.bcel.generic.InstructionHandle)1 InstructionList (org.apache.bcel.generic.InstructionList)1 InvokeInstruction (org.apache.bcel.generic.InvokeInstruction)1 POP (org.apache.bcel.generic.POP)1