changeset 6373:12fb1809cedc

added AND, OR and XOR intrinsics on Word types
author Doug Simon <doug.simon@oracle.com>
date Thu, 13 Sep 2012 08:18:36 +0200
parents a063fdfda5e7
children 9fc86a7159d7
files graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/WordTest.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Word.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/WordTypeRewriterPhase.java
diffstat 3 files changed, 166 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/WordTest.java	Thu Sep 13 00:27:23 2012 +0200
+++ b/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/WordTest.java	Thu Sep 13 08:18:36 2012 +0200
@@ -63,12 +63,38 @@
                 test("plus_int", word, -addend);
                 test("minus_int", word, addend);
                 test("minus_int", word, -addend);
+                test("plus_long", word, (long) addend);
+                test("plus_long", word, (long) -addend);
+                test("minus_long", word, (long) addend);
+                test("minus_long", word, (long) -addend);
+
+                test("and_int", word, addend);
+                test("and_int", word, -addend);
+                test("or_int", word, addend);
+                test("or_int", word, -addend);
+                test("and_long", word, (long) addend);
+                test("and_long", word, (long) -addend);
+                test("or_long", word, (long) addend);
+                test("or_long", word, (long) -addend);
             }
             for (long addend : words) {
                 test("plus_int", word, (int) addend);
                 test("minus_int", word, (int) addend);
                 test("plus_int", word, -((int) addend));
                 test("minus_int", word, -((int) addend));
+                test("plus_long", word, addend);
+                test("minus_long", word, addend);
+                test("plus_long", word, -addend);
+                test("minus_long", word, -addend);
+
+                test("and_int", word, (int) addend);
+                test("or_int", word, (int) addend);
+                test("and_int", word, -((int) addend));
+                test("or_int", word, -((int) addend));
+                test("and_long", word, addend);
+                test("or_long", word, addend);
+                test("and_long", word, -addend);
+                test("or_long", word, -addend);
             }
         }
     }
@@ -108,10 +134,20 @@
 
     @Snippet
     public static long minus_int(long word, int addend) {
+        return Word.fromLong(word).minus(addend).toLong();
+    }
+
+    @Snippet
+    public static long plus_long(long word, long addend) {
         return Word.fromLong(word).plus(addend).toLong();
     }
 
     @Snippet
+    public static long minus_long(long word, long addend) {
+        return Word.fromLong(word).minus(addend).toLong();
+    }
+
+    @Snippet
     public static boolean aboveOrEqual(long word1, long word2) {
         return Word.fromLong(word1).aboveOrEqual(Word.fromLong(word2));
     }
@@ -135,5 +171,24 @@
     public static int fromToObject(Object o1, Object o2) {
         return Word.fromObject(o1).toObject().hashCode() + Word.fromObject(o2).toObject().hashCode();
     }
+
+    @Snippet
+    public static long and_int(long word, int addend) {
+        return Word.fromLong(word).and(addend).toLong();
+    }
+
+    @Snippet
+    public static long or_int(long word, int addend) {
+        return Word.fromLong(word).or(addend).toLong();
+    }
+
+    @Snippet
+    public static long and_long(long word, long addend) {
+        return Word.fromLong(word).and(addend).toLong();
+    }
+
+    @Snippet
+    public static long or_long(long word, long addend) {
+        return Word.fromLong(word).or(addend).toLong();
+    }
 }
-
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Word.java	Thu Sep 13 00:27:23 2012 +0200
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Word.java	Thu Sep 13 08:18:36 2012 +0200
@@ -53,6 +53,9 @@
         W2I,
         PLUS,
         MINUS,
+        OR,
+        AND,
+        XOR,
         BELOW,
         BELOW_EQUAL,
         ABOVE,
@@ -177,4 +180,59 @@
         assert object == null;
         return new Word(value - addend.value, null);
     }
+
+    @Operation(OR)
+    public Word or(int other) {
+        assert object == null;
+        return new Word(value | other, null);
+    }
+
+    @Operation(OR)
+    public Word or(long other) {
+        assert object == null;
+        return new Word(value | other, null);
+    }
+
+    @Operation(OR)
+    public Word or(Word other) {
+        assert object == null;
+        return new Word(value | other.value, null);
+    }
+
+    @Operation(AND)
+    public Word and(int other) {
+        assert object == null;
+        return new Word(value & other, null);
+    }
+
+    @Operation(AND)
+    public Word and(long other) {
+        assert object == null;
+        return new Word(value & other, null);
+    }
+
+    @Operation(AND)
+    public Word and(Word other) {
+        assert object == null;
+        return new Word(value & other.value, null);
+    }
+
+    @Operation(XOR)
+    public Word xor(int other) {
+        assert object == null;
+        return new Word(value | other, null);
+    }
+
+    @Operation(XOR)
+    public Word xor(long other) {
+        assert object == null;
+        return new Word(value | other, null);
+    }
+
+    @Operation(XOR)
+    public Word xor(Word other) {
+        assert object == null;
+        return new Word(value | other.value, null);
+    }
+
 }
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/WordTypeRewriterPhase.java	Thu Sep 13 00:27:23 2012 +0200
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/WordTypeRewriterPhase.java	Thu Sep 13 08:18:36 2012 +0200
@@ -32,6 +32,7 @@
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.snippets.Word.Opcode;
 import com.oracle.graal.snippets.Word.Operation;
 
