changeset 19191:ef52cebd4030

Fold away obvious identities when building induction variable expressions
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Mon, 09 Feb 2015 15:55:00 -0800
parents 18c2fd3d7fc7
children a7fb05f3d7e1
files graal/com.oracle.graal.loop/src/com/oracle/graal/loop/BasicInductionVariable.java graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedOffsetInductionVariable.java graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedScaledInductionVariable.java graal/com.oracle.graal.loop/src/com/oracle/graal/loop/MathUtil.java
diffstat 5 files changed, 99 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/BasicInductionVariable.java	Mon Feb 09 15:52:17 2015 -0800
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/BasicInductionVariable.java	Mon Feb 09 15:55:00 2015 -0800
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.loop;
 
+import static com.oracle.graal.loop.MathUtil.*;
+
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.nodes.*;
@@ -135,7 +137,7 @@
         if (!maxTripCount.stamp().isCompatible(stamp)) {
             maxTripCount = IntegerConvertNode.convert(maxTripCount, stamp, graph());
         }
-        return BinaryArithmeticNode.add(graph, BinaryArithmeticNode.mul(graph, stride, BinaryArithmeticNode.sub(graph, maxTripCount, ConstantNode.forIntegerStamp(stamp, 1, graph))), initNode);
+        return add(graph, mul(graph, stride, sub(graph, maxTripCount, ConstantNode.forIntegerStamp(stamp, 1, graph))), initNode);
     }
 
     @Override
@@ -145,7 +147,7 @@
         if (!maxTripCount.stamp().isCompatible(stamp)) {
             maxTripCount = IntegerConvertNode.convert(maxTripCount, stamp, graph());
         }
-        return BinaryArithmeticNode.add(graph(), BinaryArithmeticNode.mul(graph(), strideNode(), maxTripCount), initNode());
+        return add(graph(), mul(graph(), strideNode(), maxTripCount), initNode());
     }
 
     @Override
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java	Mon Feb 09 15:52:17 2015 -0800
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java	Mon Feb 09 15:55:00 2015 -0800
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.loop;
 
-import static com.oracle.graal.nodes.calc.BinaryArithmeticNode.*;
+import static com.oracle.graal.loop.MathUtil.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
@@ -55,20 +55,19 @@
     public ValueNode maxTripCountNode(boolean assumePositive) {
         StructuredGraph graph = iv.valueNode().graph();
         Stamp stamp = iv.valueNode().stamp();
-        BinaryArithmeticNode<?> range = BinaryArithmeticNode.sub(graph, end, iv.initNode());
+        ValueNode range = sub(graph, end, iv.initNode());
         if (oneOff) {
             if (iv.direction() == Direction.Up) {
-                range = BinaryArithmeticNode.add(graph, range, ConstantNode.forIntegerStamp(stamp, 1, graph));
+                range = add(graph, range, ConstantNode.forIntegerStamp(stamp, 1, graph));
             } else {
-                range = BinaryArithmeticNode.sub(graph, range, ConstantNode.forIntegerStamp(stamp, 1, graph));
+                range = sub(graph, range, ConstantNode.forIntegerStamp(stamp, 1, graph));
             }
         }
-        IntegerDivNode div = graph.add(new IntegerDivNode(range, iv.strideNode()));
-        graph.addBeforeFixed(loop.entryPoint(), div);
-        ConstantNode zero = ConstantNode.forIntegerStamp(stamp, 0, graph);
+        ValueNode div = divBefore(graph, loop.entryPoint(), range, iv.strideNode());
         if (assumePositive) {
             return div;
         }
+        ConstantNode zero = ConstantNode.forIntegerStamp(stamp, 0, graph);
         return graph.unique(new ConditionalNode(graph.unique(new IntegerLessThanNode(zero, div)), div, zero));
     }
 
