changeset 2908:d5f6a22dd959

Canonicalization of FloatArithmetic nodes
author Gilles Duboscq <gilles.duboscq@oracle.com>
date Wed, 08 Jun 2011 18:54:05 +0200
parents 43224fe0f240
children d6cfe798a265
files graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalMetrics.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatAdd.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatDiv.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatMul.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatRem.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatSub.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerRem.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerSub.java
diffstat 10 files changed, 275 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalMetrics.java	Wed Jun 08 15:43:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalMetrics.java	Wed Jun 08 18:54:05 2011 +0200
@@ -40,7 +40,6 @@
     public static int InlinedFinalizerChecks;
     public static int InlineForcedMethods;
     public static int InlineForbiddenMethods;
-    public static int InlinedJsrs;
     public static int BlocksDeleted;
     public static int BytecodesCompiled;
     public static int CodeBytesEmitted;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java	Wed Jun 08 15:43:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java	Wed Jun 08 18:54:05 2011 +0200
@@ -24,7 +24,7 @@
 
 import java.io.*;
 import java.util.*;
-import java.util.Map.*;
+import java.util.Map.Entry;
 
 import com.oracle.max.graal.compiler.ir.*;
 import com.oracle.max.graal.compiler.schedule.*;
@@ -52,7 +52,7 @@
 
     private final HashSet<Class<?>> omittedClasses = new HashSet<Class<?>>();
     private final PrintStream stream;
-    private final List<Node> noBlockNodes = new LinkedList<Node>();
+    private final Set<Node> noBlockNodes = new HashSet<Node>();
 
     /**
      * Creates a new {@link IdealGraphPrinter} that writes to the specified output stream.
@@ -111,7 +111,7 @@
      */
     public void print(Graph graph, String title, boolean shortNames) {
         stream.printf(" <graph name='%s'>%n", escape(title));
-
+        noBlockNodes.clear();
         Schedule schedule = null;
         try {
             schedule = new Schedule();
@@ -228,6 +228,7 @@
                 }
             }
         }
+
         // add all framestates and phis to their blocks
         for (Node node : block.getInstructions()) {
             if (node instanceof Instruction && ((Instruction) node).stateAfter() != null) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java	Wed Jun 08 15:43:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java	Wed Jun 08 18:54:05 2011 +0200
@@ -73,8 +73,10 @@
         }
 
         new GraphBuilderPhase(compilation, compilation.method, false).apply(compilation.graph);
-        new DuplicationPhase().apply(compilation.graph);
+        verifyAndPrint("After GraphBuilder");
+        //new DuplicationPhase().apply(compilation.graph);
         new DeadCodeEliminationPhase().apply(compilation.graph);
