# HG changeset patch # User Doug Simon # Date 1347517116 -7200 # Node ID 12fb1809cedcfee7f0e064fa77e03906e02eddd4 # Parent a063fdfda5e792da01b569972fff3d84463491f0 added AND, OR and XOR intrinsics on Word types diff -r a063fdfda5e7 -r 12fb1809cedc graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/WordTest.java --- 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(); + } } - diff -r a063fdfda5e7 -r 12fb1809cedc graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Word.java --- 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); + } + } diff -r a063fdfda5e7 -r 12fb1809cedc graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/WordTypeRewriterPhase.java --- 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()); }