# HG changeset patch # User Gilles Duboscq # Date 1340292825 -7200 # Node ID b32dc49bc024cae82f323995bc21078d416d857b # Parent 2f714239cc685ac0fe74bc43452510880df9ddcc# Parent 48a2505efb54f2de95131c01eadfc2f4e4a92de0 Merge diff -r 2f714239cc68 -r b32dc49bc024 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TLABAllocateNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TLABAllocateNode.java Thu Jun 21 17:27:58 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TLABAllocateNode.java Thu Jun 21 17:33:45 2012 +0200 @@ -27,6 +27,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.snippets.*; /** * Allocates some uninitialized area. This is used for TLAB allocation @@ -37,7 +38,7 @@ private final int size; public TLABAllocateNode(int size, Kind wordKind) { - super(StampFactory.forKind(wordKind)); + super(StampFactory.forWord(wordKind, true)); this.size = size; } @@ -55,7 +56,7 @@ */ @SuppressWarnings("unused") @NodeIntrinsic - public static Object allocate(@ConstantNodeParameter int size, @ConstantNodeParameter Kind wordKind) { + public static Word allocate(@ConstantNodeParameter int size, @ConstantNodeParameter Kind wordKind) { throw new UnsupportedOperationException(); } } diff -r 2f714239cc68 -r b32dc49bc024 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewInstanceSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewInstanceSnippets.java Thu Jun 21 17:27:58 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewInstanceSnippets.java Thu Jun 21 17:33:45 2012 +0200 @@ -24,8 +24,6 @@ import static com.oracle.graal.hotspot.nodes.RegisterNode.*; import static com.oracle.graal.hotspot.snippets.DirectObjectStoreNode.*; -import static com.oracle.graal.nodes.calc.Condition.*; -import static com.oracle.graal.nodes.extended.UnsafeCastNode.*; import static com.oracle.graal.nodes.extended.UnsafeLoadNode.*; import static com.oracle.graal.snippets.SnippetTemplate.Arguments.*; import static com.oracle.graal.snippets.nodes.ExplodeLoopNode.*; @@ -55,29 +53,28 @@ public class NewInstanceSnippets implements SnippetsInterface { @Snippet - public static Object allocate(@ConstantParameter("size") int size) { + public static Word allocate(@ConstantParameter("size") int size) { Word thread = asWord(register(r15, wordKind())); Word top = loadWord(thread, threadTlabTopOffset()); Word end = loadWord(thread, threadTlabEndOffset()); Word newTop = top.plus(size); - if (newTop.cmp(BE, end)) { - Object memory = cast(top, Object.class); + if (newTop.belowOrEqual(end)) { store(thread, 0, threadTlabTopOffset(), newTop); - return memory; + return top; } - return null; + return Word.zero(); } @Snippet public static Object initialize( - @Parameter("memory") Object memory, + @Parameter("memory") Word memory, @Parameter("hub") Object hub, @ConstantParameter("size") int size) { - if (memory == null) { + if (memory == Word.zero()) { return NewInstanceStubCall.call(hub); } - Object instance = cast(memory, Object.class); + Object instance = memory.toObject(); formatInstance(hub, size, instance); return verifyOop(instance); } @@ -90,18 +87,24 @@ } private static Word asWord(Object object) { - return cast(object, Word.class); + return Word.fromObject(object); } private static Word loadWord(Object object, int offset) { - return cast(load(object, 0, offset, wordKind()), Word.class); + Object value = loadObject(object, 0, offset, true); + return asWord(value); + } + + private static Word loadWord(Word address, int offset) { + Object value = loadObject(address, 0, offset, true); + return asWord(value); } /** * Formats the header of a created instance and zeroes out its body. */ private static void formatInstance(Object hub, int size, Object instance) { - Word headerPrototype = cast(load(hub, 0, instanceHeaderPrototypeOffset(), wordKind()), Word.class); + Word headerPrototype = loadWord(hub, instanceHeaderPrototypeOffset()); store(instance, 0, 0, headerPrototype); store(instance, 0, hubOffset(), hub); explodeLoop(); @@ -159,7 +162,7 @@ this.useTLAB = useTLAB; try { allocate = runtime.getResolvedJavaMethod(NewInstanceSnippets.class.getDeclaredMethod("allocate", int.class)); - initialize = runtime.getResolvedJavaMethod(NewInstanceSnippets.class.getDeclaredMethod("initialize", Object.class, Object.class, int.class)); + initialize = runtime.getResolvedJavaMethod(NewInstanceSnippets.class.getDeclaredMethod("initialize", Word.class, Object.class, int.class)); } catch (NoSuchMethodException e) { throw new GraalInternalError(e); } diff -r 2f714239cc68 -r b32dc49bc024 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Thu Jun 21 17:27:58 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Thu Jun 21 17:33:45 2012 +0200 @@ -42,7 +42,7 @@ } public UnsafeCastNode(ValueNode object, ResolvedJavaType toType) { - super(StampFactory.declared(toType, object.stamp().nonNull())); + super(toType.kind().isObject() ? StampFactory.declared(toType, object.stamp().nonNull()) : StampFactory.forKind(toType.kind())); this.object = object; this.toType = toType; } diff -r 2f714239cc68 -r b32dc49bc024 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 Jun 21 17:27:58 2012 +0200 +++ b/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/WordTest.java Thu Jun 21 17:33:45 2012 +0200 @@ -22,8 +22,6 @@ */ package com.oracle.graal.snippets; -import static com.oracle.graal.nodes.calc.Condition.*; - import java.lang.reflect.*; import org.junit.*; @@ -34,7 +32,6 @@ import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.tests.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; /** * Tests for the {@link Word} type. @@ -78,9 +75,9 @@ long[] words = new long[] {Long.MIN_VALUE, Long.MIN_VALUE + 1, -1L, 0L, 1L, Long.MAX_VALUE - 1, Long.MAX_VALUE}; for (long word1 : words) { for (long word2 : words) { - for (Condition cond : new Condition[] {AE, AT, EQ, NE, BE, BT}) { - test("compare" + cond.name(), word1, word2); - test("compare" + cond.name(), word2, word1); + for (String method : new String[] {"aboveOrEqual", "above", "belowOrEqual", "below"}) { + test(method, word1, word2); + test(method, word2, word1); } } } @@ -97,28 +94,23 @@ } @Snippet - public static boolean compareAE(long word1, long word2) { - return Word.fromLong(word1).cmp(Condition.AE, Word.fromLong(word2)); + public static boolean aboveOrEqual(long word1, long word2) { + return Word.fromLong(word1).aboveOrEqual(Word.fromLong(word2)); } + @Snippet - public static boolean compareAT(long word1, long word2) { - return Word.fromLong(word1).cmp(Condition.AT, Word.fromLong(word2)); - } - @Snippet - public static boolean compareEQ(long word1, long word2) { - return Word.fromLong(word1).cmp(Condition.EQ, Word.fromLong(word2)); + public static boolean above(long word1, long word2) { + return Word.fromLong(word1).above(Word.fromLong(word2)); } - @Snippet - public static boolean compareNE(long word1, long word2) { - return Word.fromLong(word1).cmp(Condition.NE, Word.fromLong(word2)); - } + @Snippet - public static boolean compareBE(long word1, long word2) { - return Word.fromLong(word1).cmp(Condition.BE, Word.fromLong(word2)); + public static boolean belowOrEqual(long word1, long word2) { + return Word.fromLong(word1).belowOrEqual(Word.fromLong(word2)); } + @Snippet - public static boolean compareBT(long word1, long word2) { - return Word.fromLong(word1).cmp(Condition.BT, Word.fromLong(word2)); + public static boolean below(long word1, long word2) { + return Word.fromLong(word1).below(Word.fromLong(word2)); } } diff -r 2f714239cc68 -r b32dc49bc024 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java Thu Jun 21 17:27:58 2012 +0200 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java Thu Jun 21 17:33:45 2012 +0200 @@ -163,6 +163,8 @@ Debug.dump(graph, "%s: %s", method.name(), GraphBuilderPhase.class.getSimpleName()); + new SnippetVerificationPhase().apply(graph); + new SnippetIntrinsificationPhase(runtime, pool).apply(graph); for (Invoke invoke : graph.getInvokes()) { @@ -173,7 +175,7 @@ InliningUtil.inline(invoke, targetGraph, true); Debug.dump(graph, "after inlining %s", callee); if (GraalOptions.OptCanonicalizer) { - new WordTypeRewriterPhase(target).apply(graph); + new WordTypeRewriterPhase(target.wordKind, runtime.getResolvedJavaType(target.wordKind)).apply(graph); new CanonicalizerPhase(target, runtime, null).apply(graph); } } @@ -181,7 +183,7 @@ new SnippetIntrinsificationPhase(runtime, pool).apply(graph); - new WordTypeRewriterPhase(target).apply(graph); + new WordTypeRewriterPhase(target.wordKind, runtime.getResolvedJavaType(target.wordKind)).apply(graph); new DeadCodeEliminationPhase().apply(graph); if (GraalOptions.OptCanonicalizer) { diff -r 2f714239cc68 -r b32dc49bc024 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetVerificationPhase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetVerificationPhase.java Thu Jun 21 17:33:45 2012 +0200 @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.snippets; + +import static com.oracle.graal.snippets.WordTypeRewriterPhase.*; + +import java.lang.reflect.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.phases.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.Node.NodeIntrinsic; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.util.*; +import com.oracle.graal.snippets.Word.*; + +/** + * Verifies invariants that must hold for snippet code above and beyond normal + * bytecode verification. + */ +public class SnippetVerificationPhase extends Phase { + + @Override + protected void run(StructuredGraph graph) { + for (ValueNode node : graph.getNodes().filter(ValueNode.class)) { + for (Node usage : node.usages()) { + if (usage instanceof AccessMonitorNode) { + verify(!isWord(node), node, usage, "word value has no monitor"); + } else if (usage instanceof LoadFieldNode) { + verify(!isWord(node) || ((LoadFieldNode) usage).object() != node, node, usage, "cannot load from word value"); + } else if (usage instanceof StoreFieldNode) { + verify(!isWord(node) || ((StoreFieldNode) usage).object() != node, node, usage, "cannot store to word value"); + } else if (usage instanceof CheckCastNode) { + verify(!isWord(node), node, usage, "word value cannot be cast"); + verify(!isWord(((CheckCastNode) usage).targetClass()), node, usage, "cannot cast to word value"); + } else if (usage instanceof LoadIndexedNode) { + verify(!isWord(node) || ((LoadIndexedNode) usage).array() != node, node, usage, "cannot load from word value"); + verify(!isWord(node) || ((LoadIndexedNode) usage).index() != node, node, usage, "cannot use word value as index"); + } else if (usage instanceof StoreIndexedNode) { + verify(!isWord(node) || ((StoreIndexedNode) usage).array() != node, node, usage, "cannot store to word value"); + verify(!isWord(node) || ((StoreIndexedNode) usage).index() != node, node, usage, "cannot use word value as index"); + verify(!isWord(node) || ((StoreIndexedNode) usage).value() != node, node, usage, "cannot store word value to array"); + } else if (usage instanceof MethodCallTargetNode) { + MethodCallTargetNode callTarget = (MethodCallTargetNode) usage; + ResolvedJavaMethod method = callTarget.targetMethod(); + if (method.getAnnotation(NodeIntrinsic.class) == null) { + Invoke invoke = (Invoke) callTarget.usages().first(); + NodeInputList arguments = callTarget.arguments(); + boolean isStatic = Modifier.isStatic(method.accessFlags()); + int argc = 0; + if (!isStatic) { + ValueNode receiver = arguments.get(argc); + if (receiver == node && isWord(node)) { + Operation operation = method.getAnnotation(Word.Operation.class); + verify(operation != null, node, invoke.node(), "cannot dispatch on word value to non @Operation annotated method " + method); + } + argc++; + } + Signature signature = method.signature(); + for (int i = 0; i < signature.argumentCount(false); i++) { + ValueNode argument = arguments.get(argc); + if (argument == node) { + ResolvedJavaType type = (ResolvedJavaType) signature.argumentTypeAt(i, method.holder()); + verify((type.toJava() == Word.class) == isWord(argument), node, invoke.node(), "cannot pass word value to non-word parameter " + i + " or vice-versa"); + } + argc++; + } + } + } else if (usage instanceof ArrayLengthNode) { + verify(!isWord(node) || ((ArrayLengthNode) usage).array() != node, node, usage, "cannot get array length from word value"); + } else if (usage instanceof PhiNode) { + if (!(node instanceof MergeNode)) { + PhiNode phi = (PhiNode) usage; + for (ValueNode input : phi.values()) { + verify(isWord(node) == isWord(input), node, input, "cannot merge word and non-word values"); + } + } + } + } + } + } + + private static void verify(boolean condition, Node node, Node usage, String message) { + if (!condition) { + error(node, usage, message); + } + } + + private static void error(Node node, Node usage, String message) { + throw new GraalInternalError(String.format("Snippet verification error: %s" + + "%n node: %s (%s)" + + "%n usage: %s (%s)", message, node, sourceLocation(node), usage, sourceLocation(usage))); + } + + private static String sourceLocation(Node n) { + if (n instanceof PhiNode) { + StringBuilder buf = new StringBuilder(); + for (Node usage : n.usages()) { + String loc = sourceLocation(usage); + if (!loc.equals("")) { + if (buf.length() != 0) { + buf.append(", "); + } + buf.append(loc); + } + } + return buf.toString(); + } else { + String loc = GraphUtil.approxSourceLocation(n); + return loc == null ? "" : loc; + } + } +} diff -r 2f714239cc68 -r b32dc49bc024 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 Jun 21 17:27:58 2012 +0200 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Word.java Thu Jun 21 17:33:45 2012 +0200 @@ -26,9 +26,6 @@ import java.lang.annotation.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.calc.*; - /** * Special type for use in snippets to represent machine word sized data. */ @@ -47,83 +44,137 @@ * The canonical {@link Operation} represented by a method in the {@link Word} class. */ public enum Opcode { + ZERO, + W2A, + A2W, L2W, I2W, W2L, W2I, PLUS, MINUS, - COMPARE; + BELOW, + BELOW_EQUAL, + ABOVE, + ABOVE_EQUAL; } - private Word(long value) { + private Word(long value, Object object) { + assert object == null || value == 0L; this.value = value; + this.object = object; } private final long value; + private final Object object; + + @Operation(ZERO) + public static Word zero() { + return new Word(0L, null); + } + + @Operation(W2A) + public Object toObject() { + assert value == 0L; + return object; + } + + @Operation(A2W) + public static Word fromObject(Object value) { + return new Word(0L, value); + } @Operation(L2W) public static Word fromLong(long value) { - return new Word(value); + return new Word(value, null); } @Operation(I2W) public static Word fromInt(int value) { - return new Word(value); + return new Word(value, null); } @Operation(W2I) public int toInt() { + assert object == null; return (int) value; } @Operation(W2L) public long toLong() { + assert object == null; return value; } - @Operation(COMPARE) - public boolean cmp(Condition condition, Word other) { + @Operation(ABOVE) + public boolean above(Word other) { + assert object == null; + assert other.object == null; + long a = value; + long b = other.value; + return (a > b) ^ ((a < 0) != (b < 0)); + } + + @Operation(ABOVE_EQUAL) + public boolean aboveOrEqual(Word other) { + assert object == null; + assert other.object == null; long a = value; long b = other.value; - switch (condition) { - case AE: return (a >= b) ^ ((a < 0) != (b < 0)); - case AT: return (a > b) ^ ((a < 0) != (b < 0)); - case BE: return (a <= b) ^ ((a < 0) != (b < 0)); - case BT: return (a < b) ^ ((a < 0) != (b < 0)); - case EQ: return a == b; - case NE: return a != b; - default: throw new GraalInternalError("Unexpected operation on word: " + condition); - } + return (a >= b) ^ ((a < 0) != (b < 0)); + } + + @Operation(BELOW) + public boolean below(Word other) { + assert object == null; + assert other.object == null; + long a = value; + long b = other.value; + return (a < b) ^ ((a < 0) != (b < 0)); + } + + @Operation(BELOW_EQUAL) + public boolean belowOrEqual(Word other) { + assert object == null; + assert other.object == null; + long a = value; + long b = other.value; + return (a <= b) ^ ((a < 0) != (b < 0)); } @Operation(PLUS) public Word plus(int addend) { - return new Word(value + addend); + assert object == null; + return new Word(value + addend, null); } @Operation(PLUS) public Word plus(long addend) { - return new Word(value + addend); + assert object == null; + return new Word(value + addend, null); } @Operation(PLUS) public Word plus(Word addend) { - return new Word(value + addend.value); + assert object == null; + return new Word(value + addend.value, null); } @Operation(MINUS) public Word minus(int addend) { - return new Word(value - addend); + assert object == null; + return new Word(value - addend, null); } @Operation(MINUS) public Word minus(long addend) { - return new Word(value - addend); + assert object == null; + return new Word(value - addend, null); } @Operation(MINUS) public Word minus(Word addend) { - return new Word(value - addend.value); + assert object == null; + return new Word(value - addend.value, null); } } diff -r 2f714239cc68 -r b32dc49bc024 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 Jun 21 17:27:58 2012 +0200 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/WordTypeRewriterPhase.java Thu Jun 21 17:33:45 2012 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.snippets; -import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.phases.*; import com.oracle.graal.graph.*; @@ -44,9 +43,11 @@ public class WordTypeRewriterPhase extends Phase { private final Kind wordKind; + private final ResolvedJavaType wordType; - public WordTypeRewriterPhase(TargetDescription target) { - this.wordKind = target.wordKind; + public WordTypeRewriterPhase(Kind wordKind, ResolvedJavaType wordType) { + this.wordKind = wordKind; + this.wordType = wordType; } @Override @@ -60,14 +61,6 @@ } } - // Remove all checkcasts to Word - for (CheckCastNode checkCastNode : graph.getNodes(CheckCastNode.class).snapshot()) { - if (!checkCastNode.object().stamp().kind().isObject()) { - checkCastNode.replaceAtUsages(checkCastNode.object()); - graph.removeFixed(checkCastNode); - } - } - // Remove unnecessary/redundant unsafe casts for (UnsafeCastNode unsafeCastNode : graph.getNodes().filter(UnsafeCastNode.class).snapshot()) { if (!unsafeCastNode.isDeleted() && unsafeCastNode.object().stamp() == unsafeCastNode.stamp()) { @@ -85,11 +78,33 @@ Opcode opcode = operation.value(); switch (opcode) { - case COMPARE: { - assert arguments.size() == 3; - assert arguments.get(1) instanceof ConstantNode; - Condition condition = (Condition) arguments.get(1).asConstant().asObject(); - invoke.intrinsify(compare(condition, graph, arguments.first(), arguments.last())); + case ZERO: { + assert arguments.size() == 0; + invoke.intrinsify(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())); + break; + } + + case ABOVE_EQUAL: { + assert arguments.size() == 2; + invoke.intrinsify(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())); + break; + } + + case BELOW_EQUAL: { + assert arguments.size() == 2; + invoke.intrinsify(compare(Condition.BE, graph, arguments.first(), arguments.last())); break; } @@ -100,9 +115,18 @@ break; } + case W2A: { + assert arguments.size() == 1; + ValueNode value = arguments.first(); + ResolvedJavaType targetType = (ResolvedJavaType) targetMethod.signature().returnType(targetMethod.holder()); + UnsafeCastNode cast = graph.unique(new UnsafeCastNode(value, targetType)); + invoke.intrinsify(cast); + break; + } + case W2I: { assert arguments.size() == 1; - ValueNode value = arguments.last(); + ValueNode value = arguments.first(); ValueNode intValue = fromWordKindTo(graph, value, Kind.Int); invoke.intrinsify(intValue); break; @@ -110,15 +134,24 @@ case W2L: { assert arguments.size() == 1; - ValueNode value = arguments.last(); + ValueNode value = arguments.first(); ValueNode longValue = fromWordKindTo(graph, value, Kind.Long); invoke.intrinsify(longValue); break; } + case A2W: { + assert arguments.size() == 1; + ValueNode value = arguments.first(); + assert value.kind() == Kind.Object : value + ", " + targetMethod; + UnsafeCastNode cast = graph.unique(new UnsafeCastNode(value, wordType)); + invoke.intrinsify(cast); + break; + } + case L2W: { assert arguments.size() == 1; - ValueNode value = arguments.last(); + ValueNode value = arguments.first(); assert value.kind() == Kind.Long; ValueNode wordValue = asWordKind(graph, value); invoke.intrinsify(wordValue); @@ -127,7 +160,7 @@ case I2W: { assert arguments.size() == 1; - ValueNode value = arguments.last(); + ValueNode value = arguments.first(); assert value.kind() == Kind.Int; invoke.intrinsify(asWordKind(graph, value)); break; @@ -145,7 +178,7 @@ * Creates comparison node for a given condition and two input values. */ private ValueNode compare(Condition condition, StructuredGraph graph, ValueNode left, ValueNode right) { - assert condition.isUnsigned() || condition == Condition.EQ || condition == Condition.NE : condition; + assert condition.isUnsigned() : condition; assert left.kind() == wordKind; assert right.kind() == wordKind; @@ -155,12 +188,7 @@ ValueNode a = mirror ? right : left; ValueNode b = mirror ? left : right; - MaterializeNode materialize; - if (condition == Condition.EQ || condition == Condition.NE) { - materialize = MaterializeNode.create(graph.unique(new IntegerEqualsNode(a, b)), graph); - } else { - materialize = MaterializeNode.create(graph.unique(new IntegerBelowThanNode(a, b)), graph); - } + MaterializeNode materialize = MaterializeNode.create(graph.unique(new IntegerBelowThanNode(a, b)), graph); ValueNode op; if (condition.canonicalNegate()) { @@ -207,11 +235,11 @@ return value; } - public boolean isWord(ValueNode node) { + public static boolean isWord(ValueNode node) { return isWord(node.stamp().declaredType()); } - public boolean isWord(ResolvedJavaType type) { + public static boolean isWord(ResolvedJavaType type) { if (type != null && type.toJava() == Word.class) { return true; } @@ -228,10 +256,6 @@ changeToWord((ValueNode) n); PhiNode phi = (PhiNode) n; assert phi.type() == PhiType.Value; -// for (ValueNode v : phi.values()) { -// assertTrue(v.kind() == phi.kind(), "all phi values must have same kind"); -// } - } else if (n instanceof ReturnNode) { changeToWord((ValueNode) n); }