@@ -144,14 +143,14 @@
         CompareNode cond; // we use a negated guard with a < condition to achieve a >=
         ConstantNode one = ConstantNode.forIntegerStamp(stamp, 1, graph);
         if (iv.direction() == Direction.Up) {
-            BinaryArithmeticNode<?> v1 = sub(graph, ConstantNode.forIntegerStamp(stamp, CodeUtil.maxValue(stamp.getBits()), graph), sub(graph, iv.strideNode(), one));
+            ValueNode v1 = sub(graph, ConstantNode.forIntegerStamp(stamp, CodeUtil.maxValue(stamp.getBits()), graph), sub(graph, iv.strideNode(), one));
             if (oneOff) {
                 v1 = sub(graph, v1, one);
             }
             cond = graph.unique(new IntegerLessThanNode(v1, end));
         } else {
             assert iv.direction() == Direction.Down;
-            BinaryArithmeticNode<?> v1 = add(graph, ConstantNode.forIntegerStamp(stamp, CodeUtil.minValue(stamp.getBits()), graph), sub(graph, one, iv.strideNode()));
+            ValueNode v1 = add(graph, ConstantNode.forIntegerStamp(stamp, CodeUtil.minValue(stamp.getBits()), graph), sub(graph, one, iv.strideNode()));
             if (oneOff) {
                 v1 = add(graph, v1, one);
             }
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedOffsetInductionVariable.java	Mon Feb 09 15:52:17 2015 -0800
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedOffsetInductionVariable.java	Mon Feb 09 15:55:00 2015 -0800
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.loop;
 
+import static com.oracle.graal.loop.MathUtil.*;
+
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.nodes.*;
@@ -125,14 +127,14 @@
 
     private ValueNode op(ValueNode b, ValueNode o) {
         if (value instanceof AddNode) {
-            return BinaryArithmeticNode.add(graph(), b, o);
+            return add(graph(), b, o);
         }
         if (value instanceof SubNode) {
             if (base.valueNode() == value.getX()) {
-                return BinaryArithmeticNode.sub(graph(), b, o);
+                return sub(graph(), b, o);
             } else {
                 assert base.valueNode() == value.getY();
-                return BinaryArithmeticNode.sub(graph(), o, b);
+                return sub(graph(), o, b);
             }
         }
         throw GraalInternalError.shouldNotReachHere();
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedScaledInductionVariable.java	Mon Feb 09 15:52:17 2015 -0800
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedScaledInductionVariable.java	Mon Feb 09 15:55:00 2015 -0800
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.loop;
 
+import static com.oracle.graal.loop.MathUtil.*;
+
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
@@ -69,12 +71,12 @@
 
     @Override
     public ValueNode initNode() {
-        return BinaryArithmeticNode.mul(graph(), base.initNode(), scale);
+        return mul(graph(), base.initNode(), scale);
     }
 
     @Override
     public ValueNode strideNode() {
-        return BinaryArithmeticNode.mul(graph(), base.strideNode(), scale);
+        return mul(graph(), base.strideNode(), scale);
     }
 
     @Override
@@ -99,12 +101,12 @@
 
     @Override
     public ValueNode extremumNode(boolean assumePositiveTripCount, Stamp stamp) {
-        return BinaryArithmeticNode.mul(graph(), base.extremumNode(assumePositiveTripCount, stamp), IntegerConvertNode.convert(scale, stamp, graph()));
+        return mul(graph(), base.extremumNode(assumePositiveTripCount, stamp), IntegerConvertNode.convert(scale, stamp, graph()));
     }
 
     @Override
     public ValueNode exitValueNode() {
-        return BinaryArithmeticNode.mul(graph(), base.exitValueNode(), scale);
+        return mul(graph(), base.exitValueNode(), scale);
     }
 
     @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/MathUtil.java	Mon Feb 09 15:55:00 2015 -0800
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.loop;
+
+import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+
+/**
+ * Utility methods to perform integer math with some obvious constant folding first.
+ */
+public class MathUtil {
+    private static boolean isConstantOne(ValueNode v1) {
+        return v1.isConstant() && v1.stamp() instanceof IntegerStamp && v1.asJavaConstant().asLong() == 1;
+    }
+
+    private static boolean isConstantZero(ValueNode v1) {
+        return v1.isConstant() && v1.stamp() instanceof IntegerStamp && v1.asJavaConstant().asLong() == 0;
+    }
+
+    public static ValueNode add(StructuredGraph graph, ValueNode v1, ValueNode v2) {
+        if (isConstantZero(v1)) {
+            return v2;
+        }
+        if (isConstantZero(v2)) {
+            return v1;
+        }
+        return BinaryArithmeticNode.add(graph, v1, v2);
+    }
+
+    public static ValueNode mul(StructuredGraph graph, ValueNode v1, ValueNode v2) {
+        if (isConstantOne(v1)) {
+            return v2;
+        }
+        if (isConstantOne(v2)) {
+            return v1;
+        }
+        return BinaryArithmeticNode.mul(graph, v1, v2);
+    }
+
+    public static ValueNode sub(StructuredGraph graph, ValueNode v1, ValueNode v2) {
+        if (isConstantZero(v2)) {
+            return v1;
+        }
+        return BinaryArithmeticNode.sub(graph, v1, v2);
+    }
+
+    public static ValueNode divBefore(StructuredGraph graph, FixedNode before, ValueNode dividend, ValueNode divisor) {
+        if (isConstantOne(divisor)) {
+            return dividend;
+        }
+        IntegerDivNode div = graph.add(new IntegerDivNode(dividend, divisor));
+        graph.addBeforeFixed(before, div);
+        return div;
+    }
+}