use of org.jikesrvm.compilers.opt.ir.operand.Operand 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.operand.Operand 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();
}
}
use of org.jikesrvm.compilers.opt.ir.operand.Operand in project JikesRVM by JikesRVM.
the class AssemblerBase method doLOWTABLESWITCH.
/**
* Emit the given instruction, assuming that
* it is a MIR_LowTableSwitch instruction
* and has a MIR_LOWTABLESWITCH operator
*
* @param inst the instruction to assemble
*/
protected void doLOWTABLESWITCH(Instruction inst) {
// n = number of normal cases (0..n-1)
int n = MIR_LowTableSwitch.getNumberOfTargets(inst);
GPR ms = GPR.lookup(MIR_LowTableSwitch.getMethodStart(inst).getRegister().number);
GPR idx = GPR.lookup(MIR_LowTableSwitch.getIndex(inst).getRegister().number);
emitTableswitchCode(ms, idx);
// loaded for the cases
for (int i = 0; i < n; i++) {
Operand target = MIR_LowTableSwitch.getTarget(inst, i);
emitOFFSET_Imm_ImmOrLabel(i, getImm(target), getLabel(target));
}
}
use of org.jikesrvm.compilers.opt.ir.operand.Operand in project JikesRVM by JikesRVM.
the class AssemblerBase method isQuad.
/**
* Does the given instruction operate upon quad-sized data
* <em>for the purposes of assembling the instruction</em>?
* The opt compiler does not represent the size of register data, so
* it is necessary to determine whether to emit a quad instruction.
* As described above, this method is only concerned with quad data
* that changes the instruction. For example, this method will return
* {@code false} for {@code FSTP}. {@code FSTP} operates on quad-data
* but the instruction's operation is the same for 32-bit and 64-bit
* mode, so it is not a quad instruction for the purposes of this method.
* <p>
* This method typically looks at the memory operand, if any, and
* checks whether that is a byte. This method also recognizes
* the operator convention that __q on the end of the operator
* name means operate upon quad data. Moreover, it looks at data types
* for x64.
*
* @param inst the instruction being queried
* @return {@code true} if instruction operates upon quad data <b>AND</b>
* is treated as a quad instruction for the purpose of assembling the
* machine code
*/
boolean isQuad(Instruction inst) {
for (Operator opr : quadSizeOperators) {
if (opr == inst.operator()) {
return true;
}
}
if (VM.BuildFor32Addr) {
for (int i = 0; i < inst.getNumberOfOperands(); i++) {
Operand op = inst.getOperand(i);
if (op instanceof MemoryOperand) {
return ((MemoryOperand) op).size == 8;
}
}
} else {
// 64-bit
for (int i = 0; i < inst.getNumberOfOperands(); i++) {
Operand op = inst.getOperand(i);
if (op == null) {
// The operand may only be null for a few cases.
if (VM.VerifyAssertions) {
// Return has 2 return operands on IA32 because it
// must be able to return a 64-bit value. On x64, only
// one of the operands is needed, the other one is null.
boolean isReturn = MIR_Return.conforms(inst);
if (isReturn) {
VM._assert(i == MIR_Return.indexOfVal2(inst));
}
// Guards may be null for divides
boolean isDivide = MIR_Divide.conforms(inst);
if (isDivide) {
VM._assert(i == MIR_Divide.indexOfGuard(inst));
}
// For all other cases, all operands must be non null
String msg = inst.toString();
VM._assert(isReturn || isDivide, msg);
}
continue;
}
if (op.isLong() || op.isRef() || op.isAddress()) {
return true;
}
boolean quadMemOp = false;
if (op instanceof MemoryOperand) {
quadMemOp = op.asMemory().size == 8;
} else if (op instanceof StackLocationOperand) {
quadMemOp = op.asStackLocation().getSize() == 8;
}
// even if this one won't
if (quadMemOp) {
return true;
}
}
}
return false;
}
use of org.jikesrvm.compilers.opt.ir.operand.Operand in project JikesRVM by JikesRVM.
the class FinalMIRExpansion method expandUnconditionalYieldpoint.
/* generate yieldpoint without checking threadSwith request
*/
private static void expandUnconditionalYieldpoint(Instruction s, IR ir, RVMMethod meth) {
// split the basic block after the yieldpoint, create a new
// block at the end of the IR to hold the yieldpoint,
// remove the yieldpoint (to prepare to out it in the new block at the end)
BasicBlock thisBlock = s.getBasicBlock();
BasicBlock nextBlock = thisBlock.splitNodeWithLinksAt(s, ir);
BasicBlock yieldpoint = thisBlock.createSubBlock(s.getBytecodeIndex(), ir);
thisBlock.insertOut(yieldpoint);
yieldpoint.insertOut(nextBlock);
ir.cfg.addLastInCodeOrder(yieldpoint);
s.remove();
// change thread switch instruction into call to thread switch routine
// NOTE: must make s the call instruction: it is the GC point!
// must also inform the GCMap that s has been moved!!!
Offset offset = meth.getOffset();
LocationOperand loc = new LocationOperand(offset);
Operand guard = TG();
Operand target;
if (JTOC_REGISTER == null) {
target = MemoryOperand.D(Magic.getTocPointer().plus(offset), (byte) BYTES_IN_ADDRESS, loc, guard);
} else {
target = MemoryOperand.BD(ir.regpool.makeTocOp().asRegister(), offset, (byte) BYTES_IN_ADDRESS, loc, guard);
}
MIR_Call.mutate0(s, CALL_SAVE_VOLATILE, null, null, target, MethodOperand.STATIC(meth));
yieldpoint.appendInstruction(s);
ir.MIRInfo.gcIRMap.moveToEnd(s);
yieldpoint.appendInstruction(MIR_Branch.create(IA32_JMP, nextBlock.makeJumpTarget()));
// make a jump to yield block
thisBlock.appendInstruction(MIR_Branch.create(IA32_JMP, yieldpoint.makeJumpTarget()));
}
Aggregations