use of org.jikesrvm.compilers.opt.ir.operand.LocationOperand in project JikesRVM by JikesRVM.
the class ComplexLIR2MIRExpansion method attempt.
private static void attempt(Instruction s, IR ir, boolean isAddress, boolean isLong) {
BasicBlock BB1 = s.getBasicBlock();
BasicBlock BB4 = BB1.splitNodeAt(s, ir);
BasicBlock BB2 = BB1.createSubBlock(0, ir);
BasicBlock BB3 = BB2.createSubBlock(0, ir);
BB1.insertOut(BB2);
BB1.insertOut(BB3);
BB2.insertOut(BB4);
BB3.insertOut(BB4);
ir.cfg.linkInCodeOrder(BB1, BB2);
ir.cfg.linkInCodeOrder(BB2, BB3);
ir.cfg.linkInCodeOrder(BB3, BB4);
// mutate ATTEMPT into a STWCX
RegisterOperand newValue = (RegisterOperand) Attempt.getNewValue(s);
RegisterOperand address = (RegisterOperand) Attempt.getAddress(s);
Operand offset = Attempt.getOffset(s);
LocationOperand location = Attempt.getLocation(s);
Operand guard = Attempt.getGuard(s);
RegisterOperand result = Attempt.getResult(s);
MIR_Store.mutate(s, (isAddress || isLong ? PPC_STAddrCXr : PPC_STWCXr), newValue, address, offset, location, guard);
// Branch to BB3 iff the STWXC succeeds (CR(0) is EQUAL)
// Else fall through to BB2
PhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet().asPPC();
BB1.appendInstruction(MIR_CondBranch.create(PPC_BCOND, I(phys.getConditionRegister(0)), PowerPCConditionOperand.EQUAL(), BB3.makeJumpTarget(), new BranchProfileOperand()));
// BB2 sets result to FALSE and jumps to BB4
BB2.appendInstruction(MIR_Unary.create(PPC_LDI, result.copyRO(), IC(0)));
BB2.appendInstruction(MIR_Branch.create(PPC_B, BB4.makeJumpTarget()));
// BB3 sets result to TRUE and falls through to BB4
BB3.appendInstruction(MIR_Unary.create(PPC_LDI, result.copyRO(), IC(1)));
}
use of org.jikesrvm.compilers.opt.ir.operand.LocationOperand in project JikesRVM by JikesRVM.
the class NormalizeConstants method perform.
/**
* Doit.
*
* @param ir IR to normalize
*/
public static void perform(IR ir) {
// This greatly reduces the number of cases we have to worry about below.
if (VM.VerifyAssertions)
VM._assert(ir.options.SIMPLIFY_INTEGER_OPS && ir.options.SIMPLIFY_LONG_OPS && ir.options.SIMPLIFY_REF_OPS);
for (Instruction s = ir.firstInstructionInCodeOrder(); s != null; s = s.nextInstructionInCodeOrder()) {
// STEP ONE: Get 'large' constants into a form that the PPC 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) {
RegisterOperand rop = ir.regpool.makeTemp(use.getType());
RegisterOperand jtoc = (RegisterOperand) ir.regpool.makeJTOCOp();
ObjectConstantOperand oc = (ObjectConstantOperand) use;
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(VM.BuildFor32Addr ? INT_LOAD : LONG_LOAD, rop, jtoc, asImmediateOrRegOffset(AC(offset), s, ir, true), loc));
s.putOperand(idx, rop.copyD2U());
} else if (use instanceof DoubleConstantOperand) {
RegisterOperand rop = ir.regpool.makeTemp(TypeReference.Double);
RegisterOperand jtoc = (RegisterOperand) ir.regpool.makeJTOCOp();
DoubleConstantOperand dc = (DoubleConstantOperand) use;
Offset offset = dc.offset;
if (offset.isZero()) {
offset = Offset.fromIntSignExtend(Statics.findOrCreateLongSizeLiteral(Double.doubleToLongBits(dc.value)));
}
LocationOperand loc = new LocationOperand(offset);
s.insertBefore(Load.create(DOUBLE_LOAD, rop, jtoc, asImmediateOrRegOffset(AC(offset), s, ir, true), loc));
s.putOperand(idx, rop.copyD2U());
} else if (use instanceof FloatConstantOperand) {
RegisterOperand rop = ir.regpool.makeTemp(TypeReference.Float);
RegisterOperand jtoc = (RegisterOperand) ir.regpool.makeJTOCOp();
FloatConstantOperand fc = (FloatConstantOperand) use;
Offset offset = fc.offset;
if (offset.isZero()) {
offset = Offset.fromIntSignExtend(Statics.findOrCreateIntSizeLiteral(Float.floatToIntBits(fc.value)));
}
LocationOperand loc = new LocationOperand(offset);
s.insertBefore(Load.create(FLOAT_LOAD, rop, jtoc, asImmediateOrRegOffset(AC(offset), s, ir, true), loc));
s.putOperand(idx, rop.copyD2U());
} else if (use instanceof LongConstantOperand) {
if (!VM.BuildFor64Addr) {
if (s.getOpcode() != TRAP_IF_opcode) {
RegisterOperand rop = ir.regpool.makeTemp(TypeReference.Long);
s.insertBefore(Move.create(LONG_MOVE, rop, use.copy()));
s.putOperand(idx, rop.copyD2U());
}
}
} else if (use instanceof NullConstantOperand) {
s.putOperand(idx, AC(Address.zero()));
} else if (use instanceof TIBConstantOperand) {
RegisterOperand rop = ir.regpool.makeTemp(TypeReference.JavaLangObjectArray);
Operand jtoc = ir.regpool.makeJTOCOp();
Offset offset = ((TIBConstantOperand) use).value.getTibOffset();
LocationOperand loc = new LocationOperand(offset);
s.insertBefore(Load.create(VM.BuildFor32Addr ? INT_LOAD : LONG_LOAD, rop, jtoc, asImmediateOrRegOffset(AC(offset), s, ir, true), 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(VM.BuildFor32Addr ? INT_LOAD : LONG_LOAD, rop, jtoc, asImmediateOrRegOffset(AC(offset), s, ir, true), loc));
s.putOperand(idx, rop.copyD2U());
}
}
}
}
// Calling Simplifier.simplify ensures that the instruction is
// in normalized form. This reduces the number of cases we have to
// worry about (and does last minute constant folding on the off chance
// we've missed an opportunity...)
Simplifier.simplify(false, ir.regpool, ir.options, s);
switch(s.getOpcode()) {
// ////////
case REF_STORE_opcode:
s.changeOperatorTo(VM.BuildFor32Addr ? INT_STORE : LONG_STORE);
// On PowerPC, the value being stored must be in a register
Store.setValue(s, asRegPolymorphic(Store.getClearValue(s), s, ir));
// Supported addressing modes are quite limited.
Store.setAddress(s, asRegAddress(Store.getClearAddress(s), s, ir));
Store.setOffset(s, asImmediateOrRegOffset(Store.getClearOffset(s), s, ir, true));
break;
case BYTE_STORE_opcode:
case SHORT_STORE_opcode:
case INT_STORE_opcode:
case LONG_STORE_opcode:
// On PowerPC, the value being stored must be in a register
Store.setValue(s, asRegPolymorphic(Store.getClearValue(s), s, ir));
// Supported addressing modes are quite limited.
Store.setAddress(s, asRegAddress(Store.getClearAddress(s), s, ir));
Store.setOffset(s, asImmediateOrRegOffset(Store.getClearOffset(s), s, ir, true));
break;
case FLOAT_STORE_opcode:
case DOUBLE_STORE_opcode:
// Supported addressing modes are quite limited.
Store.setAddress(s, asRegAddress(Store.getClearAddress(s), s, ir));
Store.setOffset(s, asImmediateOrRegOffset(Store.getClearOffset(s), s, ir, true));
break;
case REF_LOAD_opcode:
s.changeOperatorTo(VM.BuildFor32Addr ? INT_LOAD : LONG_LOAD);
// Supported addressing modes are quite limited.
Load.setAddress(s, asRegAddress(Load.getClearAddress(s), s, ir));
Load.setOffset(s, asImmediateOrRegOffset(Load.getClearOffset(s), s, ir, true));
break;
case BYTE_LOAD_opcode:
case UBYTE_LOAD_opcode:
case SHORT_LOAD_opcode:
case USHORT_LOAD_opcode:
case INT_LOAD_opcode:
case LONG_LOAD_opcode:
case FLOAT_LOAD_opcode:
case DOUBLE_LOAD_opcode:
// Supported addressing modes are quite limited.
Load.setAddress(s, asRegAddress(Load.getClearAddress(s), s, ir));
Load.setOffset(s, asImmediateOrRegOffset(Load.getClearOffset(s), s, ir, true));
break;
case ATTEMPT_INT_opcode:
case ATTEMPT_LONG_opcode:
case ATTEMPT_ADDR_opcode:
// On PowerPC, the value being stored must be in a register
Attempt.setNewValue(s, asRegPolymorphic(Attempt.getClearNewValue(s), s, ir));
// not used on powerpc.
Attempt.setOldValue(s, null);
// Supported addressing modes are quite limited.
Attempt.setAddress(s, asRegAddress(Attempt.getClearAddress(s), s, ir));
Attempt.setOffset(s, asRegOffset(Attempt.getClearOffset(s), s, ir));
break;
case PREPARE_INT_opcode:
case PREPARE_LONG_opcode:
case PREPARE_ADDR_opcode:
// Supported addressing modes are quite limited.
Prepare.setAddress(s, asRegAddress(Prepare.getClearAddress(s), s, ir));
Prepare.setOffset(s, asRegOffset(Prepare.getClearOffset(s), s, ir));
break;
case LONG_MOVE_opcode:
if (VM.BuildFor64Addr) {
s.changeOperatorTo(REF_MOVE);
}
break;
case INT_MOVE_opcode:
s.changeOperatorTo(REF_MOVE);
break;
case REF_COND_MOVE_opcode:
s.changeOperatorTo(VM.BuildFor32Addr ? INT_COND_MOVE : LONG_COND_MOVE);
break;
case REF_IFCMP_opcode:
s.changeOperatorTo(VM.BuildFor32Addr ? INT_IFCMP : LONG_IFCMP);
// val1 can't be a constant, val2 must be small enough.
IfCmp.setVal1(s, asRegPolymorphic(IfCmp.getClearVal1(s), s, ir));
IfCmp.setVal2(s, asImmediateOrRegPolymorphic(IfCmp.getClearVal2(s), s, ir, true));
case LONG_IFCMP_opcode:
if (VM.BuildFor64Addr) {
// val1 can't be a constant, val2 must be small enough.
IfCmp.setVal1(s, asRegPolymorphic(IfCmp.getClearVal1(s), s, ir));
IfCmp.setVal2(s, asImmediateOrRegPolymorphic(IfCmp.getClearVal2(s), s, ir, true));
}
break;
case INT_IFCMP_opcode:
// val1 can't be a constant, val2 must be small enough.
IfCmp.setVal1(s, asRegPolymorphic(IfCmp.getClearVal1(s), s, ir));
IfCmp.setVal2(s, asImmediateOrRegPolymorphic(IfCmp.getClearVal2(s), s, ir, true));
break;
case INT_IFCMP2_opcode:
// val1 can't be a constant, val2 must be small enough.
IfCmp2.setVal1(s, asRegInt(IfCmp2.getClearVal1(s), s, ir));
IfCmp2.setVal2(s, asImmediateOrRegInt(IfCmp2.getClearVal2(s), s, ir, true));
break;
case BOOLEAN_CMP_INT_opcode:
case BOOLEAN_CMP_ADDR_opcode:
// val2 must be small enough.
BooleanCmp.setVal2(s, asImmediateOrRegPolymorphic(BooleanCmp.getClearVal2(s), s, ir, !BooleanCmp.getCond(s).isUNSIGNED()));
break;
case LONG_CMP_opcode:
Binary.setVal1(s, asRegPolymorphic(Binary.getVal1(s), s, ir));
Binary.setVal2(s, asRegPolymorphic(Binary.getVal2(s), s, ir));
break;
case LONG_ADD_opcode:
if (VM.BuildFor64Addr) {
s.changeOperatorTo(REF_ADD);
Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, true));
}
break;
case INT_ADD_opcode:
s.changeOperatorTo(REF_ADD);
Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, true));
break;
case REF_ADD_opcode:
Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, true));
break;
case LONG_SUB_opcode:
if (VM.BuildFor64Addr) {
s.changeOperatorTo(REF_SUB);
Binary.setVal1(s, asImmediateOrRegPolymorphic(Binary.getClearVal1(s), s, ir, true));
// val2 isn't be constant (if it were, Simplifier would have
// converted this into an ADD of -Val2).
}
break;
case INT_SUB_opcode:
s.changeOperatorTo(REF_SUB);
Binary.setVal1(s, asImmediateOrRegPolymorphic(Binary.getClearVal1(s), s, ir, true));
// converted this into an ADD of -Val2).
break;
case REF_SUB_opcode:
Binary.setVal1(s, asImmediateOrRegPolymorphic(Binary.getClearVal1(s), s, ir, true));
// converted this into an ADD of -Val2).
break;
case INT_MUL_opcode:
Binary.setVal2(s, asImmediateOrRegInt(Binary.getClearVal2(s), s, ir, true));
break;
case LONG_MUL_opcode:
if (VM.BuildFor64Addr) {
Binary.setVal2(s, asImmediateOrRegLong(Binary.getClearVal2(s), s, ir, true));
}
break;
// seem to expect constant operands at all.
case INT_REM_opcode:
case INT_DIV_opcode:
GuardedBinary.setVal1(s, asRegInt(GuardedBinary.getClearVal1(s), s, ir));
GuardedBinary.setVal2(s, asRegInt(GuardedBinary.getClearVal2(s), s, ir));
break;
case LONG_REM_opcode:
case LONG_DIV_opcode:
if (VM.BuildFor64Addr) {
GuardedBinary.setVal1(s, asRegLong(GuardedBinary.getClearVal1(s), s, ir));
GuardedBinary.setVal2(s, asRegLong(GuardedBinary.getClearVal2(s), s, ir));
}
break;
case LONG_NEG_opcode:
if (VM.BuildFor64Addr) {
s.changeOperatorTo(REF_NEG);
}
break;
case INT_NEG_opcode:
s.changeOperatorTo(REF_NEG);
break;
case LONG_NOT_opcode:
if (VM.BuildFor64Addr) {
s.changeOperatorTo(REF_NOT);
}
break;
case INT_NOT_opcode:
s.changeOperatorTo(REF_NOT);
break;
case LONG_AND_opcode:
if (VM.BuildFor64Addr) {
s.changeOperatorTo(REF_AND);
// unsigned immediate
Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
}
break;
case INT_AND_opcode:
s.changeOperatorTo(REF_AND);
// unsigned immediate
Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
break;
case REF_AND_opcode:
// unsigned immediate
Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
break;
case LONG_OR_opcode:
if (VM.BuildFor64Addr) {
s.changeOperatorTo(REF_OR);
// unsigned immediate
Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
}
break;
case INT_OR_opcode:
s.changeOperatorTo(REF_OR);
// unsigned immediate
Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
break;
case REF_OR_opcode:
// unsigned immediate
Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
break;
case LONG_XOR_opcode:
if (VM.BuildFor64Addr) {
s.changeOperatorTo(REF_XOR);
// unsigned immediate
Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
}
break;
case INT_XOR_opcode:
s.changeOperatorTo(REF_XOR);
// unsigned immediate
Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
break;
case REF_XOR_opcode:
// unsigned immediate
Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
break;
case REF_SHL_opcode:
s.changeOperatorTo(VM.BuildFor32Addr ? INT_SHL : LONG_SHL);
// Val2 could be a constant, but Val1 apparently can't be.
Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
break;
case LONG_SHL_opcode:
if (VM.BuildFor64Addr) {
// Val2 could be a constant, but Val1 apparently can't be.
Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
}
break;
case INT_SHL_opcode:
// Val2 could be a constant, but Val1 apparently can't be.
Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
break;
case REF_SHR_opcode:
s.changeOperatorTo(VM.BuildFor32Addr ? INT_SHR : LONG_SHR);
// Val2 could be a constant, but Val1 apparently can't be.
Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
break;
case LONG_SHR_opcode:
if (VM.BuildFor64Addr) {
// Val2 could be a constant, but Val1 apparently can't be.
Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
}
break;
case INT_SHR_opcode:
// Val2 could be a constant, but Val1 apparently can't be.
Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
break;
case REF_USHR_opcode:
s.changeOperatorTo(VM.BuildFor32Addr ? INT_USHR : LONG_USHR);
// Val2 could be a constant, but Val1 apparently can't be.
Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
break;
case LONG_USHR_opcode:
if (VM.BuildFor64Addr) {
// Val2 could be a constant, but Val1 apparently can't be.
Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
}
break;
case INT_USHR_opcode:
// Val2 could be a constant, but Val1 apparently can't be.
Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
break;
// Deal with Simplifier.CF_FLOAT or Simplifier.CF_DOUBLE being false
case INT_2DOUBLE_opcode:
case INT_2FLOAT_opcode:
case INT_BITS_AS_FLOAT_opcode:
Unary.setVal(s, asRegInt(Unary.getVal(s), s, ir));
break;
case ADDR_2INT_opcode:
s.changeOperatorTo(VM.BuildFor32Addr ? REF_MOVE : LONG_2INT);
break;
case ADDR_2LONG_opcode:
s.changeOperatorTo(VM.BuildFor32Addr ? INT_2LONG : REF_MOVE);
break;
case INT_2ADDRSigExt_opcode:
s.changeOperatorTo(VM.BuildFor32Addr ? REF_MOVE : INT_2LONG);
break;
case INT_2ADDRZerExt_opcode:
if (VM.BuildFor32Addr) {
s.changeOperatorTo(REF_MOVE);
}
break;
case LONG_2ADDR_opcode:
s.changeOperatorTo(VM.BuildFor64Addr ? REF_MOVE : LONG_2INT);
break;
case NULL_CHECK_opcode:
NullCheck.setRef(s, asRegAddress(NullCheck.getClearRef(s), s, ir));
break;
// Force all call parameters to be in registers
case SYSCALL_opcode:
case CALL_opcode:
{
int numArgs = Call.getNumberOfParams(s);
for (int i = 0; i < numArgs; i++) {
Call.setParam(s, i, asRegPolymorphic(Call.getClearParam(s, i), s, ir));
}
}
break;
case RETURN_opcode:
if (Return.hasVal(s)) {
Return.setVal(s, asRegPolymorphic(Return.getClearVal(s), s, ir));
}
break;
}
}
}
use of org.jikesrvm.compilers.opt.ir.operand.LocationOperand in project JikesRVM by JikesRVM.
the class SSADictionary method getStaticHelper.
/**
* Record the effects of a getstatic instruction on the heap array
* SSA form. Register the heap variables that this instruction uses and
* defs. Note that if inserting uphi functions, a getstatic defs a new
* heap variable name.
*
* @param s the getstatic instruction
* @param b the basic block containing s
*/
private void getStaticHelper(Instruction s, BasicBlock b) {
LocationOperand locOp = GetStatic.getLocation(s);
FieldReference field = locOp.getFieldRef();
registerUse(s, field);
if (uphi) {
registerDef(s, b, field);
}
}
use of org.jikesrvm.compilers.opt.ir.operand.LocationOperand in project JikesRVM by JikesRVM.
the class SSADictionary method putStaticHelper.
/**
* Record the effects of a putstatic instruction on the heap array
* SSA form. Register the heap variables that this instruction uses and
* defs.
*
* @param s the putstatic instruction
* @param b the basic block containing s
*/
private void putStaticHelper(Instruction s, BasicBlock b) {
LocationOperand locOp = PutStatic.getLocation(s);
FieldReference field = locOp.getFieldRef();
registerUse(s, field);
registerDef(s, b, field);
}
use of org.jikesrvm.compilers.opt.ir.operand.LocationOperand in project JikesRVM by JikesRVM.
the class LICM method checkLoop.
/*
* TODO document xidx parameter and turn this comment into proper JavaDoc.
* <p>
* Checks that inside the loop, the heap variable is only used/defed
* by simple, non-volatile loads/stores
*
* @param inst a phi instruction
* @param hop the result operand of the phi instruction
* @param xidx
* @param block the block that contains the phi instruction
*
* @return one of {@link #CL_LOADS_ONLY}, {@link #CL_STORES_ONLY},
* {@link #CL_LOADS_AND_STORES}, {@link #CL_COMPLEX}
*/
private int checkLoop(Instruction inst, HeapOperand<Object> hop, int xidx, BasicBlock block) {
HashSet<Instruction> seen = new HashSet<Instruction>();
Queue<Instruction> workList = new Queue<Instruction>();
int _state = CL_NONE;
int instUses = 0;
seen.add(inst);
for (int i = Phi.getNumberOfValues(inst) - 1; i >= 0; --i) {
if (i == xidx)
continue;
Instruction y = definingInstruction(Phi.getValue(inst, i));
if (y == inst)
instUses++;
if (!(seen.contains(y))) {
seen.add(y);
workList.insert(y);
}
}
while (!(workList.isEmpty())) {
Instruction y = workList.remove();
if (Phi.conforms(y)) {
for (int i = Phi.getNumberOfValues(y) - 1; i >= 0; --i) {
Instruction z = definingInstruction(Phi.getValue(y, i));
if (z == inst)
instUses++;
if (!(seen.contains(z))) {
seen.add(z);
workList.insert(z);
}
}
} else if ((y.isPEI()) || !LocationCarrier.conforms(y) || y.operator().isAcquire() || y.operator().isRelease()) {
return CL_COMPLEX;
} else {
// check for access to volatile field
LocationOperand loc = LocationCarrier.getLocation(y);
if (loc == null || loc.mayBeVolatile()) {
// VM.sysWriteln (" no loc or volatile field");
return CL_COMPLEX;
}
if (y.isImplicitStore()) {
// conservatively estimate loop-invariance by header domination
if (!inVariantLocation(y, block))
return CL_COMPLEX;
_state |= CL_STORES_ONLY;
} else {
_state |= CL_LOADS_ONLY;
}
for (HeapOperand<?> op : ssad.getHeapUses(y)) {
if (op.value.isExceptionHeapType())
continue;
if (op.getHeapType() != hop.getHeapType())
return CL_COMPLEX;
y = definingInstruction(op);
if (y == inst)
instUses++;
if (!(seen.contains(y))) {
seen.add(y);
workList.insert(y);
}
}
}
}
if (_state == CL_STORES_ONLY && ssad.getNumberOfUses(hop.value) != instUses) {
return CL_COMPLEX;
}
return _state;
}
Aggregations