use of org.jikesrvm.compilers.opt.ir.BasicBlock 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.BasicBlock 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.BasicBlock 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.BasicBlock in project JikesRVM by JikesRVM.
the class InstrumentationSamplingFramework method myCopyWithoutLinks.
/**
* The same as BasicBlock.copyWithoutLinks except that it
* renames all temp variables that are never used outside the basic
* block. This 1) helps eliminate the artificially large live
* ranges that might have been created (assuming the reg allocator
* isn't too smart) and 2) it prevents BURS from crashing.
* <p>
* PRECONDITION: the spansBasicBlock bit must be correct by calling
* DefUse.recomputeSpansBasicBlock(IR);
*
* @param bb the basic block to process
* @param ir the IR that contains the block
* @return the copied block
*/
private static BasicBlock myCopyWithoutLinks(BasicBlock bb, IR ir) {
BasicBlock newBlock = bb.copyWithoutLinks(ir);
// Without this, there were sanity errors at one point.
updateTemps(newBlock, ir);
return newBlock;
}
use of org.jikesrvm.compilers.opt.ir.BasicBlock in project JikesRVM by JikesRVM.
the class LowerInstrumentation method lowerInstrumentation.
/**
* Actually perform the lowering
*
* @param ir the governing IR
*/
static void lowerInstrumentation(IR ir) {
/*
for (Enumeration<BasicBlock> bbe = ir.getBasicBlocks();
bbe.hasMoreElements(); ) {
BasicBlock bb = bbe.nextElement();
bb.printExtended();
}
*/
ArrayList<Instruction> instrumentedInstructions = new ArrayList<Instruction>();
// enumeration.
for (Enumeration<BasicBlock> bbe = ir.getBasicBlocks(); bbe.hasMoreElements(); ) {
BasicBlock bb = bbe.nextElement();
Instruction i = bb.firstInstruction();
while (i != null && i != bb.lastInstruction()) {
if (i.operator() == INSTRUMENTED_EVENT_COUNTER) {
instrumentedInstructions.add(i);
}
i = i.nextInstructionInCodeOrder();
}
}
// the counter manager to convert them into real instructions
for (final Instruction i : instrumentedInstructions) {
// Have the counter manager for this data convert this into the
// actual counting code. For now, we'll hard code the counter
// manager. Ideally it should be stored in the instruction,
// (to allow multiple counter managers. It would also make this
// code independent of the adaptive system..)
InstrumentedEventCounterManager counterManager = Instrumentation.eventCounterManager;
counterManager.mutateOptEventCounterInstruction(i, ir);
}
/*
for (Enumeration<BasicBlock> bbe = ir.getBasicBlocks();
bbe.hasMoreElements(); ) {
BasicBlock bb = bbe.nextElement();
bb.printExtended();
}
*/
}
Aggregations