# HG changeset patch # User Lukas Stadler # Date 1337106292 -7200 # Node ID ae759e820ce7ab7c33e3acea56928e5d4602373f # Parent 136e9e8daf3d60922871616ce9e3ff47249c297b AMD64LIRGenerator: reorder compare operands to prevent unnecessary loads of constants diff -r 136e9e8daf3d -r ae759e820ce7 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64LIRGenerator.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64LIRGenerator.java Tue May 15 20:14:52 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64LIRGenerator.java Tue May 15 20:24:52 2012 +0200 @@ -44,6 +44,7 @@ import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.JumpOp; import com.oracle.graal.lir.StandardOp.LabelOp; +import com.oracle.graal.lir.ValueUtil; import com.oracle.graal.lir.amd64.AMD64Arithmetic.DivOp; import com.oracle.graal.lir.amd64.AMD64Arithmetic.Op1Reg; import com.oracle.graal.lir.amd64.AMD64Arithmetic.Op1Stack; @@ -218,39 +219,56 @@ @Override public void emitBranch(CiValue left, CiValue right, Condition cond, boolean unorderedIsTrue, LabelRef label, LIRDebugInfo info) { - emitCompare(left, right); - switch (left.kind) { - case Boolean: + boolean mirrored = emitCompare(left, right); + Condition finalCondition = mirrored ? cond.mirror() : cond; + switch (left.kind.stackKind()) { case Int: case Long: - case Object: append(new BranchOp(cond, label, info)); break; + case Object: append(new BranchOp(finalCondition, label, info)); break; case Float: - case Double: append(new FloatBranchOp(cond, unorderedIsTrue, label, info)); break; + case Double: append(new FloatBranchOp(finalCondition, unorderedIsTrue, label, info)); break; default: throw GraalInternalError.shouldNotReachHere("" + left.kind); } } @Override public Variable emitCMove(CiValue left, CiValue right, Condition cond, boolean unorderedIsTrue, CiValue trueValue, CiValue falseValue) { - emitCompare(left, right); + boolean mirrored = emitCompare(left, right); + Condition finalCondition = mirrored ? cond.mirror() : cond; Variable result = newVariable(trueValue.kind); - switch (left.kind) { - case Boolean: + switch (left.kind.stackKind()) { case Int: case Long: - case Object: append(new CondMoveOp(result, cond, load(trueValue), loadNonConst(falseValue))); break; + case Object: append(new CondMoveOp(result, finalCondition, load(trueValue), loadNonConst(falseValue))); break; case Float: - case Double: append(new FloatCondMoveOp(result, cond, unorderedIsTrue, load(trueValue), load(falseValue))); break; + case Double: append(new FloatCondMoveOp(result, finalCondition, unorderedIsTrue, load(trueValue), load(falseValue))); break; } return result; } - private void emitCompare(CiValue a, CiValue b) { - Variable left = load(a); - CiValue right = loadNonConst(b); - switch (left.kind) { + /** + * This method emits the compare instruction, and may reorder the operands. It returns true if it did so. + * + * @param a the left operand of the comparison + * @param b the right operand of the comparison + * @return true if the left and right operands were switched, false otherwise + */ + private boolean emitCompare(CiValue a, CiValue b) { + Variable left; + CiValue right; + boolean mirrored; + if (ValueUtil.isVariable(b)) { + left = load(b); + right = loadNonConst(a); + mirrored = true; + } else { + left = load(a); + right = loadNonConst(b); + mirrored = false; + } + switch (left.kind.stackKind()) { case Jsr: case Int: append(new CompareOp(ICMP, left, right)); break; case Long: append(new CompareOp(LCMP, left, right)); break; @@ -259,6 +277,7 @@ case Double: append(new CompareOp(DCMP, left, right)); break; default: throw GraalInternalError.shouldNotReachHere(); } + return mirrored; } @Override @@ -560,7 +579,6 @@ @Override protected void emitNullCheckGuard(NullCheckNode node, long leafGraphId) { - assert !node.expectedNull; Variable value = load(operand(node.object())); LIRDebugInfo info = state(leafGraphId); append(new NullCheckOp(value, info));