use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.
the class Simplifier method checkcastNotNull.
private static DefUseEffect checkcastNotNull(Instruction s, OptOptions opts) {
Operand ref = TypeCheck.getRef(s);
TypeReference lhsType = TypeCheck.getType(s).getTypeRef();
TypeReference rhsType = ref.getType();
byte ans = ClassLoaderProxy.includesType(lhsType, rhsType);
if (ans == YES) {
Move.mutate(s, REF_MOVE, TypeCheck.getResult(s), ref);
if (ref.isConstant())
return DefUseEffect.MOVE_FOLDED;
else
return DefUseEffect.MOVE_REDUCED;
} else if (ans == NO) {
RVMType rType = rhsType.peekType();
if (rType != null && rType.isClassType() && rType.asClass().isFinal()) {
// only final (or precise) rhs types can be optimized since rhsType may be conservative
Trap.mutate(s, TRAP, null, TrapCodeOperand.CheckCast());
return DefUseEffect.TRAP_REDUCED;
} else {
return DefUseEffect.UNCHANGED;
}
} else {
return DefUseEffect.UNCHANGED;
}
}
use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.
the class ClassLoaderProxy method findCommonSuperclass.
/**
* Returns a common superclass of the two types.
* NOTE: If both types are references, but are not both loaded, then this
* may be a conservative approximation (java.lang.Object).
*
* @param t1 first type
* @param t2 second type
* @return a common superclass or {@code null} if there's none
*/
public static TypeReference findCommonSuperclass(TypeReference t1, TypeReference t2) {
if (t1 == t2) {
return t1;
}
if (t1.isPrimitiveType() || t2.isPrimitiveType()) {
if (t1.isIntLikeType() && t2.isIntLikeType()) {
// 2 non-identical int like types, return the largest
if (t1.isIntType() || t2.isIntType()) {
return TypeReference.Int;
} else if (t1.isCharType() || t2.isCharType()) {
return TypeReference.Char;
} else if (t1.isShortType() || t2.isShortType()) {
return TypeReference.Short;
} else if (t1.isByteType() || t2.isByteType()) {
return TypeReference.Byte;
} else {
if (VM.VerifyAssertions)
VM._assert(VM.NOT_REACHED);
return null;
}
} else if (t1.isWordLikeType() && t2.isWordLikeType()) {
return TypeReference.Word;
} else {
// other primitive and unboxed types have no commonality so return null
return null;
}
}
// the other operand is the most precise
if (t1 == TypeReference.NULL_TYPE) {
return t2;
} else if (t2 == TypeReference.NULL_TYPE) {
return t1;
}
if (DBG_TYPE) {
VM.sysWrite("finding common supertype of " + t1 + " and " + t2);
}
// Strip off all array junk.
int arrayDimensions = 0;
while (t1.isArrayType() && t2.isArrayType()) {
++arrayDimensions;
t1 = t1.getArrayElementType();
t2 = t2.getArrayElementType();
}
// dimensionality
if (t1.isPrimitiveType() || t2.isPrimitiveType()) {
TypeReference type = TypeReference.JavaLangObject;
if (t1 == t2) {
// Unboxed types are wrapped in their own array objects
if (t1.isUnboxedType()) {
arrayDimensions++;
type = t1;
} else {
if (VM.VerifyAssertions)
VM._assert(VM.NOT_REACHED);
}
}
--arrayDimensions;
while (arrayDimensions-- > 0) {
type = type.getArrayTypeForElementType();
}
if (DBG_TYPE) {
VM.sysWrite("one is a primitive array, so supertype is " + type);
}
return type;
}
// is this a case of arrays with different dimensionalities?
if (t1.isArrayType() || t2.isArrayType()) {
// one is a class type, while the other is an array
TypeReference type = TypeReference.JavaLangObject;
while (arrayDimensions-- > 0) {
type = type.getArrayTypeForElementType();
}
if (DBG_TYPE) {
VM.sysWrite("differing dimensionalities for arrays, so supertype is " + type);
}
return type;
}
// At this point they both must be class types.
// technique: push heritage of each type on a separate stack,
// then find the highest point in the stack where they differ.
RVMClass c1 = (RVMClass) t1.peekType();
RVMClass c2 = (RVMClass) t2.peekType();
if (c1 != null && c2 != null) {
// The ancestor hierarchy is available, so do this exactly
Stack<RVMClass> s1 = new Stack<RVMClass>();
do {
s1.push(c1);
c1 = c1.getSuperClass();
} while (c1 != null);
Stack<RVMClass> s2 = new Stack<RVMClass>();
do {
s2.push(c2);
c2 = c2.getSuperClass();
} while (c2 != null);
if (DBG_TYPE) {
VM.sysWrite("stack 1: " + s1);
}
if (DBG_TYPE) {
VM.sysWrite("stack 2: " + s2);
}
TypeReference best = TypeReference.JavaLangObject;
while (!s1.empty() && !s2.empty()) {
RVMClass temp = s1.pop();
if (temp == s2.pop()) {
best = temp.getTypeRef();
} else {
break;
}
}
if (DBG_TYPE) {
VM.sysWrite("common supertype of the two classes is " + best);
}
while (arrayDimensions-- > 0) {
best = best.getArrayTypeForElementType();
}
return best;
} else {
if (DBG_TYPE && c1 == null) {
VM.sysWrite(c1 + " is not loaded, using Object as common supertype");
}
if (DBG_TYPE && c2 == null) {
VM.sysWrite(c2 + " is not loaded, using Object as common supertype");
}
TypeReference common = TypeReference.JavaLangObject;
while (arrayDimensions-- > 0) {
common = common.getArrayTypeForElementType();
}
return common;
}
}
use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.
the class ExpressionFolding method transform.
/**
* Perform the transformation on the instruction
*
* @param s
* the instruction to transform of the form y = x op c1
* @param def
* the definition of x, the defining instruction is of the form x = a
* op c2
* @return the new instruction to replace s;
*/
private static Instruction transform(Instruction s, Instruction def) {
// x = a op1 c1 <-- def
// y = x op2 c2 <-- s
final RegisterOperand a = getUseFromCandidate(def);
final RegisterOperand x = getDefFromCandidate(def, true);
if (x == null) {
return null;
}
final RegisterOperand y = getDefFromCandidate(s, false);
if (y == null) {
return null;
}
if (VM.VerifyAssertions) {
RegisterOperand x2;
x2 = getUseFromCandidate(s);
boolean similar = x.similar(x2);
if (!similar) {
String msg = "x not similar to x2 " + x + " : " + x2;
VM._assert(VM.NOT_REACHED, msg);
}
}
switch(s.getOpcode()) {
// Foldable operators
case INT_ADD_opcode:
{
if (FOLD_INTS && FOLD_ADDS) {
int c2 = getIntValue(Binary.getVal2(s));
if (def.operator() == INT_ADD) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a + c1; y = x + c2
return Binary.create(INT_ADD, y.copyRO(), a.copyRO(), IC(c1 + c2));
} else if (def.operator() == INT_SUB) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a - c1; y = x + c2
return Binary.create(INT_ADD, y.copyRO(), a.copyRO(), IC(c2 - c1));
} else if (def.operator() == INT_NEG && FOLD_CONSTANTS_TO_LHS) {
// x = -a; y = x + c2;
return Binary.create(INT_SUB, y.copyRO(), IC(c2), a.copyRO());
}
}
return null;
}
case REF_ADD_opcode:
{
if (FOLD_REFS && FOLD_ADDS) {
Address c2 = getAddressValue(Binary.getVal2(s));
if (def.operator() == REF_ADD) {
Address c1 = getAddressValue(Binary.getVal2(def));
// x = a + c1; y = x + c2
return Binary.create(REF_ADD, y.copyRO(), a.copyRO(), AC(c1.toWord().plus(c2.toWord()).toAddress()));
} else if (def.operator() == REF_SUB) {
Address c1 = getAddressValue(Binary.getVal2(def));
// x = a - c1; y = x + c2
return Binary.create(REF_ADD, y.copyRO(), a.copyRO(), AC(c2.toWord().minus(c1.toWord()).toAddress()));
} else if (def.operator() == REF_NEG && FOLD_CONSTANTS_TO_LHS) {
// x = -a; y = x + c2;
return Binary.create(REF_SUB, y.copyRO(), AC(c2), a.copyRO());
}
}
return null;
}
case LONG_ADD_opcode:
{
if (FOLD_LONGS && FOLD_ADDS) {
long c2 = getLongValue(Binary.getVal2(s));
if (def.operator() == LONG_ADD) {
long c1 = getLongValue(Binary.getVal2(def));
// x = a + c1; y = x + c2
return Binary.create(LONG_ADD, y.copyRO(), a.copyRO(), LC(c1 + c2));
} else if (def.operator() == LONG_SUB) {
long c1 = getLongValue(Binary.getVal2(def));
// x = a - c1; y = x + c2
return Binary.create(LONG_ADD, y.copyRO(), a.copyRO(), LC(c2 - c1));
} else if (def.operator() == LONG_NEG && FOLD_CONSTANTS_TO_LHS) {
// x = -a; y = x + c2;
return Binary.create(LONG_SUB, y.copyRO(), LC(c2), a.copyRO());
}
}
return null;
}
case FLOAT_ADD_opcode:
{
if (FOLD_FLOATS && FOLD_ADDS) {
float c2 = getFloatValue(Binary.getVal2(s));
if (def.operator() == FLOAT_ADD) {
float c1 = getFloatValue(Binary.getVal2(def));
// x = a + c1; y = x + c2
return Binary.create(FLOAT_ADD, y.copyRO(), a.copyRO(), FC(c1 + c2));
} else if (def.operator() == FLOAT_SUB) {
float c1 = getFloatValue(Binary.getVal2(def));
// x = a - c1; y = x + c2
return Binary.create(FLOAT_ADD, y.copyRO(), a.copyRO(), FC(c2 - c1));
} else if (def.operator() == FLOAT_NEG && FOLD_CONSTANTS_TO_LHS) {
// x = -a; y = x + c2;
return Binary.create(FLOAT_SUB, y.copyRO(), FC(c2), a.copyRO());
}
}
return null;
}
case DOUBLE_ADD_opcode:
{
if (FOLD_DOUBLES && FOLD_ADDS) {
double c2 = getDoubleValue(Binary.getVal2(s));
if (def.operator() == DOUBLE_ADD) {
double c1 = getDoubleValue(Binary.getVal2(def));
// x = a + c1; y = x + c2
return Binary.create(DOUBLE_ADD, y.copyRO(), a.copyRO(), DC(c1 + c2));
} else if (def.operator() == DOUBLE_SUB) {
double c1 = getDoubleValue(Binary.getVal2(def));
// x = a - c1; y = x + c2
return Binary.create(DOUBLE_ADD, y.copyRO(), a.copyRO(), DC(c2 - c1));
} else if (def.operator() == DOUBLE_NEG && FOLD_CONSTANTS_TO_LHS) {
// x = -a; y = x + c2;
return Binary.create(DOUBLE_SUB, y.copyRO(), DC(c2), a.copyRO());
}
}
return null;
}
case INT_SUB_opcode:
{
if (FOLD_INTS && FOLD_SUBS) {
int c2 = getIntValue(Binary.getVal2(s));
if (def.operator() == INT_ADD) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a + c1; y = x - c2
return Binary.create(INT_ADD, y.copyRO(), a.copyRO(), IC(c1 - c2));
} else if (def.operator() == INT_SUB) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a - c1; y = x - c2
return Binary.create(INT_ADD, y.copyRO(), a.copyRO(), IC(-c1 - c2));
} else if (def.operator() == INT_NEG && FOLD_CONSTANTS_TO_LHS) {
// x = -a; y = x - c2;
return Binary.create(INT_SUB, y.copyRO(), IC(-c2), a.copyRO());
}
}
return null;
}
case REF_SUB_opcode:
{
if (FOLD_REFS && FOLD_SUBS) {
Address c2 = getAddressValue(Binary.getVal2(s));
if (def.operator() == REF_ADD) {
Address c1 = getAddressValue(Binary.getVal2(def));
// x = a + c1; y = x - c2
return Binary.create(REF_ADD, y.copyRO(), a.copyRO(), AC(c1.toWord().minus(c2.toWord()).toAddress()));
} else if (def.operator() == REF_SUB) {
Address c1 = getAddressValue(Binary.getVal2(def));
// x = a - c1; y = x - c2
return Binary.create(REF_ADD, y.copyRO(), a.copyRO(), AC(Word.zero().minus(c1.toWord()).minus(c2.toWord()).toAddress()));
} else if (def.operator() == REF_NEG && FOLD_CONSTANTS_TO_LHS) {
// x = -a; y = x - c2;
return Binary.create(REF_SUB, y.copyRO(), AC(Word.zero().minus(c2.toWord()).toAddress()), a.copyRO());
}
}
return null;
}
case LONG_SUB_opcode:
{
if (FOLD_LONGS && FOLD_SUBS) {
long c2 = getLongValue(Binary.getVal2(s));
if (def.operator() == LONG_ADD) {
long c1 = getLongValue(Binary.getVal2(def));
// x = a + c1; y = x - c2
return Binary.create(LONG_ADD, y.copyRO(), a.copyRO(), LC(c1 - c2));
} else if (def.operator() == LONG_SUB) {
long c1 = getLongValue(Binary.getVal2(def));
// x = a - c1; y = x - c2
return Binary.create(LONG_ADD, y.copyRO(), a.copyRO(), LC(-c1 - c2));
} else if (def.operator() == LONG_NEG && FOLD_CONSTANTS_TO_LHS) {
// x = -a; y = x - c2;
return Binary.create(LONG_SUB, y.copyRO(), LC(-c2), a.copyRO());
}
}
return null;
}
case FLOAT_SUB_opcode:
{
if (FOLD_FLOATS && FOLD_SUBS) {
float c2 = getFloatValue(Binary.getVal2(s));
if (def.operator() == FLOAT_ADD) {
float c1 = getFloatValue(Binary.getVal2(def));
// x = a + c1; y = x - c2
return Binary.create(FLOAT_ADD, y.copyRO(), a.copyRO(), FC(c1 - c2));
} else if (def.operator() == FLOAT_SUB) {
float c1 = getFloatValue(Binary.getVal2(def));
// x = a - c1; y = x - c2
return Binary.create(FLOAT_ADD, y.copyRO(), a.copyRO(), FC(-c1 - c2));
} else if (def.operator() == FLOAT_NEG && FOLD_CONSTANTS_TO_LHS) {
// x = -a; y = x - c2;
return Binary.create(FLOAT_SUB, y.copyRO(), FC(-c2), a.copyRO());
}
}
return null;
}
case DOUBLE_SUB_opcode:
{
if (FOLD_DOUBLES && FOLD_SUBS) {
double c2 = getDoubleValue(Binary.getVal2(s));
if (def.operator() == FLOAT_ADD) {
double c1 = getDoubleValue(Binary.getVal2(def));
// x = a + c1; y = x - c2
return Binary.create(DOUBLE_ADD, y.copyRO(), a.copyRO(), DC(c1 - c2));
} else if (def.operator() == DOUBLE_SUB) {
double c1 = getDoubleValue(Binary.getVal2(def));
// x = a - c1; y = x + c2
return Binary.create(DOUBLE_ADD, y.copyRO(), a.copyRO(), DC(-c1 - c2));
} else if (def.operator() == DOUBLE_NEG && FOLD_CONSTANTS_TO_LHS) {
// x = -a; y = x - c2;
return Binary.create(DOUBLE_SUB, y.copyRO(), DC(-c2), a.copyRO());
}
}
return null;
}
case INT_MUL_opcode:
{
if (FOLD_INTS && FOLD_MULTS) {
int c2 = getIntValue(Binary.getVal2(s));
if (def.operator() == INT_MUL) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a * c1; y = x * c2
return Binary.create(INT_MUL, y.copyRO(), a.copyRO(), IC(c1 * c2));
} else if (def.operator() == INT_NEG) {
// x = -a; y = x * c2;
return Binary.create(INT_MUL, y.copyRO(), a.copyRO(), IC(-c2));
}
}
return null;
}
case LONG_MUL_opcode:
{
if (FOLD_LONGS && FOLD_MULTS) {
long c2 = getLongValue(Binary.getVal2(s));
if (def.operator() == LONG_MUL) {
long c1 = getLongValue(Binary.getVal2(def));
// x = a * c1; y = x * c2
return Binary.create(LONG_MUL, y.copyRO(), a.copyRO(), LC(c1 * c2));
} else if (def.operator() == LONG_NEG) {
// x = -a; y = x * c2;
return Binary.create(LONG_MUL, y.copyRO(), a.copyRO(), LC(-c2));
}
}
return null;
}
case FLOAT_MUL_opcode:
{
if (FOLD_FLOATS && FOLD_MULTS) {
float c2 = getFloatValue(Binary.getVal2(s));
if (def.operator() == FLOAT_MUL) {
float c1 = getFloatValue(Binary.getVal2(def));
// x = a * c1; y = x * c2
return Binary.create(FLOAT_MUL, y.copyRO(), a.copyRO(), FC(c1 * c2));
} else if (def.operator() == FLOAT_NEG) {
// x = -a; y = x * c2;
return Binary.create(FLOAT_MUL, y.copyRO(), a.copyRO(), FC(-c2));
}
}
return null;
}
case DOUBLE_MUL_opcode:
{
if (FOLD_DOUBLES && FOLD_MULTS) {
double c2 = getDoubleValue(Binary.getVal2(s));
if (def.operator() == DOUBLE_MUL) {
double c1 = getDoubleValue(Binary.getVal2(def));
// x = a * c1; y = x * c2
return Binary.create(DOUBLE_MUL, y.copyRO(), a.copyRO(), DC(c1 * c2));
} else if (def.operator() == DOUBLE_NEG) {
// x = -a; y = x * c2;
return Binary.create(DOUBLE_MUL, y.copyRO(), a.copyRO(), DC(-c2));
}
}
return null;
}
case INT_DIV_opcode:
{
if (FOLD_INTS && FOLD_DIVS) {
int c2 = getIntValue(GuardedBinary.getVal2(s));
if (def.operator() == INT_DIV) {
int c1 = getIntValue(GuardedBinary.getVal2(def));
Operand guard = GuardedBinary.getGuard(def);
// x = a / c1; y = x / c2
return GuardedBinary.create(INT_DIV, y.copyRO(), a.copyRO(), IC(c1 * c2), guard);
} else if (def.operator() == INT_NEG) {
Operand guard = GuardedBinary.getGuard(s);
// x = -a; y = x / c2;
return GuardedBinary.create(INT_DIV, y.copyRO(), a.copyRO(), IC(-c2), guard);
}
}
return null;
}
case LONG_DIV_opcode:
{
if (FOLD_LONGS && FOLD_DIVS) {
long c2 = getLongValue(GuardedBinary.getVal2(s));
if (def.operator() == LONG_DIV) {
long c1 = getLongValue(GuardedBinary.getVal2(def));
Operand guard = GuardedBinary.getGuard(def);
// x = a / c1; y = x / c2
return GuardedBinary.create(LONG_DIV, y.copyRO(), a.copyRO(), LC(c1 * c2), guard);
} else if (def.operator() == LONG_NEG) {
Operand guard = GuardedBinary.getGuard(s);
// x = -a; y = x / c2;
return GuardedBinary.create(LONG_DIV, y.copyRO(), a.copyRO(), LC(-c2), guard);
}
}
return null;
}
case FLOAT_DIV_opcode:
{
if (FOLD_FLOATS && FOLD_DIVS) {
float c2 = getFloatValue(Binary.getVal2(s));
if (def.operator() == FLOAT_DIV) {
float c1 = getFloatValue(Binary.getVal2(def));
// x = a / c1; y = x / c2
return Binary.create(FLOAT_DIV, y.copyRO(), a.copyRO(), FC(c1 * c2));
} else if (def.operator() == FLOAT_NEG) {
// x = -a; y = x / c2;
return Binary.create(FLOAT_DIV, y.copyRO(), a.copyRO(), FC(-c2));
}
}
return null;
}
case DOUBLE_DIV_opcode:
{
if (FOLD_DOUBLES && FOLD_DIVS) {
double c2 = getDoubleValue(Binary.getVal2(s));
if (def.operator() == DOUBLE_DIV) {
double c1 = getDoubleValue(Binary.getVal2(def));
// x = a / c1; y = x / c2
return Binary.create(DOUBLE_DIV, y.copyRO(), a.copyRO(), DC(c1 * c2));
} else if (def.operator() == DOUBLE_NEG) {
// x = -a; y = x / c2;
return Binary.create(DOUBLE_DIV, y.copyRO(), a.copyRO(), DC(-c2));
}
}
return null;
}
case INT_SHL_opcode:
{
if (FOLD_INTS && FOLD_SHIFTLS) {
int c2 = getIntValue(Binary.getVal2(s));
if (def.operator() == INT_SHL) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a << c1; y = x << c2
return Binary.create(INT_SHL, y.copyRO(), a.copyRO(), IC(c1 + c2));
} else if ((def.operator() == INT_SHR) || (def.operator() == INT_USHR)) {
int c1 = getIntValue(Binary.getVal2(def));
if (c1 == c2) {
// x = a >> c1; y = x << c1
return Binary.create(INT_AND, y.copyRO(), a.copyRO(), IC(-1 << c1));
}
} else if (def.operator() == INT_AND) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a & c1; y = << c2
if ((c1 << c2) == (-1 << c2)) {
// the first mask is redundant
return Binary.create(INT_SHL, y.copyRO(), a.copyRO(), IC(c2));
}
} else if ((def.operator() == INT_OR) || (def.operator() == INT_XOR)) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a | c1; y = << c2
if ((c1 << c2) == 0) {
// the first mask is redundant
return Binary.create(INT_SHL, y.copyRO(), a.copyRO(), IC(c2));
}
}
}
return null;
}
case REF_SHL_opcode:
{
if (FOLD_REFS && FOLD_SHIFTLS) {
int c2 = getIntValue(Binary.getVal2(s));
if (def.operator() == REF_SHL) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a << c1; y = x << c2
return Binary.create(REF_SHL, y.copyRO(), a.copyRO(), IC(c1 + c2));
} else if ((def.operator() == REF_SHR) || (def.operator() == REF_USHR)) {
int c1 = getIntValue(Binary.getVal2(def));
if (c1 == c2) {
// x = a >> c1; y = x << c1
return Binary.create(REF_AND, y.copyRO(), a.copyRO(), AC(Word.zero().minus(Word.one()).lsh(c1).toAddress()));
}
} else if (def.operator() == REF_AND) {
Address c1 = getAddressValue(Binary.getVal2(def));
// x = a & c1; y = x << c2
if (c1.toWord().lsh(c2).EQ(Word.fromIntSignExtend(-1).lsh(c2))) {
// the first mask is redundant
return Binary.create(REF_SHL, y.copyRO(), a.copyRO(), IC(c2));
}
} else if ((def.operator() == REF_OR) || (def.operator() == REF_XOR)) {
Address c1 = getAddressValue(Binary.getVal2(def));
// x = a | c1; y = x << c2
if (c1.toWord().lsh(c2).EQ(Word.zero())) {
// the first mask is redundant
return Binary.create(REF_SHL, y.copyRO(), a.copyRO(), IC(c2));
}
}
}
return null;
}
case LONG_SHL_opcode:
{
if (FOLD_LONGS && FOLD_SHIFTLS) {
int c2 = getIntValue(Binary.getVal2(s));
if (def.operator() == LONG_SHL) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a << c1; y = x << c2
return Binary.create(LONG_SHL, y.copyRO(), a.copyRO(), IC(c1 + c2));
} else if ((def.operator() == LONG_SHR) || (def.operator() == LONG_USHR)) {
int c1 = getIntValue(Binary.getVal2(def));
if (c1 == c2) {
// x = a >> c1; y = x << c1
return Binary.create(LONG_AND, y.copyRO(), a.copyRO(), LC(-1L << c1));
}
} else if (def.operator() == LONG_AND) {
long c1 = getLongValue(Binary.getVal2(def));
// x = a & c1; y = << c2
if ((c1 << c2) == (-1L << c2)) {
// the first mask is redundant
return Binary.create(LONG_SHL, y.copyRO(), a.copyRO(), IC(c2));
}
} else if ((def.operator() == LONG_OR) || (def.operator() == LONG_XOR)) {
long c1 = getLongValue(Binary.getVal2(def));
// x = a | c1; y = << c2
if ((c1 << c2) == 0L) {
// the first mask is redundant
return Binary.create(LONG_SHL, y.copyRO(), a.copyRO(), IC(c2));
}
}
}
return null;
}
case INT_SHR_opcode:
{
if (FOLD_INTS && FOLD_SHIFTRS) {
int c2 = getIntValue(Binary.getVal2(s));
if (def.operator() == INT_SHR) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a >> c1; y = x >> c2
return Binary.create(INT_SHR, y.copyRO(), a.copyRO(), IC(c1 + c2));
} else if (def.operator() == INT_SHL) {
int c1 = getIntValue(Binary.getVal2(def));
if (c1 == c2) {
if (c1 == 24) {
// x = a << 24; y = x >> 24
return Unary.create(INT_2BYTE, y.copyRO(), a.copyRO());
} else if (c1 == 16) {
// x = a << 16; y = x >> 16
return Unary.create(INT_2SHORT, y.copyRO(), a.copyRO());
}
}
} else if (def.operator() == INT_AND) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a & c1; y = >> c2
if ((c1 >> c2) == -1) {
// the first mask is redundant
return Binary.create(INT_SHR, y.copyRO(), a.copyRO(), IC(c2));
}
} else if ((def.operator() == INT_OR) || (def.operator() == INT_XOR)) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a | c1; y = >> c2
if ((c1 >>> c2) == 0) {
// the first mask is redundant
return Binary.create(INT_SHR, y.copyRO(), a.copyRO(), IC(c2));
}
}
}
return null;
}
case REF_SHR_opcode:
{
if (FOLD_REFS && FOLD_SHIFTRS) {
int c2 = getIntValue(Binary.getVal2(s));
if (def.operator() == REF_SHR) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a >> c1; y = x >> c2
return Binary.create(REF_SHR, y.copyRO(), a.copyRO(), IC(c1 + c2));
} else if (def.operator() == REF_AND) {
Address c1 = getAddressValue(Binary.getVal2(def));
// x = a & c1; y = x >> c2
if (c1.toWord().rsha(c2).EQ(Word.zero().minus(Word.one()))) {
// the first mask is redundant
return Binary.create(REF_SHR, y.copyRO(), a.copyRO(), IC(c2));
}
} else if ((def.operator() == REF_OR) || (def.operator() == REF_XOR)) {
Address c1 = getAddressValue(Binary.getVal2(def));
// x = a | c1; y = x >> c2
if (c1.toWord().rshl(c2).EQ(Word.zero())) {
// the first mask is redundant
return Binary.create(REF_SHR, y.copyRO(), a.copyRO(), IC(c2));
}
}
}
return null;
}
case LONG_SHR_opcode:
{
if (FOLD_LONGS && FOLD_SHIFTRS) {
int c2 = getIntValue(Binary.getVal2(s));
if (def.operator() == LONG_SHR) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a >> c1; y = x >> c2
return Binary.create(LONG_SHR, y.copyRO(), a.copyRO(), IC(c1 + c2));
} else if (def.operator() == LONG_AND) {
long c1 = getLongValue(Binary.getVal2(def));
// x = a & c1; y = >> c2
if ((c1 >> c2) == -1L) {
// the first mask is redundant
return Binary.create(LONG_SHR, y.copyRO(), a.copyRO(), IC(c2));
}
} else if ((def.operator() == LONG_OR) || (def.operator() == LONG_XOR)) {
long c1 = getLongValue(Binary.getVal2(def));
// x = a & c1; y = >> c2
if ((c1 >>> c2) == 0L) {
// the first mask is redundant
return Binary.create(LONG_SHR, y.copyRO(), a.copyRO(), IC(c2));
}
}
}
return null;
}
case INT_USHR_opcode:
{
if (FOLD_INTS && FOLD_SHIFTRS) {
int c2 = getIntValue(Binary.getVal2(s));
if (def.operator() == INT_USHR) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a >>> c1; y = x >>> c2
return Binary.create(INT_USHR, y.copyRO(), a.copyRO(), IC(c1 + c2));
} else if (def.operator() == INT_SHL) {
int c1 = getIntValue(Binary.getVal2(def));
if (c1 == c2) {
// x = a << c1; y = x >>> c1
return Binary.create(INT_AND, y.copyRO(), a.copyRO(), IC(-1 >>> c1));
}
} else if (def.operator() == INT_AND) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a & c1; y = >>> c2
if ((c1 >> c2) == -1L) {
// the first mask is redundant
return Binary.create(INT_USHR, y.copyRO(), a.copyRO(), IC(c2));
}
} else if ((def.operator() == INT_OR) || (def.operator() == INT_XOR)) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a | c1; y = >>> c2
if ((c1 >>> c2) == 0) {
// the first mask is redundant
return Binary.create(INT_USHR, y.copyRO(), a.copyRO(), IC(c2));
}
}
}
return null;
}
case REF_USHR_opcode:
{
if (FOLD_REFS && FOLD_SHIFTRS) {
int c2 = getIntValue(Binary.getVal2(s));
if (def.operator() == REF_USHR) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a >>> c1; y = x >>> c2
return Binary.create(REF_USHR, y.copyRO(), a.copyRO(), IC(c1 + c2));
} else if (def.operator() == REF_SHL) {
int c1 = getIntValue(Binary.getVal2(def));
if (c1 == c2) {
// x = a << c1; y = x >>> c1
return Binary.create(REF_AND, y.copyRO(), a.copyRO(), AC(Word.zero().minus(Word.one()).rshl(c1).toAddress()));
}
} else if (def.operator() == REF_AND) {
// IAN!!!
Address c1 = getAddressValue(Binary.getVal2(def));
// x = a & c1; y = x >>> c2
if (c1.toWord().rsha(c2).EQ(Word.zero().minus(Word.one()))) {
// the first mask is redundant
return Binary.create(REF_USHR, y.copyRO(), a.copyRO(), IC(c2));
}
} else if (false) {
// (def.operator() == REF_OR) || (def.operator() == REF_XOR)) {
Address c1 = getAddressValue(Binary.getVal2(def));
// x = a | c1; y = x >>> c2
if (c1.toWord().rshl(c2).EQ(Word.zero())) {
// the first mask is redundant
return Binary.create(REF_USHR, y.copyRO(), a.copyRO(), IC(c2));
}
}
}
return null;
}
case LONG_USHR_opcode:
{
if (FOLD_LONGS && FOLD_SHIFTRS) {
int c2 = getIntValue(Binary.getVal2(s));
if (def.operator() == LONG_USHR) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a >>> c1; y = x >>> c2
return Binary.create(LONG_USHR, y.copyRO(), a.copyRO(), IC(c1 + c2));
} else if (def.operator() == LONG_SHL) {
int c1 = getIntValue(Binary.getVal2(def));
if (c1 == c2) {
// x = a << c1; y = x >>> c1
return Binary.create(LONG_AND, y.copyRO(), a.copyRO(), LC(-1L >>> c1));
}
} else if (def.operator() == LONG_AND) {
long c1 = getLongValue(Binary.getVal2(def));
// x = a & c1; y = >>> c2
if ((c1 >> c2) == -1L) {
// the first mask is redundant
return Binary.create(LONG_USHR, y.copyRO(), a.copyRO(), IC(c2));
}
} else if ((def.operator() == LONG_OR) || (def.operator() == LONG_XOR)) {
long c1 = getLongValue(Binary.getVal2(def));
// x = a & c1; y = >>> c2
if ((c1 >>> c2) == 0L) {
// the first mask is redundant
return Binary.create(LONG_USHR, y.copyRO(), a.copyRO(), IC(c2));
}
}
}
return null;
}
case INT_AND_opcode:
{
if (FOLD_INTS && FOLD_ANDS) {
int c2 = getIntValue(Binary.getVal2(s));
if (def.operator() == INT_AND) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a & c1; y = x & c2
return Binary.create(INT_AND, y.copyRO(), a.copyRO(), IC(c1 & c2));
} else if (def.operator() == INT_OR) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a | c1; y = x & c2
if ((c1 & c2) == 0) {
return Binary.create(INT_AND, y.copyRO(), a.copyRO(), IC(c2));
}
} else if (def.operator() == INT_XOR) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a ^ c1; y = x & c2
if ((c1 & c2) == 0) {
return Binary.create(INT_AND, y.copyRO(), a.copyRO(), IC(c2));
}
} else if (def.operator() == INT_SHR) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a >> c1; y = x & c2
if ((-1 >>> c1) == c2) {
// turn arithmetic shifts into logical shifts if possible
return Binary.create(INT_USHR, y.copyRO(), a.copyRO(), IC(c1));
}
} else if (def.operator() == INT_SHL) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a << c1; y = x & c2
if (((-1 << c1) & c2) == (-1 << c1)) {
// does the mask zero bits already cleared by the shift?
return Binary.create(INT_SHL, y.copyRO(), a.copyRO(), IC(c1));
}
} else if (def.operator() == INT_USHR) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a >>> c1; y = x & c2
if (((-1 >>> c1) & c2) == (-1 >>> c1)) {
// does the mask zero bits already cleared by the shift?
return Binary.create(INT_USHR, y.copyRO(), a.copyRO(), IC(c1));
}
}
}
return null;
}
case REF_AND_opcode:
{
if (FOLD_REFS && FOLD_ANDS) {
Address c2 = getAddressValue(Binary.getVal2(s));
if (def.operator() == REF_AND) {
Address c1 = getAddressValue(Binary.getVal2(def));
// x = a & c1; y = x & c2
return Binary.create(REF_AND, y.copyRO(), a.copyRO(), AC(c1.toWord().and(c2.toWord()).toAddress()));
} else if (def.operator() == REF_OR) {
Address c1 = getAddressValue(Binary.getVal2(def));
// x = a | c1; y = x & c2
if (c1.toWord().and(c2.toWord()).EQ(Word.zero())) {
return Binary.create(REF_AND, y.copyRO(), a.copyRO(), AC(c2));
}
} else if (def.operator() == REF_XOR) {
Address c1 = getAddressValue(Binary.getVal2(def));
// x = a ^ c1; y = x & c2
if (c1.toWord().and(c2.toWord()).EQ(Word.zero())) {
return Binary.create(REF_AND, y.copyRO(), a.copyRO(), AC(c2));
}
} else if (def.operator() == REF_SHR) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a >> c1; y = x & c2
if (Word.zero().minus(Word.one()).rshl(c1).toAddress().EQ(c2)) {
// turn arithmetic shifts into logical ones if possible
return Binary.create(REF_USHR, y.copyRO(), a.copyRO(), IC(c1));
}
} else if (def.operator() == REF_SHL) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a << c1; y = x & c2
if (Word.zero().minus(Word.one()).lsh(c1).and(c2.toWord()).EQ(Word.zero().minus(Word.one()).lsh(c1))) {
// does the mask zero bits already cleared by the shift?
return Binary.create(REF_SHL, y.copyRO(), a.copyRO(), IC(c1));
}
} else if (def.operator() == REF_USHR) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a >>> c1; y = x & c2
if (Word.zero().minus(Word.one()).rshl(c1).and(c2.toWord()).EQ(Word.zero().minus(Word.one()).rshl(c1))) {
// does the mask zero bits already cleared by the shift?
return Binary.create(REF_USHR, y.copyRO(), a.copyRO(), IC(c1));
}
}
}
return null;
}
case LONG_AND_opcode:
{
if (FOLD_LONGS && FOLD_ANDS) {
long c2 = getLongValue(Binary.getVal2(s));
if (def.operator() == LONG_AND) {
long c1 = getLongValue(Binary.getVal2(def));
// x = a & c1; y = x & c2
return Binary.create(LONG_AND, y.copyRO(), a.copyRO(), LC(c1 & c2));
} else if (def.operator() == LONG_OR) {
long c1 = getLongValue(Binary.getVal2(def));
// x = a | c1; y = x & c2
if ((c1 & c2) == 0) {
return Binary.create(LONG_AND, y.copyRO(), a.copyRO(), LC(c2));
}
} else if (def.operator() == LONG_XOR) {
long c1 = getLongValue(Binary.getVal2(def));
// x = a ^ c1; y = x & c2
if ((c1 & c2) == 0) {
return Binary.create(LONG_AND, y.copyRO(), a.copyRO(), LC(c2));
}
} else if (def.operator() == LONG_SHR) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a >> c1; y = x & c2
if ((-1L >>> c1) == c2) {
// turn arithmetic shifts into logical ones if possible
return Binary.create(LONG_USHR, y.copyRO(), a.copyRO(), IC(c1));
}
} else if (def.operator() == LONG_SHL) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a << c1; y = x & c2
if (((-1L << c1) & c2) == (-1L << c1)) {
// does the mask zero bits already cleared by the shift?
return Binary.create(LONG_SHL, y.copyRO(), a.copyRO(), IC(c1));
}
} else if (def.operator() == LONG_USHR) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a >>> c1; y = x & c2
if (((-1L >>> c1) & c2) == (-1L >>> c1)) {
// does the mask zero bits already cleared by the shift?
return Binary.create(LONG_USHR, y.copyRO(), a.copyRO(), IC(c1));
}
}
}
return null;
}
case INT_OR_opcode:
{
if (FOLD_INTS && FOLD_ORS) {
int c2 = getIntValue(Binary.getVal2(s));
if (def.operator() == INT_OR) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a | c1; y = x | c2
return Binary.create(INT_OR, y.copyRO(), a.copyRO(), IC(c1 | c2));
} else if (def.operator() == INT_AND) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a & c1; y = x | c2
if ((~c1 | c2) == c2) {
return Binary.create(INT_OR, y.copyRO(), a.copyRO(), IC(c2));
}
} else if (def.operator() == INT_XOR) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a ^ c1; y = x | c2
if ((c1 | c2) == c2) {
return Binary.create(INT_OR, y.copyRO(), a.copyRO(), IC(c2));
}
}
}
return null;
}
case REF_OR_opcode:
{
if (FOLD_REFS && FOLD_ORS) {
Address c2 = getAddressValue(Binary.getVal2(s));
if (def.operator() == REF_OR) {
Address c1 = getAddressValue(Binary.getVal2(def));
// x = a | c1; y = x | c2
return Binary.create(REF_OR, y.copyRO(), a.copyRO(), AC(c1.toWord().or(c2.toWord()).toAddress()));
} else if (def.operator() == REF_AND) {
Address c1 = getAddressValue(Binary.getVal2(def));
// x = a & c1; y = x | c2
if (c1.toWord().not().or(c2.toWord()).EQ(c2.toWord())) {
return Binary.create(REF_OR, y.copyRO(), a.copyRO(), AC(c2));
}
} else if (def.operator() == REF_XOR) {
Address c1 = getAddressValue(Binary.getVal2(def));
// x = a ^ c1; y = x | c2
if (c1.toWord().or(c2.toWord()).EQ(c2.toWord())) {
return Binary.create(REF_OR, y.copyRO(), a.copyRO(), AC(c2));
}
}
}
return null;
}
case LONG_OR_opcode:
{
if (FOLD_LONGS && FOLD_ORS) {
long c2 = getLongValue(Binary.getVal2(s));
if (def.operator() == LONG_OR) {
long c1 = getLongValue(Binary.getVal2(def));
// x = a | c1; y = x | c2
return Binary.create(LONG_OR, y.copyRO(), a.copyRO(), LC(c1 | c2));
} else if (def.operator() == LONG_AND) {
long c1 = getLongValue(Binary.getVal2(def));
// x = a & c1; y = x | c2
if ((~c1 | c2) == c2) {
return Binary.create(LONG_OR, y.copyRO(), a.copyRO(), LC(c2));
}
} else if (def.operator() == LONG_XOR) {
long c1 = getLongValue(Binary.getVal2(def));
// x = a ^ c1; y = x | c2
if ((c1 | c2) == c2) {
return Binary.create(LONG_OR, y.copyRO(), a.copyRO(), LC(c2));
}
}
}
return null;
}
case INT_XOR_opcode:
{
if (FOLD_INTS && FOLD_XORS) {
int c2 = getIntValue(Binary.getVal2(s));
if (def.operator() == INT_XOR) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a ^ c1; y = x ^ c2
return Binary.create(INT_XOR, y.copyRO(), a.copyRO(), IC(c1 ^ c2));
} else if (def.operator() == INT_NOT) {
// x = ~a; y = x ^ c2
return Binary.create(INT_XOR, y.copyRO(), a.copyRO(), IC(~c2));
} else if (def.operator() == BOOLEAN_NOT) {
// x = !a; y = x ^ c2
return Binary.create(INT_XOR, y.copyRO(), a.copyRO(), IC(c2 ^ 1));
}
}
return null;
}
case REF_XOR_opcode:
{
if (FOLD_REFS && FOLD_XORS) {
Address c2 = getAddressValue(Binary.getVal2(s));
if (def.operator() == REF_XOR) {
Address c1 = getAddressValue(Binary.getVal2(def));
// x = a ^ c1; y = x ^ c2
return Binary.create(REF_XOR, y.copyRO(), a.copyRO(), AC(c1.toWord().xor(c2.toWord()).toAddress()));
} else if (def.operator() == REF_NOT) {
// x = ~a; y = x ^ c2
return Binary.create(REF_XOR, y.copyRO(), a.copyRO(), AC(c2.toWord().not().toAddress()));
}
}
return null;
}
case LONG_XOR_opcode:
{
if (FOLD_LONGS && FOLD_XORS) {
long c2 = getLongValue(Binary.getVal2(s));
if (def.operator() == LONG_XOR) {
long c1 = getLongValue(Binary.getVal2(def));
// x = a ^ c1; y = x ^ c2
return Binary.create(LONG_XOR, y.copyRO(), a.copyRO(), LC(c1 ^ c2));
} else if (def.operator() == LONG_NOT) {
// x = ~a; y = x ^ c2
return Binary.create(LONG_XOR, y.copyRO(), a.copyRO(), LC(~c2));
}
}
return null;
}
case LONG_CMP_opcode:
{
if (FOLD_LONGS && FOLD_CMPS) {
long c2 = getLongValue(Binary.getVal2(s));
if (def.operator() == LONG_NEG) {
// x = -a; y = x cmp c2
return Binary.create(LONG_CMP, y.copyRO(), LC(-c2), a.copyRO());
}
}
return null;
}
case FLOAT_CMPL_opcode:
case FLOAT_CMPG_opcode:
{
if (FOLD_FLOATS && FOLD_CMPS) {
float c2 = getFloatValue(Binary.getVal2(s));
if (def.operator() == FLOAT_ADD) {
float c1 = getFloatValue(Binary.getVal2(def));
// x = a + c1; y = x cmp c2
return Binary.create(s.operator(), y.copyRO(), a.copyRO(), FC(c2 - c1));
} else if (def.operator() == FLOAT_SUB) {
float c1 = getFloatValue(Binary.getVal2(def));
// x = a - c1; y = x cmp c2
return Binary.create(s.operator(), y.copyRO(), a.copyRO(), FC(c1 + c2));
} else if (def.operator() == FLOAT_NEG) {
// x = -a; y = x cmp c2
return Binary.create(s.operator(), y.copyRO(), FC(-c2), a.copyRO());
}
}
return null;
}
case DOUBLE_CMPL_opcode:
case DOUBLE_CMPG_opcode:
{
if (FOLD_DOUBLES && FOLD_CMPS) {
double c2 = getDoubleValue(Binary.getVal2(s));
if (def.operator() == DOUBLE_ADD) {
double c1 = getDoubleValue(Binary.getVal2(def));
// x = a + c1; y = x cmp c2
return Binary.create(s.operator(), y.copyRO(), a.copyRO(), DC(c2 - c1));
} else if (def.operator() == DOUBLE_SUB) {
double c1 = getDoubleValue(Binary.getVal2(def));
// x = a - c1; y = x cmp c2
return Binary.create(s.operator(), y.copyRO(), a.copyRO(), DC(c1 + c2));
} else if (def.operator() == DOUBLE_NEG) {
// x = -a; y = x cmp c2
return Binary.create(s.operator(), y.copyRO(), DC(-c2), a.copyRO());
}
}
return null;
}
case BOOLEAN_CMP_INT_opcode:
{
if (FOLD_INTS && FOLD_CMPS) {
int c2 = getIntValue(BooleanCmp.getVal2(s));
ConditionOperand cond = (ConditionOperand) BooleanCmp.getCond(s).copy();
BranchProfileOperand prof = (BranchProfileOperand) BooleanCmp.getBranchProfile(s).copy();
if (cond.isEQUAL() || cond.isNOT_EQUAL()) {
if (def.operator() == INT_ADD) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a + c1; y = x cmp c2
return BooleanCmp.create(BOOLEAN_CMP_INT, y.copyRO(), a.copyRO(), IC(c2 - c1), cond, prof);
} else if (def.operator() == INT_SUB) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a - c1; y = x cmp c2
return BooleanCmp.create(BOOLEAN_CMP_INT, y.copyRO(), a.copyRO(), IC(c1 + c2), cond, prof);
} else if (def.operator() == INT_NEG) {
// x = -a; y = x cmp c2
return BooleanCmp.create(BOOLEAN_CMP_INT, y.copyRO(), a.copyRO(), IC(-c2), cond.flipOperands(), prof);
} else if (def.operator() == BOOLEAN_CMP_INT) {
int c1 = getIntValue(BooleanCmp.getVal2(def));
ConditionOperand cond2 = BooleanCmp.getCond(def).copy().asCondition();
// x = a cmp c1 ? true : false; y = x cmp c2 ? true : false
if ((cond.isEQUAL() && c2 == 1) || (cond.isNOT_EQUAL() && c2 == 0)) {
// Fold away redundancy boolean_cmp
return BooleanCmp.create(BOOLEAN_CMP_INT, y.copyRO(), a.copyRO(), IC(c1), cond2, prof);
} else if ((cond.isEQUAL() && c2 == 0) || (cond.isNOT_EQUAL() && c2 == 1)) {
// Fold away redundancy boolean_cmp
return BooleanCmp.create(BOOLEAN_CMP_INT, y.copyRO(), a.copyRO(), IC(c1), cond2.flipCode(), prof);
}
} else if (def.operator() == BOOLEAN_CMP_LONG) {
long c1 = getLongValue(BooleanCmp.getVal2(def));
ConditionOperand cond2 = BooleanCmp.getCond(def).copy().asCondition();
// x = a cmp c1 ? true : false; y = x cmp c2 ? true : false
if ((cond.isEQUAL() && c2 == 1) || (cond.isNOT_EQUAL() && c2 == 0)) {
// Fold away redundancy boolean_cmp
return BooleanCmp.create(BOOLEAN_CMP_LONG, y.copyRO(), a.copyRO(), LC(c1), cond2, prof);
} else if ((cond.isEQUAL() && c2 == 0) || (cond.isNOT_EQUAL() && c2 == 1)) {
// Fold away redundancy boolean_cmp
return BooleanCmp.create(BOOLEAN_CMP_LONG, y.copyRO(), a.copyRO(), LC(c1), cond2.flipCode(), prof);
}
} else if (def.operator() == BOOLEAN_CMP_ADDR) {
Address c1 = getAddressValue(BooleanCmp.getVal2(def));
ConditionOperand cond2 = BooleanCmp.getCond(def).copy().asCondition();
// x = a cmp c1 ? true : false; y = x cmp c2 ? true : false
if ((cond.isEQUAL() && c2 == 1) || (cond.isNOT_EQUAL() && c2 == 0)) {
// Fold away redundancy boolean_cmp
return BooleanCmp.create(BOOLEAN_CMP_ADDR, y.copyRO(), a.copyRO(), AC(c1), cond2, prof);
} else if ((cond.isEQUAL() && c2 == 0) || (cond.isNOT_EQUAL() && c2 == 1)) {
// Fold away redundancy boolean_cmp
return BooleanCmp.create(BOOLEAN_CMP_ADDR, y.copyRO(), a.copyRO(), AC(c1), cond2.flipCode(), prof);
}
} else if (def.operator() == BOOLEAN_CMP_FLOAT) {
float c1 = getFloatValue(BooleanCmp.getVal2(def));
ConditionOperand cond2 = BooleanCmp.getCond(def).copy().asCondition();
// x = a cmp c1 ? true : false; y = x cmp c2 ? true : false
if ((cond.isEQUAL() && c2 == 1) || (cond.isNOT_EQUAL() && c2 == 0)) {
// Fold away redundancy boolean_cmp
return BooleanCmp.create(BOOLEAN_CMP_FLOAT, y.copyRO(), a.copyRO(), FC(c1), cond2, prof);
} else if ((cond.isEQUAL() && c2 == 0) || (cond.isNOT_EQUAL() && c2 == 1)) {
// Fold away redundancy boolean_cmp
return BooleanCmp.create(BOOLEAN_CMP_FLOAT, y.copyRO(), a.copyRO(), FC(c1), cond2.flipCode(), prof);
}
} else if (def.operator() == BOOLEAN_CMP_DOUBLE) {
double c1 = getDoubleValue(BooleanCmp.getVal2(def));
ConditionOperand cond2 = BooleanCmp.getCond(def).copy().asCondition();
// x = a cmp c1 ? true : false; y = x cmp c2 ? true : false
if ((cond.isEQUAL() && c2 == 1) || (cond.isNOT_EQUAL() && c2 == 0)) {
// Fold away redundancy boolean_cmp
return BooleanCmp.create(BOOLEAN_CMP_DOUBLE, y.copyRO(), a.copyRO(), DC(c1), cond2, prof);
} else if ((cond.isEQUAL() && c2 == 0) || (cond.isNOT_EQUAL() && c2 == 1)) {
// Fold away redundancy boolean_cmp
return BooleanCmp.create(BOOLEAN_CMP_DOUBLE, y.copyRO(), a.copyRO(), DC(c1), cond2.flipCode(), prof);
}
} else if (def.operator() == LONG_CMP) {
long c1 = getLongValue(Binary.getVal2(def));
// x = a lcmp c1; y = y = x cmp c2 ? true : false
if (cond.isEQUAL() && c2 == 0) {
return BooleanCmp.create(BOOLEAN_CMP_LONG, y.copyRO(), a.copyRO(), LC(c1), ConditionOperand.EQUAL(), prof);
} else if (cond.isNOT_EQUAL() && c2 == 0) {
return BooleanCmp.create(BOOLEAN_CMP_LONG, y.copyRO(), a.copyRO(), LC(c1), ConditionOperand.NOT_EQUAL(), prof);
} else if ((cond.isEQUAL() && c2 == 1) || (cond.isGREATER() && c2 == 0)) {
return BooleanCmp.create(BOOLEAN_CMP_LONG, y.copyRO(), a.copyRO(), LC(c1), ConditionOperand.GREATER(), prof);
} else if (cond.isGREATER_EQUAL() && c2 == 0) {
return BooleanCmp.create(BOOLEAN_CMP_LONG, y.copyRO(), a.copyRO(), LC(c1), ConditionOperand.GREATER_EQUAL(), prof);
} else if ((cond.isEQUAL() && c2 == -1) || (cond.isLESS() && c2 == 0)) {
return BooleanCmp.create(BOOLEAN_CMP_LONG, y.copyRO(), a.copyRO(), LC(c1), ConditionOperand.LESS(), prof);
} else if (cond.isLESS_EQUAL() && c2 == 0) {
return BooleanCmp.create(BOOLEAN_CMP_LONG, y.copyRO(), a.copyRO(), LC(c1), ConditionOperand.LESS_EQUAL(), prof);
}
}
}
}
return null;
}
case BOOLEAN_CMP_LONG_opcode:
{
if (FOLD_LONGS && FOLD_CMPS) {
long c2 = getLongValue(BooleanCmp.getVal2(s));
ConditionOperand cond = (ConditionOperand) BooleanCmp.getCond(s).copy();
BranchProfileOperand prof = (BranchProfileOperand) BooleanCmp.getBranchProfile(s).copy();
if (cond.isEQUAL() || cond.isNOT_EQUAL()) {
if (def.operator() == LONG_ADD) {
long c1 = getLongValue(Binary.getVal2(def));
// x = a + c1; y = x cmp c2
return BooleanCmp.create(BOOLEAN_CMP_LONG, y.copyRO(), a.copyRO(), LC(c2 - c1), cond, prof);
} else if (def.operator() == LONG_SUB) {
long c1 = getLongValue(Binary.getVal2(def));
// x = a - c1; y = x cmp c2
return BooleanCmp.create(BOOLEAN_CMP_LONG, y.copyRO(), a.copyRO(), LC(c1 + c2), cond, prof);
} else if (def.operator() == LONG_NEG) {
// x = -a; y = x cmp c2
return BooleanCmp.create(BOOLEAN_CMP_INT, y.copyRO(), a.copyRO(), LC(-c2), cond.flipOperands(), prof);
}
}
}
return null;
}
case BOOLEAN_CMP_ADDR_opcode:
{
if (FOLD_REFS && FOLD_CMPS) {
Address c2 = getAddressValue(BooleanCmp.getVal2(s));
ConditionOperand cond = (ConditionOperand) BooleanCmp.getCond(s).copy();
BranchProfileOperand prof = (BranchProfileOperand) BooleanCmp.getBranchProfile(s).copy();
if (cond.isEQUAL() || cond.isNOT_EQUAL()) {
if (def.operator() == REF_ADD) {
Address c1 = getAddressValue(Binary.getVal2(def));
// x = a + c1; y = x cmp c2
return BooleanCmp.create(BOOLEAN_CMP_ADDR, y.copyRO(), a.copyRO(), AC(c2.toWord().minus(c1.toWord()).toAddress()), cond, prof);
} else if (def.operator() == REF_SUB) {
Address c1 = getAddressValue(Binary.getVal2(def));
// x = a - c1; y = x cmp c2
return BooleanCmp.create(BOOLEAN_CMP_ADDR, y.copyRO(), a.copyRO(), AC(c1.toWord().plus(c2.toWord()).toAddress()), cond, prof);
} else if (def.operator() == REF_NEG) {
// x = -a; y = x cmp c2
return BooleanCmp.create(BOOLEAN_CMP_ADDR, y.copyRO(), a.copyRO(), AC(Word.zero().minus(c2.toWord()).toAddress()), cond.flipOperands(), prof);
}
}
}
return null;
}
case INT_IFCMP_opcode:
{
if (FOLD_INTS && FOLD_IFCMPS) {
int c2 = getIntValue(IfCmp.getVal2(s));
ConditionOperand cond = (ConditionOperand) IfCmp.getCond(s).copy();
BranchOperand target = (BranchOperand) IfCmp.getTarget(s).copy();
BranchProfileOperand prof = (BranchProfileOperand) IfCmp.getBranchProfile(s).copy();
if (cond.isEQUAL() || cond.isNOT_EQUAL()) {
if (def.operator() == INT_ADD) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a + c1; y = x cmp c2
return IfCmp.create(INT_IFCMP, y.copyRO(), a.copyRO(), IC(c2 - c1), cond, target, prof);
} else if (def.operator() == INT_SUB) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a - c1; y = x cmp c2
return IfCmp.create(INT_IFCMP, y.copyRO(), a.copyRO(), IC(c1 + c2), cond, target, prof);
} else if (def.operator() == INT_NEG) {
// x = -a; y = x cmp c2
return IfCmp.create(INT_IFCMP, y.copyRO(), a.copyRO(), IC(-c2), cond.flipOperands(), target, prof);
} else if (def.operator() == BOOLEAN_CMP_INT) {
int c1 = getIntValue(BooleanCmp.getVal2(def));
ConditionOperand cond2 = BooleanCmp.getCond(def).copy().asCondition();
// x = a cmp<cond2> c1 ? true : false; y = x cmp<cond> c2
if ((cond.isEQUAL() && c2 == 1) || (cond.isNOT_EQUAL() && c2 == 0)) {
// x = a cmp<cond2> c1; y = x == 1 ==> y = a cmp<cond2> c1
return IfCmp.create(INT_IFCMP, y.copyRO(), a.copyRO(), IC(c1), cond2, target, prof);
} else if ((cond.isEQUAL() && c2 == 0) || (cond.isNOT_EQUAL() && c2 == 1)) {
// x = a cmp<cond2> c1; y = x == 0 ==> y = a cmp<!cond2> c1
return IfCmp.create(INT_IFCMP, y.copyRO(), a.copyRO(), IC(c1), cond2.flipCode(), target, prof);
}
} else if (def.operator() == BOOLEAN_CMP_LONG) {
long c1 = getLongValue(BooleanCmp.getVal2(def));
ConditionOperand cond2 = BooleanCmp.getCond(def).copy().asCondition();
// x = a cmp c1 ? true : false; y = x cmp c2
if ((cond.isEQUAL() && c2 == 1) || (cond.isNOT_EQUAL() && c2 == 0)) {
// Fold away redundant boolean_cmp
return IfCmp.create(LONG_IFCMP, y.copyRO(), a.copyRO(), LC(c1), cond2, target, prof);
} else if ((cond.isEQUAL() && c2 == 0) || (cond.isNOT_EQUAL() && c2 == 1)) {
// Fold away redundant boolean_cmp
return IfCmp.create(LONG_IFCMP, y.copyRO(), a.copyRO(), LC(c1), cond2.flipCode(), target, prof);
}
} else if (def.operator() == BOOLEAN_CMP_ADDR) {
Address c1 = getAddressValue(BooleanCmp.getVal2(def));
ConditionOperand cond2 = BooleanCmp.getCond(def).copy().asCondition();
// x = a cmp c1 ? true : false; y = x cmp c2
if ((cond.isEQUAL() && c2 == 1) || (cond.isNOT_EQUAL() && c2 == 0)) {
// Fold away redundant boolean_cmp
return IfCmp.create(REF_IFCMP, y.copyRO(), a.copyRO(), AC(c1), cond2, target, prof);
} else if ((cond.isEQUAL() && c2 == 0) || (cond.isNOT_EQUAL() && c2 == 1)) {
// Fold away redundant boolean_cmp
return IfCmp.create(REF_IFCMP, y.copyRO(), a.copyRO(), AC(c1), cond2.flipCode(), target, prof);
}
} else if (def.operator() == BOOLEAN_CMP_FLOAT) {
float c1 = getFloatValue(BooleanCmp.getVal2(def));
ConditionOperand cond2 = BooleanCmp.getCond(def).copy().asCondition();
// x = a cmp c1 ? true : false; y = x cmp c2
if ((cond.isEQUAL() && c2 == 1) || (cond.isNOT_EQUAL() && c2 == 0)) {
// Fold away redundant boolean_cmp
return IfCmp.create(FLOAT_IFCMP, y.copyRO(), a.copyRO(), FC(c1), cond2, target, prof);
} else if ((cond.isEQUAL() && c2 == 0) || (cond.isNOT_EQUAL() && c2 == 1)) {
// Fold away redundant boolean_cmp
return IfCmp.create(FLOAT_IFCMP, y.copyRO(), a.copyRO(), FC(c1), cond2.flipCode(), target, prof);
}
} else if (def.operator() == BOOLEAN_CMP_DOUBLE) {
double c1 = getDoubleValue(BooleanCmp.getVal2(def));
ConditionOperand cond2 = BooleanCmp.getCond(def).copy().asCondition();
// x = a cmp c1 ? true : false; y = x cmp c2
if ((cond.isEQUAL() && c2 == 1) || (cond.isNOT_EQUAL() && c2 == 0)) {
// Fold away redundant boolean_cmp
return IfCmp.create(DOUBLE_IFCMP, y.copyRO(), a.copyRO(), DC(c1), cond2, target, prof);
} else if ((cond.isEQUAL() && c2 == 0) || (cond.isNOT_EQUAL() && c2 == 1)) {
// Fold away redundant boolean_cmp
return IfCmp.create(DOUBLE_IFCMP, y.copyRO(), a.copyRO(), DC(c1), cond2.flipCode(), target, prof);
}
} else if (def.operator() == LONG_CMP) {
long c1 = getLongValue(Binary.getVal2(def));
// x = a lcmp c1; y = y = x cmp c2
if (cond.isEQUAL() && c2 == 0) {
return IfCmp.create(LONG_IFCMP, y.copyRO(), a.copyRO(), LC(c1), ConditionOperand.EQUAL(), target, prof);
} else if (cond.isNOT_EQUAL() && c2 == 0) {
return IfCmp.create(LONG_IFCMP, y.copyRO(), a.copyRO(), LC(c1), ConditionOperand.NOT_EQUAL(), target, prof);
} else if ((cond.isEQUAL() && c2 == 1) || (cond.isGREATER() && c2 == 0)) {
return IfCmp.create(LONG_IFCMP, y.copyRO(), a.copyRO(), LC(c1), ConditionOperand.GREATER(), target, prof);
} else if (cond.isGREATER_EQUAL() && c2 == 0) {
return IfCmp.create(LONG_IFCMP, y.copyRO(), a.copyRO(), LC(c1), ConditionOperand.GREATER_EQUAL(), target, prof);
} else if ((cond.isEQUAL() && c2 == -1) || (cond.isLESS() && c2 == 0)) {
return IfCmp.create(LONG_IFCMP, y.copyRO(), a.copyRO(), LC(c1), ConditionOperand.LESS(), target, prof);
} else if (cond.isLESS_EQUAL() && c2 == 0) {
return IfCmp.create(LONG_IFCMP, y.copyRO(), a.copyRO(), LC(c1), ConditionOperand.LESS_EQUAL(), target, prof);
}
}
}
}
return null;
}
case LONG_IFCMP_opcode:
{
if (FOLD_LONGS && FOLD_IFCMPS) {
long c2 = getLongValue(IfCmp.getVal2(s));
ConditionOperand cond = (ConditionOperand) IfCmp.getCond(s).copy();
BranchOperand target = (BranchOperand) IfCmp.getTarget(s).copy();
BranchProfileOperand prof = (BranchProfileOperand) IfCmp.getBranchProfile(s).copy();
if (cond.isEQUAL() || cond.isNOT_EQUAL()) {
if (def.operator() == LONG_ADD) {
long c1 = getLongValue(Binary.getVal2(def));
// x = a + c1; y = x cmp c2
return IfCmp.create(LONG_IFCMP, y.copyRO(), a.copyRO(), LC(c2 - c1), cond, target, prof);
} else if (def.operator() == LONG_SUB) {
long c1 = getLongValue(Binary.getVal2(def));
// x = a - c1; y = x cmp c2
return IfCmp.create(LONG_IFCMP, y.copyRO(), a.copyRO(), LC(c1 + c2), cond, target, prof);
} else if (def.operator() == LONG_NEG) {
// x = -a; y = x cmp c2
return IfCmp.create(LONG_IFCMP, y.copyRO(), a.copyRO(), LC(-c2), cond.flipOperands(), target, prof);
}
}
}
return null;
}
case FLOAT_IFCMP_opcode:
{
if (FOLD_FLOATS && FOLD_IFCMPS) {
float c2 = getFloatValue(IfCmp.getVal2(s));
ConditionOperand cond = (ConditionOperand) IfCmp.getCond(s).copy();
BranchOperand target = (BranchOperand) IfCmp.getTarget(s).copy();
BranchProfileOperand prof = (BranchProfileOperand) IfCmp.getBranchProfile(s).copy();
if (def.operator() == FLOAT_ADD) {
float c1 = getFloatValue(Binary.getVal2(def));
// x = a + c1; y = x cmp c2
return IfCmp.create(FLOAT_IFCMP, y.copyRO(), a.copyRO(), FC(c2 - c1), cond, target, prof);
} else if (def.operator() == FLOAT_SUB) {
float c1 = getFloatValue(Binary.getVal2(def));
// x = a - c1; y = x cmp c2
return IfCmp.create(FLOAT_IFCMP, y.copyRO(), a.copyRO(), FC(c1 + c2), cond, target, prof);
} else if (def.operator() == FLOAT_NEG) {
// x = -a; y = x cmp c2
return IfCmp.create(FLOAT_IFCMP, y.copyRO(), a.copyRO(), FC(-c2), cond.flipOperands(), target, prof);
}
}
return null;
}
case DOUBLE_IFCMP_opcode:
{
if (FOLD_DOUBLES && FOLD_IFCMPS) {
double c2 = getDoubleValue(IfCmp.getVal2(s));
ConditionOperand cond = (ConditionOperand) IfCmp.getCond(s).copy();
BranchOperand target = (BranchOperand) IfCmp.getTarget(s).copy();
BranchProfileOperand prof = (BranchProfileOperand) IfCmp.getBranchProfile(s).copy();
if (def.operator() == DOUBLE_ADD) {
double c1 = getDoubleValue(Binary.getVal2(def));
// x = a + c1; y = x cmp c2
return IfCmp.create(DOUBLE_IFCMP, y.copyRO(), a.copyRO(), DC(c2 - c1), cond, target, prof);
} else if (def.operator() == DOUBLE_SUB) {
double c1 = getDoubleValue(Binary.getVal2(def));
// x = a - c1; y = x cmp c2
return IfCmp.create(DOUBLE_IFCMP, y.copyRO(), a.copyRO(), DC(c1 + c2), cond, target, prof);
} else if (def.operator() == DOUBLE_NEG) {
// x = -a; y = x cmp c2
return IfCmp.create(DOUBLE_IFCMP, y.copyRO(), a.copyRO(), DC(-c2), cond.flipOperands(), target, prof);
}
}
return null;
}
case REF_IFCMP_opcode:
{
if (FOLD_REFS && FOLD_IFCMPS) {
Address c2 = getAddressValue(IfCmp.getVal2(s));
ConditionOperand cond = (ConditionOperand) IfCmp.getCond(s).copy();
BranchOperand target = (BranchOperand) IfCmp.getTarget(s).copy();
BranchProfileOperand prof = (BranchProfileOperand) IfCmp.getBranchProfile(s).copy();
if (cond.isEQUAL() || cond.isNOT_EQUAL()) {
if ((def.operator() == NEW || def.operator() == NEWARRAY) && c2.EQ(Address.zero())) {
// x = new ... ; y = x cmp null
return IfCmp.create(REF_IFCMP, y.copyRO(), AC(Address.zero()), AC(Address.zero()), cond.flipCode(), target, prof);
} else if (def.operator() == REF_ADD) {
Address c1 = getAddressValue(Binary.getVal2(def));
// x = a + c1; y = x cmp c2
return IfCmp.create(REF_IFCMP, y.copyRO(), a.copyRO(), AC(c2.toWord().minus(c1.toWord()).toAddress()), cond, target, prof);
} else if (def.operator() == REF_SUB) {
Address c1 = getAddressValue(Binary.getVal2(def));
// x = a - c1; y = x cmp c2
return IfCmp.create(REF_IFCMP, y.copyRO(), a.copyRO(), AC(c1.toWord().plus(c2.toWord()).toAddress()), cond, target, prof);
} else if (def.operator() == REF_NEG) {
// x = -a; y = x cmp c2
return IfCmp.create(REF_IFCMP, y.copyRO(), a.copyRO(), AC(Word.zero().minus(c2.toWord()).toAddress()), cond.flipOperands(), target, prof);
}
}
}
return null;
}
case INT_IFCMP2_opcode:
{
if (FOLD_INTS && FOLD_IFCMPS) {
int c2 = getIntValue(IfCmp2.getVal2(s));
ConditionOperand cond1 = (ConditionOperand) IfCmp2.getCond1(s).copy();
ConditionOperand cond2 = (ConditionOperand) IfCmp2.getCond2(s).copy();
BranchOperand target1 = (BranchOperand) IfCmp2.getTarget1(s).copy();
BranchOperand target2 = (BranchOperand) IfCmp2.getTarget2(s).copy();
BranchProfileOperand prof1 = (BranchProfileOperand) IfCmp2.getBranchProfile1(s).copy();
BranchProfileOperand prof2 = (BranchProfileOperand) IfCmp2.getBranchProfile2(s).copy();
if ((cond1.isEQUAL() || cond1.isNOT_EQUAL()) && (cond2.isEQUAL() || cond2.isNOT_EQUAL())) {
if (def.operator() == INT_ADD) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a + c1; y = x cmp c2
return IfCmp2.create(INT_IFCMP2, y.copyRO(), a.copyRO(), IC(c2 - c1), cond1, target1, prof1, cond2, target2, prof2);
} else if (def.operator() == INT_SUB) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a - c1; y = x cmp c2
return IfCmp2.create(INT_IFCMP2, y.copyRO(), a.copyRO(), IC(c1 + c2), cond1, target1, prof1, cond2, target2, prof2);
} else if (def.operator() == INT_NEG) {
// x = -a; y = x cmp c2
return IfCmp2.create(INT_IFCMP2, y.copyRO(), a.copyRO(), IC(-c2), cond1.flipOperands(), target1, prof1, cond2.flipOperands(), target2, prof2);
}
}
}
return null;
}
case INT_COND_MOVE_opcode:
case LONG_COND_MOVE_opcode:
case REF_COND_MOVE_opcode:
case FLOAT_COND_MOVE_opcode:
case DOUBLE_COND_MOVE_opcode:
case GUARD_COND_MOVE_opcode:
{
if (FOLD_INTS && FOLD_CONDMOVES) {
Operand trueValue = CondMove.getTrueValue(s);
Operand falseValue = CondMove.getFalseValue(s);
ConditionOperand cond = (ConditionOperand) CondMove.getCond(s).copy();
boolean isEqualityTest = cond.isEQUAL() || cond.isNOT_EQUAL();
switch(def.getOpcode()) {
case INT_ADD_opcode:
if (isEqualityTest) {
int c1 = getIntValue(Binary.getVal2(def));
int c2 = getIntValue(CondMove.getVal2(s));
// x = a + c1; y = x cmp c2 ? trueValue : falseValue
return CondMove.create(s.operator(), y.copyRO(), a.copyRO(), IC(c2 - c1), cond, trueValue, falseValue);
}
break;
case LONG_ADD_opcode:
if (isEqualityTest) {
long c1 = getLongValue(Binary.getVal2(def));
long c2 = getLongValue(CondMove.getVal2(s));
// x = a + c1; y = x cmp c2 ? trueValue : falseValue
return CondMove.create(s.operator(), y.copyRO(), a.copyRO(), LC(c2 - c1), cond, trueValue, falseValue);
}
break;
case REF_ADD_opcode:
if (isEqualityTest) {
Address c1 = getAddressValue(Binary.getVal2(def));
Address c2 = getAddressValue(CondMove.getVal2(s));
// x = a + c1; y = x cmp c2 ? trueValue : falseValue
return CondMove.create(s.operator(), y.copyRO(), a.copyRO(), AC(c2.toWord().minus(c1.toWord()).toAddress()), cond, trueValue, falseValue);
}
break;
case FLOAT_ADD_opcode:
{
float c1 = getFloatValue(Binary.getVal2(def));
float c2 = getFloatValue(CondMove.getVal2(s));
// x = a + c1; y = x cmp c2 ? trueValue : falseValue
return CondMove.create(s.operator(), y.copyRO(), a.copyRO(), FC(c2 - c1), cond, trueValue, falseValue);
}
case DOUBLE_ADD_opcode:
{
double c1 = getDoubleValue(Binary.getVal2(def));
double c2 = getDoubleValue(CondMove.getVal2(s));
// x = a + c1; y = x cmp c2 ? trueValue : falseValue
return CondMove.create(s.operator(), y.copyRO(), a.copyRO(), DC(c2 - c1), cond, trueValue, falseValue);
}
case INT_SUB_opcode:
if (isEqualityTest) {
int c1 = getIntValue(Binary.getVal2(def));
int c2 = getIntValue(CondMove.getVal2(s));
// x = a - c1; y = x cmp c2 ? trueValue : falseValue
return CondMove.create(s.operator(), y.copyRO(), a.copyRO(), IC(c1 + c2), cond, trueValue, falseValue);
}
break;
case LONG_SUB_opcode:
if (isEqualityTest) {
long c1 = getLongValue(Binary.getVal2(def));
long c2 = getLongValue(CondMove.getVal2(s));
// x = a - c1; y = x cmp c2 ? trueValue : falseValue
return CondMove.create(s.operator(), y.copyRO(), a.copyRO(), LC(c1 + c2), cond, trueValue, falseValue);
}
break;
case REF_SUB_opcode:
if (isEqualityTest) {
Address c1 = getAddressValue(Binary.getVal2(def));
Address c2 = getAddressValue(CondMove.getVal2(s));
// x = a - c1; y = x cmp c2 ? trueValue : falseValue
return CondMove.create(s.operator(), y.copyRO(), a.copyRO(), AC(c1.toWord().plus(c2.toWord()).toAddress()), cond, trueValue, falseValue);
}
break;
case FLOAT_SUB_opcode:
{
float c1 = getFloatValue(Binary.getVal2(def));
float c2 = getFloatValue(CondMove.getVal2(s));
// x = a - c1; y = x cmp c2 ? trueValue : falseValue
return CondMove.create(s.operator(), y.copyRO(), a.copyRO(), FC(c1 + c2), cond, trueValue, falseValue);
}
case DOUBLE_SUB_opcode:
{
double c1 = getDoubleValue(Binary.getVal2(def));
double c2 = getDoubleValue(CondMove.getVal2(s));
// x = a - c1; y = x cmp c2 ? trueValue : falseValue
return CondMove.create(s.operator(), y.copyRO(), a.copyRO(), DC(c1 + c2), cond, trueValue, falseValue);
}
case INT_NEG_opcode:
if (isEqualityTest) {
int c2 = getIntValue(CondMove.getVal2(s));
// x = -a; y = x cmp c2 ? trueValue : falseValue
return CondMove.create(s.operator(), y.copyRO(), a.copyRO(), IC(-c2), cond.flipOperands(), trueValue, falseValue);
}
break;
case LONG_NEG_opcode:
if (isEqualityTest) {
long c2 = getLongValue(CondMove.getVal2(s));
// x = -a; y = x cmp c2 ? trueValue : falseValue
return CondMove.create(s.operator(), y.copyRO(), a.copyRO(), LC(-c2), cond.flipOperands(), trueValue, falseValue);
}
break;
case REF_NEG_opcode:
if (isEqualityTest) {
Address c2 = getAddressValue(CondMove.getVal2(s));
// x = -a; y = x cmp c2 ? trueValue : falseValue
return CondMove.create(s.operator(), y.copyRO(), a.copyRO(), AC(Word.zero().minus(c2.toWord()).toAddress()), cond.flipOperands(), trueValue, falseValue);
}
break;
case FLOAT_NEG_opcode:
{
float c2 = getFloatValue(CondMove.getVal2(s));
// x = -a; y = x cmp c2 ? trueValue : falseValue
return CondMove.create(s.operator(), y.copyRO(), a.copyRO(), FC(-c2), cond.flipOperands(), trueValue, falseValue);
}
case DOUBLE_NEG_opcode:
{
double c2 = getDoubleValue(CondMove.getVal2(s));
// x = -a; y = x cmp c2 ? trueValue : falseValue
return CondMove.create(s.operator(), y.copyRO(), a.copyRO(), DC(-c2), cond.flipOperands(), trueValue, falseValue);
}
case BOOLEAN_CMP_INT_opcode:
{
int c1 = getIntValue(BooleanCmp.getVal2(def));
int c2 = getIntValue(CondMove.getVal2(s));
// x = a cmp c1 ? true : false; y = x cmp c2 ? trueValue : falseValue
if ((cond.isEQUAL() && c2 == 1) || (cond.isNOT_EQUAL() && c2 == 0)) {
return CondMove.create(s.operator(), y.copyRO(), a.copyRO(), IC(c1), BooleanCmp.getCond(def).copy().asCondition(), trueValue, falseValue);
} else if ((cond.isEQUAL() && c2 == 0) || (cond.isNOT_EQUAL() && c2 == 1)) {
return CondMove.create(s.operator(), y.copyRO(), a.copyRO(), IC(c1), BooleanCmp.getCond(def).copy().asCondition().flipCode(), trueValue, falseValue);
}
break;
}
case BOOLEAN_CMP_ADDR_opcode:
{
Address c1 = getAddressValue(BooleanCmp.getVal2(def));
int c2 = getIntValue(CondMove.getVal2(s));
// x = a cmp c1 ? true : false; y = x cmp c2 ? trueValue : falseValue
if ((cond.isEQUAL() && c2 == 1) || (cond.isNOT_EQUAL() && c2 == 0)) {
return CondMove.create(s.operator(), y.copyRO(), a.copyRO(), AC(c1), BooleanCmp.getCond(def).copy().asCondition(), trueValue, falseValue);
} else if ((cond.isEQUAL() && c2 == 0) || (cond.isNOT_EQUAL() && c2 == 1)) {
return CondMove.create(s.operator(), y.copyRO(), a.copyRO(), AC(c1), BooleanCmp.getCond(def).flipCode(), trueValue, falseValue);
}
break;
}
case BOOLEAN_CMP_LONG_opcode:
{
long c1 = getLongValue(BooleanCmp.getVal2(def));
int c2 = getIntValue(CondMove.getVal2(s));
// x = a cmp c1 ? true : false; y = x cmp c2 ? trueValue : falseValue
if ((cond.isEQUAL() && c2 == 1) || (cond.isNOT_EQUAL() && c2 == 0)) {
return CondMove.create(s.operator(), y.copyRO(), a.copyRO(), LC(c1), BooleanCmp.getCond(def).copy().asCondition(), trueValue, falseValue);
} else if ((cond.isEQUAL() && c2 == 0) || (cond.isNOT_EQUAL() && c2 == 1)) {
return CondMove.create(s.operator(), y.copyRO(), a.copyRO(), LC(c1), BooleanCmp.getCond(def).copy().asCondition().flipCode(), trueValue, falseValue);
} else {
return null;
}
}
case BOOLEAN_CMP_DOUBLE_opcode:
{
double c1 = getDoubleValue(BooleanCmp.getVal2(def));
int c2 = getIntValue(CondMove.getVal2(s));
// x = a cmp c1 ? true : false; y = x cmp c2 ? trueValue : falseValue
if ((cond.isEQUAL() && c2 == 1) || (cond.isNOT_EQUAL() && c2 == 0)) {
return CondMove.create(s.operator(), y.copyRO(), a.copyRO(), DC(c1), BooleanCmp.getCond(def).copy().asCondition(), trueValue, falseValue);
} else if ((cond.isEQUAL() && c2 == 0) || (cond.isNOT_EQUAL() && c2 == 1)) {
return CondMove.create(s.operator(), y.copyRO(), a.copyRO(), DC(c1), BooleanCmp.getCond(def).copy().asCondition().flipCode(), trueValue, falseValue);
}
break;
}
case BOOLEAN_CMP_FLOAT_opcode:
{
float c1 = getFloatValue(BooleanCmp.getVal2(def));
int c2 = getIntValue(CondMove.getVal2(s));
// x = a cmp c1 ? true : false; y = x cmp c2 ? trueValue : falseValue
if ((cond.isEQUAL() && c2 == 1) || (cond.isNOT_EQUAL() && c2 == 0)) {
return CondMove.create(s.operator(), y.copyRO(), a.copyRO(), FC(c1), BooleanCmp.getCond(def).copy().asCondition(), trueValue, falseValue);
} else if ((cond.isEQUAL() && c2 == 0) || (cond.isNOT_EQUAL() && c2 == 1)) {
return CondMove.create(s.operator(), y.copyRO(), a.copyRO(), FC(c1), BooleanCmp.getCond(def).copy().asCondition().flipCode(), trueValue, falseValue);
}
break;
}
case LONG_CMP_opcode:
{
long c1 = getLongValue(Binary.getVal2(def));
int c2 = getIntValue(CondMove.getVal2(s));
// x = a lcmp c1; y = y = x cmp c2 ? trueValue : falseValue
if (cond.isEQUAL() && c2 == 0) {
return CondMove.create(s.operator(), y.copyRO(), a.copyRO(), LC(c1), ConditionOperand.EQUAL(), trueValue, falseValue);
} else if (cond.isNOT_EQUAL() && c2 == 0) {
return CondMove.create(s.operator(), y.copyRO(), a.copyRO(), LC(c1), ConditionOperand.NOT_EQUAL(), trueValue, falseValue);
} else if ((cond.isEQUAL() && c2 == 1) || (cond.isGREATER() && c2 == 0)) {
return CondMove.create(s.operator(), y.copyRO(), a.copyRO(), LC(c1), ConditionOperand.GREATER(), trueValue, falseValue);
} else if (cond.isGREATER_EQUAL() && c2 == 0) {
return CondMove.create(s.operator(), y.copyRO(), a.copyRO(), LC(c1), ConditionOperand.GREATER_EQUAL(), trueValue, falseValue);
} else if ((cond.isEQUAL() && c2 == -1) || (cond.isLESS() && c2 == 0)) {
return CondMove.create(s.operator(), y.copyRO(), a.copyRO(), LC(c1), ConditionOperand.LESS(), trueValue, falseValue);
} else if (cond.isLESS_EQUAL() && c2 == 0) {
return CondMove.create(s.operator(), y.copyRO(), a.copyRO(), LC(c1), ConditionOperand.LESS_EQUAL(), trueValue, falseValue);
}
break;
}
default:
}
}
return null;
}
case INT_NEG_opcode:
{
if (FOLD_INTS && FOLD_NEGS) {
if (def.operator() == INT_NEG) {
// x = -z; y = -x;
return Move.create(INT_MOVE, y.copyRO(), Unary.getVal(def).copy());
} else if (def.operator() == INT_MUL) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a * c1; y = -x;
return Binary.create(INT_MUL, y.copyRO(), a.copyRO(), IC(-c1));
} else if (def.operator() == INT_DIV) {
int c1 = getIntValue(GuardedBinary.getVal2(def));
Operand guard = GuardedBinary.getGuard(def);
// x = a / c1; y = -x;
return GuardedBinary.create(INT_DIV, y.copyRO(), a.copyRO(), IC(-c1), guard.copy());
} else if (FOLD_CONSTANTS_TO_LHS && (def.operator() == INT_ADD)) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a + c1; y = -x;
return Binary.create(INT_SUB, y.copyRO(), IC(-c1), a.copyRO());
} else if (FOLD_CONSTANTS_TO_LHS && (def.operator() == INT_SUB)) {
int c1 = getIntValue(Binary.getVal2(def));
// x = a - c1; y = -x;
return Binary.create(INT_SUB, y.copyRO(), IC(c1), a.copyRO());
}
}
return null;
}
case REF_NEG_opcode:
{
if (FOLD_REFS && FOLD_NEGS) {
if (def.operator() == REF_NEG) {
// x = -z; y = -x;
return Move.create(REF_MOVE, y.copyRO(), Unary.getVal(def).copy());
} else if (FOLD_CONSTANTS_TO_LHS && (def.operator() == REF_ADD)) {
Address c1 = getAddressValue(Binary.getVal2(def));
// x = a + c1; y = -x;
return Binary.create(REF_SUB, y.copyRO(), AC(Word.zero().minus(c1.toWord()).toAddress()), a.copyRO());
} else if (FOLD_CONSTANTS_TO_LHS && (def.operator() == REF_SUB)) {
Address c1 = getAddressValue(Binary.getVal2(def));
// x = a - c1; y = -x;
return Binary.create(REF_SUB, y.copyRO(), AC(c1), a.copyRO());
}
}
return null;
}
case LONG_NEG_opcode:
{
if (FOLD_LONGS && FOLD_NEGS) {
if (def.operator() == LONG_NEG) {
// x = -z; y = -x;
return Move.create(LONG_MOVE, y.copyRO(), Unary.getVal(def).copy());
} else if (def.operator() == LONG_MUL) {
long c1 = getLongValue(Binary.getVal2(def));
// x = a * c1; y = -x;
return Binary.create(LONG_MUL, y.copyRO(), a.copyRO(), LC(-c1));
} else if (def.operator() == LONG_DIV) {
long c1 = getLongValue(GuardedBinary.getVal2(def));
Operand guard = GuardedBinary.getGuard(def);
// x = a / c1; y = -x;
return GuardedBinary.create(LONG_DIV, y.copyRO(), a.copyRO(), LC(-c1), guard.copy());
} else if (FOLD_CONSTANTS_TO_LHS && (def.operator() == LONG_ADD)) {
long c1 = getLongValue(Binary.getVal2(def));
// x = a + c1; y = -x;
return Binary.create(LONG_SUB, y.copyRO(), LC(-c1), a.copyRO());
} else if (FOLD_CONSTANTS_TO_LHS && (def.operator() == LONG_SUB)) {
long c1 = getLongValue(Binary.getVal2(def));
// x = a - c1; y = -x;
return Binary.create(LONG_SUB, y.copyRO(), LC(c1), a.copyRO());
}
}
return null;
}
case FLOAT_NEG_opcode:
{
if (FOLD_FLOATS && FOLD_NEGS) {
if (def.operator() == FLOAT_NEG) {
// x = -z; y = -x;
return Move.create(FLOAT_MOVE, y.copyRO(), Unary.getVal(def).copy());
} else if (def.operator() == FLOAT_MUL) {
float c1 = getFloatValue(Binary.getVal2(def));
// x = a * c1; y = -x;
return Binary.create(FLOAT_MUL, y.copyRO(), a.copyRO(), FC(-c1));
} else if (def.operator() == FLOAT_DIV) {
float c1 = getFloatValue(Binary.getVal2(def));
// x = a / c1; y = -x;
return Binary.create(FLOAT_DIV, y.copyRO(), a.copyRO(), FC(-c1));
} else if (FOLD_CONSTANTS_TO_LHS && (def.operator() == FLOAT_ADD)) {
float c1 = getFloatValue(Binary.getVal2(def));
// x = a + c1; y = -x;
return Binary.create(FLOAT_SUB, y.copyRO(), FC(-c1), a.copyRO());
} else if (FOLD_CONSTANTS_TO_LHS && (def.operator() == FLOAT_SUB)) {
float c1 = getFloatValue(Binary.getVal2(def));
// x = a - c1; y = -x;
return Binary.create(FLOAT_SUB, y.copyRO(), FC(c1), a.copyRO());
}
}
return null;
}
case DOUBLE_NEG_opcode:
{
if (FOLD_DOUBLES && FOLD_NEGS) {
if (def.operator() == DOUBLE_NEG) {
// x = -z; y = -x;
return Move.create(DOUBLE_MOVE, y.copyRO(), Unary.getVal(def).copy());
} else if (def.operator() == DOUBLE_MUL) {
double c1 = getDoubleValue(Binary.getVal2(def));
// x = a * c1; y = -x;
return Binary.create(DOUBLE_MUL, y.copyRO(), a.copyRO(), DC(-c1));
} else if (def.operator() == DOUBLE_DIV) {
double c1 = getDoubleValue(Binary.getVal2(def));
// x = a / c1; y = -x;
return Binary.create(DOUBLE_DIV, y.copyRO(), a.copyRO(), DC(-c1));
} else if (FOLD_CONSTANTS_TO_LHS && (def.operator() == DOUBLE_ADD)) {
double c1 = getDoubleValue(Binary.getVal2(def));
// x = a + c1; y = -x;
return Binary.create(DOUBLE_SUB, y.copyRO(), DC(-c1), a.copyRO());
} else if (FOLD_CONSTANTS_TO_LHS && (def.operator() == DOUBLE_SUB)) {
double c1 = getDoubleValue(Binary.getVal2(def));
// x = a - c1; y = -x;
return Binary.create(DOUBLE_SUB, y.copyRO(), DC(c1), a.copyRO());
}
}
return null;
}
case BOOLEAN_NOT_opcode:
{
if (FOLD_INTS && FOLD_NOTS) {
if (def.operator() == BOOLEAN_NOT) {
// x = 1 ^ a; y = 1 ^ x;
return Move.create(INT_MOVE, y.copyRO(), Unary.getVal(def).copy());
} else if (BooleanCmp.conforms(def)) {
// x = a cmp b; y = !x
return BooleanCmp.create(def.operator(), y.copyRO(), BooleanCmp.getVal1(def).copy(), BooleanCmp.getVal2(def).copy(), ((ConditionOperand) BooleanCmp.getCond(def).copy()).flipCode(), ((BranchProfileOperand) BooleanCmp.getBranchProfile(def).copy()));
}
}
return null;
}
case INT_NOT_opcode:
{
if (FOLD_INTS && FOLD_NOTS) {
if (def.operator() == INT_NOT) {
// x = -1 ^ a; y = -1 ^ x;
return Move.create(INT_MOVE, y.copyRO(), a.copy());
}
}
return null;
}
case REF_NOT_opcode:
{
if (FOLD_REFS && FOLD_NOTS) {
if (def.operator() == REF_NOT) {
// x = -1 ^ a; y = -1 ^ x;
return Move.create(REF_MOVE, y.copyRO(), a.copy());
}
}
return null;
}
case LONG_NOT_opcode:
{
if (FOLD_LONGS && FOLD_NOTS) {
if (def.operator() == LONG_NOT) {
// x = -1 ^ a; y = -1 ^ x;
return Move.create(LONG_MOVE, y.copyRO(), a.copy());
}
}
return null;
}
case INT_2BYTE_opcode:
{
if (FOLD_INTS && FOLD_2CONVERSION) {
if ((def.operator() == INT_2BYTE) || (def.operator() == INT_2SHORT)) {
// x = (short)a; y = (byte)x;
return Unary.create(INT_2BYTE, y.copyRO(), a.copy());
} else if (def.operator() == INT_2USHORT) {
// x = (char)a; y = (byte)x;
return Binary.create(INT_AND, y.copyRO(), a.copy(), IC(0xFF));
}
}
return null;
}
case INT_2SHORT_opcode:
{
if (FOLD_INTS && FOLD_2CONVERSION) {
if (def.operator() == INT_2BYTE) {
// x = (byte)a; y = (short)x;
return Unary.create(INT_2BYTE, y.copyRO(), a.copy());
} else if (def.operator() == INT_2SHORT) {
// x = (short)a; y = (short)x;
return Unary.create(INT_2SHORT, y.copyRO(), a.copy());
} else if (def.operator() == INT_2USHORT) {
// x = (char)a; y = (short)x;
return Unary.create(INT_2USHORT, y.copyRO(), a.copy());
}
}
return null;
}
case INT_2USHORT_opcode:
{
if (FOLD_INTS && FOLD_2CONVERSION) {
if ((def.operator() == INT_2SHORT) || (def.operator() == INT_2USHORT)) {
// x = (short)a; y = (char)x;
return Unary.create(INT_2USHORT, y.copyRO(), a.copy());
}
}
return null;
}
case LONG_2INT_opcode:
{
if (FOLD_LONGS && FOLD_2CONVERSION) {
if (def.operator() == INT_2LONG) {
// x = (long)a; y = (int)x;
return Move.create(INT_MOVE, y.copyRO(), a.copy());
}
}
return null;
}
case INT_2LONG_opcode:
// unused
return null;
case DOUBLE_2FLOAT_opcode:
{
if (FOLD_DOUBLES && FOLD_2CONVERSION) {
if (def.operator() == FLOAT_2DOUBLE) {
// x = (double)a; y = (float)x;
return Move.create(FLOAT_MOVE, y.copyRO(), a.copy());
}
}
return null;
}
case FLOAT_2DOUBLE_opcode:
// unused
return null;
case INT_ZERO_CHECK_opcode:
{
if (FOLD_INTS && FOLD_CHECKS) {
if (def.operator() == INT_NEG) {
// x = -z; y = zerocheck x;
return ZeroCheck.create(INT_ZERO_CHECK, y.copyRO(), Unary.getVal(def).copy());
}
}
return null;
}
case LONG_ZERO_CHECK_opcode:
{
if (FOLD_INTS && FOLD_CHECKS) {
if (def.operator() == INT_NEG) {
// x = -z; y = zerocheck x;
return ZeroCheck.create(INT_ZERO_CHECK, y.copyRO(), Unary.getVal(def).copy());
}
}
return null;
}
case NEWARRAY_opcode:
// unused
return null;
case BOUNDS_CHECK_opcode:
{
if (FOLD_CHECKS) {
if (def.operator() == NEWARRAY) {
// x = newarray xxx[c1]; y = boundscheck x, c2;
int c1 = getIntValue(NewArray.getSize(def));
int c2 = getIntValue(BoundsCheck.getIndex(s));
if (c2 >= 0 && c2 < c1) {
return Move.create(GUARD_MOVE, y.copyRO(), BoundsCheck.getGuard(def).copy());
}
}
}
return null;
}
case NULL_CHECK_opcode:
{
if (FOLD_CHECKS) {
if (def.operator() == NEWARRAY || def.operator() == NEW) {
// x = new xxx; y = nullcheck x;
return Move.create(GUARD_MOVE, y.copyRO(), new TrueGuardOperand());
}
}
return null;
}
case INSTANCEOF_opcode:
{
if (FOLD_CHECKS) {
TypeReference newType;
if (def.operator() == NEW) {
// x = new xxx; y = instanceof x, zzz;
newType = New.getType(def).getTypeRef();
} else if (def.operator() == NEWARRAY) {
// x = newarray xxx; y = instanceof x, zzz;
newType = NewArray.getType(def).getTypeRef();
} else {
return null;
}
TypeReference instanceofType = InstanceOf.getType(s).getTypeRef();
if (newType == instanceofType) {
return Move.create(INT_MOVE, y.copyRO(), IC(1));
} else {
return Move.create(INT_MOVE, y.copyRO(), IC(RuntimeEntrypoints.isAssignableWith(instanceofType.resolve(), newType.resolve()) ? 1 : 0));
}
}
return null;
}
case ARRAYLENGTH_opcode:
{
if (FOLD_CHECKS) {
if (def.operator() == NEWARRAY) {
// x = newarray xxx[c1]; y = arraylength x;
return Move.create(INT_MOVE, y.copyRO(), NewArray.getSize(def).copy());
}
}
return null;
}
default:
OptimizingCompilerException.UNREACHABLE();
return null;
}
}
use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.
the class FieldAnalysis method perform.
/**
* Record field analysis information for an IR.
*
* @param ir the governing IR
*/
@Override
public void perform(IR ir) {
// BOTTOM if the concrete type is unknown.
for (Enumeration<Instruction> e = ir.forwardInstrEnumerator(); e.hasMoreElements(); ) {
Instruction s = e.nextElement();
if (PutField.conforms(s)) {
LocationOperand l = PutField.getLocation(s);
RVMField f = l.getFieldRef().peekResolvedField();
if (f == null)
continue;
if (!isCandidate(f.getType()))
continue;
// gleaned from context, does not hold everywhere
if (s.position().getMethod() != ir.method) {
continue;
}
Operand value = PutField.getValue(s);
if (value.isRegister()) {
if (value.asRegister().isPreciseType()) {
TypeReference type = value.asRegister().getType();
recordConcreteType(ir.method, f, type);
} else {
recordBottom(ir.method, f);
}
}
} else if (PutStatic.conforms(s)) {
LocationOperand l = PutStatic.getLocation(s);
RVMField f = l.getFieldRef().peekResolvedField();
if (f == null)
continue;
if (!isCandidate(f.getType()))
continue;
// gleaned from context, does not hold everywhere
if (s.position().getMethod() != ir.method) {
continue;
}
Operand value = PutStatic.getValue(s);
if (value.isRegister()) {
if (value.asRegister().isPreciseType()) {
TypeReference type = value.asRegister().getType();
recordConcreteType(ir.method, f, type);
} else {
recordBottom(ir.method, f);
}
}
}
}
}
use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.
the class FieldAnalysis method recordConcreteType.
/**
* Record that a method stores an object of a particular concrete type
* to a field.
*
* @param m the writing method
* @param f the written field
* @param t the concrete type
*/
private static synchronized void recordConcreteType(RVMMethod m, RVMField f, TypeReference t) {
// for now, only track private fields
if (!f.isPrivate()) {
return;
}
FieldDatabase.FieldDatabaseEntry entry = db.findOrCreateEntry(f);
FieldDatabase.FieldWriterInfo info = entry.findMethodInfo(m);
info.setAnalyzed();
if (info.isBottom()) {
return;
}
TypeReference oldType = info.concreteType;
if (oldType == null) {
// set a new concrete type for this field.
info.concreteType = t;
} else if (oldType != t) {
// we've previously determined a DIFFERENT! concrete type.
// meet the two types: i.e., change it to bottom.
info.setBottom();
}
}
Aggregations