@@ -91,38 +92,66 @@
                 switch (opcode) {
                     case ZERO: {
                         assert arguments.size() == 0;
-                        invoke.intrinsify(wordKind.isLong() ? ConstantNode.forLong(0L, graph) : ConstantNode.forInt(0, graph));
+                        replace(invoke, wordKind.isLong() ? ConstantNode.forLong(0L, graph) : ConstantNode.forInt(0, graph));
                         break;
                     }
 
                     case ABOVE: {
                         assert arguments.size() == 2;
-                        invoke.intrinsify(compare(Condition.AT, graph, arguments.first(), arguments.last()));
+                        replace(invoke, compare(Condition.AT, graph, arguments.first(), arguments.last()));
                         break;
                     }
 
                     case ABOVE_EQUAL: {
                         assert arguments.size() == 2;
-                        invoke.intrinsify(compare(Condition.AE, graph, arguments.first(), arguments.last()));
+                        replace(invoke, compare(Condition.AE, graph, arguments.first(), arguments.last()));
                         break;
                     }
 
                     case BELOW: {
                         assert arguments.size() == 2;
-                        invoke.intrinsify(compare(Condition.BT, graph, arguments.first(), arguments.last()));
+                        replace(invoke, compare(Condition.BT, graph, arguments.first(), arguments.last()));
                         break;
                     }
 
                     case BELOW_EQUAL: {
                         assert arguments.size() == 2;
-                        invoke.intrinsify(compare(Condition.BE, graph, arguments.first(), arguments.last()));
+                        replace(invoke, compare(Condition.BE, graph, arguments.first(), arguments.last()));
                         break;
                     }
 
                     case PLUS: {
                         ValueNode addend = asWordKind(graph, arguments.last());
                         IntegerAddNode op = graph.unique(new IntegerAddNode(wordKind, arguments.first(), addend));
-                        invoke.intrinsify(op);
+                        replace(invoke, op);
+                        break;
+                    }
+
+                    case MINUS: {
+                        ValueNode addend = asWordKind(graph, arguments.last());
+                        IntegerSubNode op = graph.unique(new IntegerSubNode(wordKind, arguments.first(), addend));
+                        replace(invoke, op);
+                        break;
+                    }
+
+                    case AND: {
+                        ValueNode operand = asWordKind(graph, arguments.last());
+                        AndNode op = graph.unique(new AndNode(wordKind, arguments.first(), operand));
+                        replace(invoke, op);
+                        break;
+                    }
+
+                    case OR: {
+                        ValueNode operand = asWordKind(graph, arguments.last());
+                        OrNode op = graph.unique(new OrNode(wordKind, arguments.first(), operand));
+                        replace(invoke, op);
+                        break;
+                    }
+
+                    case XOR: {
+                        ValueNode operand = asWordKind(graph, arguments.last());
+                        XorNode op = graph.unique(new XorNode(wordKind, arguments.first(), operand));
+                        replace(invoke, op);
                         break;
                     }
 
@@ -131,7 +160,7 @@
                         ValueNode value = arguments.first();
                         ResolvedJavaType targetType = (ResolvedJavaType) targetMethod.signature().returnType(targetMethod.holder());
                         UnsafeCastNode cast = graph.unique(new UnsafeCastNode(value, targetType));
-                        invoke.intrinsify(cast);
+                        replace(invoke, cast);
                         break;
                     }
 
@@ -139,7 +168,7 @@
                         assert arguments.size() == 1;
                         ValueNode value = arguments.first();
                         ValueNode intValue = fromWordKindTo(graph, value, Kind.Int);
-                        invoke.intrinsify(intValue);
+                        replace(invoke, intValue);
                         break;
                     }
 
@@ -147,7 +176,7 @@
                         assert arguments.size() == 1;
                         ValueNode value = arguments.first();
                         ValueNode longValue = fromWordKindTo(graph, value, Kind.Long);
-                        invoke.intrinsify(longValue);
+                        replace(invoke, longValue);
                         break;
                     }
 
@@ -156,7 +185,7 @@
                         ValueNode value = arguments.first();
                         assert value.kind() == Kind.Object : value + ", " + targetMethod;
                         UnsafeCastNode cast = graph.unique(new UnsafeCastNode(value, wordType));
-                        invoke.intrinsify(cast);
+                        replace(invoke, cast);
                         break;
                     }
 
@@ -165,7 +194,7 @@
                         ValueNode value = arguments.first();
                         assert value.kind() == Kind.Long;
                         ValueNode wordValue = asWordKind(graph, value);
-                        invoke.intrinsify(wordValue);
+                        replace(invoke, wordValue);
                         break;
                     }
 
@@ -173,7 +202,7 @@
                         assert arguments.size() == 1;
                         ValueNode value = arguments.first();
                         assert value.kind() == Kind.Int;
-                        invoke.intrinsify(asWordKind(graph, value));
+                        replace(invoke, asWordKind(graph, value));
                         break;
                     }
 
@@ -185,6 +214,14 @@
         }
     }
 
+    protected void replace(Invoke invoke, ValueNode value) {
+        FixedNode next = invoke.next();
+        invoke.setNext(null);
+        invoke.node().replaceAtPredecessor(next);
+        invoke.node().replaceAtUsages(value);
+        GraphUtil.killCFG(invoke.node());
+    }
+
     /**
      * Creates comparison node for a given condition and two input values.
      */
@@ -247,6 +284,9 @@
     }
 
     public static boolean isWord(ValueNode node) {
+        if (node.stamp() instanceof WordStamp) {
+            return true;
+        }
         if (node.kind().isObject()) {
             return isWord(node.objectStamp().type());
         }