+        verifyAndPrint("After DeadCodeElimination");
 
         if (GraalOptions.Inline) {
             new InliningPhase(compilation, this).apply(compilation.graph);
@@ -90,6 +92,8 @@
         if (GraalOptions.OptCanonicalizer) {
             new CanonicalizerPhase().apply(graph);
             verifyAndPrint("After Canonicalization");
+            new DeadCodeEliminationPhase().apply(compilation.graph);
+            verifyAndPrint("After DeadCodeElimination");
         }
 
         new SplitCriticalEdgesPhase().apply(graph);
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatAdd.java	Wed Jun 08 15:43:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatAdd.java	Wed Jun 08 18:54:05 2011 +0200
@@ -22,12 +22,14 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
 import com.sun.cri.ci.*;
 
 
 public final class FloatAdd extends FloatArithmetic {
+    private static final FloatAddCanonicalizerOp CANONICALIZER = new FloatAddCanonicalizerOp();
 
     public FloatAdd(CiKind kind, Value x, Value y, boolean isStrictFP, Graph graph) {
         super(kind, kind == CiKind.Double ? Bytecodes.DADD : Bytecodes.FADD, x, y, isStrictFP, graph);
@@ -44,4 +46,51 @@
         return x;
     }
 
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T extends Op> T lookup(Class<T> clazz) {
+        if (clazz == CanonicalizerOp.class) {
+            return (T) CANONICALIZER;
+        }
+        return super.lookup(clazz);
+    }
+
+    private static class FloatAddCanonicalizerOp implements CanonicalizerOp {
+        @Override
+        public Node canonical(Node node) {
+            FloatAdd add = (FloatAdd) node;
+            Value x = add.x();
+            Value y = add.y();
+            CiKind kind = add.kind;
+            Graph graph = add.graph();
+            if (x.isConstant() && !y.isConstant()) {
+                add.swapOperands();
+                Value t = y;
+                y = x;
+                x = t;
+            }
+            if (x.isConstant()) {
+                if (kind == CiKind.Float) {
+                    return Constant.forFloat(x.asConstant().asFloat() + y.asConstant().asFloat(), graph);
+                } else {
+                    assert kind == CiKind.Double;
+                    return Constant.forDouble(x.asConstant().asDouble() + y.asConstant().asDouble(), graph);
+                }
+            } else if (y.isConstant()) {
+                if (kind == CiKind.Float) {
+                    float c = y.asConstant().asFloat();
+                    if (c == 0.0f) {
+                        return x;
+                    }
+                } else {
+                    assert kind == CiKind.Long;
+                    double c = y.asConstant().asDouble();
+                    if (c == 0.0) {
+                        return x;
+                    }
+                }
+            }
+            return add;
+        }
+    }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatDiv.java	Wed Jun 08 15:43:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatDiv.java	Wed Jun 08 18:54:05 2011 +0200
@@ -22,24 +22,14 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
 import com.sun.cri.ci.*;
 
-
-/**
- *
- */
 public final class FloatDiv extends FloatArithmetic {
+    private static final FloatDivCanonicalizerOp CANONICALIZER = new FloatDivCanonicalizerOp();
 
-    /**
-     * @param opcode
-     * @param kind
-     * @param x
-     * @param y
-     * @param isStrictFP
-     * @param graph
-     */
     public FloatDiv(CiKind kind, Value x, Value y, boolean isStrictFP, Graph graph) {
         super(kind, kind == CiKind.Double ? Bytecodes.DDIV : Bytecodes.FDIV, x, y, isStrictFP, graph);
     }
@@ -55,4 +45,33 @@
         return x;
     }
 
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T extends Op> T lookup(Class<T> clazz) {
+        if (clazz == CanonicalizerOp.class) {
+            return (T) CANONICALIZER;
+        }
+        return super.lookup(clazz);
+    }
+
+    private static class FloatDivCanonicalizerOp implements CanonicalizerOp {
+        @Override
+        public Node canonical(Node node) {
+            FloatDiv div = (FloatDiv) node;
+            Value x = div.x();
+            Value y = div.y();
+            if (x.isConstant() && y.isConstant()) {
+                CiKind kind = div.kind;
+                Graph graph = div.graph();
+                if (kind == CiKind.Float) {
+                    return Constant.forFloat(x.asConstant().asFloat() / y.asConstant().asFloat(), graph);
+                } else {
+                    assert kind == CiKind.Double;
+                    return Constant.forDouble(x.asConstant().asDouble() / y.asConstant().asDouble(), graph);
+                }
+            }
+            return div;
+        }
+    }
+
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatMul.java	Wed Jun 08 15:43:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatMul.java	Wed Jun 08 18:54:05 2011 +0200
@@ -22,6 +22,7 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
 import com.sun.cri.ci.*;
@@ -31,6 +32,7 @@
  *
  */
 public final class FloatMul extends FloatArithmetic {
+    private static final FloatMulCanonicalizerOp CANONICALIZER = new FloatMulCanonicalizerOp();
 
     /**
      * @param opcode
@@ -54,4 +56,51 @@
         return new FloatMul(kind, null, null, isStrictFP(), into);
     }
 
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T extends Op> T lookup(Class<T> clazz) {
+        if (clazz == CanonicalizerOp.class) {
+            return (T) CANONICALIZER;
+        }
+        return super.lookup(clazz);
+    }
+
+    private static class FloatMulCanonicalizerOp implements CanonicalizerOp {
+        @Override
+        public Node canonical(Node node) {
+            FloatMul mul = (FloatMul) node;
+            Value x = mul.x();
+            Value y = mul.y();
+            CiKind kind = mul.kind;
+            Graph graph = mul.graph();
+            if (x.isConstant() && !y.isConstant()) {
+                mul.swapOperands();
+                Value t = y;
+                y = x;
+                x = t;
+            }
+            if (x.isConstant()) {
+                if (kind == CiKind.Float) {
+                    return Constant.forFloat(x.asConstant().asFloat() * y.asConstant().asFloat(), graph);
+                } else {
+                    assert kind == CiKind.Double;
+                    return Constant.forDouble(x.asConstant().asDouble() * y.asConstant().asDouble(), graph);
+                }
+            } else if (y.isConstant()) {
+                if (kind == CiKind.Float) {
+                    float c = y.asConstant().asFloat();
+                    if (c == 0.0f) {
+                        return Constant.forFloat(0.0f, graph);
+                    }
+                } else {
+                    assert kind == CiKind.Double;
+                    double c = y.asConstant().asDouble();
+                    if (c == 0.0) {
+                        return Constant.forDouble(0.0, graph);
+                    }
+                }
+            }
+            return mul;
+        }
+    }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatRem.java	Wed Jun 08 15:43:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatRem.java	Wed Jun 08 18:54:05 2011 +0200
@@ -22,24 +22,15 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
 import com.sun.cri.ci.*;
 
 
-/**
- *
- */
 public final class FloatRem extends FloatArithmetic {
+    private static final FloatRemCanonicalizerOp CANONICALIZER = new FloatRemCanonicalizerOp();
 
-    /**
-     * @param opcode
-     * @param kind
-     * @param x
-     * @param y
-     * @param isStrictFP
-     * @param graph
-     */
     public FloatRem(CiKind kind, Value x, Value y, boolean isStrictFP, Graph graph) {
         super(kind, kind == CiKind.Double ? Bytecodes.DREM : Bytecodes.FREM, x, y, isStrictFP, graph);
     }
@@ -54,4 +45,32 @@
         return new FloatRem(kind, null, null, isStrictFP(), into);
     }
 
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T extends Op> T lookup(Class<T> clazz) {
+        if (clazz == CanonicalizerOp.class) {
+            return (T) CANONICALIZER;
+        }
+        return super.lookup(clazz);
+    }
+
+    private static class FloatRemCanonicalizerOp implements CanonicalizerOp {
+        @Override
+        public Node canonical(Node node) {
+            FloatRem rem = (FloatRem) node;
+            Value x = rem.x();
+            Value y = rem.y();
+            if (x.isConstant() && y.isConstant()) {
+                CiKind kind = rem.kind;
+                Graph graph = rem.graph();
+                if (kind == CiKind.Float) {
+                    return Constant.forFloat(x.asConstant().asFloat() % y.asConstant().asFloat(), graph);
+                } else {
+                    assert kind == CiKind.Double;
+                    return Constant.forDouble(x.asConstant().asDouble() % y.asConstant().asDouble(), graph);
+                }
+            }
+            return rem;
+        }
+    }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatSub.java	Wed Jun 08 15:43:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatSub.java	Wed Jun 08 18:54:05 2011 +0200
@@ -22,12 +22,14 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
 import com.sun.cri.ci.*;
 
 
 public final class FloatSub extends FloatArithmetic {
+    private static final FloatSubCanonicalizerOp CANONICALIZER = new FloatSubCanonicalizerOp();
 
     public FloatSub(CiKind kind, Value x, Value y, boolean isStrictFP, Graph graph) {
         super(kind, kind == CiKind.Double ? Bytecodes.DSUB : Bytecodes.FSUB, x, y, isStrictFP, graph);
@@ -43,4 +45,67 @@
         return new FloatSub(kind, null, null, isStrictFP(), into);
     }
 
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T extends Op> T lookup(Class<T> clazz) {
+        if (clazz == CanonicalizerOp.class) {
+            return (T) CANONICALIZER;
+        }
+        return super.lookup(clazz);
+    }
+
+    private static class FloatSubCanonicalizerOp implements CanonicalizerOp {
+        @Override
+        public Node canonical(Node node) {
+            FloatSub sub = (FloatSub) node;
+            Value x = sub.x();
+            Value y = sub.y();
+            CiKind kind = sub.kind;
+            Graph graph = sub.graph();
+            if (x == y) {
+                if (kind == CiKind.Float) {
+                    return Constant.forFloat(0.0f, graph);
+                } else {
+                    assert kind == CiKind.Double;
+                    return Constant.forDouble(0.0, graph);
+                }
+            }
+            if (x.isConstant() && y.isConstant()) {
+                if (kind == CiKind.Float) {
+                    return Constant.forFloat(x.asConstant().asFloat() - y.asConstant().asFloat(), graph);
+                } else {
+                    assert kind == CiKind.Double;
+                    return Constant.forDouble(x.asConstant().asDouble() - y.asConstant().asDouble(), graph);
+                }
+            } else if (y.isConstant()) {
+                if (kind == CiKind.Float) {
+                    float c = y.asConstant().asFloat();
+                    if (c == 0.0f) {
+                        return x;
+                    }
+                } else {
+                    assert kind == CiKind.Double;
+                    double c = y.asConstant().asDouble();
+                    if (c == 0.0) {
+                        return x;
+                    }
+                }
+            } else if (x.isConstant()) {
+                // TODO (gd) check that Negate impl for floating point is really faster/better than 0.0 - x
+                if (kind == CiKind.Float) {
+                    float c = x.asConstant().asFloat();
+                    if (c == 0.0f) {
+                        return new Negate(y, graph);
+                    }
+                } else {
+                    assert kind == CiKind.Double;
+                    double c = x.asConstant().asDouble();
+                    if (c == 0.0) {
+                        return new Negate(y, graph);
+                    }
+                }
+            }
+            return sub;
+        }
+    }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerRem.java	Wed Jun 08 15:43:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerRem.java	Wed Jun 08 18:54:05 2011 +0200
@@ -22,12 +22,14 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
 import com.sun.cri.ci.*;
 
 
 public final class IntegerRem extends IntegerArithmetic {
+    private static final IntegerRemCanonicalizerOp CANONICALIZER = new IntegerRemCanonicalizerOp();
 
     public IntegerRem(CiKind kind, Value x, Value y, Graph graph) {
         super(kind, kind == CiKind.Int ? Bytecodes.IREM : Bytecodes.LREM, x, y, graph);
@@ -43,4 +45,41 @@
         return new IntegerRem(kind, null, null, into);
     }
 
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T extends Op> T lookup(Class<T> clazz) {
+        if (clazz == CanonicalizerOp.class) {
+            return (T) CANONICALIZER;
+        }
+        return super.lookup(clazz);
+    }
+
+    private static class IntegerRemCanonicalizerOp implements CanonicalizerOp {
+        @Override
+        public Node canonical(Node node) {
+            IntegerRem rem = (IntegerRem) node;
+            Value x = rem.x();
+            Value y = rem.y();
+            CiKind kind = rem.kind;
+            Graph graph = rem.graph();
+            if (x.isConstant() && y.isConstant()) {
+                long yConst = y.asConstant().asLong();
+                if (yConst == 0) {
+                    return rem; // this will trap, can not canonicalize
+                }
+                if (kind == CiKind.Int) {
+                    return Constant.forInt(x.asConstant().asInt() % (int) yConst, graph);
+                } else {
+                    assert kind == CiKind.Long;
+                    return Constant.forLong(x.asConstant().asLong() % yConst, graph);
+                }
+            } else if (y.isConstant()) {
+                long c = y.asConstant().asLong();
+                if (c == 1) {
+                    return x;
+                }
+            }
+            return rem;
+        }
+    }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerSub.java	Wed Jun 08 15:43:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerSub.java	Wed Jun 08 18:54:05 2011 +0200
@@ -78,17 +78,9 @@
                     return Constant.forLong(x.asConstant().asLong() - y.asConstant().asLong(), graph);
                 }
             } else if (y.isConstant()) {
-                if (kind == CiKind.Int) {
-                    int c = y.asConstant().asInt();
-                    if (c == 0) {
-                        return x;
-                    }
-                } else {
-                    assert kind == CiKind.Long;
-                    long c = y.asConstant().asLong();
-                    if (c == 0) {
-                        return x;
-                    }
+                long c = y.asConstant().asLong();
+                if (c == 0) {
+                    return x;
                 }
             } else if (x.isConstant()) {
                 long c = x.asConstant().asLong();