Search in sources :

Example 1 with Instruction

use of org.jikesrvm.compilers.opt.ir.Instruction in project JikesRVM by JikesRVM.

the class InsertInstructionCounters method perform.

/**
 * Insert a counter on every instruction, and group counts by
 * opcode type.
 *
 * @param ir the governing IR
 */
@Override
public final void perform(IR ir) {
    // the boot image, or when instrumentation is disabled
    if (!ir.method.isInterruptible() || ir.method.getDeclaringClass().isInBootImage() || !Instrumentation.instrumentationEnabled()) {
        return;
    }
    // Get the data object that handles the counters
    StringEventCounterData data = AOSDatabase.instructionCounterData;
    // Create a vector of basic blocks up front because the blocks
    // are modified as we iterate below.
    ArrayList<BasicBlock> bbList = new ArrayList<BasicBlock>();
    for (Enumeration<BasicBlock> bbe = ir.getBasicBlocks(); bbe.hasMoreElements(); ) {
        BasicBlock bb = bbe.nextElement();
        bbList.add(bb);
    }
    // Iterate through the basic blocks
    for (BasicBlock bb : bbList) {
        // Add instructions to vector so enumeration doesn't mess
        // things up.  There is probably a better way to do this, but
        // it doesn't matter because this is a debugging phase.
        ArrayList<Instruction> iList = new ArrayList<Instruction>();
        Instruction inst = bb.firstInstruction();
        while (inst != null && inst != bb.lastInstruction()) {
            iList.add(inst);
            inst = inst.nextInstructionInCodeOrder();
        }
        // Iterate through all the instructions in this block.
        for (Instruction i : iList) {
            // Skip dangerous instructions
            if (i.operator() == LABEL || Prologue.conforms(i)) {
                continue;
            }
            if (i.isBranch() || i.operator() == RETURN) {
                // It's a branch, so you need to be careful how you insert the
                // counter.
                Instruction prev = i.prevInstructionInCodeOrder();
                // must end with branches only.  Solve by splitting block.
                if (prev.isBranch()) {
                    // BasicBlock newBlock =
                    bb.splitNodeWithLinksAt(prev, ir);
                    bb.recomputeNormalOut(ir);
                }
                // Use the name of the operator as the name of the event
                Instruction counterInst = data.getCounterInstructionForEvent(i.operator().toString());
                // Insert the new instruction into the code order
                i.insertBefore(counterInst);
            } else {
                // It's a non-branching instruction.  Insert counter before
                // the instruction.
                // Use the name of the operator as the name of the event
                Instruction counterInst = data.getCounterInstructionForEvent(i.operator().toString());
                i.insertBefore(counterInst);
            }
        }
    }
}
Also used : BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) ArrayList(java.util.ArrayList) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) StringEventCounterData(org.jikesrvm.adaptive.measurements.instrumentation.StringEventCounterData)

Example 2 with Instruction

use of org.jikesrvm.compilers.opt.ir.Instruction in project JikesRVM by JikesRVM.

the class InsertMethodInvocationCounter method perform.

/**
 * Insert basic block counters
 *
 * @param ir the governing IR
 */
@Override
public final void perform(IR ir) {
    // save volatile methods, or when instrumentation is disabled
    if (!ir.method.isInterruptible() || !Instrumentation.instrumentationEnabled() || ir.method.getDeclaringClass().hasSaveVolatileAnnotation()) {
        return;
    }
    BasicBlock firstBB = ir.cfg.entry();
    MethodInvocationCounterData data = AOSDatabase.methodInvocationCounterData;
    int cmid = ir.compiledMethod.getId();
    // Create a dummy instruction that is later converted into an
    // increment of the appropriate CounterArray element.
    Instruction c = data.createEventCounterInstruction(cmid);
    // Insert it at the beginning of the basic block
    firstBB.prependInstructionRespectingPrologue(c);
}
Also used : MethodInvocationCounterData(org.jikesrvm.adaptive.measurements.instrumentation.MethodInvocationCounterData) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 3 with Instruction

use of org.jikesrvm.compilers.opt.ir.Instruction in project JikesRVM by JikesRVM.

the class InsertYieldpointCounters method perform.

/**
 * counters after all yieldpoint instructions
 *
 * @param ir the governing IR
 */
@Override
public final void perform(IR ir) {
    // the boot image, or when instrumentation is disabled
    if (!ir.method.isInterruptible() || ir.method.getDeclaringClass().isInBootImage() || !Instrumentation.instrumentationEnabled()) {
        return;
    }
    YieldpointCounterData data = AOSDatabase.yieldpointCounterData;
    if (InsertYieldpointCounters.DEBUG) {
        VM.sysWriteln("InsertYieldpointCounters.perform() " + ir.method);
    }
    // For each yieldpoint, insert a counter.
    for (Enumeration<BasicBlock> bbe = ir.getBasicBlocks(); bbe.hasMoreElements(); ) {
        BasicBlock bb = bbe.nextElement();
        if (InsertYieldpointCounters.DEBUG) {
            VM.sysWriteln("Considering basic block " + bb.toString());
            bb.printExtended();
        }
        Instruction i = bb.firstInstruction();
        while (i != null && i != bb.lastInstruction()) {
            if (i.operator() == YIELDPOINT_PROLOGUE || i.operator() == YIELDPOINT_EPILOGUE || i.operator() == YIELDPOINT_BACKEDGE) {
                String prefix = yieldpointPrefix(i.operator());
                double incrementValue = 1.0;
                if (i.operator() == YIELDPOINT_EPILOGUE) {
                    prefix = "METHOD ENTRY ";
                } else if (i.operator() == YIELDPOINT_PROLOGUE) {
                    prefix = "METHOD EXIT ";
                } else {
                    prefix = "BACKEDGE ";
                    incrementValue = 1.0;
                }
                // Create an instruction to increment the counter for this
                // method.  By appending the prefix and method name, it
                // maintains a separate counter for each method, and
                // separates between method entry and backedges.
                Instruction counterInst = data.getCounterInstructionForEvent(prefix + ir.method.toString(), incrementValue);
                // Insert the new instruction into the code order
                i.insertAfter(counterInst);
            }
            i = i.nextInstructionInCodeOrder();
        }
    }
}
Also used : YieldpointCounterData(org.jikesrvm.adaptive.measurements.instrumentation.YieldpointCounterData) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 4 with Instruction

