changeset 17217:1738211d4cdb

Multiply use shift-add|subtract operations when easily possible. In DivNode use rightshift
author Stefan Anzinger <stefan.anzinger@oracle.com>
date Thu, 25 Sep 2014 18:54:59 -0700
parents 7d8bb35e67c8
children 43a89fe3ff8b
files graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/DivNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/MulNode.java
diffstat 2 files changed, 46 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/DivNode.java	Thu Sep 25 09:42:28 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/DivNode.java	Thu Sep 25 18:54:59 2014 -0700
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.nodes.calc;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.spi.*;
@@ -53,6 +54,25 @@
             if (getOp().isNeutral(c)) {
                 return forX;
             }
+            if (c.getKind().isNumericInteger()) {
+                long i = c.asLong();
+                boolean signFlip = false;
+                if (i < 0) {
+                    i = -i;
+                    signFlip = true;
+                }
+                ValueNode divResult = null;
+                if (CodeUtil.isPowerOf2(i)) {
+                    divResult = RightShiftNode.create(forX, ConstantNode.forInt(CodeUtil.log2(i)));
+                }
+                if (divResult != null) {
+                    if (signFlip) {
+                        return NegateNode.create(divResult);
+                    } else {
+                        return divResult;
+                    }
+                }
+            }
         }
         return this;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/MulNode.java	Thu Sep 25 09:42:28 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/MulNode.java	Thu Sep 25 18:54:59 2014 -0700
@@ -60,13 +60,32 @@
 
             if (c.getKind().isNumericInteger()) {
                 long i = c.asLong();
-                long abs = Math.abs(i);
-                if (abs > 0 && CodeUtil.isPowerOf2(abs)) {
-                    LeftShiftNode shift = LeftShiftNode.create(forX, ConstantNode.forInt(CodeUtil.log2(abs)));
-                    if (i < 0) {
-                        return NegateNode.create(shift);
-                    } else {
-                        return shift;
+                boolean signFlip = false;
+                if (i < 0) {
+                    i = -i;
+                    signFlip = true;
+                }
+                if (i > 0) {
+                    ValueNode mulResult = null;
+                    long bit1 = i & -i;
+                    long bit2 = i - bit1;
+                    bit2 = bit2 & -bit2;    // Extract 2nd bit
+                    if (CodeUtil.isPowerOf2(i)) { //
+                        mulResult = LeftShiftNode.create(forX, ConstantNode.forInt(CodeUtil.log2(i)));
+                    } else if (bit2 + bit1 == i) { // We can work with two shifts and add
+                        ValueNode shift1 = LeftShiftNode.create(forX, ConstantNode.forInt(CodeUtil.log2(bit1)));
+                        ValueNode shift2 = LeftShiftNode.create(forX, ConstantNode.forInt(CodeUtil.log2(bit2)));
+                        mulResult = AddNode.create(shift1, shift2);
+                    } else if (CodeUtil.isPowerOf2(i + 1)) { // shift and subtract
+                        ValueNode shift1 = LeftShiftNode.create(forX, ConstantNode.forInt(CodeUtil.log2(i + 1)));
+                        mulResult = SubNode.create(shift1, forX);
+                    }
+                    if (mulResult != null) {
+                        if (signFlip) {
+                            return NegateNode.create(mulResult);
+                        } else {
+                            return mulResult;
+                        }
                     }
                 }
             }