diff graal/GraalCompiler/src/com/sun/c1x/ir/Or.java @ 2863:4f64bd98f9dc

Canonicalization work
author Gilles Duboscq <gilles.duboscq@oracle.com>
date Tue, 07 Jun 2011 17:04:55 +0200
parents b20f0a48fec3
children fc75fd3fa5e4
line wrap: on
line diff
--- 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;
+        }
+    }
 }