From: <mic...@us...> - 2007-03-28 13:09:25
|
Revision: 12 http://svn.sourceforge.net/pearcolator/?rev=12&view=rev Author: michael_baer Date: 2007-03-28 06:09:25 -0700 (Wed, 28 Mar 2007) Log Message: ----------- Updates due to package renaming Modified Paths: -------------- rvmroot.patch Modified: rvmroot.patch =================================================================== --- rvmroot.patch 2007-03-27 15:41:07 UTC (rev 11) +++ rvmroot.patch 2007-03-28 13:09:25 UTC (rev 12) @@ -96,6 +96,109 @@ # Load a singed byte # NOTE: Because of our strategy of using explict guard instructions, there is no # way in the HIR/LIR that the actual load instruction can except. +Index: rvm/src/org/jikesrvm/opt/ia32/OPT_ConvertALUOperators.java +=================================================================== +--- rvm/src/org/jikesrvm/opt/ia32/OPT_ConvertALUOperators.java (revision 11903) ++++ rvm/src/org/jikesrvm/opt/ia32/OPT_ConvertALUOperators.java (working copy) +@@ -152,6 +152,7 @@ + case REF_XOR_opcode: commutative(s, INT_XOR_ACC, ir); break; + case INT_XOR_opcode: commutative(s, INT_XOR_ACC, ir); break; + case INT_NEG_opcode: unary(s, INT_NEG_ACC, ir); break; ++ case REF_NEG_opcode: unary(s, INT_NEG_ACC, ir); break; + case REF_NOT_opcode: unary(s, INT_NOT_ACC, ir); break; + case INT_NOT_opcode: unary(s, INT_NOT_ACC, ir); break; + +Index: rvm/src/org/jikesrvm/opt/OPT_Simplifier.java +=================================================================== +--- rvm/src/org/jikesrvm/opt/OPT_Simplifier.java (revision 11903) ++++ rvm/src/org/jikesrvm/opt/OPT_Simplifier.java (working copy) +@@ -1476,6 +1476,11 @@ + return DefUseEffect.REDUCED; + } + } ++ else if (op1.isIntConstant() && (op1.asIntConstant().value == 0)) { ++ Unary.mutate(s, INT_NEG, Binary.getClearResult(s), ++ Binary.getClearVal2(s)); ++ return DefUseEffect.REDUCED; ++ } + } + return DefUseEffect.UNCHANGED; + } +@@ -1742,6 +1747,14 @@ + return DefUseEffect.REDUCED; + } + } ++ else if (op1.isConstant() && !op1.isObjectConstant()) { ++ Address val1 = getAddressValue(op1); ++ if (val1.EQ(Address.zero())) { ++ Unary.mutate(s, REF_NEG, Binary.getClearResult(s), ++ Binary.getClearVal2(s)); ++ return DefUseEffect.REDUCED; ++ } ++ } + } + return DefUseEffect.UNCHANGED; + } +@@ -2147,6 +2160,11 @@ + } + } + } ++ else if (op1.isLongConstant() && (op1.asLongConstant().value == 0)) { ++ Unary.mutate(s, LONG_NEG, Binary.getClearResult(s), ++ Binary.getClearVal2(s)); ++ return DefUseEffect.REDUCED; ++ } + } + return DefUseEffect.UNCHANGED; + } +@@ -2345,10 +2363,10 @@ + } + private static DefUseEffect floatSub(OPT_Instruction s) { + if (CF_FLOAT) { ++ OPT_Operand op1 = Binary.getVal1(s); + OPT_Operand op2 = Binary.getVal2(s); + if (op2.isFloatConstant()) { + float val2 = op2.asFloatConstant().value; +- OPT_Operand op1 = Binary.getVal1(s); + if (op1.isFloatConstant()) { + // BOTH CONSTANTS: FOLD + float val1 = op1.asFloatConstant().value; +@@ -2363,6 +2381,11 @@ + return DefUseEffect.MOVE_REDUCED; + } + } ++ else if (op1.isFloatConstant() && (op1.asFloatConstant().value == 0.0f)) { ++ Unary.mutate(s, FLOAT_NEG, Binary.getClearResult(s), ++ Binary.getClearVal2(s)); ++ return DefUseEffect.REDUCED; ++ } + } + return DefUseEffect.UNCHANGED; + } +@@ -2496,10 +2519,10 @@ + } + private static DefUseEffect doubleSub(OPT_Instruction s) { + if (CF_DOUBLE) { ++ OPT_Operand op1 = Binary.getVal1(s); + OPT_Operand op2 = Binary.getVal2(s); + if (op2.isDoubleConstant()) { + double val2 = op2.asDoubleConstant().value; +- OPT_Operand op1 = Binary.getVal1(s); + if (op1.isDoubleConstant()) { + // BOTH CONSTANTS: FOLD + double val1 = op1.asDoubleConstant().value; +@@ -2514,6 +2537,11 @@ + return DefUseEffect.MOVE_REDUCED; + } + } ++ else if (op1.isDoubleConstant() && (op1.asDoubleConstant().value == 0.0)) { ++ Unary.mutate(s, DOUBLE_NEG, Binary.getClearResult(s), ++ Binary.getClearVal2(s)); ++ return DefUseEffect.REDUCED; ++ } + } + return DefUseEffect.UNCHANGED; + } Index: rvm/src/org/jikesrvm/opt/VM_OptCompiledMethod.java =================================================================== --- rvm/src/org/jikesrvm/opt/VM_OptCompiledMethod.java (revision 11903) @@ -122,6 +225,1519 @@ VM_BytecodeStream bcodes = realMethod.getBytecodes(); bcodes.reset(bci); int opcode = bcodes.nextInstruction(); +Index: rvm/src/org/jikesrvm/opt/OPT_ExpressionFolding.java +=================================================================== +--- rvm/src/org/jikesrvm/opt/OPT_ExpressionFolding.java (revision 11903) ++++ rvm/src/org/jikesrvm/opt/OPT_ExpressionFolding.java (working copy) +@@ -15,35 +15,68 @@ + import java.util.HashSet; + import java.util.Iterator; + import org.vmmagic.unboxed.Address; +- ++import org.vmmagic.unboxed.Word; ++import static org.jikesrvm.opt.ir.OPT_IRTools.AC; ++import static org.jikesrvm.opt.ir.OPT_IRTools.DC; ++import static org.jikesrvm.opt.ir.OPT_IRTools.FC; ++import static org.jikesrvm.opt.ir.OPT_IRTools.IC; ++import static org.jikesrvm.opt.ir.OPT_IRTools.LC; + /** + * This class simplifies expressions in SSA form. + * + * @author Stephen Fink ++ * @author Ian Rogers ++ * @author Michael Baer + */ + class OPT_ExpressionFolding { + private static final boolean RESTRICT_TO_DEAD_EXPRESSIONS = true; + ++ /** ++ * Basic configuration options to enable/disable folding of certain instructions and operands. ++ */ ++ private final static boolean FOLD_INTS = true; ++ private final static boolean FOLD_REFS = true; ++ private final static boolean FOLD_LONGS = true; ++ private final static boolean FOLD_FLOATS = true; ++ private final static boolean FOLD_DOUBLES = true; ++ ++ private final static boolean FOLD_SUBS = true; ++ private final static boolean FOLD_ADDS = true; ++ private final static boolean FOLD_MULTS = true; ++ private final static boolean FOLD_SHIFTLS = true; ++ private final static boolean FOLD_SHIFTRS = true; ++ private final static boolean FOLD_CMPS = true; ++ private final static boolean FOLD_IFCMPS = true; ++ private final static boolean FOLD_XORS = true; ++ private final static boolean FOLD_ORS = true; ++ private final static boolean FOLD_ANDS = true; ++ private final static boolean FOLD_NEGS = true; ++ private final static boolean FOLD_NOTS = true; ++ private final static boolean FOLD_NEG_ADD = true; //fold NEG followed by ADD to a SUB? ++ private final static boolean FOLD_NEG_SUB = true; //fold NEG followed by SUB to a reversed SUB? ++ + /** + * Perform the transformation. + * + * If we have, in SSA form, + * <pre> +- * x = a + c1 +- * y = x + c2 ++ * x = a op1 c1 ++ * y = x op2 c2 + * </pre> + * where c1 and c2 are constants, replace the def of y by + * <pre> +- * y = a + (c1+c2) ++ * y = a op1 (c1 op3 c2) + * </pre> +- * Perform a similar transformation for subtraction. ++ * Where op1, op2 and op3 are add, subtract, multiply, and, or, xor and ++ * compare. Repeatedly apply transformation until all expressions are ++ * folded. + * + * <p> PRECONDITIONS: SSA form, register lists computed + * + * @param ir the governing IR + */ + public static void perform(OPT_IR ir) { +- ++ + // Create a set of potential computations to fold. + HashSet<OPT_Register> candidates = new HashSet<OPT_Register>(20); + +@@ -64,38 +97,101 @@ + boolean didSomething = true; + while (didSomething) { + didSomething = false; +- for (OPT_Register r : candidates) { ++ ++ for ( Iterator<OPT_Register> it = candidates.iterator(); it.hasNext();) { ++ OPT_Register r = it.next(); + OPT_Instruction s = r.getFirstDef(); +- OPT_Operand val1 = Binary.getVal1(s); ++ OPT_Operand val1; ++ ++ if (Binary.conforms(s)) ++ val1 = Binary.getVal1(s); ++ else if (Unary.conforms(s)) { ++ val1 = Unary.getVal(s); ++ } ++ else if (BooleanCmp.conforms(s)) { ++ val1 = BooleanCmp.getVal1(s); ++ } ++ else if (IfCmp.conforms(s)) { ++ val1 = IfCmp.getVal1(s); ++ } ++ else if (IfCmp2.conforms(s)) { ++ val1 = IfCmp2.getVal1(s); ++ } ++ else { ++ // we're not optimising any other instruction types ++ continue; ++ } ++ + if (VM.VerifyAssertions) { + if (!val1.isRegister()) + VM.sysWrite("Expression folding trouble AAA" + s); + VM._assert(val1.isRegister()); + } ++ //purely debug ++ if (val1.isConstant()) ++ { ++ OPT_Operand val2 = Binary.getVal2(s); ++ throw new RuntimeException("Constant?" + val2.isConstant() + " | val2 " + val2 + " | Val2 Type: " + val2.getClass().toString() + " | Instr: " + s.toString() + " | " + s.getClass().toString()); ++ } ++ + if (candidates.contains(val1.asRegister().register)) { + OPT_Instruction def = val1.asRegister().register.getFirstDef(); +- OPT_Operand def1 = Binary.getVal1(def); ++ ++ /* check if the defining instruction has not mutated yet*/ ++ if (isCandidateExpression(def) == null) ++ continue; ++ + if (VM.VerifyAssertions) { +- if (!def1.isRegister()) +- VM.sysWrite("Expression folding trouble BBB" + def); +- VM._assert(def1.isRegister()); ++ OPT_Operand def1; ++ if (Binary.conforms(def)) ++ def1 = Binary.getVal1(def); ++ else if (Unary.conforms(def)) { ++ def1 = Unary.getVal(def); ++ } ++ else { ++ def1 = null; ++ } ++ ++ if (def1 != null) { ++ if (!def1.isRegister()) ++ VM.sysWrite("Expression folding trouble BBB" + def); ++ VM._assert(def1.isRegister()); ++ } + } +- OPT_Operand def2 = Binary.getVal2(def); ++ + if (VM.VerifyAssertions) { +- if (!def2.isConstant()) +- VM.sysWrite("Expression folding trouble CCC" + def); +- VM._assert(def2.isConstant()); ++ OPT_Operand def2; ++ if (Binary.conforms(def)) ++ def2 = Binary.getVal1(def); ++ else if (Unary.conforms(def)) { ++ def2 = Unary.getVal(def); ++ } ++ else { ++ def2 = null; ++ } ++ ++ if (def2 != null) { ++ if (!def2.isRegister()) ++ VM.sysWrite("Expression folding trouble BBB" + def); ++ VM._assert(def2.isRegister()); ++ } + } + + OPT_Instruction newS = transform(s, def); +- s.insertAfter(newS); +- OPT_DefUse.updateDUForNewInstruction(newS); +- OPT_DefUse.removeInstructionAndUpdateDU(s); +- didSomething = true; ++ if (newS != null) { ++ /* check if this expression is still an optimisation candidate */ ++ if (isCandidateExpression(newS) == null) ++ it.remove(); ++ ++ s.insertAfter(newS); ++ OPT_DefUse.updateDUForNewInstruction(newS); ++ OPT_DefUse.removeInstructionAndUpdateDU(s); ++ didSomething = true; ++ } + } + } + } +- } ++ } + + /** + * Prune the candidate set; restrict candidates to only allow +@@ -105,7 +201,29 @@ + for (Iterator<OPT_Register> i = candidates.iterator(); i.hasNext(); ) { + OPT_Register r = i.next(); + OPT_Instruction s = r.getFirstDef(); +- OPT_Operand val1 = Binary.getVal1(s); ++ OPT_Operand val1; ++ if (Binary.conforms(s)) { ++ val1 = Binary.getVal1(s); ++ } ++ else if (Unary.conforms(s)) { ++ val1 = Unary.getVal(s); ++ } ++ else if (BooleanCmp.conforms(s)) { ++ val1 = BooleanCmp.getVal1(s); ++ } ++ else if (IfCmp.conforms(s)) { ++ val1 = IfCmp.getVal1(s); ++ } ++ else if (IfCmp2.conforms(s)) { ++ val1 = IfCmp2.getVal1(s); ++ } ++ else { ++ OPT_OptimizingCompilerException.UNREACHABLE(); ++ return; ++ } ++ ++ if (VM.VerifyAssertions) VM._assert(!val1.isConstant(), "Error with val1 of "+s); ++ + OPT_Register v1 = val1.asRegister().register; + if (candidates.contains(v1)) { + for (Enumeration<OPT_RegisterOperand> uses = OPT_DefUse.uses(v1); uses.hasMoreElements();) { +@@ -121,113 +239,965 @@ + } + + /** +- * Perform the transfomation on the instruction s = A +/- c +- * where def is the definition of A. ++ * Perform the transfomation 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 OPT_Instruction transform(OPT_Instruction s, +- OPT_Instruction def) { +- if (s.operator == INT_ADD || s.operator == INT_SUB) { +- return transformForInt(s,def); +- } else if (s.operator == REF_ADD || s.operator == REF_SUB) { +- return transformForWord(s,def); +- } else { +- return transformForLong(s,def); ++ OPT_Instruction def) { ++ // x = a op1 c1 ++ // y = x op2 c2 ++ OPT_RegisterOperand a; ++ OPT_RegisterOperand y; ++ if (Binary.conforms(def)) ++ a = Binary.getVal1(def).asRegister(); ++ else if (Unary.conforms(def)) ++ a = Unary.getVal(def).asRegister(); ++ else if (BooleanCmp.conforms(def) || IfCmp.conforms(def) || IfCmp2.conforms(def)) ++ // we don't fold in case of a Boolean/IfCmp coming before ++ // the instruction to be folded ++ return null; ++ else { ++ OPT_OptimizingCompilerException.UNREACHABLE(); ++ return null; + } +- } + +- private static int getIntValue(OPT_Operand op) { +- if (op instanceof OPT_NullConstantOperand) //is this still necessary? +- return 0; +- if (op instanceof OPT_IntConstantOperand) +- return op.asIntConstant().value; +- throw new OPT_OptimizingCompilerException("Cannot getIntValue from this operand " + op); +- } ++ if (Binary.conforms(s)) ++ y = Binary.getResult(s); ++ else if (Unary.conforms(s)) ++ y = Unary.getResult(s); ++ else if (BooleanCmp.conforms(s)) ++ y = BooleanCmp.getResult(s); ++ else if (IfCmp.conforms(s)) ++ y = IfCmp.getGuardResult(s); ++ else if (IfCmp2.conforms(s)) ++ y = IfCmp2.getGuardResult(s); ++ else { ++ OPT_OptimizingCompilerException.UNREACHABLE(); ++ return null; ++ } + +- private static Address getAddressValue(OPT_Operand op) { +- if (op instanceof OPT_NullConstantOperand) +- return Address.zero(); +- if (op instanceof OPT_AddressConstantOperand) +- return op.asAddressConstant().value; +- if (op instanceof OPT_IntConstantOperand) +- return Address.fromIntSignExtend(op.asIntConstant().value); +- if (VM.BuildFor64Addr && op instanceof OPT_LongConstantOperand) +- return Address.fromLong(op.asLongConstant().value); +- throw new OPT_OptimizingCompilerException("Cannot getWordValue from this operand " + op); +- } ++ switch(s.operator.opcode) { ++ // 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_NEG_ADD) { ++ // 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_NEG_ADD) { ++ // 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_NEG_ADD) { ++ // 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_NEG_ADD) { ++ // 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_NEG_ADD) { ++ // 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_NEG_SUB) { ++ // 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_NEG_SUB) { ++ // 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_NEG_SUB) { ++ // 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_NEG_SUB) { ++ // 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_NEG_SUB) { ++ // 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_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)); ++ } ++ } ++ 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)); ++ } ++ } ++ 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)); ++ } ++ } ++ 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)); ++ } ++ } ++ 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)); ++ } ++ } ++ 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 { ++ return null; ++ } ++ } ++ else ++ 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)); ++ } ++ } ++ 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)); + +- private static OPT_AddressConstantOperand addConstantValues(boolean neg1, OPT_Operand op1, boolean neg2, OPT_Operand op2) { +- Address a = getAddressValue(op1); +- if (neg1) a = Address.zero().minus(a.toWord().toOffset()); //negate op1 +- if (neg2) a = a.minus(getAddressValue(op2).toWord().toOffset()); //sub op2 +- else a = a.plus(getAddressValue(op2).toWord().toOffset()); //add op2 +- return new OPT_AddressConstantOperand(a); +- } +- +- /** +- * Perform the transfomation on the instruction s = A +/- c +- * where def is the definition of A. +- * @return the new instruction to replace s; +- */ +- private static OPT_Instruction transformForInt(OPT_Instruction s, +- OPT_Instruction def) { +- // s is y = A + c +- OPT_RegisterOperand y = Binary.getResult(s); +- // OPT_RegisterOperand A = Binary.getVal1(s).asRegister(); - unused +- int c = getIntValue(Binary.getVal2(s)); +- if (s.operator == INT_SUB) c = -c; ++ } ++ } ++ 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)); ++ } ++ } ++ 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)); ++ } ++ } ++ } ++ 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)); ++ } ++ } ++ } ++ 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)); ++ } ++ } ++ } ++ 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)); ++ } ++ } ++ 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_ADD) { ++ long c1 = getLongValue(Binary.getVal2(def)); ++ // x = a + c1; y = x cmp c2 ++ return Binary.create(LONG_CMP, y.copyRO(), a.copyRO(), LC(c2-c1)); ++ } ++ else if (def.operator == LONG_SUB) { ++ long c1 = getLongValue(Binary.getVal2(def)); ++ // x = a - c1; y = x cmp c2 ++ return Binary.create(LONG_CMP, y.copyRO(), a.copyRO(), LC(c1+c2)); ++ } + +- // A = B + d +- OPT_RegisterOperand B = Binary.getVal1(def).asRegister(); +- int d = getIntValue(Binary.getVal2(def)); +- if (def.operator == INT_SUB) d = -d; ++ else 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)); ++ OPT_ConditionOperand cond = (OPT_ConditionOperand)BooleanCmp.getCond(s).copy(); ++ OPT_BranchProfileOperand prof = (OPT_BranchProfileOperand)BooleanCmp.getBranchProfile(s).copy(); ++ 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); ++ } ++ } ++ return null; ++ } ++ case BOOLEAN_CMP_LONG_opcode: { ++ if (FOLD_LONGS && FOLD_CMPS) { ++ long c2 = getLongValue(BooleanCmp.getVal2(s)); ++ OPT_ConditionOperand cond = (OPT_ConditionOperand)BooleanCmp.getCond(s).copy(); ++ OPT_BranchProfileOperand prof = (OPT_BranchProfileOperand)BooleanCmp.getBranchProfile(s).copy(); ++ 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)); ++ OPT_ConditionOperand cond = (OPT_ConditionOperand)BooleanCmp.getCond(s).copy(); ++ OPT_BranchProfileOperand prof = (OPT_BranchProfileOperand)BooleanCmp.getBranchProfile(s).copy(); ++ if (def.operator == REF_ADD) { ++ Address c1 = getAddressValue(BooleanCmp.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(BooleanCmp.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)); ++ OPT_ConditionOperand cond = (OPT_ConditionOperand)IfCmp.getCond(s).copy(); ++ OPT_BranchOperand target = (OPT_BranchOperand)IfCmp.getTarget(s).copy(); ++ OPT_BranchProfileOperand prof = (OPT_BranchProfileOperand)IfCmp.getBranchProfile(s).copy(); ++ if (def.operator == INT_ADD) { ++ int c1 = getIntValue(IfCmp.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(IfCmp.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); ++ } ++ } ++ return null; ++ } ++ case LONG_IFCMP_opcode: { ++ if (FOLD_LONGS && FOLD_IFCMPS) { ++ long c2 = getLongValue(IfCmp.getVal2(s)); ++ OPT_ConditionOperand cond = (OPT_ConditionOperand)IfCmp.getCond(s).copy(); ++ OPT_BranchOperand target = (OPT_BranchOperand)IfCmp.getTarget(s).copy(); ++ OPT_BranchProfileOperand prof = (OPT_BranchProfileOperand)IfCmp.getBranchProfile(s).copy(); ++ if (def.operator == LONG_ADD) { ++ long c1 = getLongValue(IfCmp.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(IfCmp.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)); ++ OPT_ConditionOperand cond = (OPT_ConditionOperand)IfCmp.getCond(s).copy(); ++ OPT_BranchOperand target = (OPT_BranchOperand)IfCmp.getTarget(s).copy(); ++ OPT_BranchProfileOperand prof = (OPT_BranchProfileOperand)IfCmp.getBranchProfile(s).copy(); ++ if (def.operator == FLOAT_ADD) { ++ float c1 = getFloatValue(IfCmp.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(IfCmp.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)); ++ OPT_ConditionOperand cond = (OPT_ConditionOperand)IfCmp.getCond(s).copy(); ++ OPT_BranchOperand target = (OPT_BranchOperand)IfCmp.getTarget(s).copy(); ++ OPT_BranchProfileOperand prof = (OPT_BranchProfileOperand)IfCmp.getBranchProfile(s).copy(); ++ if (def.operator == DOUBLE_ADD) { ++ double c1 = getDoubleValue(IfCmp.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(IfCmp.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)); ++ OPT_ConditionOperand cond = (OPT_ConditionOperand)IfCmp.getCond(s).copy(); ++ OPT_BranchOperand target = (OPT_BranchOperand)IfCmp.getTarget(s).copy(); ++ OPT_BranchProfileOperand prof = (OPT_BranchProfileOperand)IfCmp.getBranchProfile(s).copy(); ++ if (def.operator == REF_ADD) { ++ Address c1 = getAddressValue(IfCmp.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(IfCmp.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(IfCmp.getVal2(s)); ++ OPT_ConditionOperand cond1 = (OPT_ConditionOperand)IfCmp2.getCond1(s).copy(); ++ OPT_ConditionOperand cond2 = (OPT_ConditionOperand)IfCmp2.getCond2(s).copy(); ++ OPT_BranchOperand target1 = (OPT_BranchOperand)IfCmp2.getTarget1(s).copy(); ++ OPT_BranchOperand target2 = (OPT_BranchOperand)IfCmp2.getTarget2(s).copy(); ++ OPT_BranchProfileOperand prof1 = (OPT_BranchProfileOperand)IfCmp2.getBranchProfile1(s).copy(); ++ OPT_BranchProfileOperand prof2 = (OPT_BranchProfileOperand)IfCmp2.getBranchProfile2(s).copy(); ++ if (def.operator == INT_ADD) { ++ int c1 = getIntValue(IfCmp.getVal2(def)); ++ // x = a + c1; y = x cmp c2 ++ return IfCmp2.create(INT_IFCMP, y.copyRO(), a.copyRO(), IC(c2-c1), ++ cond1, target1, prof1, cond2, target2, prof2); ++ } ++ else if (def.operator == INT_SUB) { ++ int c1 = getIntValue(IfCmp.getVal2(def)); ++ // x = a - c1; y = x cmp c2 ++ return IfCmp2.create(INT_IFCMP, y.copyRO(), a.copyRO(), IC(c1+c2), ++ cond1, target1, prof1, cond2, target2, prof2); ++ } ++ } ++ return null; ++ } + +- // rewrite so y = B + (c+d) +- OPT_IntConstantOperand val2 = new OPT_IntConstantOperand(c+d); +- return Binary.create(INT_ADD,y.copyRO(),B.copy(),val2); +- } ++ case INT_NEG_opcode: { ++ if (FOLD_INTS && FOLD_NEGS) { ++ if (def.operator == INT_NEG) { ++ //x = -z; y = -x; ++ return Unary.create(INT_MOVE, y.copyRO(), Unary.getVal(def)); ++ } ++ } ++ return null; ++ } + +- /** +- * Perform the transfomation on the instruction s = A +/- c +- * where def is the definition of A. +- * @return the new instruction to replace s; +- */ +- private static OPT_Instruction transformForLong(OPT_Instruction s, +- OPT_Instruction def) { +- // s is y = A + c +- OPT_RegisterOperand y = Binary.getResult(s); +- // OPT_RegisterOperand A = Binary.getVal1(s).asRegister(); - unused +- long c = Binary.getVal2(s).asLongConstant().value; +- if (s.operator == LONG_SUB) c = -c; ++ case REF_NEG_opcode: { ++ if (FOLD_REFS && FOLD_NEGS) { ++ if (def.operator == REF_NEG) { ++ //x = -z; y = -x; ++ return Unary.create(REF_MOVE, y.copyRO(), Unary.getVal(def)); ++ } ++ } ++ return null; ++ } + +- // A = B + d +- OPT_RegisterOperand B = Binary.getVal1(def).asRegister(); +- long d = Binary.getVal2(def).asLongConstant().value; +- if (def.operator == LONG_SUB) d = -d; ++ case LONG_NEG_opcode: { ++ if (FOLD_LONGS && FOLD_NEGS) { ++ if (def.operator == LONG_NEG) { ++ //x = -z; y = -x; ++ return Unary.create(LONG_MOVE, y.copyRO(), Unary.getVal(def)); ++ } ++ } ++ return null; ++ } + +- // rewrite so y = B + (c+d) +- OPT_LongConstantOperand val2 = new OPT_LongConstantOperand(c+d); +- return Binary.create(LONG_ADD,y.copyRO(),B.copy(),val2); +- } ++ case FLOAT_NEG_opcode: { ++ if (FOLD_FLOATS && FOLD_NEGS) { ++ if (def.operator == FLOAT_NEG) { ++ //x = -z; y = -x; ++ return Unary.create(FLOAT_MOVE, y.copyRO(), Unary.getVal(def)); ++ } ++ } ++ return null; ++ } + +- /** +- * Perform the transfomation on the instruction s = A +/- c +- * where def is the definition of A. +- * @return the new instruction to replace s; +- */ +- private static OPT_Instruction transformForWord(OPT_Instruction s, +- OPT_Instruction def) { +- // s is y = A + c +- OPT_RegisterOperand y = Binary.getResult(s); +- // OPT_RegisterOperand A = Binary.getVal1(s).asRegister(); - unused ++ case DOUBLE_NEG_opcode: { ++ if (FOLD_DOUBLES && FOLD_NEGS) { ++ if (def.operator == DOUBLE_NEG) { ++ //x = -z; y = -x; ++ return Unary.create(DOUBLE_MOVE, y.copyRO(), Unary.getVal(def)); ++ } ++ } ++ return null; ++ } + +- // A = B + d +- OPT_RegisterOperand B = Binary.getVal1(def).asRegister(); ++ case INT_NOT_opcode: { ++ if (FOLD_INTS && FOLD_NOTS) { ++ if (def.operator == INT_NOT) { ++ //x = -1 ^ z; y = -1 ^ x; ++ return Unary.create(INT_MOVE, y.copyRO(), Unary.getVal(def)); ++ } ++ } ++ return null; ++ } + +- // rewrite so y = B + (c+d) +- OPT_AddressConstantOperand val2 = addConstantValues(s.operator == REF_SUB, Binary.getVal2(s), def.operator == REF_SUB, Binary.getVal2(def)); +- return Binary.create(REF_ADD,y.copyRO(),B.copy(),val2); ++ case REF_NOT_opcode: { ++ if (FOLD_REFS && FOLD_NOTS) { ++ if (def.operator == REF_NOT) { ++ //x = -1 ^ z; y = -1 ^ x; ++ return Unary.create(REF_MOVE, y.copyRO(), Unary.getVal(def)); ++ } ++ } ++ return null; ++ } ++ ++ ++ case LONG_NOT_opcode: { ++ if (FOLD_LONGS && FOLD_NOTS) { ++ if (def.operator == LONG_NOT) { ++ //x = -1 ^ z; y = -1 ^ x; ++ return Unary.create(LONG_MOVE, y.copyRO(), Unary.getVal(def)); ++ } ++ } ++ return null; ++ } ++ ++ default: ++ OPT_OptimizingCompilerException.UNREACHABLE(); ++ return null; ++ } + } + + /** +@@ -236,19 +1206,218 @@ + * @return the computed register, or null + */ + private static OPT_Register isCandidateExpression(OPT_Instruction s) { +- if (s.operator == INT_ADD || s.operator == LONG_ADD || +- s.operator == REF_ADD || s.operator == REF_SUB || +- s.operator == INT_SUB || s.operator == LONG_SUB ) { ++ ++ switch(s.operator.opcode) { ++ // Foldable operators ++ ++ case INT_NOT_opcode: ++ case REF_NOT_opcode: ++ case LONG_NOT_opcode: ++ ++ case INT_NEG_opcode: ++ case REF_NEG_opcode: ++ case LONG_NEG_opcode: ++ case FLOAT_NEG_opcode: ++ case DOUBLE_NEG_opcode: { ++ OPT_Operand val1 = Unary.getVal(s); ++ // if val1 is constant too, this should've been constant folded ++ // beforehand. Give up. ++ if (val1.isConstant()) return null; ++ return Unary.getResult(s).asRegister().register; ++ } ++ ++ case INT_ADD_opcode: ++ case REF_ADD_opcode: ++ case LONG_ADD_opcode: ++ case FLOAT_ADD_opcode: ++ case DOUBLE_ADD_opcode: ++ ++ case INT_SUB_opcode: ++ case REF_SUB_opcode: ++ case LONG_SUB_opcode: ++ case FLOAT_SUB_opcode: ++ case DOUBLE_SUB_opcode: ++ ++ case INT_MUL_opcode: ++ case LONG_MUL_opcode: ++ case FLOAT_MUL_opcode: ++ case DOUBLE_MUL_opcode: ++ ++ case INT_SHL_opcode: ++ case REF_SHL_opcode: ++ case LONG_SHL_opcode: ++ ++ case INT_SHR_opcode: ++ case REF_SHR_opcode: ++ case LONG_SHR_opcode: ++ ++ case INT_USHR_opcode: ++ case REF_USHR_opcode: ++ case LONG_USHR_opcode: ++ ++ case INT_AND_opcode: ++ case REF_AND_opcode: ++ case LONG_AND_opcode: ++ ++ case INT_OR_opcode: ++ case REF_OR_opcode: ++ case LONG_OR_opcode: ++ ++ case INT_XOR_opcode: ++ case REF_XOR_opcode: ++ case LONG_XOR_opcode: ++ ++ case LONG_CMP_opcode: ++ case FLOAT_CMPL_opcode: ++ case DOUBLE_CMPL_opcode: ++ case FLOAT_CMPG_opcode: ++ case DOUBLE_CMPG_opcode: { ++ + OPT_Operand val2 = Binary.getVal2(s); +- if (val2.isConstant()) { +- OPT_Operand val1 = Binary.getVal1(s); +- // if val1 is constant too, this should've been constant folded +- // beforehand. Give up. +- if (val1.isConstant()) return null; ++ if (!val2.isObjectConstant()) ++ { ++ if (val2.isConstant()) ++ { ++ OPT_Operand val1 = Binary.getVal1(s); ++ // if val1 is constant too, this should've been constant folded ++ // beforehand. Give up. ++ if (val1.isConstant()) ++ return null; + +- return Binary.getResult(s).asRegister().register; ++ return Binary.getResult(s).asRegister().register; ++ } ++ else ++ { ++ if (VM.VerifyAssertions) ++ VM._assert(val2.isRegister()); ++ ++ OPT_Operand val1 = Binary.getVal1(s); ++ if (s.operator.isCommutative() && val1.isConstant() ++ && !val1.isObjectConstant()) ++ { ++ Binary.setVal1(s, Binary.getClearVal2(s)); ++ Binary.setVal2(s, val1); ++ return Binary.getResult(s).asRegister().register; ++ } ++ } + } ++ return null; + } +- return null; ++ case BOOLEAN_CMP_INT_opcode: ++ case BOOLEAN_CMP_LONG_opcode: ++ case BOOLEAN_CMP_ADDR_opcode: { ++ OPT_Operand val2 = BooleanCmp.getVal2(s); ++ if (!val2.isObjectConstant()) { ++ if (val2.isConstant()) { ++ OPT_Operand val1 = Binary.getVal1(s); ++ // if val1 is constant too, this should've been constant folded ++ // beforehand. Give up. ++ if (val1.isConstant()) return null; ++ ++ return BooleanCmp.getResult(s).asRegister().register; ++ } else { ++ if (VM.VerifyAssertions) VM._assert(val2.isRegister()); ++ OPT_Operand val1 = BooleanCmp.getVal1(s); ++ if (val1.isConstant() && !val1.isObjectConstant()) { ++ BooleanCmp.setVal1(s, BooleanCmp.getClearVal2(s)); ++ BooleanCmp.setVal2(s, val1); ++ BooleanCmp.getCond(s).flipOperands(); ++ return BooleanCmp.getResult(s).asRegister().register; ++ } ++ } ++ } ++ return null; ++ } ++ case INT_IFCMP_opcode: ++ case LONG_IFCMP_opcode: ++ case FLOAT_IFCMP_opcode: ++ case DOUBLE_IFCMP_opcode: ++ case REF_IFCMP_opcode: { ++ OPT... [truncated message content] |