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);
}
}
}
}
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);
}
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();
}
}
}
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();
}
}
}
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();
}
}
Aggregations