use of org.jikesrvm.compilers.opt.ir.Instruction in project JikesRVM by JikesRVM.

the class InstrumentationSamplingFramework method appendLoad.

/**
 * Append a load of the global counter to the given basic block.
 *
 * WARNING: Tested for LIR only!
 *
 * @param bb The block to append the load to
 * @param ir The IR
 */
private void appendLoad(BasicBlock bb, IR ir) {
    if (DEBUG)
        VM.sysWriteln("Adding load to " + bb);
    Instruction load = null;
    if (ir.options.ADAPTIVE_PROCESSOR_SPECIFIC_COUNTER) {
        if (ir.isHIR()) {
            VM.sysFail("Not implemented yet.");
        } else {
            // Phase is being used in LIR
            if (VM.VerifyAssertions)
                VM._assert(ir.isLIR());
            // Insert the load instruction.
            load = Load.create(INT_LOAD, cbsReg.copyRO(), ir.regpool.makeTROp(), IRTools.AC(AosEntrypoints.threadCBSField.getOffset()), new LocationOperand(AosEntrypoints.threadCBSField));
            bb.appendInstruction(load);
        }
    } else {
        // Use global counter
        if (ir.isHIR()) {
            Operand offsetOp = new AddressConstantOperand(AosEntrypoints.globalCBSField.getOffset());
            load = GetStatic.create(GETSTATIC, cbsReg.copyRO(), offsetOp, new LocationOperand(AosEntrypoints.globalCBSField));
            bb.appendInstruction(load);
        } else {
            // LIR
            Instruction dummy = Load.create(INT_LOAD, null, null, null, null);
            bb.appendInstruction(dummy);
            load = Load.create(INT_LOAD, cbsReg.copyRO(), ir.regpool.makeJTOCOp(), IRTools.AC(AosEntrypoints.globalCBSField.getOffset()), new LocationOperand(AosEntrypoints.globalCBSField));
            dummy.insertBefore(load);
            dummy.remove();
        }
    }
}
Also used : LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 5 with Instruction

use of org.jikesrvm.compilers.opt.ir.Instruction in project JikesRVM by JikesRVM.

the class InstrumentationSamplingFramework method prependCounterReset.

/**
 * Prepend the code to reset the global counter to the given basic
 * block.
 *
 * Warning:  Tested in LIR only!
 *
 * @param bb The block to append the load to
 * @param ir The IR
 */
private void prependCounterReset(BasicBlock bb, IR ir) {
    Instruction load = null;
    Instruction store = null;
    if (ir.isHIR()) {
        // Not tested
        Operand offsetOp = new AddressConstantOperand(AosEntrypoints.cbsResetValueField.getOffset());
        load = GetStatic.create(GETSTATIC, cbsReg.copyRO(), offsetOp, new LocationOperand(AosEntrypoints.cbsResetValueField));
        store = PutStatic.create(PUTSTATIC, cbsReg.copyRO(), new AddressConstantOperand(AosEntrypoints.globalCBSField.getOffset()), new LocationOperand(AosEntrypoints.globalCBSField));
        bb.prependInstruction(store);
        bb.prependInstruction(load);
    } else {
        // LIR
        if (VM.VerifyAssertions)
            VM._assert(ir.isLIR());
        Instruction dummy = Load.create(INT_LOAD, null, null, null, null);
        bb.prependInstruction(dummy);
        // Load the reset value
        load = Load.create(INT_LOAD, cbsReg.copyRO(), ir.regpool.makeJTOCOp(), IRTools.AC(AosEntrypoints.cbsResetValueField.getOffset()), new LocationOperand(AosEntrypoints.cbsResetValueField));
        dummy.insertBefore(load);
        // Store it in the counter register
        if (ir.options.ADAPTIVE_PROCESSOR_SPECIFIC_COUNTER) {
            store = Store.create(INT_STORE, cbsReg.copyRO(), ir.regpool.makeTROp(), IRTools.AC(AosEntrypoints.threadCBSField.getOffset()), new LocationOperand(AosEntrypoints.threadCBSField));
        } else {
            // Use global counter
            store = Store.create(INT_STORE, cbsReg.copyRO(), ir.regpool.makeJTOCOp(), IRTools.AC(AosEntrypoints.globalCBSField.getOffset()), new LocationOperand(AosEntrypoints.globalCBSField));
        }
        dummy.insertBefore(store);
        dummy.remove();
    }
}
Also used : LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Aggregations

Instruction (org.jikesrvm.compilers.opt.ir.Instruction)356 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)204 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)144 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)117 Register (org.jikesrvm.compilers.opt.ir.Register)106 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)72 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)61 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)61 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)54 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)53 Test (org.junit.Test)49 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)46 TypeReference (org.jikesrvm.classloader.TypeReference)38 BranchOperand (org.jikesrvm.compilers.opt.ir.operand.BranchOperand)38 NullConstantOperand (org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand)35 BasicBlockOperand (org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand)33 HeapOperand (org.jikesrvm.compilers.opt.ir.operand.HeapOperand)33 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)31 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)28 TypeOperand (org.jikesrvm.compilers.opt.ir.operand.TypeOperand)27