From: <mic...@us...> - 2007-08-06 14:18:05
|
Revision: 156 http://pearcolator.svn.sourceforge.net/pearcolator/?rev=156&view=rev Author: michael_baer Date: 2007-08-06 07:18:07 -0700 (Mon, 06 Aug 2007) Log Message: ----------- - Removed file due to lack of differences against current JRVM version Removed Paths: ------------- ext/org/jikesrvm/compilers/opt/OPT_Simplifier.java Deleted: ext/org/jikesrvm/compilers/opt/OPT_Simplifier.java =================================================================== --- ext/org/jikesrvm/compilers/opt/OPT_Simplifier.java 2007-08-06 09:37:44 UTC (rev 155) +++ ext/org/jikesrvm/compilers/opt/OPT_Simplifier.java 2007-08-06 14:18:07 UTC (rev 156) @@ -1,3266 +0,0 @@ -/* - * This file is part of Jikes RVM (http://jikesrvm.sourceforge.net). - * The Jikes RVM project is distributed under the Common Public License (CPL). - * A copy of the license is included in the distribution, and is also - * available at http://www.opensource.org/licenses/cpl1.0.php - * - * (C) Copyright IBM Corp. 2001 - */ -package org.jikesrvm.compilers.opt; - -import org.jikesrvm.classloader.*; -import org.jikesrvm.compilers.opt.ir.*; -import org.jikesrvm.objectmodel.VM_TIBLayoutConstants; -import org.jikesrvm.VM; -import org.vmmagic.unboxed.*; -import java.lang.reflect.Array; -import static org.jikesrvm.VM_SizeConstants.*; -import static org.jikesrvm.compilers.opt.ir.OPT_Operators.*; - -/** - * A constant folder, strength reducer and axiomatic simplifier. - * - * <p> - * This module performs no analysis, it simply attempts to simplify the - * instruction as is. The intent is that analysis modules can call this - * transformation engine, allowing us to share the tedious simplification code - * among multiple analysis modules. - * - * <p> - * NOTE: For maintainability purposes, I've intentionally avoided being clever - * about combining 'similar' operators together into a combined case of the main - * switch switch statement. Also, operators are in sorted ordered within each - * major grouping. Please maintain this coding style. I'd rather have this - * module be 2000 lines of obviously correct code than 500 lines of clever code. - * - * @author Dave Grove - * @author Ian Rogers - */ -public abstract class OPT_Simplifier extends OPT_IRTools { - // NOTE: The convention is that constant folding is controlled based - // on the type of the result of the operator, not the type of its inputs. - /** - * Constant fold integer operations? - */ - public static final boolean CF_INT = true; - - /** - * Constant fold address operations? - */ - public static final boolean CF_LONG = true; - - /** - * Constant fold address operations? - */ - public static final boolean CF_ADDR = true; - - /** - * Constant fold float operations? Default is true, flip to avoid consuming - * precious JTOC slots to hold new constant values. - */ - public static final boolean CF_FLOAT = true; - - /** - * Constant fold double operations? Default is true, flip to avoid consuming - * precious JTOC slots to hold new constant values. - */ - public static final boolean CF_DOUBLE = true; - - /** - * Constant fold field operations? Default is true, flip to avoid consuming - * precious JTOC slots to hold new constant values. - */ - public static final boolean CF_FIELDS = false; - - /** - * Constant fold TIB operations? Default is true, flip to avoid consuming - * precious JTOC slots to hold new constant values. - */ - public static final boolean CF_TIB = false; - - /** - * Effect of the simplification on Def-Use chains - */ - public enum DefUseEffect { - /** - * Enumeration value to indicate an operation is unchanged, although the - * order of operands may have been canonicalized and type information - * strengthened. - */ - UNCHANGED, - /** - * Enumeration value to indicate an operation has been replaced by a move - * instruction with a constant right hand side. - */ - MOVE_FOLDED, - /** - * Enumeration value to indicate an operation has been replaced by a move - * instruction with a non-constant right hand side. - */ - MOVE_REDUCED, - /** - * Enumeration value to indicate an operation has been replaced by an - * unconditional trap instruction. - */ - TRAP_REDUCED, - /** - * Enumeration value to indicate an operation has been replaced by a - * cheaper, but non-move instruction. - */ - REDUCED - } - - /** - * Given an instruction, attempt to simplify it. The instruction will be - * mutated in place. - * - * <p> - * We don't deal with branching operations here -- doing peephole - * optimizations of branches is the job of a separate module. - * - * @param regpool - * register pool in case simplification requires a temporary register - * @param s - * the instruction to simplify - * @return one of UNCHANGED, MOVE_FOLDED, MOVE_REDUCED, TRAP_REDUCED, REDUCED - */ - public static DefUseEffect simplify(OPT_AbstractRegisterPool regpool, - OPT_Instruction s) { - DefUseEffect result; - char opcode = s.getOpcode(); - switch (opcode) { - // ////////////////// - // GUARD operations - // ////////////////// - case GUARD_COMBINE_opcode: - result = guardCombine(s); - break; - // ////////////////// - // TRAP operations - // ////////////////// - case TRAP_IF_opcode: - result = trapIf(s); - break; - case NULL_CHECK_opcode: - result = nullCheck(s); - break; - case INT_ZERO_CHECK_opcode: - result = intZeroCheck(s); - break; - case LONG_ZERO_CHECK_opcode: - result = longZeroCheck(s); - break; - case CHECKCAST_opcode: - result = checkcast(regpool, s); - break; - case CHECKCAST_UNRESOLVED_opcode: - result = checkcast(regpool, s); - break; - case CHECKCAST_NOTNULL_opcode: - result = checkcastNotNull(s); - break; - case INSTANCEOF_opcode: - result = instanceOf(regpool, s); - break; - case INSTANCEOF_NOTNULL_opcode: - result = instanceOfNotNull(s); - break; - case OBJARRAY_STORE_CHECK_opcode: - result = objarrayStoreCheck(s); - break; - case OBJARRAY_STORE_CHECK_NOTNULL_opcode: - result = objarrayStoreCheckNotNull(s); - break; - case MUST_IMPLEMENT_INTERFACE_opcode: - result = mustImplementInterface(s); - break; - // ////////////////// - // Conditional moves - // ////////////////// - case INT_COND_MOVE_opcode: - result = intCondMove(s); - break; - case LONG_COND_MOVE_opcode: - result = longCondMove(s); - break; - case FLOAT_COND_MOVE_opcode: - result = floatCondMove(s); - break; - case DOUBLE_COND_MOVE_opcode: - result = doubleCondMove(s); - break; - case REF_COND_MOVE_opcode: - result = refCondMove(s); - break; - case GUARD_COND_MOVE_opcode: - result = guardCondMove(s); - break; - // ////////////////// - // INT ALU operations - // ////////////////// - case BOOLEAN_NOT_opcode: - result = booleanNot(s); - break; - case BOOLEAN_CMP_INT_opcode: - result = booleanCmpInt(s); - break; - case BOOLEAN_CMP_ADDR_opcode: - result = booleanCmpAddr(s); - break; - case BOOLEAN_CMP2_INT_OR_opcode: - result = booleanCmp2IntOr(s); - break; - // case BOOLEAN_CMP2_INT_AND: - // result = booleanCmp2IntAnd(s); - // break; - case INT_ADD_opcode: - result = intAdd(s); - break; - case INT_AND_opcode: - result = intAnd(s); - break; - case INT_DIV_opcode: - result = intDiv(s); - break; - case INT_MUL_opcode: - result = intMul(regpool, s); - break; - case INT_NEG_opcode: - result = intNeg(s); - break; - case INT_NOT_opcode: - result = intNot(s); - break; - case INT_OR_opcode: - result = intOr(s); - break; - case INT_REM_opcode: - result = intRem(s); - break; - case INT_SHL_opcode: - result = intShl(s); - break; - case INT_SHR_opcode: - result = intShr(s); - break; - case INT_SUB_opcode: - result = intSub(s); - break; - case INT_USHR_opcode: - result = intUshr(s); - break; - case INT_XOR_opcode: - result = intXor(s); - break; - // ////////////////// - // WORD ALU operations - // ////////////////// - case REF_ADD_opcode: - result = refAdd(s); - break; - case REF_AND_opcode: - result = refAnd(s); - break; - case REF_SHL_opcode: - result = refShl(s); - break; - case REF_SHR_opcode: - result = refShr(s); - break; - case REF_NOT_opcode: - result = refNot(s); - break; - case REF_OR_opcode: - result = refOr(s); - break; - case REF_SUB_opcode: - result = refSub(s); - break; - case REF_USHR_opcode: - result = regUshr(s); - break; - case REF_XOR_opcode: - result = refXor(s); - break; - // ////////////////// - // LONG ALU operations - // ////////////////// - case LONG_ADD_opcode: - result = longAdd(s); - break; - case LONG_AND_opcode: - result = longAnd(s); - break; - case LONG_CMP_opcode: - result = longCmp(s); - break; - case LONG_DIV_opcode: - result = longDiv(s); - break; - case LONG_MUL_opcode: - result = longMul(s); - break; - case LONG_NEG_opcode: - result = longNeg(s); - break; - case LONG_NOT_opcode: - result = longNot(s); - break; - case LONG_OR_opcode: - result = longOr(s); - break; - case LONG_REM_opcode: - result = longRem(s); - break; - case LONG_SHL_opcode: - result = longShl(s); - break; - case LONG_SHR_opcode: - result = longShr(s); - break; - case LONG_SUB_opcode: - result = longSub(s); - break; - case LONG_USHR_opcode: - result = longUshr(s); - break; - case LONG_XOR_opcode: - result = longXor(s); - break; - // ////////////////// - // FLOAT ALU operations - // ////////////////// - case FLOAT_ADD_opcode: - result = floatAdd(s); - break; - case FLOAT_CMPG_opcode: - result = floatCmpg(s); - break; - case FLOAT_CMPL_opcode: - result = floatCmpl(s); - break; - case FLOAT_DIV_opcode: - result = floatDiv(s); - break; - case FLOAT_MUL_opcode: - result = floatMul(s); - break; - case FLOAT_NEG_opcode: - result = floatNeg(s); - break; - case FLOAT_REM_opcode: - result = floatRem(s); - break; - case FLOAT_SUB_opcode: - result = floatSub(s); - break; - // ////////////////// - // DOUBLE ALU operations - // ////////////////// - case DOUBLE_ADD_opcode: - result = doubleAdd(s); - break; - case DOUBLE_CMPG_opcode: - result = doubleCmpg(s); - break; - case DOUBLE_CMPL_opcode: - result = doubleCmpl(s); - break; - case DOUBLE_DIV_opcode: - result = doubleDiv(s); - break; - case DOUBLE_MUL_opcode: - result = doubleMul(s); - break; - case DOUBLE_NEG_opcode: - result = doubleNeg(s); - break; - case DOUBLE_REM_opcode: - result = doubleRem(s); - break; - case DOUBLE_SUB_opcode: - result = doubleSub(s); - break; - // ////////////////// - // CONVERSION operations - // ////////////////// - case DOUBLE_2FLOAT_opcode: - result = double2Float(s); - break; - case DOUBLE_2INT_opcode: - result = double2Int(s); - break; - case DOUBLE_2LONG_opcode: - result = double2Long(s); - break; - case DOUBLE_AS_LONG_BITS_opcode: - result = doubleAsLongBits(s); - break; - case INT_2DOUBLE_opcode: - result = int2Double(s); - break; - case INT_2BYTE_opcode: - result = int2Byte(s); - break; - case INT_2USHORT_opcode: - result = int2UShort(s); - break; - case INT_2FLOAT_opcode: - result = int2Float(s); - break; - case INT_2LONG_opcode: - result = int2Long(s); - break; - case INT_2ADDRSigExt_opcode: - result = int2AddrSigExt(s); - break; - case INT_2ADDRZerExt_opcode: - result = int2AddrZerExt(s); - break; - case LONG_2ADDR_opcode: - result = long2Addr(s); - break; - case INT_2SHORT_opcode: - result = int2Short(s); - break; - case INT_BITS_AS_FLOAT_opcode: - result = intBitsAsFloat(s); - break; - case ADDR_2INT_opcode: - result = addr2Int(s); - break; - case ADDR_2LONG_opcode: - result = addr2Long(s); - break; - case FLOAT_2DOUBLE_opcode: - result = float2Double(s); - break; - case FLOAT_2INT_opcode: - result = float2Int(s); - break; - case FLOAT_2LONG_opcode: - result = float2Long(s); - break; - case FLOAT_AS_INT_BITS_opcode: - result = floatAsIntBits(s); - break; - case LONG_2FLOAT_opcode: - result = long2Float(s); - break; - case LONG_2INT_opcode: - result = long2Int(s); - break; - case LONG_2DOUBLE_opcode: - result = long2Double(s); - break; - case LONG_BITS_AS_DOUBLE_opcode: - result = longBitsAsDouble(s); - break; - // ////////////////// - // Field operations - // ////////////////// - case ARRAYLENGTH_opcode: - result = arrayLength(s); - break; - case BOUNDS_CHECK_opcode: - result = boundsCheck(s); - break; - case CALL_opcode: - result = call(s); - break; - case GETFIELD_opcode: - result = getField(s); - break; - case GET_OBJ_TIB_opcode: - result = getObjTib(s); - break; - case GET_CLASS_TIB_opcode: - result = getClassTib(s); - break; - case GET_TYPE_FROM_TIB_opcode: - result = getTypeFromTib(s); - break; - case GET_ARRAY_ELEMENT_TIB_FROM_TIB_opcode: - result = getArrayElementTibFromTib(s); - break; - case GET_SUPERCLASS_IDS_FROM_TIB_opcode: - result = getSuperclassIdsFromTib(s); - break; - case GET_DOES_IMPLEMENT_FROM_TIB_opcode: - result = getDoesImplementFromTib(s); - break; - case REF_LOAD_opcode: - result = refLoad(s); - break; - default: - result = DefUseEffect.UNCHANGED; - } - if (VM.VerifyAssertions) { - switch (result) { - case MOVE_FOLDED: - // Check move has constant RHS - VM._assert(Move.conforms(s) - && (Move.getVal(s) instanceof OPT_ConstantOperand), "RHS of move " - + s + " should be constant during simplification of " - + OPT_OperatorNames.operatorName[opcode]); - break; - case MOVE_REDUCED: - // Check move has non-constant RHS - VM._assert(Move.conforms(s) - && !(Move.getVal(s) instanceof OPT_ConstantOperand), "RHS of move " - + s + " shouldn't be constant during simplification of " - + OPT_OperatorNames.operatorName[opcode]); - break; - default: - // Nothing to check - } - } - return result; - } - - private static DefUseEffect guardCombine(OPT_Instruction s) { - OPT_Operand op1 = Binary.getVal1(s); - OPT_Operand op2 = Binary.getVal2(s); - if (op1.similar(op2) || (op2 instanceof OPT_TrueGuardOperand)) { - Move.mutate(s, GUARD_MOVE, Binary.getClearResult(s), op1); - if (op1 instanceof OPT_TrueGuardOperand) { - // BOTH true guards: FOLD - return DefUseEffect.MOVE_FOLDED; - } else { - // ONLY OP2 IS TrueGuard: MOVE REDUCE - return DefUseEffect.MOVE_REDUCED; - } - } else if (op1 instanceof OPT_TrueGuardOperand) { - // ONLY OP1 IS TrueGuard: MOVE REDUCE - Move.mutate(s, GUARD_MOVE, Binary.getClearResult(s), op2); - return DefUseEffect.MOVE_REDUCED; - } else { - return DefUseEffect.UNCHANGED; - } - } - - private static DefUseEffect trapIf(OPT_Instruction s) { - { - OPT_Operand op1 = TrapIf.getVal1(s); - OPT_Operand op2 = TrapIf.getVal2(s); - if (op1.isConstant()) { - if (op2.isConstant()) { - int willTrap = TrapIf.getCond(s).evaluate(op1, op2); - if (willTrap == OPT_ConditionOperand.TRUE) { - Trap.mutate(s, TRAP, TrapIf.getClearGuardResult(s), TrapIf - .getClearTCode(s)); - return DefUseEffect.TRAP_REDUCED; - } else if (willTrap == OPT_ConditionOperand.FALSE) { - Move.mutate(s, GUARD_MOVE, TrapIf.getClearGuardResult(s), TG()); - return DefUseEffect.MOVE_FOLDED; - } - } else { - // canonicalize - TrapIf.mutate(s, TRAP_IF, TrapIf.getClearGuardResult(s), TrapIf - .getClearVal2(s), TrapIf.getClearVal1(s), TrapIf.getClearCond(s) - .flipOperands(), TrapIf.getClearTCode(s)); - } - } - } - return DefUseEffect.UNCHANGED; - } - - private static DefUseEffect nullCheck(OPT_Instruction s) { - OPT_Operand ref = NullCheck.getRef(s); - if (ref.isNullConstant() - || (ref.isAddressConstant() && ref.asAddressConstant().value.isZero())) { - Trap.mutate(s, TRAP, NullCheck.getClearGuardResult(s), - OPT_TrapCodeOperand.NullPtr()); - return DefUseEffect.TRAP_REDUCED; - } else if (ref.isConstant()) { - // object, string, class or non-null address constant - - // Make the slightly suspect assumption that all non-zero address - // constants are actually valid pointers. Not necessarily true, - // but unclear what else we can do. - Move.mutate(s, GUARD_MOVE, NullCheck.getClearGuardResult(s), TG()); - return DefUseEffect.MOVE_FOLDED; - } else { - return DefUseEffect.UNCHANGED; - } - } - - private static DefUseEffect intZeroCheck(OPT_Instruction s) { - { - OPT_Operand op = ZeroCheck.getValue(s); - if (op.isIntConstant()) { - int val = op.asIntConstant().value; - if (val == 0) { - Trap.mutate(s, TRAP, ZeroCheck.getClearGuardResult(s), - OPT_TrapCodeOperand.DivByZero()); - return DefUseEffect.TRAP_REDUCED; - } else { - Move.mutate(s, GUARD_MOVE, ZeroCheck.getClearGuardResult(s), TG()); - return DefUseEffect.MOVE_FOLDED; - } - } - } - return DefUseEffect.UNCHANGED; - } - - private static DefUseEffect longZeroCheck(OPT_Instruction s) { - { - OPT_Operand op = ZeroCheck.getValue(s); - if (op.isLongConstant()) { - long val = op.asLongConstant().value; - if (val == 0L) { - Trap.mutate(s, TRAP, ZeroCheck.getClearGuardResult(s), - OPT_TrapCodeOperand.DivByZero()); - return DefUseEffect.TRAP_REDUCED; - } else { - Move.mutate(s, GUARD_MOVE, ZeroCheck.getClearGuardResult(s), TG()); - return DefUseEffect.MOVE_FOLDED; - } - } - } - return DefUseEffect.UNCHANGED; - } - - private static DefUseEffect checkcast(OPT_AbstractRegisterPool regpool, - OPT_Instruction s) { - OPT_Operand ref = TypeCheck.getRef(s); - if (ref.isNullConstant()) { - Empty.mutate(s, NOP); - return DefUseEffect.REDUCED; - } else if (ref.isConstant()) { - s.operator = CHECKCAST_NOTNULL; - return checkcastNotNull(s); - } else { - VM_TypeReference lhsType = TypeCheck.getType(s).getTypeRef(); - VM_TypeReference rhsType = ref.getType(); - byte ans = OPT_ClassLoaderProxy.includesType(lhsType, rhsType); - if (ans == OPT_Constants.YES) { - Empty.mutate(s, NOP); - return DefUseEffect.REDUCED; - } else { - // NOTE: OPT_Constants.NO can't help us because (T)null always succeeds - return DefUseEffect.UNCHANGED; - } - } - } - - private static DefUseEffect checkcastNotNull(OPT_Instruction s) { - OPT_Operand ref = TypeCheck.getRef(s); - VM_TypeReference lhsType = TypeCheck.getType(s).getTypeRef(); - VM_TypeReference rhsType = ref.getType(); - byte ans = OPT_ClassLoaderProxy.includesType(lhsType, rhsType); - if (ans == OPT_Constants.YES) { - Empty.mutate(s, NOP); - return DefUseEffect.REDUCED; - } else if (ans == OPT_Constants.NO) { - VM_Type rType = rhsType.peekResolvedType(); - 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, OPT_TrapCodeOperand.CheckCast()); - return DefUseEffect.TRAP_REDUCED; - } else { - return DefUseEffect.UNCHANGED; - } - } else { - return DefUseEffect.UNCHANGED; - } - } - - private static DefUseEffect instanceOf(OPT_AbstractRegisterPool regpool, - OPT_Instruction s) { - OPT_Operand ref = InstanceOf.getRef(s); - if (ref.isNullConstant()) { - Move.mutate(s, INT_MOVE, InstanceOf.getClearResult(s), IC(0)); - return DefUseEffect.MOVE_FOLDED; - } else if (ref.isConstant()) { - s.operator = INSTANCEOF_NOTNULL; - return instanceOfNotNull(s); - } else { - VM_TypeReference lhsType = InstanceOf.getType(s).getTypeRef(); - VM_TypeReference rhsType = ref.getType(); - byte ans = OPT_ClassLoaderProxy.includesType(lhsType, rhsType); - // NOTE: OPT_Constants.YES doesn't help because ref may be null and null - // instanceof T is false - if (ans == OPT_Constants.NO) { - VM_Type rType = rhsType.peekResolvedType(); - if (rType != null && rType.isClassType() && rType.asClass().isFinal()) { - // only final (or precise) rhs types can be optimized since rhsType - // may be conservative - Move.mutate(s, INT_MOVE, InstanceOf.getClearResult(s), IC(0)); - return DefUseEffect.MOVE_FOLDED; - } else { - return DefUseEffect.UNCHANGED; - } - } else { - return DefUseEffect.UNCHANGED; - } - } - } - - private static DefUseEffect instanceOfNotNull(OPT_Instruction s) { - { - OPT_Operand ref = InstanceOf.getRef(s); - VM_TypeReference lhsType = InstanceOf.getType(s).getTypeRef(); - VM_TypeReference rhsType = ref.getType(); - byte ans = OPT_ClassLoaderProxy.includesType(lhsType, rhsType); - if (ans == OPT_Constants.YES) { - Move.mutate(s, INT_MOVE, InstanceOf.getClearResult(s), IC(1)); - return DefUseEffect.MOVE_FOLDED; - } else if (ans == OPT_Constants.NO) { - VM_Type rType = rhsType.peekResolvedType(); - if (rType != null && rType.isClassType() && rType.asClass().isFinal()) { - // only final (or precise) rhs types can be optimized since rhsType - // may be conservative - Move.mutate(s, INT_MOVE, InstanceOf.getClearResult(s), IC(0)); - return DefUseEffect.MOVE_FOLDED; - } - } - } - return DefUseEffect.UNCHANGED; - } - - private static DefUseEffect objarrayStoreCheck(OPT_Instruction s) { - OPT_Operand val = StoreCheck.getVal(s); - if (val.isNullConstant()) { - // Writing null into an array is trivially safe - Move.mutate(s, GUARD_MOVE, StoreCheck.getClearGuardResult(s), StoreCheck - .getClearGuard(s)); - return DefUseEffect.MOVE_REDUCED; - } else { - OPT_Operand ref = StoreCheck.getRef(s); - VM_TypeReference arrayTypeRef = ref.getType(); - VM_Type typeOfIMElem = arrayTypeRef.getInnermostElementType() - .peekResolvedType(); - if (typeOfIMElem != null) { - VM_Type typeOfVal = val.getType().peekResolvedType(); - if ((typeOfIMElem == typeOfVal) - && (typeOfIMElem.isPrimitiveType() || typeOfIMElem.asClass() - .isFinal())) { - // Writing something of a final type to an array of that - // final type is safe - Move.mutate(s, GUARD_MOVE, StoreCheck.getClearGuardResult(s), - StoreCheck.getClearGuard(s)); - return DefUseEffect.MOVE_REDUCED; - } - } - if (ref.isConstant() - && (arrayTypeRef == VM_TypeReference.JavaLangObjectArray)) { - // We know this to be an array of objects so any store must - // be safe - Move.mutate(s, GUARD_MOVE, StoreCheck.getClearGuardResult(s), - StoreCheck.getClearGuard(s)); - return DefUseEffect.MOVE_REDUCED; - } - if (val.isConstant() && ref.isConstant()) { - // writing a constant value into a constant array - byte ans = OPT_ClassLoaderProxy.includesType(arrayTypeRef - .getArrayElementType(), val.getType()); - if (ans == OPT_Constants.YES) { - // all stores should succeed - Move.mutate(s, GUARD_MOVE, StoreCheck.getClearGuardResult(s), - StoreCheck.getClearGuard(s)); - return DefUseEffect.MOVE_REDUCED; - } else if (ans == OPT_Constants.NO) { - // all stores will fail - Trap.mutate(s, TRAP, StoreCheck.getClearGuardResult(s), - OPT_TrapCodeOperand.StoreCheck()); - return DefUseEffect.TRAP_REDUCED; - } - } - return DefUseEffect.UNCHANGED; - } - } - - private static DefUseEffect objarrayStoreCheckNotNull(OPT_Instruction s) { - OPT_Operand val = StoreCheck.getVal(s); - OPT_Operand ref = StoreCheck.getRef(s); - VM_TypeReference arrayTypeRef = ref.getType(); - VM_Type typeOfIMElem = arrayTypeRef.getInnermostElementType() - .peekResolvedType(); - if (typeOfIMElem != null) { - VM_Type typeOfVal = val.getType().peekResolvedType(); - if ((typeOfIMElem == typeOfVal) - && (typeOfIMElem.isPrimitiveType() || typeOfIMElem.asClass() - .isFinal())) { - // Writing something of a final type to an array of that - // final type is safe - Move.mutate(s, GUARD_MOVE, StoreCheck.getClearGuardResult(s), - StoreCheck.getClearGuard(s)); - return DefUseEffect.MOVE_REDUCED; - } - } - if (ref.isConstant() - && (arrayTypeRef == VM_TypeReference.JavaLangObjectArray)) { - // We know this to be an array of objects so any store must - // be safe - Move.mutate(s, GUARD_MOVE, StoreCheck.getClearGuardResult(s), StoreCheck - .getClearGuard(s)); - return DefUseEffect.MOVE_REDUCED; - } - if (val.isConstant() && ref.isConstant()) { - // writing a constant value into a constant array - byte ans = OPT_ClassLoaderProxy.includesType(arrayTypeRef - .getArrayElementType(), val.getType()); - if (ans == OPT_Constants.YES) { - // all stores should succeed - Move.mutate(s, GUARD_MOVE, StoreCheck.getClearGuardResult(s), - StoreCheck.getClearGuard(s)); - return DefUseEffect.MOVE_REDUCED; - } else if (ans == OPT_Constants.NO) { - // all stores will fail - Trap.mutate(s, TRAP, StoreCheck.getClearGuardResult(s), - OPT_TrapCodeOperand.StoreCheck()); - return DefUseEffect.TRAP_REDUCED; - } - } - return DefUseEffect.UNCHANGED; - } - - private static DefUseEffect mustImplementInterface(OPT_Instruction s) { - OPT_Operand ref = TypeCheck.getRef(s); - if (ref.isNullConstant()) { - // Possible sitatution from constant propagation. This operation - // is really a nop as a null_check should have happened already - Trap.mutate(s, TRAP, null, OPT_TrapCodeOperand.NullPtr()); - return DefUseEffect.TRAP_REDUCED; - } else { - VM_TypeReference lhsType = TypeCheck.getType(s).getTypeRef(); // the - // interface - // that must - // be - // implemented - VM_TypeReference rhsType = ref.getType(); // our type - byte ans = OPT_ClassLoaderProxy.includesType(lhsType, rhsType); - if (ans == OPT_Constants.YES) { - Empty.mutate(s, NOP); - return DefUseEffect.REDUCED; - } else if (ans == OPT_Constants.NO) { - VM_Type rType = rhsType.peekResolvedType(); - 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, OPT_TrapCodeOperand.MustImplement()); - return DefUseEffect.TRAP_REDUCED; - } - } - return DefUseEffect.UNCHANGED; - } - } - - private static DefUseEffect intCondMove(OPT_Instruction s) { - { - OPT_Operand val1 = CondMove.getVal1(s); - OPT_Operand val2 = CondMove.getVal2(s); - int cond = CondMove.getCond(s).evaluate(val1, val2); - if (cond != OPT_ConditionOperand.UNKNOWN) { - // BOTH CONSTANTS OR SIMILAR: FOLD - OPT_Operand val = (cond == OPT_ConditionOperand.TRUE) ? CondMove - .getClearTrueValue(s) : CondMove.getClearFalseValue(s); - Move.mutate(s, INT_MOVE, CondMove.getClearResult(s), val); - return val.isConstant() ? DefUseEffect.MOVE_FOLDED - : DefUseEffect.MOVE_REDUCED; - } - if (val1.isConstant() && !val2.isConstant()) { - // Canonicalize by switching operands and fliping code. - OPT_Operand tmp = CondMove.getClearVal1(s); - CondMove.setVal1(s, CondMove.getClearVal2(s)); - CondMove.setVal2(s, tmp); - CondMove.getCond(s).flipOperands(); - } - OPT_Operand tv = CondMove.getTrueValue(s); - OPT_Operand fv = CondMove.getFalseValue(s); - if (tv.similar(fv)) { - Move.mutate(s, INT_MOVE, CondMove.getClearResult(s), tv); - return tv.isConstant() ? DefUseEffect.MOVE_FOLDED - : DefUseEffect.MOVE_REDUCED; - } - if (tv.isIntConstant() && fv.isIntConstant() - && !CondMove.getCond(s).isFLOATINGPOINT()) { - int itv = tv.asIntConstant().value; - int ifv = fv.asIntConstant().value; - OPT_Operator op = null; - if (val1.isLong()) { - op = BOOLEAN_CMP_LONG; - } else if (val1.isFloat()) { - op = BOOLEAN_CMP_FLOAT; - } else if (val1.isDouble()) { - op = BOOLEAN_CMP_DOUBLE; - } else { - op = BOOLEAN_CMP_INT; - } - if (itv == 1 && ifv == 0) { - BooleanCmp.mutate(s, op, CondMove.getClearResult(s), CondMove - .getClearVal1(s), CondMove.getClearVal2(s), CondMove - .getClearCond(s), new OPT_BranchProfileOperand()); - return DefUseEffect.REDUCED; - } - if (itv == 0 && ifv == 1) { - BooleanCmp.mutate(s, op, CondMove.getClearResult(s), CondMove - .getClearVal1(s), CondMove.getClearVal2(s), CondMove - .getClearCond(s).flipCode(), new OPT_BranchProfileOperand()); - return DefUseEffect.REDUCED; - } - } - } - return DefUseEffect.UNCHANGED; - } - - private static DefUseEffect longCondMove(OPT_Instruction s) { - { - OPT_Operand val1 = CondMove.getVal1(s); - OPT_Operand val2 = CondMove.getVal2(s); - int cond = CondMove.getCond(s).evaluate(val1, val2); - if (cond != OPT_ConditionOperand.UNKNOWN) { - // BOTH CONSTANTS OR SIMILAR: FOLD - OPT_Operand val = (cond == OPT_ConditionOperand.TRUE) ? CondMove - .getClearTrueValue(s) : CondMove.getClearFalseValue(s); - Move.mutate(s, LONG_MOVE, CondMove.getClearResult(s), val); - return val.isConstant() ? DefUseEffect.MOVE_FOLDED - : DefUseEffect.MOVE_REDUCED; - } - if (val1.isConstant() && !val2.isConstant()) { - // Canonicalize by switching operands and fliping code. - OPT_Operand tmp = CondMove.getClearVal1(s); - CondMove.setVal1(s, CondMove.getClearVal2(s)); - CondMove.setVal2(s, tmp); - CondMove.getCond(s).flipOperands(); - } - OPT_Operand tv = CondMove.getTrueValue(s); - OPT_Operand fv = CondMove.getFalseValue(s); - if (tv.similar(fv)) { - Move.mutate(s, LONG_MOVE, CondMove.getClearResult(s), tv); - return tv.isConstant() ? DefUseEffect.MOVE_FOLDED - : DefUseEffect.MOVE_REDUCED; - } - if (tv.isLongConstant() && fv.isLongConstant() - && !CondMove.getCond(s).isFLOATINGPOINT()) { - long itv = tv.asLongConstant().value; - long ifv = fv.asLongConstant().value; - OPT_Operator op = null; - if (val1.isLong()) { - op = BOOLEAN_CMP_LONG; - } else if (val1.isFloat()) { - op = BOOLEAN_CMP_FLOAT; - } else if (val1.isDouble()) { - op = BOOLEAN_CMP_DOUBLE; - } else { - op = BOOLEAN_CMP_INT; - } - if (itv == 1 && ifv == 0) { - BooleanCmp.mutate(s, op, CondMove.getClearResult(s), CondMove - .getClearVal1(s), CondMove.getClearVal2(s), CondMove - .getClearCond(s), new OPT_BranchProfileOperand()); - return DefUseEffect.REDUCED; - } - if (itv == 0 && ifv == 1) { - BooleanCmp.mutate(s, op, CondMove.getClearResult(s), CondMove - .getClearVal1(s), CondMove.getClearVal2(s), CondMove - .getClearCond(s).flipCode(), new OPT_BranchProfileOperand()); - return DefUseEffect.REDUCED; - } - } - } - return DefUseEffect.UNCHANGED; - } - - private static DefUseEffect floatCondMove(OPT_Instruction s) { - { - OPT_Operand val1 = CondMove.getVal1(s); - OPT_Operand val2 = CondMove.getVal2(s); - int cond = CondMove.getCond(s).evaluate(val1, val2); - if (cond != OPT_ConditionOperand.UNKNOWN) { - // BOTH CONSTANTS OR SIMILAR: FOLD - OPT_Operand val = (cond == OPT_ConditionOperand.TRUE) ? CondMove - .getClearTrueValue(s) : CondMove.getClearFalseValue(s); - Move.mutate(s, FLOAT_MOVE, CondMove.getClearResult(s), val); - return val.isConstant() ? DefUseEffect.MOVE_FOLDED - : DefUseEffect.MOVE_REDUCED; - } - if (val1.isConstant() && !val2.isConstant()) { - // Canonicalize by switching operands and fliping code. - OPT_Operand tmp = CondMove.getClearVal1(s); - CondMove.setVal1(s, CondMove.getClearVal2(s)); - CondMove.setVal2(s, tmp); - CondMove.getCond(s).flipOperands(); - } - OPT_Operand tv = CondMove.getTrueValue(s); - OPT_Operand fv = CondMove.getFalseValue(s); - if (tv.similar(fv)) { - Move.mutate(s, FLOAT_MOVE, CondMove.getClearResult(s), tv); - return tv.isConstant() ? DefUseEffect.MOVE_FOLDED - : DefUseEffect.MOVE_REDUCED; - } - } - return DefUseEffect.UNCHANGED; - } - - private static DefUseEffect doubleCondMove(OPT_Instruction s) { - { - OPT_Operand val1 = CondMove.getVal1(s); - OPT_Operand val2 = CondMove.getVal2(s); - int cond = CondMove.getCond(s).evaluate(val1, val2); - if (cond != OPT_ConditionOperand.UNKNOWN) { - // BOTH CONSTANTS OR SIMILAR: FOLD - OPT_Operand val = (cond == OPT_ConditionOperand.TRUE) ? CondMove - .getClearTrueValue(s) : CondMove.getClearFalseValue(s); - Move.mutate(s, DOUBLE_MOVE, CondMove.getClearResult(s), val); - return val.isConstant() ? DefUseEffect.MOVE_FOLDED - : DefUseEffect.MOVE_REDUCED; - } - if (val1.isConstant() && !val2.isConstant()) { - // Canonicalize by switching operands and fliping code. - OPT_Operand tmp = CondMove.getClearVal1(s); - CondMove.setVal1(s, CondMove.getClearVal2(s)); - CondMove.setVal2(s, tmp); - CondMove.getCond(s).flipOperands(); - } - OPT_Operand tv = CondMove.getTrueValue(s); - OPT_Operand fv = CondMove.getFalseValue(s); - if (tv.similar(fv)) { - Move.mutate(s, DOUBLE_MOVE, CondMove.getClearResult(s), tv); - return tv.isConstant() ? DefUseEffect.MOVE_FOLDED - : DefUseEffect.MOVE_REDUCED; - } - } - return DefUseEffect.UNCHANGED; - } - - private static DefUseEffect refCondMove(OPT_Instruction s) { - { - OPT_Operand val1 = CondMove.getVal1(s); - if (val1.isConstant()) { - OPT_Operand val2 = CondMove.getVal2(s); - if (val2.isConstant()) { - // BOTH CONSTANTS: FOLD - int cond = CondMove.getCond(s).evaluate(val1, val2); - if (cond != OPT_ConditionOperand.UNKNOWN) { - OPT_Operand val = (cond == OPT_ConditionOperand.TRUE) ? CondMove - .getClearTrueValue(s) : CondMove.getClearFalseValue(s); - Move.mutate(s, REF_MOVE, CondMove.getClearResult(s), val); - return val.isConstant() ? DefUseEffect.MOVE_FOLDED - : DefUseEffect.MOVE_REDUCED; - } - } else { - // Canonicalize by switching operands and fliping code. - OPT_Operand tmp = CondMove.getClearVal1(s); - CondMove.setVal1(s, CondMove.getClearVal2(s)); - CondMove.setVal2(s, tmp); - CondMove.getCond(s).flipOperands(); - } - } - if (CondMove.getTrueValue(s).similar(CondMove.getFalseValue(s))) { - OPT_Operand val = CondMove.getClearTrueValue(s); - Move.mutate(s, REF_MOVE, CondMove.getClearResult(s), val); - return val.isConstant() ? DefUseEffect.MOVE_FOLDED - : DefUseEffect.MOVE_REDUCED; - } - } - return DefUseEffect.UNCHANGED; - } - - private static DefUseEffect guardCondMove(OPT_Instruction s) { - { - OPT_Operand val1 = CondMove.getVal1(s); - if (val1.isConstant()) { - OPT_Operand val2 = CondMove.getVal2(s); - if (val2.isConstant()) { - // BOTH CONSTANTS: FOLD - int cond = CondMove.getCond(s).evaluate(val1, val2); - if (cond == OPT_ConditionOperand.UNKNOWN) { - OPT_Operand val = (cond == OPT_ConditionOperand.TRUE) ? CondMove - .getClearTrueValue(s) : CondMove.getClearFalseValue(s); - Move.mutate(s, GUARD_MOVE, CondMove.getClearResult(s), val); - return val.isConstant() ? DefUseEffect.MOVE_FOLDED - : DefUseEffect.MOVE_REDUCED; - } - } else { - // Canonicalize by switching operands and fliping code. - OPT_Operand tmp = CondMove.getClearVal1(s); - CondMove.setVal1(s, CondMove.getClearVal2(s)); - CondMove.setVal2(s, tmp); - CondMove.getCond(s).flipOperands(); - } - } - if (CondMove.getTrueValue(s).similar(CondMove.getFalseValue(s))) { - OPT_Operand val = CondMove.getClearTrueValue(s); - Move.mutate(s, GUARD_MOVE, CondMove.getClearResult(s), val); - return val.isConstant() ? DefUseEffect.MOVE_FOLDED - : DefUseEffect.MOVE_REDUCED; - } - } - return DefUseEffect.UNCHANGED; - } - - private static DefUseEffect booleanNot(OPT_Instruction s) { - if (CF_INT) { - OPT_Operand op = Unary.getVal(s); - if (op.isIntConstant()) { - // CONSTANT: FOLD - int val = op.asIntConstant().value; - if (val == 0) { - Move.mutate(s, INT_MOVE, Unary.getClearResult(s), IC(1)); - } else { - Move.mutate(s, INT_MOVE, Unary.getClearResult(s), IC(0)); - } - return DefUseEffect.MOVE_FOLDED; - } - } - return DefUseEffect.UNCHANGED; - } - - private static DefUseEffect booleanCmpInt(OPT_Instruction s) { - if (CF_INT) { - OPT_Operand op1 = BooleanCmp.getVal1(s); - OPT_Operand op2 = BooleanCmp.getVal2(s); - if (op1.isConstant()) { - if (op2.isConstant()) { - // BOTH CONSTANTS: FOLD - int cond = BooleanCmp.getCond(s).evaluate(op1, op2); - if (cond != OPT_ConditionOperand.UNKNOWN) { - Move.mutate(s, INT_MOVE, BooleanCmp.getResult(s), - (cond == OPT_ConditionOperand.TRUE) ? IC(1) : IC(0)); - return DefUseEffect.MOVE_FOLDED; - } - } else { - // Canonicalize by switching operands and fliping code. - OPT_Operand tmp = BooleanCmp.getClearVal1(s); - BooleanCmp.setVal1(s, BooleanCmp.getClearVal2(s)); - BooleanCmp.setVal2(s, tmp); - BooleanCmp.getCond(s).flipOperands(); - } - } - } - return DefUseEffect.UNCHANGED; - } - - private static DefUseEffect booleanCmpAddr(OPT_Instruction s) { - if (CF_ADDR) { - OPT_Operand op1 = BooleanCmp.getVal1(s); - OPT_Operand op2 = BooleanCmp.getVal2(s); - if (op1.isConstant()) { - if (op2.isConstant()) { - // BOTH CONSTANTS: FOLD - int cond = BooleanCmp.getCond(s).evaluate(op1, op2); - if (cond != OPT_ConditionOperand.UNKNOWN) { - Move.mutate(s, REF_MOVE, BooleanCmp.getResult(s), - (cond == OPT_ConditionOperand.TRUE) ? IC(1) : IC(0)); - return DefUseEffect.MOVE_FOLDED; - } - } else { - // Canonicalize by switching operands and fliping code. - OPT_Operand tmp = BooleanCmp.getClearVal1(s); - BooleanCmp.setVal1(s, BooleanCmp.getClearVal2(s)); - BooleanCmp.setVal2(s, tmp); - BooleanCmp.getCond(s).flipOperands(); - } - } - } - return DefUseEffect.UNCHANGED; - } - - private static DefUseEffect booleanCmp2IntOr(OPT_Instruction s) { - if (CF_INT) { - OPT_Operand op1 = BooleanCmp2.getVal1(s); - OPT_Operand op2 = BooleanCmp2.getVal2(s); - if (op1.isConstant()) { - if (op2.isConstant()) { - // 1st 2 operands are constants, can fold if result is true - int cond1 = BooleanCmp2.getCond1(s).evaluate(op1, op2); - if (cond1 == OPT_ConditionOperand.TRUE) { - Move.mutate(s, REF_MOVE, BooleanCmp2.getResult(s), IC(1)); - return DefUseEffect.MOVE_FOLDED; - } else if (cond1 == OPT_ConditionOperand.FALSE) { - BooleanCmp.mutate(s, BOOLEAN_CMP_INT, BooleanCmp2.getResult(s), - BooleanCmp2.getVal3(s), BooleanCmp2.getVal4(s), BooleanCmp2 - .getCond2(s), BooleanCmp2.getBranchProfile2(s)); - DefUseEffect result = booleanCmpInt(s); - return (result == DefUseEffect.UNCHANGED) ? DefUseEffect.REDUCED - : result; - } - } - } - OPT_Operand op3 = BooleanCmp2.getVal3(s); - OPT_Operand op4 = BooleanCmp2.getVal4(s); - if (op3.isConstant()) { - if (op4.isConstant()) { - // 3rd and 4th operands are constants, can fold if result is true - int cond2 = BooleanCmp2.getCond1(s).evaluate(op3, op4); - if (cond2 == OPT_ConditionOperand.TRUE) { - Move.mutate(s, REF_MOVE, BooleanCmp2.getResult(s), IC(1)); - return DefUseEffect.MOVE_FOLDED; - } else if (cond2 == OPT_ConditionOperand.FALSE) { - BooleanCmp.mutate(s, BOOLEAN_CMP_INT, BooleanCmp2.getResult(s), - BooleanCmp2.getVal1(s), BooleanCmp2.getVal2(s), BooleanCmp2 - .getCond1(s), BooleanCmp2.getBranchProfile1(s)); - DefUseEffect result = booleanCmpInt(s); - return (result == DefUseEffect.UNCHANGED) ? DefUseEffect.REDUCED - : result; - } - } - } - } - return DefUseEffect.UNCHANGED; - } - - private static DefUseEffect intAdd(OPT_Instruction s) { - if (CF_INT) { - canonicalizeCommutativeOperator(s); - OPT_Operand op2 = Binary.getVal2(s); - if (op2.isIntConstant()) { - int val2 = op2.asIntConstant().value; - OPT_Operand op1 = Binary.getVal1(s); - if (op1.isIntConstant()) { - // BOTH CONSTANTS: FOLD - int val1 = op1.asIntConstant().value; - Move.mutate(s, INT_MOVE, Binary.getClearResult(s), IC(val1 + val2)); - return DefUseEffect.MOVE_FOLDED; - } else { - // ONLY OP2 IS CONSTANT: ATTEMPT TO APPLY AXIOMS - if (val2 == 0) { - Move.mutate(s, INT_MOVE, Binary.getClearResult(s), Binary - .getClearVal1(s)); - return DefUseEffect.MOVE_REDUCED; - } - } - } - } - return DefUseEffect.UNCHANGED; - } - - private static DefUseEffect intAnd(OPT_Instruction s) { - if (CF_INT) { - canonicalizeCommutativeOperator(s); - OPT_Operand op1 = Binary.getVal1(s); - OPT_Operand op2 = Binary.getVal2(s); - if (op1.similar(op2)) { - // THE SAME OPERAND: x & x == x - Move.mutate(s, INT_MOVE, Binary.getClearResult(s), Binary - .getClearVal1(s)); - return op1.isConstant() ? DefUseEffect.MOVE_FOLDED - : DefUseEffect.MOVE_REDUCED; - } - if (op2.isIntConstant()) { - int val2 = op2.asIntConstant().value; - if (op1.isIntConstant()) { - // BOTH CONSTANTS: FOLD - int val1 = op1.asIntConstant().value; - Move.mutate(s, INT_MOVE, Binary.getClearResult(s), IC(val1 & val2)); - return DefUseEffect.MOVE_FOLDED; - } else { - // ONLY OP2 IS CONSTANT: ATTEMPT TO APPLY AXIOMS - if (val2 == 0) { // x & 0 == 0 - Move.mutate(s, INT_MOVE, Binary.getClearResult(s), IC(0)); - return DefUseEffect.MOVE_FOLDED; - } - if (val2 == -1) { // x & -1 == x & 0xffffffff == x - Move.mutate(s, INT_MOVE, Binary.getClearResult(s), Binary - .getClearVal1(s)); - return DefUseEffect.MOVE_REDUCED; - } - } - } - } - return DefUseEffect.UNCHANGED; - } - - private static DefUseEffect intDiv(OPT_Instruction s) { - if (CF_INT) { - OPT_Operand op1 = GuardedBinary.getVal1(s); - OPT_Operand op2 = GuardedBinary.getVal2(s); - if (op1.similar(op2)) { - // THE SAME OPERAND: x / x == 1 - Move.mutate(s, INT_MOVE, GuardedBinary.getClearResult(s), IC(1)); - return DefUseEffect.MOVE_FOLDED; - } - if (op2.isIntConstant()) { - int val2 = op2.asIntConstant().value; - if (val2 == 0) { - // TODO: This instruction is actually unreachable. - // There will be an INT_ZERO_CHECK - // guarding this instruction that will result in an - // ArithmeticException. We - // should probabbly just remove the INT_DIV as dead code. - return DefUseEffect.UNCHANGED; - } - if (op1.isIntConstant()) { - // BOTH CONSTANTS: FOLD - int val1 = op1.asIntConstant().value; - Move.mutate(s, INT_MOVE, GuardedBinary.getClearResult(s), IC(val1 - / val2)); - return DefUseEffect.MOVE_FOLDED; - } else { - // ONLY OP2 IS CONSTANT: ATTEMPT TO APPLY AXIOMS - if (val2 == 1) { // x / 1 == x; - Move.mutate(s, INT_MOVE, GuardedBinary.getClearResult(s), - GuardedBinary.getClearVal1(s)); - return DefUseEffect.MOVE_REDUCED; - } - // x / c == x >> (log c) if c is power of 2 - int power = PowerOf2(val2); - if (power != -1) { - Binary.mutate(s, INT_SHR, GuardedBinary.getClearResult(s), - GuardedBinary.getClearVal1(s), IC(power)); - return DefUseEffect.REDUCED; - } - } - } - } - return DefUseEffect.UNCHANGED; - } - - private static DefUseEffect intMul(OPT_AbstractRegisterPool regpool, - OPT_Instruction s) { - if (CF_INT) { - canonicalizeCommutativeOperator(s); - OPT_Operand op2 = Binary.getVal2(s); - if (op2.isIntConstant()) { - int val2 = op2.asIntConstant().value; - OPT_Operand op1 = Binary.getVal1(s); - if (op1.isIntConstant()) { - // BOTH CONSTANTS: FOLD - int val1 = op1.asIntConstant().value; - Move.mutate(s, INT_MOVE, Binary.getClearResult(s), IC(val1 * val2)); - return DefUseEffect.MOVE_FOLDED; - } else { - // ONLY OP2 IS CONSTANT: ATTEMPT TO APPLY AXIOMS - if (val2 == -1) { // x * -1 == -x - Unary.mutate(s, INT_NEG, Binary.getClearResult(s), Binary - .getClearVal1(s)); - return DefUseEffect.REDUCED; - } - if (val2 == 0) { // x * 0 == 0 - Move.mutate(s, INT_MOVE, Binary.getClearResult(s), IC(0)); - return DefUseEffect.MOVE_FOLDED; - } - if (val2 == 1) { // x * 1 == x - Move.mutate(s, INT_MOVE, Binary.getClearResult(s), Binary - .getClearVal1(s)); - return DefUseEffect.MOVE_REDUCED; - } - // try to reduce x*c into shift and adds, but only if cost is cheap - if (s.getPrev() != null) { - // don't attempt to reduce if this instruction isn't - // part of a well-formed sequence - int cost = 0; - for (int i = 1; i < BITS_IN_INT; i++) { - if ((val2 & (1 << i)) != 0) { - // each 1 requires a shift and add - cost++; - } - } - if (cost < 5) { - // generate shift and adds - OPT_RegisterOperand val1Operand = Binary.getClearVal1(s) - .asRegister(); - OPT_RegisterOperand resultOperand = regpool.makeTempInt(); - OPT_Instruction move; - if ((val2 & 1) == 1) { - // result = val1 * 1 - move = Move.create(INT_MOVE, resultOperand, val1Operand); - } else { - // result = 0 - move = Move.create(INT_MOVE, resultOperand, IC(0)); - } - move.copyPosition(s); - s.insertBefore(move); - for (int i = 1; i < BITS_IN_INT; i++) { - if ((val2 & (1 << i)) != 0) { - OPT_RegisterOperand tempInt = regpool.makeTempInt(); - OPT_Instruction shift = Binary.create(INT_SHL, tempInt, - val1Operand.copyRO(), IC(i)); - shift.copyPosition(s); - s.insertBefore(shift); - OPT_Instruction add = Binary.create(INT_ADD, resultOperand - .copyRO(), resultOperand.copyRO(), tempInt.copyRO()); - add.copyPosition(s); - s.insertBefore(add); - } - } - Move.mutate(s, INT_MOVE, Binary.getClearResult(s), resultOperand - .copyRO()); - return DefUseEffect.REDUCED; - } - } - } - } - } - return DefUseEffect.UNCHANGED; - } - - private static DefUseEffect intNeg(OPT_Instruction s) { - if (CF_INT) { - OPT_Operand op = Unary.getVal(s); - if (op.isIntConstant()) { - // CONSTANT: FOLD - int val = op.asIntConstant().value; - Move.mutate(s, INT_MOVE, Unary.getClearResult(s), IC(-val)); - return DefUseEffect.MOVE_FOLDED; - } - } - return DefUseEffect.UNCHANGED; - } - - private static DefUseEffect intNot(OPT_Instruction s) { - if (CF_INT) { - OPT_Operand op = Unary.getVal(s); - if (op.isIntConstant()) { - // CONSTANT: FOLD - int val = op.asIntConstant().value; - Move.mutate(s, INT_MOVE, Unary.getClearResult(s), IC(~val)); - return DefUseEffect.MOVE_FOLDED; - } - } - return DefUseEffect.UNCHANGED; - } - - private static DefUseEffect intOr(OPT_Instruction s) { - if (CF_INT) { - canonicalizeCommutativeOperator(s); - OPT_Operand op1 = Binary.getVal1(s); - OPT_Operand op2 = Binary.getVal2(s); - if (op1.similar(op2)) { - // THE SAME OPERAND: x | x == x - Move.mutate(s, INT_MOVE, Binary.getClearResult(s), Binary - .getClearVal1(s)); - return op1.isConstant() ? DefUseEffect.MOVE_FOLDED - : DefUseEffect.MOVE_REDUCED; - } - if (op2.isIntConstant()) { - int val2 = op2.asIntConstant().value; - if (op1.isIntConstant()) { - // BOTH CONSTANTS: FOLD - int val1 = op1.asIntConstant().value; - Move.mutate(s, INT_MOVE, Binary.getClearResult(s), IC(val1 | val2)); - return DefUseEffect.MOVE_FOLDED; - } else { - // ONLY OP2 IS CONSTANT: ATTEMPT TO APPLY AXIOMS - if (val2 == -1) { // x | -1 == x | 0xffffffff == 0xffffffff == -1 - Move.mutate(s, INT_MOVE, Binary.getClearResult(s), IC(-1)); - return DefUseEffect.MOVE_FOLDED; - } - if (val2 == 0) { // x | 0 == x - Move.mutate(s, INT_MOVE, Binary.getClearResult(s), Binary - .getClearVal1(s)); - return DefUseEffect.MOVE_REDUCED; - } - } - } - } - return DefUseEffect.UNCHANGED; - } - - private static DefUseEffect intRem(OPT_Instruction s) { - if (CF_INT) { - OPT_Operand op1 = GuardedBinary.getVal1(s); - OPT_Operand op2 = GuardedBinary.getVal2(s); - if (op1.similar(op2)) { - // THE SAME OPERAND: x % x == 0 - Move.mutate(s, INT_MOVE, GuardedBinary.getClearResult(s), IC(0)); - return DefUseEffect.MOVE_FOLDED; - } - if (op2.isIntConstant()) { - int val2 = op2.asIntConstant().value; - if (val2 == 0) { - // TODO: This instruction is actually unreachable. - // There will be an INT_ZERO_CHECK - // guarding this instruction that will result in an - // ArithmeticException. We - // should probabbly just remove the INT_REM as dead code. - return DefUseEffect.UNCHANGED; - } - if (op1.isIntConstant()) { - // BOTH CONSTANTS: FOLD - int val1 = op1.asIntConstant().value; - Move.mutate(s, INT_MOVE, GuardedBinary.getClearResult(s), IC(val1 - % val2)); - return DefUseEffect.MOVE_FOLDED; - } else { - // ONLY OP2 IS CONSTANT: ATTEMPT TO APPLY AXIOMS - if ((val2 == 1) || (val2 == -1)) { // x % 1 == 0 - Move.mutate(s, INT_MOVE, GuardedBinary.getClearResult(s), IC(0)); - return DefUseEffect.MOVE_FOLDED; - } - } - } - } - return DefUseEffect.UNCHANGED; - } - - private static DefUseEffect intShl(OPT_Instruction s) { - if (CF_INT) { - OPT_Operand op2 = Binary.getVal2(s); - if (op2.isIntConstant()) { - int val2 = op2.asIntConstant().value; - OPT_Operand op1 = Binary.getVal1(s); - if (op1.isIntConstant()) { - // BOTH CONSTANTS: FOLD - int val1 = op1.asIntConstant().value; - Move.mutate(s, INT_MOVE, Binary.getClearResult(s), IC(val1 << val2)); - return DefUseEffect.MOVE_FOLDED; - } else { - // ONLY OP2 IS CONSTANT: ATTEMPT TO APPLY AXIOMS - if (val2 == 0) { // x << 0 == x - Move.mutate(s, INT_MOVE, Binary.getClearResult(s), Binary - .getClearVal1(s)); - return DefUseEffect.MOVE_REDUCED; - } - if (val2 >= BITS_IN_INT) { // x << 32 == 0 - Move.mutate(s, INT_MOVE, Binary.getClearResult(s), IC(0)); - return DefUseEffect.MOVE_FOLDED; - } - } - } - } - return DefUseEffect.UNCHANGED; - } - - private static DefUseEffect intShr(OPT_Instruction s) { - if (CF_INT) { - OPT_Operand op2 = Binary.getVal2(s); - if (op2.isIntConstant()) { - int val2 = op2.asIntConstant().value; - OPT_Operand op1 = Binary.getVal1(s); - if (op1.isIntConstant()) { - // BOTH CONSTANTS: FOLD - int val1 = op1.asIntConstant().value; - Move.mutate(s, INT_MOVE, Binary.getClearResult(s), IC(val1 >> val2)); - return DefUseEffect.MOVE_FOLDED; - } else { - // ONLY OP2 IS CONSTANT: ATTEMPT TO APPLY AXIOMS - if (val2 == 0) { // x >> 0 == x - Move.mutate(s, INT_MOVE, Binary.getClearResult(s), Binary - .getClearVal1(s)); - return DefUseEffect.MOVE_REDUCED; - } - } - } - } - return DefUseEffect.UNCHANGED; - } - - private static DefUseEffect intSub(OPT_Instruction s) { - if (CF_INT) { - OPT_Operand op1 = Binary.getVal1(s); - OPT_Operand op2 = Binary.getVal2(s); - if (op1.similar(op2)) { - // THE SAME OPERAND: x - x == 0 - Move.mutate(s, INT_MOVE, Binary.getClearResult(s), IC(0)); - return DefUseEffect.MOVE_FOLDED; - } - if (op2.isIntConstant()) { - int val2 = op2.asIntConstant().value; - if (op1.isIntConstant()) { - // BOTH CONSTANTS: FOLD - int val1 = op1.asIntConstant().value; - Move.mutate(s, INT_MOVE, Binary.getClearResult(s), IC(val1 - val2)); - return DefUseEffect.MOVE_FOLDED; - } else { - // ONLY OP2 IS CONSTANT: ATTEMPT TO APPLY AXIOMS - if (val2 == 0) { // x - 0 == x - Move.mutate(s, INT_MOVE, Binary.getClearResult(s), Binary - .getClearVal1(s)); - return DefUseEffect.MOVE_REDUCED; - } - // x - c = x + -c - // prefer adds, since some architectures have addi but not subi - Binary.mutate(s, INT_ADD, Binary.getClearResult(s), Binary - .getClearVal1(s), IC(-val2)); - return DefUseEffect.REDUCED; - } - } - } - return DefUseEffect.UNCHANGED; - } - - private static DefUseEffect intUshr(OPT_Instruction s) { - if (CF_INT) { - OPT_Operand op2 = Binary.getVal2(s); - if (op2.isIntConstant()) { - int val2 = op2.asIntConstant().value; - OPT_Operand op1 = Binary.getVal1(s); - if (op1.isIntConstant()) { - // BOTH CONSTANTS: FOLD - int val1 = op1.asIntConstant().value; - Move.mutate(s, INT_MOVE, Binary.getClearResult(s), IC(val1 >>> val2)); - return DefUseEffect.MOVE_FOLDED; - } else { - // ONLY OP2 IS CONSTANT: ATTEMPT TO APPLY AXIOMS - if (val2 == 0) { // x >>> 0 == x - Move.mutate(s, INT_MOVE, Binary.getClearResult(s), Binary - .getClearVal1(s)); - return DefUseEffect.MOVE_REDUCED; - } - if (val2 >= BITS_IN_INT) { // x >>> 32 == 0 - Move.mutate(s, INT_MOVE, Binary.getClearResult(s), IC(0)); - return DefUseEffect.MOVE_FOLDED; - } - } - } - } - return DefUseEffect.UNCHANGED; - } - - private static DefUseEffect intXor(OPT_Instruction s) { - if (CF_INT) { - canonicalizeCommutativeOperator(s); - OPT_Operand op1 = Binary.getVal1(s); - OPT_Operand op2 = Binary.getVal2(s); - if (op1.similar(op2)) { - // THE SAME OPERAND: x ^ x == 0 - Move.mutate(s, INT_MOVE, Binary.getClearResult(s), IC(0)); - return DefUseEffect.MOVE_FOLDED; - } - if (op2.isIntConstant()) { - int val2 = op2.asIntConstant().value; - - if (op1.isIntConstant()) { - // BOTH CONSTANTS: FOLD - int val1 = op1.asIntConstant().value; - Move.mutate(s, INT_MOVE, Binary.getClearResult(s), IC(val1 ^ val2)); - return DefUseEffect.MOVE_FOLDED; - } else { - // ONLY OP2 IS CONSTANT: ATTEMPT TO APPLY AXIOMS - if (val2 == -1) { // x ^ -1 == x ^ 0xffffffff = ~x - Unary.mutate(s, INT_NOT, Binary.getClearResult(s), Binary - .getClearVal1(s)); - return DefUseEffect.REDUCED; - } - if (val2 == 0) { // x ^ 0 == x - Move.mutate(s, INT_MOVE, Binary.getClearResult(s), Binary - .getClearVal1(s)); - return DefUseEffect.MOVE_REDUCED; - } - } - } - } - return DefUseEffect.UNCHANGED; - } - - private static DefUseEffect refAdd(OPT_Instruction s) { - if (CF_ADDR) { - canonicalizeCommutativeOperator(s); - OPT_Operand op2 = Binary.getVal2(s); - if (op2.isConstant() && !op2.isObjectConstant()) { - Address val2 = getAddressValue(op2); - OPT_Operand op1 = Binary.getVal1(s); - if (op1.isConstant() && !op1.isObjectConstant()) { - // BOTH CONSTANTS: FOLD - Address val1 = getAddressValue(op1); - Move.mutate(s, REF_MOVE, Binary.getClearResult(s), AC(val1.plus(val2 - .toWord().toOffset()))); - return DefUseEffect.MOVE_FOLDED; - } else { - // ONLY OP2 IS CONSTANT: ATTEMPT TO APPLY AXIOMS - if (val2.isZero()) { // x + 0 == x - if (op1.isIntLike()) { - ... [truncated message content] |