changeset 2863:4f64bd98f9dc

Canonicalization work
author Gilles Duboscq <gilles.duboscq@oracle.com>
date Tue, 07 Jun 2011 17:04:55 +0200
parents e1be0d206934
children 32c3d7b51716
files graal/GraalCompiler/src/com/oracle/max/graal/opt/CanonicalizerPhase.java graal/GraalCompiler/src/com/sun/c1x/C1XMetrics.java graal/GraalCompiler/src/com/sun/c1x/C1XOptions.java graal/GraalCompiler/src/com/sun/c1x/graph/IR.java graal/GraalCompiler/src/com/sun/c1x/ir/Or.java graal/GraalCompiler/src/com/sun/c1x/ir/Xor.java graal/GraalGraph/src/com/oracle/graal/graph/NodeBitMap.java
diffstat 7 files changed, 171 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/graal/GraalCompiler/src/com/oracle/max/graal/opt/CanonicalizerPhase.java	Tue Jun 07 16:13:22 2011 +0200
+++ b/graal/GraalCompiler/src/com/oracle/max/graal/opt/CanonicalizerPhase.java	Tue Jun 07 17:04:55 2011 +0200
@@ -22,15 +22,47 @@
  */
 package com.oracle.max.graal.opt;
 
+import java.util.*;
+
 import com.oracle.graal.graph.*;
