use of org.jikesrvm.compilers.opt.OptimizingCompilerException in project JikesRVM by JikesRVM.
the class BURS_Helpers method OSR.
/**
* special case handling OSR instructions expand long type variables to two
* integers
* @param burs the burs instance
* @param s an OSRPoint instruction
*/
protected void OSR(BURS burs, Instruction s) {
if (VM.VerifyAssertions) {
opt_assert(OsrPoint.conforms(s));
}
// Check type info first because this needs to be done
// for both 32-bit and 64-bit cases.
InlinedOsrTypeInfoOperand typeInfo;
if (VM.BuildFor32Addr) {
// Clearing type info is ok, because instruction will be mutated and the
// info will be reinserted
typeInfo = OsrPoint.getClearInlinedTypeInfo(s);
} else {
// Instruction won't be changed so info needs to be left in
typeInfo = OsrPoint.getInlinedTypeInfo(s);
}
if (VM.VerifyAssertions) {
if (typeInfo == null) {
VM.sysWriteln("OsrPoint " + s + " has a <null> type info:");
VM.sysWriteln(" position :" + s.getBytecodeIndex() + "@" + s.position().method);
}
opt_assert(typeInfo != null);
}
int numparam = OsrPoint.getNumberOfElements(s);
if (VM.BuildFor32Addr) {
// 1. how many params
int numlong = 0;
for (int i = 0; i < numparam; i++) {
Operand param = OsrPoint.getElement(s, i);
if (param.getType().isLongType()) {
numlong++;
}
}
// 2. collect params
Operand[] params = new Operand[numparam];
for (int i = 0; i < numparam; i++) {
params[i] = OsrPoint.getClearElement(s, i);
}
// set the number of valid params in osr type info, used
// in LinearScan
typeInfo.validOps = numparam;
// 3: only makes second half register of long being used
// creates room for long types.
burs.append(OsrPoint.mutate(s, s.operator(), typeInfo, numparam + numlong));
int pidx = numparam;
for (int i = 0; i < numparam; i++) {
Operand param = params[i];
OsrPoint.setElement(s, i, param);
if (param instanceof RegisterOperand) {
RegisterOperand rparam = (RegisterOperand) param;
// LinearScan will update the map.
if (rparam.getType().isLongType()) {
OsrPoint.setElement(s, pidx++, L(burs.ir.regpool.getSecondReg(rparam.getRegister())));
}
} else if (param instanceof LongConstantOperand) {
LongConstantOperand val = (LongConstantOperand) param;
if (VM.TraceOnStackReplacement) {
VM.sysWriteln("caught a long const " + val);
}
OsrPoint.setElement(s, i, IC(val.upper32()));
OsrPoint.setElement(s, pidx++, IC(val.lower32()));
} else if (param instanceof IntConstantOperand) {
} else {
throw new OptimizingCompilerException("BURS_Helpers", "unexpected parameter type" + param);
}
}
if (pidx != (numparam + numlong)) {
VM.sysWriteln("pidx = " + pidx);
VM.sysWriteln("numparam = " + numparam);
VM.sysWriteln("numlong = " + numlong);
}
if (VM.VerifyAssertions) {
opt_assert(pidx == (numparam + numlong));
}
} else {
// set the number of valid params in osr type info, used
// in LinearScan
typeInfo.validOps = numparam;
burs.append(s);
}
}
use of org.jikesrvm.compilers.opt.OptimizingCompilerException in project JikesRVM by JikesRVM.
the class NormalizeConstants method perform.
/**
* Only thing we do for IA32 is to restrict the usage of
* String, Float, and Double constants. The rules are prepared
* to deal with everything else.
*
* @param ir IR to normalize
*/
public static void perform(IR ir) {
for (Instruction s = ir.firstInstructionInCodeOrder(); s != null; s = s.nextInstructionInCodeOrder()) {
// Get 'large' constants into a form the the BURS rules are
// prepared to deal with.
// Constants can't appear as defs, so only scan the uses.
//
int numUses = s.getNumberOfUses();
if (numUses > 0) {
int numDefs = s.getNumberOfDefs();
for (int idx = numDefs; idx < numUses + numDefs; idx++) {
Operand use = s.getOperand(idx);
if (use != null) {
if (use instanceof ObjectConstantOperand) {
ObjectConstantOperand oc = (ObjectConstantOperand) use;
if (oc.isMovableObjectConstant()) {
RegisterOperand rop = ir.regpool.makeTemp(use.getType());
Operand jtoc = ir.regpool.makeJTOCOp();
Offset offset = oc.offset;
if (offset.isZero()) {
if (use instanceof StringConstantOperand) {
throw new OptimizingCompilerException("String constant w/o valid JTOC offset");
} else if (use instanceof ClassConstantOperand) {
throw new OptimizingCompilerException("Class constant w/o valid JTOC offset");
}
offset = Offset.fromIntSignExtend(Statics.findOrCreateObjectLiteral(oc.value));
}
LocationOperand loc = new LocationOperand(offset);
s.insertBefore(Load.create(IA32_REF_LOAD, rop, jtoc, wordOperandForReference(offset.toWord()), loc));
s.putOperand(idx, rop.copyD2U());
} else {
// Ensure object is in JTOC to keep it alive
Statics.findOrCreateObjectLiteral(oc.value);
s.putOperand(idx, wordOperandForReference(Magic.objectAsAddress(oc.value).toWord()));
}
} else if (use instanceof DoubleConstantOperand) {
RegisterOperand rop = ir.regpool.makeTemp(TypeReference.Double);
Operand jtoc = ir.regpool.makeJTOCOp();
DoubleConstantOperand dc = (DoubleConstantOperand) use.copy();
if (dc.offset.isZero()) {
dc.offset = Offset.fromIntSignExtend(Statics.findOrCreateLongSizeLiteral(Double.doubleToLongBits(dc.value)));
}
s.insertBefore(Binary.create(MATERIALIZE_FP_CONSTANT, rop, jtoc, dc));
s.putOperand(idx, rop.copyD2U());
} else if (use instanceof FloatConstantOperand) {
RegisterOperand rop = ir.regpool.makeTemp(TypeReference.Float);
Operand jtoc = ir.regpool.makeJTOCOp();
FloatConstantOperand fc = (FloatConstantOperand) use.copy();
if (fc.offset.isZero()) {
fc.offset = Offset.fromIntSignExtend(Statics.findOrCreateIntSizeLiteral(Float.floatToIntBits(fc.value)));
}
s.insertBefore(Binary.create(MATERIALIZE_FP_CONSTANT, rop, jtoc, fc));
s.putOperand(idx, rop.copyD2U());
} else if (use instanceof NullConstantOperand) {
s.putOperand(idx, wordOperandForReference(Word.zero()));
} else if (use instanceof AddressConstantOperand) {
s.putOperand(idx, wordOperandForReference(((AddressConstantOperand) use).value.toWord()));
} else if (use instanceof TIBConstantOperand) {
RegisterOperand rop = ir.regpool.makeTemp(TypeReference.TIB);
Operand jtoc = ir.regpool.makeJTOCOp();
Offset offset = ((TIBConstantOperand) use).value.getTibOffset();
LocationOperand loc = new LocationOperand(offset);
s.insertBefore(Load.create(IA32_REF_LOAD, rop, jtoc, wordOperandForReference(offset.toWord()), loc));
s.putOperand(idx, rop.copyD2U());
} else if (use instanceof CodeConstantOperand) {
RegisterOperand rop = ir.regpool.makeTemp(TypeReference.CodeArray);
Operand jtoc = ir.regpool.makeJTOCOp();
Offset offset = ((CodeConstantOperand) use).value.findOrCreateJtocOffset();
LocationOperand loc = new LocationOperand(offset);
s.insertBefore(Load.create(IA32_REF_LOAD, rop, jtoc, wordOperandForReference(offset.toWord()), loc));
s.putOperand(idx, rop.copyD2U());
}
}
}
}
}
}
use of org.jikesrvm.compilers.opt.OptimizingCompilerException in project JikesRVM by JikesRVM.
the class BURS_Helpers method LONG_SHL.
/**
* Expansion of LONG_SHL
* @param s the instruction to expand
* @param result the result operand
* @param val1 the shifted operand
* @param val2 the shift amount operand
* @param maskWith3f should the shift operand by masked with 0x3f? This is
* default behaviour on Intel but it differs from how we combine
* shift operands in HIR
*/
protected final void LONG_SHL(Instruction s, Operand result, Operand val1, Operand val2, boolean maskWith3f) {
if (!val2.isIntConstant()) {
// the most efficient form of expanding a shift by a variable amount
// requires a branch so leave for complex operators
// NB if !maskWith3f - we assume that a mask with 0x3F was required as
// no optimizations currently exploits shift by registers of > 63
// returning 0
Binary.mutate(s, LONG_SHL, result.asRegister(), val1, val2);
EMIT(s);
} else if (result.isRegister()) {
int shift = val2.asIntConstant().value;
Register lhsReg = result.asRegister().getRegister();
Register lowlhsReg = burs.ir.regpool.getSecondReg(lhsReg);
Register rhsReg1 = val1.asRegister().getRegister();
Register lowrhsReg1 = burs.ir.regpool.getSecondReg(rhsReg1);
if (shift == 0) {
// operation is a nop.
if (!result.similar(val1)) {
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
}
} else if (shift == 1) {
if (!result.similar(val1)) {
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
}
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_ADD, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(lowlhsReg, TypeReference.Int))));
EMIT(MIR_BinaryAcc.mutate(s, IA32_ADC, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(lhsReg, TypeReference.Int)));
} else if (shift == 2) {
// bits to shift in: tmp = lowrhsReg >> 30
Register tmp = regpool.getInteger();
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(tmp, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SHR, new RegisterOperand(tmp, TypeReference.Int), IC(30))));
// compute top half: lhsReg = (rhsReg1 << 2) + tmp
EMIT(CPOS(s, MIR_Lea.create(IA32_LEA, new RegisterOperand(lhsReg, TypeReference.Int), MemoryOperand.BIS(new RegisterOperand(tmp, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int), (byte) 2, (byte) 4, null, null))));
// compute bottom half: lowlhsReg = lowlhsReg << 2
EMIT(CPOS(s, MIR_Lea.create(IA32_LEA, new RegisterOperand(lowlhsReg, TypeReference.Int), new // base
MemoryOperand(// base
null, // index
new RegisterOperand(lowrhsReg1, TypeReference.Int), // scale
(byte) 2, // displacement
Offset.zero(), // size
(byte) 4, // location
null, // guard
null))));
} else if (shift == 3) {
// bits to shift in: tmp = lowrhsReg >>> 29
Register tmp = regpool.getInteger();
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(tmp, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SHR, new RegisterOperand(tmp, TypeReference.Int), IC(29))));
// compute top half: lhsReg = (rhsReg1 << 3) + tmp
EMIT(CPOS(s, MIR_Lea.create(IA32_LEA, new RegisterOperand(lhsReg, TypeReference.Int), MemoryOperand.BIS(new RegisterOperand(tmp, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int), (byte) 3, (byte) 4, null, null))));
// compute bottom half: lowlhsReg = lowlhsReg << 3
EMIT(CPOS(s, MIR_Lea.create(IA32_LEA, new RegisterOperand(lowlhsReg, TypeReference.Int), new // base
MemoryOperand(// base
null, // index
new RegisterOperand(lowrhsReg1, TypeReference.Int), // scale
(byte) 3, // displacement
Offset.zero(), // size
(byte) 4, // location
null, // guard
null))));
} else if (shift < 32) {
if (!result.similar(val1)) {
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
}
// bits to shift in: tmp = lowrhsReg >>> (32 - shift)
Register tmp = regpool.getInteger();
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(tmp, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SHR, new RegisterOperand(tmp, TypeReference.Int), IC(32 - shift))));
// compute top half: lhsReg = (lhsReg1 << shift) | tmp
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SHL, new RegisterOperand(lhsReg, TypeReference.Int), IC(shift))));
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_OR, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(tmp, TypeReference.Int))));
// compute bottom half: lowlhsReg = lowlhsReg << shift
if (!result.similar(val1)) {
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
}
EMIT(MIR_BinaryAcc.mutate(s, IA32_SHL, new RegisterOperand(lowlhsReg, TypeReference.Int), IC(shift)));
} else if (shift == 32) {
// lhsReg = lowrhsReg1
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
// lowlhsReg = 0
EMIT(MIR_Move.mutate(s, IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), IC(0)));
} else if (shift == 33) {
// lhsReg = lowrhsReg1 << 1
EMIT(CPOS(s, MIR_Lea.create(IA32_LEA, new RegisterOperand(lhsReg, TypeReference.Int), new // base
MemoryOperand(// base
null, // index
new RegisterOperand(lowrhsReg1, TypeReference.Int), // scale
(byte) 1, // displacement
Offset.zero(), // size
(byte) 4, // location
null, // guard
null))));
// lowlhsReg = 0
EMIT(MIR_Move.mutate(s, IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), IC(0)));
} else if (shift == 34) {
// lhsReg = lowrhsReg1 << 2
EMIT(CPOS(s, MIR_Lea.create(IA32_LEA, new RegisterOperand(lhsReg, TypeReference.Int), new // base
MemoryOperand(// base
null, // index
new RegisterOperand(lowrhsReg1, TypeReference.Int), // scale
(byte) 2, // displacement
Offset.zero(), // size
(byte) 4, // location
null, // guard
null))));
// lowlhsReg = 0
EMIT(MIR_Move.mutate(s, IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), IC(0)));
} else if (shift == 35) {
// lhsReg = lowrhsReg1 << 3
EMIT(CPOS(s, MIR_Lea.create(IA32_LEA, new RegisterOperand(lhsReg, TypeReference.Int), new // base
MemoryOperand(// base
null, // index
new RegisterOperand(lowrhsReg1, TypeReference.Int), // scale
(byte) 3, // displacement
Offset.zero(), // size
(byte) 4, // location
null, // guard
null))));
// lowlhsReg = 0
EMIT(MIR_Move.mutate(s, IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), IC(0)));
} else {
if ((maskWith3f) || (shift < 64)) {
// lhsReg = lowrhsReg1 << ((shift - 32) & 0x1f)
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SHL, new RegisterOperand(lhsReg, TypeReference.Int), IC((shift - 32) & 0x1F))));
// lowlhsReg = 0
EMIT(MIR_Move.mutate(s, IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), IC(0)));
} else {
// lhsReg = 0
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), IC(0))));
// lowlhsReg = 0
EMIT(MIR_Move.mutate(s, IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), IC(0)));
}
}
} else {
throw new OptimizingCompilerException("BURS_Helpers", "unexpected parameters: " + result + "=" + val1 + "<<" + val2);
}
}
use of org.jikesrvm.compilers.opt.OptimizingCompilerException in project JikesRVM by JikesRVM.
the class BURS_Helpers method SET_EXCEPTION_OBJECT.
/**
* Emit code to move a value in a register to the stack location where a
* caught exception object is expected to be.
*
* @param s the instruction to expand
*/
protected final void SET_EXCEPTION_OBJECT(Instruction s) {
int offset = -burs.ir.stackManager.allocateSpaceForCaughtException();
StackLocationOperand sl = new StackLocationOperand(true, offset, DW);
Operand val = CacheOp.getClearRef(s);
if (val.isRegister()) {
EMIT(MIR_Move.mutate(s, IA32_MOV, sl, val));
} else if (val.isConstant()) {
RegisterOperand temp;
if (val.isIntConstant()) {
if (VM.VerifyAssertions)
opt_assert(VM.BuildFor32Addr);
temp = regpool.makeTempInt();
} else if (val.isLongConstant()) {
if (VM.VerifyAssertions)
opt_assert(VM.BuildFor64Addr);
temp = regpool.makeTempLong();
} else {
throw new OptimizingCompilerException("BURS_Helpers", "unexpected operand type " + val + " in SET_EXCEPTION_OBJECT");
}
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, temp, val)));
// for opt compiler var usage info?
val = temp.copyRO();
EMIT(MIR_Move.mutate(s, IA32_MOV, sl, temp.copy()));
} else {
throw new OptimizingCompilerException("BURS_Helpers", "unexpected operand type " + val + " in SET_EXCEPTION_OBJECT");
}
}
use of org.jikesrvm.compilers.opt.OptimizingCompilerException in project JikesRVM by JikesRVM.
the class AssemblerBase method doJCC.
/**
* Emit the given instruction, assuming that
* it is a MIR_CondBranch instruction
* and has a JCC operator
*
* @param inst the instruction to assemble
*/
protected void doJCC(Instruction inst) {
byte cond = getCond(MIR_CondBranch.getCond(inst));
if (isImm(MIR_CondBranch.getTarget(inst))) {
emitJCC_Cond_Imm(cond, getImm(MIR_CondBranch.getTarget(inst)));
} else {
if (VM.VerifyAssertions && !isLabel(MIR_CondBranch.getTarget(inst))) {
throw new OptimizingCompilerException("Unexpected operand " + inst.toString());
}
int sourceLabel = -mcOffsets.getMachineCodeOffset(inst);
int targetLabel = getLabel(MIR_CondBranch.getTarget(inst));
int delta = targetLabel - sourceLabel;
if (VM.VerifyAssertions)
opt_assert(delta >= 0);
if (delta < 10 || (delta < 90 && targetIsClose(inst, -targetLabel))) {
int miStart = mi;
ForwardReference r = new ForwardReference.ShortBranch(mi, targetLabel);
forwardRefs = ForwardReference.enqueue(forwardRefs, r);
setMachineCodes(mi++, (byte) (0x70 + cond));
// leave space for displacement
mi += 1;
if (lister != null)
lister.I(miStart, "J" + CONDITION[cond], 0);
} else {
emitJCC_Cond_Label(cond, targetLabel);
}
}
}
Aggregations