use of org.jikesrvm.compilers.opt.OptimizingCompilerException in project JikesRVM by JikesRVM.
the class IndexPropagationSystem method processALoad.
/**
* Update the set of dataflow equations to account for the actions
* of ALoad instruction s
*
* <p> The load is of the form x = A[k]. let A_1 be the array SSA
* variable before the load, and A_2 the array SSA variable after
* the load. Then we add the dataflow equation
* L(A_2) = updateUse(L(A_1), VALNUM(k))
*
* <p> Intuitively, this equation represents the fact that A[k] is available
* after the store
*
* @param s the Aload instruction
*/
void processALoad(Instruction s) {
HeapOperand<?>[] A1 = ssa.getHeapUses(s);
HeapOperand<?>[] A2 = ssa.getHeapDefs(s);
if ((A1.length != 1) || (A2.length != 1)) {
throw new OptimizingCompilerException("IndexPropagation.processALoad: aload instruction defs or uses multiple heap variables?");
}
Operand array = ALoad.getArray(s);
Operand index = ALoad.getIndex(s);
if (IRTools.mayBeVolatileFieldLoad(s) || ir.options.READS_KILL) {
// to obey JMM strictly, we must treat every load as a
// DEF
addUpdateArrayDefEquation(A2[0].getHeapVariable(), A1[0].getHeapVariable(), array, index);
} else {
// otherwise, don't have to treat every load as a DEF
addUpdateArrayUseEquation(A2[0].getHeapVariable(), A1[0].getHeapVariable(), array, index);
}
}
use of org.jikesrvm.compilers.opt.OptimizingCompilerException in project JikesRVM by JikesRVM.
the class IndexPropagationSystem method processAStore.
/**
* Update the set of dataflow equations to account for the actions
* of AStore instruction s
*
* <p> The store is of the form A[k] = val. let A_1 be the array SSA
* variable before the store, and A_2 the array SSA variable after
* the store. Then we add the dataflow equation
* L(A_2) = update(L(A_1), VALNUM(k))
*
* <p> Intuitively, this equation represents the fact that A[k] is available
* after the store
*
* @param s the Astore instruction
*/
void processAStore(Instruction s) {
HeapOperand<?>[] A1 = ssa.getHeapUses(s);
HeapOperand<?>[] A2 = ssa.getHeapDefs(s);
if ((A1.length != 1) || (A2.length != 1)) {
throw new OptimizingCompilerException("IndexPropagation.processAStore: astore instruction defs or uses multiple heap variables?");
}
Operand array = AStore.getArray(s);
Operand index = AStore.getIndex(s);
addUpdateArrayDefEquation(A2[0].getHeapVariable(), A1[0].getHeapVariable(), array, index);
}
use of org.jikesrvm.compilers.opt.OptimizingCompilerException in project JikesRVM by JikesRVM.
the class ValueGraph method findOrCreateVertex.
/**
* Find or create an ValueGraphVertex corresponding to a
* given constant operand
*
* @param op the constant operand
* @return a value graph vertex corresponding to this variable
*/
private ValueGraphVertex findOrCreateVertex(ConstantOperand op) {
Object name;
if (op.isAddressConstant()) {
name = (VM.BuildFor32Addr) ? op.asAddressConstant().value.toInt() : op.asAddressConstant().value.toLong();
} else if (op.isIntConstant()) {
name = op.asIntConstant().value;
} else if (op.isFloatConstant()) {
name = op.asFloatConstant().value;
} else if (op.isLongConstant()) {
name = op.asLongConstant().value;
} else if (op.isDoubleConstant()) {
name = op.asDoubleConstant().value;
} else if (op instanceof ObjectConstantOperand) {
name = op.asObjectConstant().value;
} else if (op instanceof TIBConstantOperand) {
name = op.asTIBConstant().value;
} else if (op.isNullConstant()) {
name = op;
} else if (op instanceof TrueGuardOperand) {
name = op;
} else if (op instanceof UnreachableOperand) {
name = op;
} else {
throw new OptimizingCompilerException("ValueGraph.findOrCreateVertex: unexpected constant operand: " + op);
}
ValueGraphVertex v = getVertex(name);
if (v == null) {
v = new ValueGraphVertex(op);
v.setLabel(op, 0);
graph.addGraphNode(v);
nameMap.put(name, v);
}
return v;
}
use of org.jikesrvm.compilers.opt.OptimizingCompilerException in project JikesRVM by JikesRVM.
the class BURS_Helpers method LONG_SHR.
/**
* Expansion of LONG_SHR
* @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_SHR(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_SHR, result.asRegister(), val1, val2);
EMIT(s);
} else if (result.isRegister()) {
int shift = val2.asIntConstant().value;
if (maskWith3f) {
shift = shift & 0x3F;
}
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))));
}
// lhsReg = lhsReg >> 1
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SAR, new RegisterOperand(lhsReg, TypeReference.Int), IC(1))));
// lowlhsReg = (lhsReg << 31) | (lowlhsReg >>> 1)
EMIT(MIR_BinaryAcc.mutate(s, IA32_RCR, new RegisterOperand(lowlhsReg, TypeReference.Int), IC(1)));
} else if (shift < 32) {
// bits to shift in: tmp = rhsReg << (32 - shift)
// TODO: use of LEA for SHL
Register tmp = regpool.getInteger();
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(tmp, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SHL, new RegisterOperand(tmp, TypeReference.Int), IC(32 - shift))));
// compute bottom half: lowlhsReg = (lowlhsReg1 >>> shift) | tmp
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_BinaryAcc.create(IA32_SHR, new RegisterOperand(lowlhsReg, TypeReference.Int), IC(shift))));
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_OR, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(tmp, TypeReference.Int))));
// compute top half: lhsReg = lhsReg >> shift
if (!result.similar(val1)) {
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
}
EMIT(MIR_BinaryAcc.mutate(s, IA32_SAR, new RegisterOperand(lhsReg, TypeReference.Int), IC(shift)));
} else if (shift == 32) {
// lowlhsReg = rhsReg1
EMIT(MIR_Move.mutate(s, IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int)));
// lhsReg = rhsReg1 >> 31
if (!result.similar(val1)) {
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_SAR, new RegisterOperand(lhsReg, TypeReference.Int), IC(31))));
} else {
if ((!maskWith3f && (shift >= 0x3F)) || (maskWith3f && ((shift & 0x3F) == 0x3F))) {
// lhsReg = rhsReg1 >> 31
if (!result.similar(val1)) {
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_SAR, new RegisterOperand(lhsReg, TypeReference.Int), IC(31))));
// lowlhsReg = lhsReg
EMIT(MIR_Move.mutate(s, IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(lhsReg, TypeReference.Int)));
} else {
// lhsReg = rhsReg1 >> 31
if (!result.similar(val1)) {
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_SAR, new RegisterOperand(lhsReg, TypeReference.Int), IC(31))));
// lowlhsReg = rhsReg1 >> shift
EMIT(MIR_Move.mutate(s, IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int)));
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SAR, new RegisterOperand(lowlhsReg, TypeReference.Int), IC((shift - 32) & 0x3F))));
}
}
} 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 SplitBasicBlock method splitEachBlock.
/**
* Splits a basic block.
*
* @param bb the block to process
* @param ir the IR that contains the block
*
* @return {@code null} if no splitting is done, returns the second block
* if splitting is done.
*/
BasicBlock splitEachBlock(BasicBlock bb, IR ir) {
if (ir.options.L2M_MAX_BLOCK_SIZE <= 0) {
throw new OptimizingCompilerException("Maximum block size must be a" + " positive number but was " + ir.options.L2M_MAX_BLOCK_SIZE + "!", true);
}
int remainingInstCount = ir.options.L2M_MAX_BLOCK_SIZE;
Enumeration<Instruction> instructions = bb.forwardRealInstrEnumerator();
while (instructions.hasMoreElements()) {
Instruction inst = instructions.nextElement();
remainingInstCount--;
if (remainingInstCount <= 0) {
// no need to split because all the rests are just branches
if (inst.isBranch()) {
return null;
}
// no need to split because the basic block does not contain any more instructions
if (!instructions.hasMoreElements()) {
return null;
}
return bb.splitNodeWithLinksAt(inst, ir);
}
}
return null;
}
Aggregations