changeset 14025:9738280055ce

Reduce bit width of integer operations where possible.
author Roland Schatz <roland.schatz@oracle.com>
date Wed, 26 Feb 2014 15:56:03 +0100
parents 34c07ef28bc9
children 57a2d00ef771
files graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BitLogicNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerConvertNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowableArithmeticNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SignExtendNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ZeroExtendNode.java
diffstat 12 files changed, 91 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java	Wed Feb 26 15:55:04 2014 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java	Wed Feb 26 15:56:03 2014 +0100
@@ -30,7 +30,7 @@
 import com.oracle.graal.nodes.type.*;
 
 @NodeInfo(shortName = "&")
-public final class AndNode extends BitLogicNode implements Canonicalizable {
+public final class AndNode extends BitLogicNode implements Canonicalizable, NarrowableArithmeticNode {
 
     public AndNode(Stamp stamp, ValueNode x, ValueNode y) {
         super(stamp, x, y);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BitLogicNode.java	Wed Feb 26 15:55:04 2014 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BitLogicNode.java	Wed Feb 26 15:56:03 2014 +0100
@@ -29,7 +29,7 @@
 /**
  * The {@code LogicNode} class definition.
  */
-public abstract class BitLogicNode extends BinaryNode implements ArithmeticLIRLowerable {
+public abstract class BitLogicNode extends BinaryNode implements ArithmeticLIRLowerable, NarrowableArithmeticNode {
 
     /**
      * Constructs a new logic operation node.
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java	Wed Feb 26 15:55:04 2014 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java	Wed Feb 26 15:56:03 2014 +0100
@@ -30,7 +30,7 @@
 import com.oracle.graal.nodes.type.*;
 
 @NodeInfo(shortName = "+")
-public class IntegerAddNode extends IntegerArithmeticNode implements Canonicalizable {
+public class IntegerAddNode extends IntegerArithmeticNode implements Canonicalizable, NarrowableArithmeticNode {
 
     public IntegerAddNode(Stamp stamp, ValueNode x, ValueNode y) {
         super(stamp, x, y);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerConvertNode.java	Wed Feb 26 15:55:04 2014 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerConvertNode.java	Wed Feb 26 15:56:03 2014 +0100
@@ -23,8 +23,6 @@
 package com.oracle.graal.nodes.calc;
 
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -32,7 +30,7 @@
 /**
  * An {@code IntegerConvert} converts an integer to an integer of different width.
  */
-public abstract class IntegerConvertNode extends ConvertNode implements Canonicalizable, ArithmeticLIRLowerable {
+public abstract class IntegerConvertNode extends ConvertNode implements ArithmeticLIRLowerable {
 
     private final int resultBits;
 
@@ -61,8 +59,7 @@
         }
     }
 
-    @Override
-    public Node canonical(CanonicalizerTool tool) {
+    protected ValueNode canonicalConvert() {
         if (getInput().stamp() instanceof IntegerStamp) {
             int inputBits = ((IntegerStamp) getInput().stamp()).getBits();
             if (inputBits == resultBits) {
@@ -73,7 +70,7 @@
             }
         }
 
-        return this;
+        return null;
     }
 
     public static ValueNode convert(ValueNode input, Stamp stamp) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java	Wed Feb 26 15:55:04 2014 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java	Wed Feb 26 15:56:03 2014 +0100
@@ -31,7 +31,7 @@
 import com.oracle.graal.nodes.type.*;
 
 @NodeInfo(shortName = "*")
-public class IntegerMulNode extends IntegerArithmeticNode implements Canonicalizable {
+public class IntegerMulNode extends IntegerArithmeticNode implements Canonicalizable, NarrowableArithmeticNode {
 
     public IntegerMulNode(Stamp stamp, ValueNode x, ValueNode y) {
         super(stamp, x, y);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java	Wed Feb 26 15:55:04 2014 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java	Wed Feb 26 15:56:03 2014 +0100
@@ -30,7 +30,7 @@
 import com.oracle.graal.nodes.type.*;
 
 @NodeInfo(shortName = "-")
-public class IntegerSubNode extends IntegerArithmeticNode implements Canonicalizable {
+public class IntegerSubNode extends IntegerArithmeticNode implements Canonicalizable, NarrowableArithmeticNode {
 
     public IntegerSubNode(Stamp stamp, ValueNode x, ValueNode y) {
         super(stamp, x, y);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowNode.java	Wed Feb 26 15:55:04 2014 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowNode.java	Wed Feb 26 15:56:03 2014 +0100
@@ -32,7 +32,7 @@
 /**
  * The {@code NarrowNode} converts an integer to a narrower integer.
  */
-public class NarrowNode extends IntegerConvertNode {
+public class NarrowNode extends IntegerConvertNode implements Simplifiable {
 
     public NarrowNode(ValueNode input, int resultBits) {
         super(StampTool.narrowingConversion(input.stamp(), resultBits), input, resultBits);
@@ -64,8 +64,12 @@
         return false;
     }
 
-    @Override
-    public Node canonical(CanonicalizerTool tool) {
+    private ValueNode tryCanonicalize() {
+        ValueNode ret = canonicalConvert();
+        if (ret != null) {
+            return ret;
+        }
+
         if (getInput() instanceof NarrowNode) {
             NarrowNode other = (NarrowNode) getInput();
             return graph().unique(new NarrowNode(other.getInput(), getResultBits()));
@@ -85,7 +89,35 @@
             }
         }
 
-        return super.canonical(tool);
+        return null;
+    }
+
+    private boolean tryNarrow(SimplifierTool tool, Stamp stamp, ValueNode node) {
+        boolean canNarrow = node instanceof NarrowableArithmeticNode && node.usages().count() == 1;
+
+        if (canNarrow) {
+            for (Node inputNode : node.inputs().snapshot()) {
+                ValueNode input = (ValueNode) inputNode;
+                if (!tryNarrow(tool, stamp, input)) {
+                    ValueNode narrow = graph().unique(new NarrowNode(input, getResultBits()));
+                    node.replaceFirstInput(input, narrow);
+                    tool.addToWorkList(narrow);
+                }
+            }
+            node.setStamp(stamp);
+        }
+
+        return canNarrow;
+    }
+
+    @Override
+    public void simplify(SimplifierTool tool) {
+        ValueNode ret = tryCanonicalize();
+        if (ret != null) {
+            graph().replaceFloating(this, ret);
+        } else if (tryNarrow(tool, stamp().unrestricted(), getInput())) {
+            graph().replaceFloating(this, getInput());
+        }
     }
 
     @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowableArithmeticNode.java	Wed Feb 26 15:56:03 2014 +0100
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2014, 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.nodes.calc;
+
+/**
+ * Marker interface for nodes where it is valid to apply a {@link NarrowNode} to its inputs and do a
+ * narrow operation instead of doing the wide operation and applying the {@link NarrowNode} to the
+ * result.
+ */
+public interface NarrowableArithmeticNode {
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java	Wed Feb 26 15:55:04 2014 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java	Wed Feb 26 15:56:03 2014 +0100
@@ -32,7 +32,7 @@
 /**
  * The {@code NegateNode} node negates its operand.
  */
-public final class NegateNode extends FloatingNode implements Canonicalizable, ArithmeticLIRLowerable {
+public final class NegateNode extends FloatingNode implements Canonicalizable, ArithmeticLIRLowerable, NarrowableArithmeticNode {
 
     @Input private ValueNode x;
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java	Wed Feb 26 15:55:04 2014 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java	Wed Feb 26 15:56:03 2014 +0100
@@ -32,7 +32,7 @@
 /**
  * Binary negation of long or integer values.
  */
-public final class NotNode extends FloatingNode implements Canonicalizable, ArithmeticLIRLowerable {
+public final class NotNode extends FloatingNode implements Canonicalizable, ArithmeticLIRLowerable, NarrowableArithmeticNode {
 
     @Input private ValueNode x;
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SignExtendNode.java	Wed Feb 26 15:55:04 2014 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SignExtendNode.java	Wed Feb 26 15:56:03 2014 +0100
@@ -32,7 +32,7 @@
 /**
  * The {@code SignExtendNode} converts an integer to a wider integer using sign extension.
  */
-public class SignExtendNode extends IntegerConvertNode {
+public class SignExtendNode extends IntegerConvertNode implements Canonicalizable {
 
     public SignExtendNode(ValueNode input, int resultBits) {
         super(StampTool.signExtend(input.stamp(), resultBits), input, resultBits);
@@ -67,6 +67,11 @@
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
+        ValueNode ret = canonicalConvert();
+        if (ret != null) {
+            return ret;
+        }
+
         if (getInput() instanceof SignExtendNode) {
             SignExtendNode other = (SignExtendNode) getInput();
             return graph().unique(new SignExtendNode(other.getInput(), getResultBits()));
@@ -84,7 +89,7 @@
             }
         }
 
-        return super.canonical(tool);
+        return this;
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ZeroExtendNode.java	Wed Feb 26 15:55:04 2014 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ZeroExtendNode.java	Wed Feb 26 15:56:03 2014 +0100
@@ -32,7 +32,7 @@
 /**
  * The {@code ZeroExtendNode} converts an integer to a wider integer using zero extension.
  */
-public class ZeroExtendNode extends IntegerConvertNode {
+public class ZeroExtendNode extends IntegerConvertNode implements Canonicalizable {
 
     public ZeroExtendNode(ValueNode input, int resultBits) {
         super(StampTool.zeroExtend(input.stamp(), resultBits), input, resultBits);
@@ -63,12 +63,17 @@
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
+        ValueNode ret = canonicalConvert();
+        if (ret != null) {
+            return ret;
+        }
+
         if (getInput() instanceof ZeroExtendNode) {
             ZeroExtendNode other = (ZeroExtendNode) getInput();
             return graph().unique(new ZeroExtendNode(other.getInput(), getResultBits()));
         }
 
-        return super.canonical(tool);
+        return this;
     }
 
     @Override