+import com.sun.c1x.*;
 
 public class CanonicalizerPhase extends Phase {
 
 
     @Override
     protected void run(Graph graph) {
-        // TODO Auto-generated method stub
+        NodeBitMap visited = graph.createNodeBitMap();
+        List<Node> nodes = new ArrayList<Node>(graph.getNodes());
+        for (Node n : nodes) {
+            if (n == null) {
+                continue;
+            }
+            if (!visited.isMarked(n)) {
+                this.canonicalize(n, visited);
+            }
+        }
+    }
 
+    private void canonicalize(Node n, NodeBitMap visited) {
+        visited.mark(n);
+        for (Node input : n.inputs()) {
+            if (input == null) {
+                continue;
+            }
+            if (!visited.isNew(input) && !visited.isMarked(input)) {
+                canonicalize(input, visited);
+            }
+        }
+
+        CanonicalizerOp op = n.lookup(CanonicalizerOp.class);
+        if (op != null) {
+            Node canonical = op.canonical(n);
+            if (canonical != n) {
+                n.replace(canonical);
+                C1XMetrics.NodesCanonicalized++;
+            }
+        }
     }
 
     public interface CanonicalizerOp extends Op {
--- a/graal/GraalCompiler/src/com/sun/c1x/C1XMetrics.java	Tue Jun 07 16:13:22 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/C1XMetrics.java	Tue Jun 07 17:04:55 2011 +0200
@@ -62,6 +62,7 @@
     public static int UniqueValueIdsAssigned;
     public static int FrameStatesCreated;
     public static int FrameStateValuesCreated;
+    public static int NodesCanonicalized;
 
     public static void print() {
         printClassFields(C1XMetrics.class);
--- a/graal/GraalCompiler/src/com/sun/c1x/C1XOptions.java	Tue Jun 07 16:13:22 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/C1XOptions.java	Tue Jun 07 17:04:55 2011 +0200
@@ -127,4 +127,6 @@
     // Assembler settings
     public static boolean CommentedAssembly                  = ____;
     public static boolean PrintLIRWithAssembly               = ____;
+
+    public static boolean OptCanonicalizer                   = true;
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/graph/IR.java	Tue Jun 07 16:13:22 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/graph/IR.java	Tue Jun 07 17:04:55 2011 +0200
@@ -26,6 +26,7 @@
 import java.util.*;
 
 import com.oracle.graal.graph.*;
+import com.oracle.max.graal.opt.*;
 import com.oracle.max.graal.schedule.*;
 import com.sun.c1x.*;
 import com.sun.c1x.debug.*;
@@ -85,6 +86,7 @@
 
         new PhiSimplifier(this);
 
+
 //        Graph newGraph = new Graph();
 //        HashMap<Node, Node> replacement = new HashMap<Node, Node>();
 //        replacement.put(compilation.graph.start(), newGraph.start());
@@ -94,6 +96,11 @@
 
         Graph graph = compilation.graph;
 
+        if (C1XOptions.OptCanonicalizer) {
+            new CanonicalizerPhase().apply(graph);
+            verifyAndPrint("After canonicalization");
+        }
+
         // Split critical edges.
         List<Node> nodes = graph.getNodes();
         for (int i = 0; i < nodes.size(); ++i) {
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/Or.java	Tue Jun 07 16:13:22 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Or.java	Tue Jun 07 17:04:55 2011 +0200
@@ -23,6 +23,7 @@
 package com.sun.c1x.ir;
 
 import com.oracle.graal.graph.*;
+import com.oracle.max.graal.opt.CanonicalizerPhase.CanonicalizerOp;
 import com.sun.cri.bytecode.*;
 import com.sun.cri.ci.*;
 
@@ -31,6 +32,7 @@
  *
  */
 public final class Or extends Logic {
+    private static final OrCanonicalizerOp CANONICALIZER = new OrCanonicalizerOp();
 
     /**
      * @param opcode
@@ -54,4 +56,61 @@
         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 OrCanonicalizerOp implements CanonicalizerOp {
+        @Override
+        public Node canonical(Node node) {
+            assert node instanceof Or;
+            Or or = (Or) node;
+            CiKind kind = or.kind;
+            Graph graph = or.graph();
+            Value x = or.x();
+            Value y = or.y();
+            if (x == y) {
+                return x;
+            }
+            if (x.isConstant() && !y.isConstant()) {
+                or.swapOperands();
+                Value t = y;
+                y = x;
+                x = t;
+            }
+            if (x.isConstant()) {
+                if (kind == CiKind.Int) {
+                    return Constant.forInt(x.asConstant().asInt() | y.asConstant().asInt(), graph);
+                } else {
+                    assert kind == CiKind.Long;
+                    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 == -1) {
+                        return Constant.forInt(-1, graph);
+                    }
+                    if (c == 0) {
+                        return x;
+                    }
+                } else {
+                    assert kind == CiKind.Long;
+                    long c = y.asConstant().asLong();
+                    if (c == -1) {
+                        return Constant.forLong(-1, graph);
+                    }
+                    if (c == 0) {
+                        return x;
+                    }
+                }
+            }
+            return or;
+        }
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/Xor.java	Tue Jun 07 16:13:22 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Xor.java	Tue Jun 07 17:04:55 2011 +0200
@@ -23,10 +23,12 @@
 package com.sun.c1x.ir;
 
 import com.oracle.graal.graph.*;
+import com.oracle.max.graal.opt.CanonicalizerPhase.CanonicalizerOp;
 import com.sun.cri.bytecode.*;
 import com.sun.cri.ci.*;
 
 public final class Xor extends Logic {
+    private static final XorCanonicalizerOp CANONICALIZER = new XorCanonicalizerOp();
 
     /**
      * @param opcode
@@ -50,4 +52,66 @@
         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 XorCanonicalizerOp implements CanonicalizerOp {
+        @Override
+        public Node canonical(Node node) {
+            assert node instanceof Xor;
+            Xor xor = (Xor) node;
+            CiKind kind = xor.kind;
+            Graph graph = xor.graph();
+            Value x = xor.x();
+            Value y = xor.y();
+            if (x == y) {
+                if (kind == CiKind.Int) {
+                    return Constant.forInt(0, graph);
+                } else {
+                    assert kind == CiKind.Long;
+                    return Constant.forLong(0L, graph);
+                }
+            }
+            if (x.isConstant() && !y.isConstant()) {
+                xor.swapOperands();
+                Value t = y;
+                y = x;
+                x = t;
+            }
+            if (x.isConstant()) {
+                if (kind == CiKind.Int) {
+                    return Constant.forInt(x.asConstant().asInt() ^ y.asConstant().asInt(), graph);
+                } else {
+                    assert kind == CiKind.Long;
+                    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 == -1) {
+                        return new Negate(x, graph);
+                    }
+                    if (c == 0) {
+                        return x;
+                    }
+                } else {
+                    assert kind == CiKind.Long;
+                    long c = y.asConstant().asLong();
+                    if (c == -1) {
+                        return new Negate(x, graph);
+                    }
+                    if (c == 0) {
+                        return x;
+                    }
+                }
+            }
+            return xor;
+        }
+    }
 }
--- a/graal/GraalGraph/src/com/oracle/graal/graph/NodeBitMap.java	Tue Jun 07 16:13:22 2011 +0200
+++ b/graal/GraalGraph/src/com/oracle/graal/graph/NodeBitMap.java	Tue Jun 07 17:04:55 2011 +0200
@@ -48,6 +48,10 @@
         return bitMap.get(node.id());
     }
 
+    public boolean isNew(Node node) {
+        return node.id() >= bitMap.size();
+    }
+
     public void mark(Node node) {
         check(node);
         bitMap.set(node.id());
@@ -60,7 +64,7 @@
 
     private void check(Node node) {
         assert node.graph == graph : "this node is not part of the graph";
-        assert node.id() < bitMap.size() : "this node (" + node.id() + ") was added to the graph after creating the node bitmap (" + bitMap.length() + ")";
+        assert !isNew(node) : "this node (" + node.id() + ") was added to the graph after creating the node bitmap (" + bitMap.length() + ")";
     }
 
     @Override