changeset 5406:ae759e820ce7

AMD64LIRGenerator: reorder compare operands to prevent unnecessary loads of constants
author Lukas Stadler <lukas.stadler@jku.at>
date Tue, 15 May 2012 20:24:52 +0200
parents 136e9e8daf3d
children 098c5eba749d
files graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64LIRGenerator.java
diffstat 1 files changed, 33 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- 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));