# HG changeset patch
# User Stefan Anzinger
# Date 1404122539 -7200
# Node ID 5f01f7c48d40ef59b9c78a5833be146b993f013e
# Parent 51f39255712497a8faf9616d400fd6d9c99ce4e9# Parent 5cdcb94a7cf7d9782107cc582f3e4b50000d5d1f
Merge with 5cdcb94a7cf7d9782107cc582f3e4b50000d5d1f
diff -r 51f392557124 -r 5f01f7c48d40 .hgignore
--- a/.hgignore Mon Jun 30 08:50:26 2014 +0200
+++ b/.hgignore Mon Jun 30 12:02:19 2014 +0200
@@ -88,3 +88,6 @@
agent/make/filelist
agent/make/sa17.tar.gz
export.json
+.recommenders
+syntax: regexp
+test\.[0-9]+\.er
diff -r 51f392557124 -r 5f01f7c48d40 CHANGELOG.md
--- a/CHANGELOG.md Mon Jun 30 08:50:26 2014 +0200
+++ b/CHANGELOG.md Mon Jun 30 12:02:19 2014 +0200
@@ -9,6 +9,7 @@
### Truffle
* `truffle.jar`: strip out build-time only dependency into a seperated JAR file (`truffle-dsl-processor.jar`)
+* New flag -G:+TraceTruffleCompilationAST to print the AST before compilation.
* ...
## Version 0.3
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.amd64/src/com/oracle/graal/amd64/AMD64.java
--- a/graal/com.oracle.graal.amd64/src/com/oracle/graal/amd64/AMD64.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.amd64/src/com/oracle/graal/amd64/AMD64.java Mon Jun 30 12:02:19 2014 +0200
@@ -38,7 +38,6 @@
public class AMD64 extends Architecture {
public static final RegisterCategory CPU = new RegisterCategory("CPU");
- public static final RegisterCategory XMM = new RegisterCategory("XMM");
// @formatter:off
@@ -66,6 +65,10 @@
r8, r9, r10, r11, r12, r13, r14, r15
};
+ private static final int XMM_REFERENCE_MAP_SHIFT = 2;
+
+ public static final RegisterCategory XMM = new RegisterCategory("XMM", cpuRegisters.length, XMM_REFERENCE_MAP_SHIFT);
+
// XMM registers
public static final Register xmm0 = new Register(16, 0, "xmm0", XMM);
public static final Register xmm1 = new Register(17, 1, "xmm1", XMM);
@@ -135,7 +138,7 @@
private final EnumSet features;
public AMD64(EnumSet features) {
- super("AMD64", 8, ByteOrder.LITTLE_ENDIAN, true, allRegisters, LOAD_STORE | STORE_STORE, 1, r15.encoding + 1, 8);
+ super("AMD64", 8, ByteOrder.LITTLE_ENDIAN, true, allRegisters, LOAD_STORE | STORE_STORE, 1, cpuRegisters.length + xmmRegisters.length << XMM_REFERENCE_MAP_SHIFT, 8);
this.features = features;
assert features.contains(CPUFeature.SSE2) : "minimum config for x64";
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Architecture.java
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Architecture.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Architecture.java Mon Jun 30 12:02:19 2014 +0200
@@ -34,11 +34,11 @@
public abstract class Architecture {
/**
- * The number of bits required in a bit map covering all the registers that may store
- * references. The bit position of a register in the map is the register's
- * {@linkplain Register#number number}.
+ * The number of entries required in a {@link ReferenceMap} covering all the registers that may
+ * store references. The index of a register in the reference map is given by
+ * {@link Register#getReferenceMapIndex()}.
*/
- private final int registerReferenceMapBitCount;
+ private final int registerReferenceMapSize;
/**
* Represents the natural size of words (typically registers and pointers) of this architecture,
@@ -85,7 +85,7 @@
private final int returnAddressSize;
protected Architecture(String name, int wordSize, ByteOrder byteOrder, boolean unalignedMemoryAccess, Register[] registers, int implicitMemoryBarriers, int nativeCallDisplacementOffset,
- int registerReferenceMapBitCount, int returnAddressSize) {
+ int registerReferenceMapSize, int returnAddressSize) {
this.name = name;
this.registers = registers;
this.wordSize = wordSize;
@@ -93,13 +93,13 @@
this.unalignedMemoryAccess = unalignedMemoryAccess;
this.implicitMemoryBarriers = implicitMemoryBarriers;
this.machineCodeCallDisplacementOffset = nativeCallDisplacementOffset;
- this.registerReferenceMapBitCount = registerReferenceMapBitCount;
+ this.registerReferenceMapSize = registerReferenceMapSize;
this.returnAddressSize = returnAddressSize;
}
/**
* Converts this architecture to a string.
- *
+ *
* @return the string representation of this architecture
*/
@Override
@@ -107,8 +107,8 @@
return getName().toLowerCase();
}
- public int getRegisterReferenceMapBitCount() {
- return registerReferenceMapBitCount;
+ public int getRegisterReferenceMapSize() {
+ return registerReferenceMapSize;
}
/**
@@ -163,7 +163,7 @@
/**
* Determines the barriers in a given barrier mask that are explicitly required on this
* architecture.
- *
+ *
* @param barriers a mask of the barrier constants
* @return the value of {@code barriers} minus the barriers unnecessary on this architecture
*/
@@ -173,9 +173,9 @@
/**
* Gets the size in bytes of the specified kind for this target.
- *
+ *
* @param kind the kind for which to get the size
- *
+ *
* @return the size in bytes of {@code kind}
*/
public int getSizeInBytes(PlatformKind kind) {
@@ -205,7 +205,7 @@
/**
* Determine whether a kind can be stored in a register of a given category.
- *
+ *
* @param category the category of the register
* @param kind the kind that should be stored in the register
*/
@@ -213,7 +213,7 @@
/**
* Return the largest kind that can be stored in a register of a given category.
- *
+ *
* @param category the category of the register
* @return the largest kind that can be stored in a register {@code category}
*/
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java Mon Jun 30 12:02:19 2014 +0200
@@ -27,9 +27,9 @@
public interface ReferenceMap {
- void setRegister(int idx, PlatformKind kind);
+ void setRegister(int idx, LIRKind kind);
- void setStackSlot(int offset, PlatformKind kind);
+ void setStackSlot(int offset, LIRKind kind);
boolean hasRegisterRefMap();
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Register.java
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Register.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Register.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2014, 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
@@ -79,10 +79,23 @@
*/
public static class RegisterCategory {
- private String name;
+ private final String name;
+
+ private final int referenceMapOffset;
+ private final int referenceMapShift;
public RegisterCategory(String name) {
+ this(name, 0, 0);
+ }
+
+ public RegisterCategory(String name, int referenceMapOffset) {
+ this(name, referenceMapOffset, 0);
+ }
+
+ public RegisterCategory(String name, int referenceMapOffset, int referenceMapShift) {
this.name = name;
+ this.referenceMapOffset = referenceMapOffset;
+ this.referenceMapShift = referenceMapShift;
}
@Override
@@ -107,7 +120,7 @@
/**
* Creates a {@link Register} instance.
- *
+ *
* @param number unique identifier for the register
* @param encoding the target machine encoding for the register
* @param name the mnemonic name for the register
@@ -125,27 +138,34 @@
}
/**
+ * Get the start index of this register in the {@link ReferenceMap}.
+ */
+ public int getReferenceMapIndex() {
+ return (encoding << registerCategory.referenceMapShift) + registerCategory.referenceMapOffset;
+ }
+
+ /**
* Gets this register as a {@linkplain RegisterValue value} with a specified kind.
- *
+ *
* @param kind the specified kind
* @return the {@link RegisterValue}
*/
- public RegisterValue asValue(PlatformKind kind) {
+ public RegisterValue asValue(LIRKind kind) {
return new RegisterValue(kind, this);
}
/**
* Gets this register as a {@linkplain RegisterValue value} with no particular kind.
- *
+ *
* @return a {@link RegisterValue} with {@link Kind#Illegal} kind.
*/
public RegisterValue asValue() {
- return asValue(Kind.Illegal);
+ return asValue(LIRKind.Illegal);
}
/**
* Determines if this is a valid register.
- *
+ *
* @return {@code true} iff this register is valid
*/
public boolean isValid() {
@@ -154,7 +174,7 @@
/**
* Gets the maximum register {@linkplain #number number} in a given set of registers.
- *
+ *
* @param registers the set of registers to process
* @return the maximum register number for any register in {@code registers}
*/
@@ -170,7 +190,7 @@
/**
* Gets the maximum register {@linkplain #encoding encoding} in a given set of registers.
- *
+ *
* @param registers the set of registers to process
* @return the maximum register encoding for any register in {@code registers}
*/
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RegisterValue.java
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RegisterValue.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RegisterValue.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2014, 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
@@ -27,8 +27,8 @@
/**
* Denotes a register that stores a value of a fixed kind. There is exactly one (canonical) instance
* of {@link RegisterValue} for each ({@link Register}, {@link Kind}) pair. Use
- * {@link Register#asValue(PlatformKind)} to retrieve the canonical {@link RegisterValue} instance
- * for a given (register,kind) pair.
+ * {@link Register#asValue(LIRKind)} to retrieve the canonical {@link RegisterValue} instance for a
+ * given (register,kind) pair.
*/
public final class RegisterValue extends AllocatableValue {
@@ -39,7 +39,7 @@
/**
* Should only be called from {@link Register#Register} to ensure canonicalization.
*/
- protected RegisterValue(PlatformKind kind, Register register) {
+ protected RegisterValue(LIRKind kind, Register register) {
super(kind);
this.reg = register;
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/StackSlot.java
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/StackSlot.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/StackSlot.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2014, 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
@@ -38,22 +38,22 @@
/**
* Gets a {@link StackSlot} instance representing a stack slot at a given index holding a value
* of a given kind.
- *
+ *
* @param kind The kind of the value stored in the stack slot.
* @param offset The offset of the stack slot (in bytes)
* @param addFrameSize Specifies if the offset is relative to the stack pointer, or the
* beginning of the frame (stack pointer + total frame size).
*/
- public static StackSlot get(PlatformKind kind, int offset, boolean addFrameSize) {
+ public static StackSlot get(LIRKind kind, int offset, boolean addFrameSize) {
assert addFrameSize || offset >= 0;
return new StackSlot(kind, offset, addFrameSize);
}
/**
- * Private constructor to enforce use of {@link #get(PlatformKind, int, boolean)} so that a
- * cache can be used.
+ * Private constructor to enforce use of {@link #get(LIRKind, int, boolean)} so that a cache can
+ * be used.
*/
- private StackSlot(PlatformKind kind, int offset, boolean addFrameSize) {
+ private StackSlot(LIRKind kind, int offset, boolean addFrameSize) {
super(kind);
this.offset = offset;
this.addFrameSize = addFrameSize;
@@ -61,7 +61,7 @@
/**
* Gets the offset of this stack slot, relative to the stack pointer.
- *
+ *
* @return The offset of this slot (in bytes).
*/
public int getOffset(int totalFrameSize) {
@@ -100,7 +100,7 @@
public StackSlot asOutArg() {
assert offset >= 0;
if (addFrameSize) {
- return get(getPlatformKind(), offset, false);
+ return get(getLIRKind(), offset, false);
}
return this;
}
@@ -111,7 +111,7 @@
public StackSlot asInArg() {
assert offset >= 0;
if (!addFrameSize) {
- return get(getPlatformKind(), offset, true);
+ return get(getLIRKind(), offset, true);
}
return this;
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TargetDescription.java
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TargetDescription.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TargetDescription.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2014, 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
@@ -56,7 +56,7 @@
* The stack alignment requirement of the platform. For example, from Appendix D of Intel 64 and IA-32 Architectures
* Optimization Reference Manual:
- *
+ *
*
* "It is important to ensure that the stack frame is aligned to a
* 16-byte boundary upon function entry to keep local __m128 data,
@@ -86,5 +86,23 @@
return arch.getSizeInBytes(kind);
}
+ public LIRKind getLIRKind(Kind javaKind) {
+ switch (javaKind) {
+ case Boolean:
+ case Byte:
+ case Short:
+ case Char:
+ case Int:
+ case Long:
+ case Float:
+ case Double:
+ return LIRKind.value(javaKind);
+ case Object:
+ return LIRKind.reference(javaKind);
+ default:
+ return LIRKind.Illegal;
+ }
+ }
+
public abstract ReferenceMap createReferenceMap(boolean hasRegisters, int stackSlotCount);
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2014, 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
@@ -47,7 +47,7 @@
* returned by {@link ResolvedJavaType#getInstanceFields(boolean) getInstanceFields(true)}. If
* {@code type} is an array then the length of the values array determines the reallocated array
* length.
- *
+ *
* @param type the type of the object whose allocation was removed during compilation. This can
* be either an instance of an array type.
* @param values an array containing all the values to be stored into the object when it is
@@ -61,7 +61,7 @@
}
private VirtualObject(ResolvedJavaType type, Value[] values, int id) {
- super(Kind.Object);
+ super(LIRKind.reference(Kind.Object));
this.type = type;
this.values = values;
this.id = id;
@@ -164,7 +164,7 @@
/**
* Overwrites the current set of values with a new one.
- *
+ *
* @param values an array containing all the values to be stored into the object when it is
* recreated.
*/
@@ -175,7 +175,7 @@
@Override
public int hashCode() {
- return getPlatformKind().hashCode() + type.hashCode();
+ return getLIRKind().hashCode() + type.hashCode();
}
@Override
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/ConstantTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/ConstantTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2014, 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.api.meta.test;
+
+import org.junit.*;
+
+import com.oracle.graal.api.meta.*;
+
+public class ConstantTest extends FieldUniverse {
+
+ @Test
+ public void testNegativeZero() {
+ Assert.assertTrue("Constant for 0.0f must be different from -0.0f", Constant.FLOAT_0 != Constant.forFloat(-0.0F));
+ Assert.assertTrue("Constant for 0.0d must be different from -0.0d", Constant.DOUBLE_0 != Constant.forDouble(-0.0d));
+ }
+
+ @Test
+ public void testNullIsNull() {
+ Assert.assertTrue(Constant.NULL_OBJECT.isNull());
+ }
+
+ @Test
+ public void testOne() {
+ for (Kind kind : Kind.values()) {
+ if (kind.isNumericInteger() || kind.isNumericFloat()) {
+ Assert.assertTrue(Constant.one(kind).getKind() == kind);
+ }
+ }
+ Assert.assertEquals(1, Constant.one(Kind.Int).asInt());
+ Assert.assertEquals(1L, Constant.one(Kind.Long).asLong());
+ Assert.assertEquals(1, Constant.one(Kind.Byte).asInt());
+ Assert.assertEquals(1, Constant.one(Kind.Short).asInt());
+ Assert.assertEquals(1, Constant.one(Kind.Char).asInt());
+ Assert.assertTrue(1F == Constant.one(Kind.Float).asFloat());
+ Assert.assertTrue(1D == Constant.one(Kind.Double).asDouble());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testIllegalOne() {
+ Constant.one(Kind.Illegal);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testVoidOne() {
+ Constant.one(Kind.Void);
+ }
+}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/AllocatableValue.java
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/AllocatableValue.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/AllocatableValue.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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
@@ -32,7 +32,7 @@
public static final AllocatableValue[] NONE = {};
- public AllocatableValue(PlatformKind platformKind) {
- super(platformKind);
+ public AllocatableValue(LIRKind lirKind) {
+ super(lirKind);
}
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2014, 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
@@ -32,38 +32,25 @@
private static final long serialVersionUID = -6355452536852663986L;
- private static final Constant[] INT_CONSTANT_CACHE = new Constant[100];
- static {
- for (int i = 0; i < INT_CONSTANT_CACHE.length; ++i) {
- INT_CONSTANT_CACHE[i] = new PrimitiveConstant(Kind.Int, i);
- }
- }
-
+ /*
+ * Using a larger cache for integers leads to only a slight increase in cache hit ratio which is
+ * not enough to justify the impact on startup time.
+ */
public static final Constant NULL_OBJECT = new NullConstant();
public static final Constant INT_MINUS_1 = new PrimitiveConstant(Kind.Int, -1);
- public static final Constant INT_0 = forInt(0);
- public static final Constant INT_1 = forInt(1);
- public static final Constant INT_2 = forInt(2);
- public static final Constant INT_3 = forInt(3);
- public static final Constant INT_4 = forInt(4);
- public static final Constant INT_5 = forInt(5);
+ public static final Constant INT_0 = new PrimitiveConstant(Kind.Int, 0);
+ public static final Constant INT_1 = new PrimitiveConstant(Kind.Int, 1);
+ public static final Constant INT_2 = new PrimitiveConstant(Kind.Int, 2);
public static final Constant LONG_0 = new PrimitiveConstant(Kind.Long, 0L);
public static final Constant LONG_1 = new PrimitiveConstant(Kind.Long, 1L);
public static final Constant FLOAT_0 = new PrimitiveConstant(Kind.Float, Float.floatToRawIntBits(0.0F));
public static final Constant FLOAT_1 = new PrimitiveConstant(Kind.Float, Float.floatToRawIntBits(1.0F));
- public static final Constant FLOAT_2 = new PrimitiveConstant(Kind.Float, Float.floatToRawIntBits(2.0F));
public static final Constant DOUBLE_0 = new PrimitiveConstant(Kind.Double, Double.doubleToRawLongBits(0.0D));
public static final Constant DOUBLE_1 = new PrimitiveConstant(Kind.Double, Double.doubleToRawLongBits(1.0D));
public static final Constant TRUE = new PrimitiveConstant(Kind.Boolean, 1L);
public static final Constant FALSE = new PrimitiveConstant(Kind.Boolean, 0L);
- static {
- assert FLOAT_0 != forFloat(-0.0F) : "Constant for 0.0f must be different from -0.0f";
- assert DOUBLE_0 != forDouble(-0.0d) : "Constant for 0.0d must be different from -0.0d";
- assert NULL_OBJECT.isNull();
- }
-
- protected Constant(PlatformKind kind) {
+ protected Constant(LIRKind kind) {
super(kind);
}
@@ -183,9 +170,6 @@
if (Float.compare(f, 1.0F) == 0) {
return FLOAT_1;
}
- if (Float.compare(f, 2.0F) == 0) {
- return FLOAT_2;
- }
return new PrimitiveConstant(Kind.Float, Float.floatToRawIntBits(f));
}
@@ -196,7 +180,13 @@
* @return a boxed copy of {@code value}
*/
public static Constant forLong(long i) {
- return i == 0 ? LONG_0 : i == 1 ? LONG_1 : new PrimitiveConstant(Kind.Long, i);
+ if (i == 0) {
+ return LONG_0;
+ } else if (i == 1) {
+ return LONG_1;
+ } else {
+ return new PrimitiveConstant(Kind.Long, i);
+ }
}
/**
@@ -206,13 +196,18 @@
* @return a boxed copy of {@code value}
*/
public static Constant forInt(int i) {
- if (i == -1) {
- return INT_MINUS_1;
+ switch (i) {
+ case -1:
+ return INT_MINUS_1;
+ case 0:
+ return INT_0;
+ case 1:
+ return INT_1;
+ case 2:
+ return INT_2;
+ default:
+ return new PrimitiveConstant(Kind.Int, i);
}
- if (i >= 0 && i < INT_CONSTANT_CACHE.length) {
- return INT_CONSTANT_CACHE[i];
- }
- return new PrimitiveConstant(Kind.Int, i);
}
/**
@@ -346,6 +341,8 @@
*/
public static Constant zero(Kind kind) {
switch (kind) {
+ case Boolean:
+ return FALSE;
case Byte:
return forByte((byte) 0);
case Char:
@@ -370,6 +367,8 @@
*/
public static Constant one(Kind kind) {
switch (kind) {
+ case Boolean:
+ return TRUE;
case Byte:
return forByte((byte) 1);
case Char:
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/LIRKind.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/LIRKind.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2014, 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.api.meta;
+
+/**
+ * Represents the type of values in the LIR. It is composed of a {@link PlatformKind} that gives the
+ * low level representation of the value, and a {@link #referenceMask} that describes the location
+ * of object references in the value.
+ */
+public final class LIRKind {
+
+ /**
+ * The non-type. This uses {@link #derivedReference}, so it can never be part of an oop map.
+ */
+ public static final LIRKind Illegal = derivedReference(Kind.Illegal);
+
+ private final PlatformKind platformKind;
+ private final int referenceMask;
+
+ private static final int DERIVED_REFERENCE = -1;
+
+ private LIRKind(PlatformKind platformKind, int referenceMask) {
+ this.platformKind = platformKind;
+ this.referenceMask = referenceMask;
+ }
+
+ /**
+ * Create a {@link LIRKind} of type {@code platformKind} that contains a primitive value.
+ */
+ public static LIRKind value(PlatformKind platformKind) {
+ assert platformKind != Kind.Object : "Object should always be used as reference type";
+ return new LIRKind(platformKind, 0);
+ }
+
+ /**
+ * Create a {@link LIRKind} of type {@code platformKind} that contains a single tracked oop
+ * reference.
+ */
+ public static LIRKind reference(PlatformKind platformKind) {
+ int length = platformKind.getVectorLength();
+ assert 0 < length && length < 32 : "vector of " + length + " references not supported";
+ return new LIRKind(platformKind, (1 << length) - 1);
+ }
+
+ /**
+ * Create a {@link LIRKind} of type {@code platformKind} that contains a value that is derived
+ * from a reference. Values of this {@link LIRKind} can not be live at safepoints.
+ */
+ public static LIRKind derivedReference(PlatformKind platformKind) {
+ return new LIRKind(platformKind, DERIVED_REFERENCE);
+ }
+
+ /**
+ * Create a new {@link LIRKind} with the same reference information and a new
+ * {@linkplain #getPlatformKind platform kind}. If the new kind is a longer vector than this,
+ * the new elements are marked as untracked values.
+ */
+ public LIRKind changeType(PlatformKind newPlatformKind) {
+ if (isDerivedReference()) {
+ return derivedReference(newPlatformKind);
+ } else if (referenceMask == 0) {
+ // value type
+ return new LIRKind(newPlatformKind, 0);
+ } else {
+ // reference type
+ int newLength = Math.min(32, newPlatformKind.getVectorLength());
+ int newReferenceMask = referenceMask & (0xFFFFFFFF >>> (32 - newLength));
+ assert newReferenceMask != DERIVED_REFERENCE;
+ return new LIRKind(newPlatformKind, newReferenceMask);
+ }
+ }
+
+ /**
+ * Create a new {@link LIRKind} with a new {@linkplain #getPlatformKind platform kind}. If the
+ * new kind is longer than this, the reference positions are repeated to fill the vector.
+ */
+ public LIRKind repeat(PlatformKind newPlatformKind) {
+ if (isDerivedReference()) {
+ return derivedReference(newPlatformKind);
+ } else if (referenceMask == 0) {
+ // value type
+ return new LIRKind(newPlatformKind, 0);
+ } else {
+ // reference type
+ int oldLength = platformKind.getVectorLength();
+ int newLength = newPlatformKind.getVectorLength();
+ assert oldLength <= newLength && newLength < 32 && (newLength % oldLength) == 0;
+
+ // repeat reference mask to fill new kind
+ int newReferenceMask = 0;
+ for (int i = 0; i < newLength; i += platformKind.getVectorLength()) {
+ newReferenceMask |= referenceMask << i;
+ }
+
+ assert newReferenceMask != DERIVED_REFERENCE;
+ return new LIRKind(newPlatformKind, newReferenceMask);
+ }
+ }
+
+ /**
+ * Create a new {@link LIRKind} with the same type, but marked as containing a derivedReference.
+ */
+ public LIRKind makeDerivedReference() {
+ return new LIRKind(platformKind, DERIVED_REFERENCE);
+ }
+
+ /**
+ * Get the low level type that is used in code generation.
+ */
+ public PlatformKind getPlatformKind() {
+ return platformKind;
+ }
+
+ /**
+ * Check whether this value is derived from a reference. If this returns {@code true}, this
+ * value must not be live at safepoints.
+ */
+ public boolean isDerivedReference() {
+ return referenceMask == DERIVED_REFERENCE;
+ }
+
+ /**
+ * Check whether the {@code idx}th part of this value is a reference that must be tracked at
+ * safepoints.
+ *
+ * @param idx The index into the vector if this is a vector kind. Must be 0 if this is a scalar
+ * kind.
+ */
+ public boolean isReference(int idx) {
+ assert 0 <= idx && idx < platformKind.getVectorLength() : "invalid index " + idx + " in " + this;
+ return !isDerivedReference() && (referenceMask & 1 << idx) != 0;
+ }
+
+ /**
+ * Check whether this kind is a value type that doesn't need to be tracked at safepoints.
+ */
+ public boolean isValue() {
+ return referenceMask == 0;
+ }
+
+ @Override
+ public String toString() {
+ if (isValue()) {
+ return platformKind.name();
+ } else if (isDerivedReference()) {
+ return platformKind.name() + "[*]";
+ } else {
+ StringBuilder ret = new StringBuilder();
+ ret.append(platformKind.name());
+ ret.append('[');
+ for (int i = 0; i < platformKind.getVectorLength(); i++) {
+ if (isReference(i)) {
+ ret.append('.');
+ } else {
+ ret.append(' ');
+ }
+ }
+ ret.append(']');
+ return ret.toString();
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((platformKind == null) ? 0 : platformKind.hashCode());
+ result = prime * result + referenceMask;
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof LIRKind)) {
+ return false;
+ }
+
+ LIRKind other = (LIRKind) obj;
+ return platformKind == other.platformKind && referenceMask == other.referenceMask;
+ }
+}
\ No newline at end of file
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/NullConstant.java
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/NullConstant.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/NullConstant.java Mon Jun 30 12:02:19 2014 +0200
@@ -30,7 +30,7 @@
private static final long serialVersionUID = 8906209595800783961L;
protected NullConstant() {
- super(Kind.Object);
+ super(LIRKind.reference(Kind.Object));
}
@Override
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/PlatformKind.java
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/PlatformKind.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/PlatformKind.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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
@@ -30,4 +30,8 @@
String name();
Constant getDefaultValue();
+
+ default int getVectorLength() {
+ return 1;
+ }
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/PrimitiveConstant.java
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/PrimitiveConstant.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/PrimitiveConstant.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2014, 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
@@ -38,7 +38,7 @@
private final long primitive;
protected PrimitiveConstant(Kind kind, long primitive) {
- super(kind);
+ super(LIRKind.value(kind));
this.primitive = primitive;
assert kind.isPrimitive() || kind == Kind.Illegal;
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Value.java
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Value.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Value.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2014, 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
@@ -32,7 +32,7 @@
private static final long serialVersionUID = -6909397188697766469L;
- @SuppressWarnings("serial") public static final AllocatableValue ILLEGAL = new AllocatableValue(Kind.Illegal) {
+ @SuppressWarnings("serial") public static final AllocatableValue ILLEGAL = new AllocatableValue(LIRKind.Illegal) {
@Override
public String toString() {
@@ -41,17 +41,17 @@
};
private final Kind kind;
- private final PlatformKind platformKind;
+ private final LIRKind lirKind;
/**
* Initializes a new value of the specified kind.
*
- * @param platformKind the kind
+ * @param lirKind the kind
*/
- protected Value(PlatformKind platformKind) {
- this.platformKind = platformKind;
- if (platformKind instanceof Kind) {
- this.kind = (Kind) platformKind;
+ protected Value(LIRKind lirKind) {
+ this.lirKind = lirKind;
+ if (getPlatformKind() instanceof Kind) {
+ this.kind = (Kind) getPlatformKind();
} else {
this.kind = Kind.Illegal;
}
@@ -72,23 +72,27 @@
return kind;
}
+ public final LIRKind getLIRKind() {
+ return lirKind;
+ }
+
/**
* Returns the platform specific kind used to store this value.
*/
public final PlatformKind getPlatformKind() {
- return platformKind;
+ return lirKind.getPlatformKind();
}
@Override
public int hashCode() {
- return 41 + platformKind.hashCode();
+ return 41 + lirKind.hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Value) {
Value that = (Value) obj;
- return kind.equals(that.kind) && platformKind.equals(that.platformKind);
+ return kind.equals(that.kind) && lirKind.equals(that.lirKind);
}
return false;
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java
--- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java Mon Jun 30 12:02:19 2014 +0200
@@ -185,7 +185,7 @@
}
private void emitArithImm8(int op, Register dst, int imm8) {
- int encode = prefixAndEncode(op, dst.encoding, true);
+ int encode = prefixAndEncode(op, false, dst.encoding, true);
emitByte(0x80);
emitByte(0xC0 | encode);
emitByte(imm8);
@@ -560,7 +560,7 @@
}
public final void cmpb(Register dst, Register src) {
- int encode = prefixAndEncode(dst.encoding, src.encoding, true);
+ int encode = prefixAndEncode(dst.encoding, true, src.encoding, true);
emitByte(0x3A);
emitByte(0xC0 | encode);
}
@@ -1137,7 +1137,7 @@
}
public final void movsbl(Register dst, Register src) {
- int encode = prefixAndEncode(dst.encoding, src.encoding, true);
+ int encode = prefixAndEncode(dst.encoding, false, src.encoding, true);
emitByte(0x0F);
emitByte(0xBE);
emitByte(0xC0 | encode);
@@ -2042,17 +2042,17 @@
}
private int prefixAndEncode(int dstEnc, int srcEnc) {
- return prefixAndEncode(dstEnc, srcEnc, false);
+ return prefixAndEncode(dstEnc, false, srcEnc, false);
}
- private int prefixAndEncode(int dstEncoding, int srcEncoding, boolean byteinst) {
+ private int prefixAndEncode(int dstEncoding, boolean dstIsByte, int srcEncoding, boolean srcIsByte) {
int srcEnc = srcEncoding;
int dstEnc = dstEncoding;
if (dstEnc < 8) {
if (srcEnc >= 8) {
emitByte(Prefix.REXB);
srcEnc -= 8;
- } else if (byteinst && srcEnc >= 4) {
+ } else if ((srcIsByte && srcEnc >= 4) || (dstIsByte && dstEnc >= 4)) {
emitByte(Prefix.REX);
}
} else {
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java
--- a/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java Mon Jun 30 12:02:19 2014 +0200
@@ -35,7 +35,6 @@
import com.oracle.graal.compiler.common.*;
import com.oracle.graal.compiler.common.calc.*;
import com.oracle.graal.compiler.common.cfg.*;
-import com.oracle.graal.compiler.common.type.*;
import com.oracle.graal.compiler.gen.*;
import com.oracle.graal.compiler.target.*;
import com.oracle.graal.debug.*;
@@ -482,7 +481,7 @@
Value classRef = lirBuilder.getClassConstant(field.getDeclaringClass());
long displacement = lirBuilder.getFieldOffset(field);
Value address = gen.emitAddress(classRef, displacement, Value.ILLEGAL, 0);
- PlatformKind readKind = gen.getPlatformKind(StampFactory.forKind(field.getKind()));
+ LIRKind readKind = backend.getTarget().getLIRKind(field.getKind());
LIRFrameState state = createFrameState(frameState);
return gen.emitLoad(readKind, address, state);
}
@@ -506,7 +505,7 @@
emitNullCheck(array);
long displacement = lirBuilder.getArrayLengthOffset();
Value address = gen.emitAddress(array, displacement, Value.ILLEGAL, 0);
- PlatformKind readKind = gen.getPlatformKind(StampFactory.forKind(Kind.Int));
+ LIRKind readKind = backend.getTarget().getLIRKind(Kind.Int);
LIRFrameState state = createFrameState(frameState);
return gen.emitLoad(readKind, address, state);
}
@@ -682,7 +681,7 @@
for (int i = 0; i < frameState.stackSize(); i++) {
Value src = frameState.stackAt(i);
if (src instanceof Constant) {
- AllocatableValue dst = gen.newVariable(src.getPlatformKind());
+ AllocatableValue dst = gen.newVariable(src.getLIRKind());
gen.emitMove(dst, src);
frameState.storeStack(i, dst);
Debug.log("introduce new variabe %s for stackslot %d (end of block %s", dst, i, currentBlock);
@@ -691,7 +690,7 @@
for (int i = 0; i < frameState.localsSize(); i++) {
Value src = frameState.localAt(i);
if (src instanceof Constant) {
- AllocatableValue dst = gen.newVariable(src.getPlatformKind());
+ AllocatableValue dst = gen.newVariable(src.getLIRKind());
gen.emitMove(dst, src);
frameState.storeLocal(i, dst);
Debug.log("introduce new variabe %s for local %d (end of block %s", dst, i, currentBlock);
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2014, 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
@@ -77,11 +77,11 @@
*/
public abstract class AMD64LIRGenerator extends LIRGenerator {
- private static final RegisterValue RAX_I = AMD64.rax.asValue(Kind.Int);
- private static final RegisterValue RAX_L = AMD64.rax.asValue(Kind.Long);
- private static final RegisterValue RDX_I = AMD64.rdx.asValue(Kind.Int);
- private static final RegisterValue RDX_L = AMD64.rdx.asValue(Kind.Long);
- private static final RegisterValue RCX_I = AMD64.rcx.asValue(Kind.Int);
+ private static final RegisterValue RAX_I = AMD64.rax.asValue(LIRKind.value(Kind.Int));
+ private static final RegisterValue RAX_L = AMD64.rax.asValue(LIRKind.value(Kind.Long));
+ private static final RegisterValue RDX_I = AMD64.rdx.asValue(LIRKind.value(Kind.Int));
+ private static final RegisterValue RDX_L = AMD64.rdx.asValue(LIRKind.value(Kind.Long));
+ private static final RegisterValue RCX_I = AMD64.rcx.asValue(LIRKind.value(Kind.Int));
private class AMD64SpillMoveFactory implements LIR.SpillMoveFactory {
@@ -125,7 +125,7 @@
@Override
public Variable emitMove(Value input) {
- Variable result = newVariable(input.getPlatformKind());
+ Variable result = newVariable(input.getLIRKind());
emitMove(result, input);
return result;
}
@@ -208,7 +208,8 @@
}
}
- return new AMD64AddressValue(target().wordKind, baseRegister, indexRegister, scaleEnum, displacementInt);
+ LIRKind resultKind = getAddressKind(base, displacement, index);
+ return new AMD64AddressValue(resultKind, baseRegister, indexRegister, scaleEnum, displacementInt);
}
public AMD64AddressValue asAddressValue(Value address) {
@@ -221,7 +222,7 @@
@Override
public Variable emitAddress(StackSlot address) {
- Variable result = newVariable(target().wordKind);
+ Variable result = newVariable(LIRKind.value(target().wordKind));
append(new StackLeaOp(result, address));
return result;
}
@@ -270,7 +271,7 @@
boolean mirrored = emitCompare(cmpKind, left, right);
Condition finalCondition = mirrored ? cond.mirror() : cond;
- Variable result = newVariable(trueValue.getKind());
+ Variable result = newVariable(trueValue.getLIRKind());
if (cmpKind == Kind.Float || cmpKind == Kind.Double) {
append(new FloatCondMoveOp(result, finalCondition, unorderedIsTrue, load(trueValue), load(falseValue)));
} else {
@@ -282,7 +283,7 @@
@Override
public Variable emitIntegerTestMove(Value left, Value right, Value trueValue, Value falseValue) {
emitIntegerTest(left, right);
- Variable result = newVariable(trueValue.getKind());
+ Variable result = newVariable(trueValue.getLIRKind());
append(new CondMoveOp(result, Condition.EQ, load(trueValue), loadNonConst(falseValue)));
return result;
}
@@ -432,7 +433,7 @@
@Override
public Variable emitNegate(Value inputVal) {
AllocatableValue input = asAllocatable(inputVal);
- Variable result = newVariable(input.getKind());
+ Variable result = newVariable(input.getLIRKind());
switch (input.getKind()) {
case Int:
append(new Unary1Op(INEG, result, input));
@@ -455,7 +456,7 @@
@Override
public Variable emitNot(Value inputVal) {
AllocatableValue input = asAllocatable(inputVal);
- Variable result = newVariable(input.getKind());
+ Variable result = newVariable(input.getLIRKind());
switch (input.getKind()) {
case Int:
append(new Unary1Op(INOT, result, input));
@@ -492,7 +493,7 @@
case IXOR:
case LXOR:
if (NumUtil.isInt(b.asLong())) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
append(new BinaryRegConst(op, result, a, b));
return result;
}
@@ -501,7 +502,7 @@
case IMUL:
case LMUL:
if (NumUtil.isInt(b.asLong())) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
append(new BinaryRegStackConst(op, result, a, b));
return result;
}
@@ -512,7 +513,7 @@
}
private Variable emitBinaryVar(AMD64Arithmetic op, boolean commutative, AllocatableValue a, AllocatableValue b) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
if (commutative) {
append(new BinaryCommutative(op, result, a, b));
} else {
@@ -601,13 +602,13 @@
}
public Value emitBinaryMemory(AMD64Arithmetic op, Kind kind, AllocatableValue a, AMD64AddressValue location, LIRFrameState state) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
append(new BinaryMemory(op, kind, result, a, location, state));
return result;
}
protected Value emitConvert2MemoryOp(PlatformKind kind, AMD64Arithmetic op, AMD64AddressValue address, LIRFrameState state) {
- Variable result = newVariable(kind);
+ Variable result = newVariable(LIRKind.value(kind));
append(new Unary2MemoryOp(op, result, (Kind) null, address, state));
return result;
}
@@ -615,13 +616,13 @@
protected Value emitZeroExtendMemory(Kind memoryKind, int resultBits, AMD64AddressValue address, LIRFrameState state) {
// Issue a zero extending load of the proper bit size and set the result to
// the proper kind.
- Variable result = newVariable(resultBits == 32 ? Kind.Int : Kind.Long);
+ Variable result = newVariable(LIRKind.value(resultBits == 32 ? Kind.Int : Kind.Long));
append(new ZeroExtendLoadOp(memoryKind, result, address, state));
return result;
}
private void emitDivRem(AMD64Arithmetic op, Value a, Value b, LIRFrameState state) {
- AllocatableValue rax = AMD64.rax.asValue(a.getPlatformKind());
+ AllocatableValue rax = AMD64.rax.asValue(a.getLIRKind());
emitMove(rax, a);
append(new DivRemOp(op, rax, asAllocatable(b), state));
}
@@ -649,12 +650,12 @@
emitDivRem(LDIV, a, b, state);
return emitMove(RAX_L);
case Float: {
- Variable result = newVariable(a.getPlatformKind());
+ Variable result = newVariable(a.getLIRKind());
append(new BinaryRegStack(FDIV, result, asAllocatable(a), asAllocatable(b)));
return result;
}
case Double: {
- Variable result = newVariable(a.getPlatformKind());
+ Variable result = newVariable(a.getLIRKind());
append(new BinaryRegStack(DDIV, result, asAllocatable(a), asAllocatable(b)));
return result;
}
@@ -673,12 +674,12 @@
emitDivRem(LREM, a, b, state);
return emitMove(RDX_L);
case Float: {
- Variable result = newVariable(a.getPlatformKind());
+ Variable result = newVariable(a.getLIRKind());
append(new FPDivRemOp(FREM, result, load(a), load(b)));
return result;
}
case Double: {
- Variable result = newVariable(a.getPlatformKind());
+ Variable result = newVariable(a.getLIRKind());
append(new FPDivRemOp(DREM, result, load(a), load(b)));
return result;
}
@@ -752,7 +753,7 @@
}
private Variable emitShift(AMD64Arithmetic op, Value a, Value b) {
- Variable result = newVariable(a.getPlatformKind());
+ Variable result = newVariable(a.getLIRKind());
AllocatableValue input = asAllocatable(a);
if (isConstant(b)) {
append(new BinaryRegConst(op, result, input, asConstant(b)));
@@ -821,22 +822,22 @@
}
}
- private AllocatableValue emitConvert2RegOp(PlatformKind kind, AMD64Arithmetic op, AllocatableValue input) {
+ private AllocatableValue emitConvert2RegOp(LIRKind kind, AMD64Arithmetic op, AllocatableValue input) {
Variable result = newVariable(kind);
append(new Unary2RegOp(op, result, input));
return result;
}
- private AllocatableValue emitConvert2Op(PlatformKind kind, AMD64Arithmetic op, AllocatableValue input) {
+ private AllocatableValue emitConvert2Op(LIRKind kind, AMD64Arithmetic op, AllocatableValue input) {
Variable result = newVariable(kind);
append(new Unary2Op(op, result, input));
return result;
}
@Override
- public Value emitReinterpret(PlatformKind to, Value inputVal) {
- Kind from = inputVal.getKind();
- if (to == from) {
+ public Value emitReinterpret(LIRKind to, Value inputVal) {
+ LIRKind from = inputVal.getLIRKind();
+ if (to.equals(from)) {
return inputVal;
}
@@ -845,27 +846,28 @@
* Conversions between integer to floating point types require moves between CPU and FPU
* registers.
*/
- switch ((Kind) to) {
+ Kind fromKind = (Kind) from.getPlatformKind();
+ switch ((Kind) to.getPlatformKind()) {
case Int:
- switch (from) {
+ switch (fromKind) {
case Float:
return emitConvert2Op(to, MOV_F2I, input);
}
break;
case Long:
- switch (from) {
+ switch (fromKind) {
case Double:
return emitConvert2Op(to, MOV_D2L, input);
}
break;
case Float:
- switch (from) {
+ switch (fromKind) {
case Int:
return emitConvert2Op(to, MOV_I2F, input);
}
break;
case Double:
- switch (from) {
+ switch (fromKind) {
case Long:
return emitConvert2Op(to, MOV_L2D, input);
}
@@ -878,25 +880,25 @@
AllocatableValue input = asAllocatable(inputVal);
switch (op) {
case D2F:
- return emitConvert2Op(Kind.Float, D2F, input);
+ return emitConvert2Op(LIRKind.value(Kind.Float), D2F, input);
case D2I:
- return emitConvert2Op(Kind.Int, D2I, input);
+ return emitConvert2Op(LIRKind.value(Kind.Int), D2I, input);
case D2L:
- return emitConvert2Op(Kind.Long, D2L, input);
+ return emitConvert2Op(LIRKind.value(Kind.Long), D2L, input);
case F2D:
- return emitConvert2Op(Kind.Double, F2D, input);
+ return emitConvert2Op(LIRKind.value(Kind.Double), F2D, input);
case F2I:
- return emitConvert2Op(Kind.Int, F2I, input);
+ return emitConvert2Op(LIRKind.value(Kind.Int), F2I, input);
case F2L:
- return emitConvert2Op(Kind.Long, F2L, input);
+ return emitConvert2Op(LIRKind.value(Kind.Long), F2L, input);
case I2D:
- return emitConvert2Op(Kind.Double, I2D, input);
+ return emitConvert2Op(LIRKind.value(Kind.Double), I2D, input);
case I2F:
- return emitConvert2Op(Kind.Float, I2F, input);
+ return emitConvert2Op(LIRKind.value(Kind.Float), I2F, input);
case L2D:
- return emitConvert2Op(Kind.Double, L2D, input);
+ return emitConvert2Op(LIRKind.value(Kind.Double), L2D, input);
case L2F:
- return emitConvert2Op(Kind.Float, L2F, input);
+ return emitConvert2Op(LIRKind.value(Kind.Float), L2F, input);
default:
throw GraalInternalError.shouldNotReachHere();
}
@@ -906,7 +908,7 @@
public Value emitNarrow(Value inputVal, int bits) {
if (inputVal.getKind() == Kind.Long && bits <= 32) {
// TODO make it possible to reinterpret Long as Int in LIR without move
- return emitConvert2RegOp(Kind.Int, L2I, asAllocatable(inputVal));
+ return emitConvert2RegOp(LIRKind.value(Kind.Int), L2I, asAllocatable(inputVal));
} else {
return inputVal;
}
@@ -921,11 +923,11 @@
// sign extend to 64 bits
switch (fromBits) {
case 8:
- return emitConvert2Op(Kind.Long, B2L, asAllocatable(inputVal));
+ return emitConvert2Op(LIRKind.value(Kind.Long), B2L, asAllocatable(inputVal));
case 16:
- return emitConvert2Op(Kind.Long, S2L, asAllocatable(inputVal));
+ return emitConvert2Op(LIRKind.value(Kind.Long), S2L, asAllocatable(inputVal));
case 32:
- return emitConvert2Op(Kind.Long, I2L, asAllocatable(inputVal));
+ return emitConvert2Op(LIRKind.value(Kind.Long), I2L, asAllocatable(inputVal));
default:
throw GraalInternalError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)");
}
@@ -933,9 +935,9 @@
// sign extend to 32 bits (smaller values are internally represented as 32 bit values)
switch (fromBits) {
case 8:
- return emitConvert2Op(Kind.Int, B2I, asAllocatable(inputVal));
+ return emitConvert2Op(LIRKind.value(Kind.Int), B2I, asAllocatable(inputVal));
case 16:
- return emitConvert2Op(Kind.Int, S2I, asAllocatable(inputVal));
+ return emitConvert2Op(LIRKind.value(Kind.Int), S2I, asAllocatable(inputVal));
case 32:
return inputVal;
default:
@@ -951,17 +953,17 @@
return inputVal;
} else if (fromBits > 32) {
assert inputVal.getKind() == Kind.Long;
- Variable result = newVariable(Kind.Long);
+ Variable result = newVariable(LIRKind.value(Kind.Long));
long mask = IntegerStamp.defaultMask(fromBits);
append(new BinaryRegConst(AMD64Arithmetic.LAND, result, asAllocatable(inputVal), Constant.forLong(mask)));
return result;
} else {
assert inputVal.getKind().getStackKind() == Kind.Int;
- Variable result = newVariable(Kind.Int);
+ Variable result = newVariable(LIRKind.value(Kind.Int));
int mask = (int) IntegerStamp.defaultMask(fromBits);
append(new BinaryRegConst(AMD64Arithmetic.IAND, result, asAllocatable(inputVal), Constant.forInt(mask)));
if (toBits > 32) {
- Variable longResult = newVariable(Kind.Long);
+ Variable longResult = newVariable(LIRKind.value(Kind.Long));
emitMove(longResult, result);
return longResult;
} else {
@@ -991,85 +993,95 @@
}
@Override
- public void emitBitCount(Variable result, Value value) {
+ public Value emitBitCount(Value value) {
+ Variable result = newVariable(LIRKind.value(Kind.Int));
if (value.getKind().getStackKind() == Kind.Int) {
append(new AMD64BitManipulationOp(IPOPCNT, result, asAllocatable(value)));
} else {
append(new AMD64BitManipulationOp(LPOPCNT, result, asAllocatable(value)));
}
+ return result;
}
@Override
- public void emitBitScanForward(Variable result, Value value) {
+ public Value emitBitScanForward(Value value) {
+ Variable result = newVariable(LIRKind.value(Kind.Int));
append(new AMD64BitManipulationOp(BSF, result, asAllocatable(value)));
+ return result;
}
@Override
- public void emitBitScanReverse(Variable result, Value value) {
+ public Value emitBitScanReverse(Value value) {
+ Variable result = newVariable(LIRKind.value(Kind.Int));
if (value.getKind().getStackKind() == Kind.Int) {
append(new AMD64BitManipulationOp(IBSR, result, asAllocatable(value)));
} else {
append(new AMD64BitManipulationOp(LBSR, result, asAllocatable(value)));
}
+ return result;
}
@Override
public Value emitMathAbs(Value input) {
- Variable result = newVariable(input.getPlatformKind());
+ Variable result = newVariable(input.getLIRKind());
append(new BinaryRegConst(DAND, result, asAllocatable(input), Constant.forDouble(Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL))));
return result;
}
@Override
public Value emitMathSqrt(Value input) {
- Variable result = newVariable(input.getPlatformKind());
+ Variable result = newVariable(input.getLIRKind());
append(new Unary2Op(SQRT, result, asAllocatable(input)));
return result;
}
@Override
public Value emitMathLog(Value input, boolean base10) {
- Variable result = newVariable(input.getPlatformKind());
+ Variable result = newVariable(input.getLIRKind());
append(new AMD64MathIntrinsicOp(base10 ? LOG10 : LOG, result, asAllocatable(input)));
return result;
}
@Override
public Value emitMathCos(Value input) {
- Variable result = newVariable(input.getPlatformKind());
+ Variable result = newVariable(input.getLIRKind());
append(new AMD64MathIntrinsicOp(COS, result, asAllocatable(input)));
return result;
}
@Override
public Value emitMathSin(Value input) {
- Variable result = newVariable(input.getPlatformKind());
+ Variable result = newVariable(input.getLIRKind());
append(new AMD64MathIntrinsicOp(SIN, result, asAllocatable(input)));
return result;
}
@Override
public Value emitMathTan(Value input) {
- Variable result = newVariable(input.getPlatformKind());
+ Variable result = newVariable(input.getLIRKind());
append(new AMD64MathIntrinsicOp(TAN, result, asAllocatable(input)));
return result;
}
@Override
- public void emitByteSwap(Variable result, Value input) {
+ public Value emitByteSwap(Value input) {
+ Variable result = newVariable(input.getLIRKind());
append(new AMD64ByteSwapOp(result, input));
+ return result;
}
@Override
- public void emitArrayEquals(Kind kind, Variable result, Value array1, Value array2, Value length) {
+ public Value emitArrayEquals(Kind kind, Value array1, Value array2, Value length) {
+ Variable result = newVariable(LIRKind.value(Kind.Int));
append(new AMD64ArrayEqualsOp(this, kind, result, array1, array2, asAllocatable(length)));
+ return result;
}
@Override
public void emitReturn(Value input) {
AllocatableValue operand = Value.ILLEGAL;
if (input != null) {
- operand = resultOperandFor(input.getKind());
+ operand = resultOperandFor(input.getLIRKind());
emitMove(operand, input);
}
append(new ReturnOp(operand));
@@ -1079,12 +1091,12 @@
public void emitStrategySwitch(SwitchStrategy strategy, Variable key, LabelRef[] keyTargets, LabelRef defaultTarget) {
// a temp is needed for loading object constants
boolean needsTemp = key.getKind() == Kind.Object;
- append(new StrategySwitchOp(strategy, keyTargets, defaultTarget, key, needsTemp ? newVariable(key.getKind()) : Value.ILLEGAL));
+ append(new StrategySwitchOp(strategy, keyTargets, defaultTarget, key, needsTemp ? newVariable(key.getLIRKind()) : Value.ILLEGAL));
}
@Override
protected void emitTableSwitch(int lowKey, LabelRef defaultTarget, LabelRef[] targets, Value key) {
- append(new TableSwitchOp(lowKey, defaultTarget, targets, key, newVariable(target().wordKind), newVariable(key.getPlatformKind())));
+ append(new TableSwitchOp(lowKey, defaultTarget, targets, key, newVariable(LIRKind.value(target().wordKind)), newVariable(key.getLIRKind())));
}
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2014, 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
@@ -64,8 +64,8 @@
FixedWithNextNode fixedWithNextNode = (FixedWithNextNode) node;
if (((fixedWithNextNode instanceof IntegerDivNode) || (fixedWithNextNode instanceof IntegerRemNode)) && fixedWithNextNode.getClass() != divRem.getClass()) {
FixedBinaryNode otherDivRem = (FixedBinaryNode) fixedWithNextNode;
- if (otherDivRem.x() == divRem.x() && otherDivRem.y() == divRem.y() && !hasOperand(otherDivRem)) {
- Value[] results = ((AMD64LIRGenerator) gen).emitIntegerDivRem(operand(divRem.x()), operand(divRem.y()), state((DeoptimizingNode) valueNode));
+ if (otherDivRem.getX() == divRem.getX() && otherDivRem.getY() == divRem.getY() && !hasOperand(otherDivRem)) {
+ Value[] results = ((AMD64LIRGenerator) gen).emitIntegerDivRem(operand(divRem.getX()), operand(divRem.getY()), state((DeoptimizingNode) valueNode));
if (divRem instanceof IntegerDivNode) {
setResult(divRem, results[0]);
setResult(otherDivRem, results[1]);
@@ -90,7 +90,7 @@
}
protected Kind getMemoryKind(Access access) {
- return (Kind) gen.getPlatformKind(access.asNode().stamp());
+ return (Kind) gen.getLIRKind(access.asNode().stamp()).getPlatformKind();
}
protected AMD64AddressValue makeAddress(Access access) {
@@ -133,33 +133,27 @@
}
}
- PlatformKind cmpKind = gen.getPlatformKind(compare.x().stamp());
- if (cmpKind instanceof Kind) {
- // emitCompareBranchMemory expects the memory on the right, so mirror the condition if
- // that's not true. It might be mirrored again the actual compare is emitted but that's
- // ok.
- Condition finalCondition = uncast(compare.x()) == access ? cond.mirror() : cond;
- return new ComplexMatchResult() {
- public Value evaluate(NodeLIRBuilder builder) {
- LabelRef trueLabel = getLIRBlock(ifNode.trueSuccessor());
- LabelRef falseLabel = getLIRBlock(ifNode.falseSuccessor());
- boolean unorderedIsTrue = compare.unorderedIsTrue();
- double trueLabelProbability = ifNode.probability(ifNode.trueSuccessor());
- Value other;
- if (value.isConstant()) {
- other = value.asConstant();
- } else {
- other = operand(value);
- }
+ // emitCompareBranchMemory expects the memory on the right, so mirror the condition if
+ // that's not true. It might be mirrored again the actual compare is emitted but that's
+ // ok.
+ Condition finalCondition = uncast(compare.getX()) == access ? cond.mirror() : cond;
+ return new ComplexMatchResult() {
+ public Value evaluate(NodeLIRBuilder builder) {
+ LabelRef trueLabel = getLIRBlock(ifNode.trueSuccessor());
+ LabelRef falseLabel = getLIRBlock(ifNode.falseSuccessor());
+ boolean unorderedIsTrue = compare.unorderedIsTrue();
+ double trueLabelProbability = ifNode.probability(ifNode.trueSuccessor());
+ Value other;
+ if (value.isConstant()) {
+ other = value.asConstant();
+ } else {
+ other = operand(value);
+ }
- getLIRGeneratorTool().emitCompareBranchMemory((Kind) cmpKind, other, makeAddress(access), getState(access), finalCondition, unorderedIsTrue, trueLabel, falseLabel,
- trueLabelProbability);
- return null;
- }
- };
- }
- return null;
-
+ getLIRGeneratorTool().emitCompareBranchMemory(kind, other, makeAddress(access), getState(access), finalCondition, unorderedIsTrue, trueLabel, falseLabel, trueLabelProbability);
+ return null;
+ }
+ };
}
private ComplexMatchResult emitIntegerTestBranchMemory(IfNode x, ValueNode value, Access access) {
@@ -273,7 +267,7 @@
return null;
}
- private Value emitReinterpretMemory(PlatformKind to, Access access) {
+ private Value emitReinterpretMemory(LIRKind to, Access access) {
AMD64AddressValue address = makeAddress(access);
LIRFrameState state = getState(access);
return getLIRGeneratorTool().emitLoad(to, address, state);
@@ -370,8 +364,8 @@
@MatchRule("(Or (LeftShift=lshift value Constant) (UnsignedRightShift=rshift value Constant))")
public ComplexMatchResult rotateLeftConstant(LeftShiftNode lshift, UnsignedRightShiftNode rshift) {
- if ((lshift.getShiftAmountMask() & (lshift.y().asConstant().asInt() + rshift.y().asConstant().asInt())) == 0) {
- return builder -> getLIRGeneratorTool().emitRol(operand(lshift.x()), operand(lshift.y()));
+ if ((lshift.getShiftAmountMask() & (lshift.getY().asConstant().asInt() + rshift.getY().asConstant().asInt())) == 0) {
+ return builder -> getLIRGeneratorTool().emitRol(operand(lshift.getX()), operand(lshift.getY()));
}
return null;
}
@@ -421,9 +415,9 @@
@MatchRule("(Write Narrow=narrow location value)")
public ComplexMatchResult writeNarrow(WriteNode root, NarrowNode narrow) {
return builder -> {
- PlatformKind writeKind = getLIRGeneratorTool().getPlatformKind(root.value().stamp());
+ LIRKind writeKind = getLIRGeneratorTool().getLIRKind(root.value().stamp());
Value address = root.location().generateAddress(builder, getLIRGeneratorTool(), operand(root.object()));
- Value v = operand(narrow.getInput());
+ Value v = operand(narrow.getValue());
getLIRGeneratorTool().emitStore(writeKind, address, v, state(root));
return null;
};
@@ -461,7 +455,7 @@
@MatchRule("(Reinterpret FloatingRead=access)")
public ComplexMatchResult reinterpret(ReinterpretNode root, Access access) {
return builder -> {
- PlatformKind kind = getLIRGeneratorTool().getPlatformKind(root.stamp());
+ LIRKind kind = getLIRGeneratorTool().getLIRKind(root.stamp());
return emitReinterpretMemory(kind, access);
};
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/UnsafeAccess.java
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractBlock.java
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractBlock.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractBlock.java Mon Jun 30 12:02:19 2014 +0200
@@ -64,6 +64,7 @@
* True if block {@code a} dominates block {@code b}.
*/
static boolean dominates(AbstractBlock> a, AbstractBlock> b) {
+ assert a != null;
return isDominatedBy(b, a);
}
@@ -71,6 +72,7 @@
* True if block {@code a} is dominated by block {@code b}.
*/
static boolean isDominatedBy(AbstractBlock> a, AbstractBlock> b) {
+ assert a != null;
if (a == b) {
return true;
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/spi/LIRKindTool.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/spi/LIRKindTool.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014, 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.compiler.common.spi;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * This interface can be used to access platform and VM specific kinds.
+ */
+public interface LIRKindTool {
+
+ LIRKind getIntegerKind(int bits);
+
+ LIRKind getFloatingKind(int bits);
+
+ LIRKind getObjectKind();
+}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/spi/PlatformKindTool.java
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/spi/PlatformKindTool.java Mon Jun 30 08:50:26 2014 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2014, 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.compiler.common.spi;
-
-import com.oracle.graal.api.meta.*;
-
-/**
- * This interface can be used to access platform and VM specific kinds.
- */
-public interface PlatformKindTool {
-
- PlatformKind getIntegerKind(int bits);
-
- PlatformKind getFloatingKind(int bits);
-
- PlatformKind getObjectKind();
-}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/AbstractObjectStamp.java
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/FloatStamp.java
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/FloatStamp.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/FloatStamp.java Mon Jun 30 12:02:19 2014 +0200
@@ -74,7 +74,7 @@
}
@Override
- public PlatformKind getPlatformKind(PlatformKindTool tool) {
+ public LIRKind getLIRKind(LIRKindTool tool) {
return tool.getFloatingKind(getBits());
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IllegalStamp.java
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IllegalStamp.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IllegalStamp.java Mon Jun 30 12:02:19 2014 +0200
@@ -40,7 +40,7 @@
}
@Override
- public PlatformKind getPlatformKind(PlatformKindTool tool) {
+ public LIRKind getLIRKind(LIRKindTool tool) {
throw GraalInternalError.shouldNotReachHere("illegal stamp should not reach backend");
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java Mon Jun 30 12:02:19 2014 +0200
@@ -84,7 +84,7 @@
}
@Override
- public PlatformKind getPlatformKind(PlatformKindTool tool) {
+ public LIRKind getLIRKind(LIRKindTool tool) {
return tool.getIntegerKind(getBits());
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ObjectStamp.java
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ObjectStamp.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ObjectStamp.java Mon Jun 30 12:02:19 2014 +0200
@@ -42,7 +42,7 @@
}
@Override
- public PlatformKind getPlatformKind(PlatformKindTool tool) {
+ public LIRKind getLIRKind(LIRKindTool tool) {
return tool.getObjectKind();
}
@@ -64,4 +64,13 @@
}
return false;
}
+
+ @Override
+ public Constant asConstant() {
+ if (alwaysNull()) {
+ return Constant.NULL_OBJECT;
+ } else {
+ return null;
+ }
+ }
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/PrimitiveStamp.java
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/Stamp.java
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/Stamp.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/Stamp.java Mon Jun 30 12:02:19 2014 +0200
@@ -51,10 +51,9 @@
public abstract Kind getStackKind();
/**
- * Gets a platform dependent {@link PlatformKind} that can be used to store a value of this
- * stamp.
+ * Gets a platform dependent {@link LIRKind} that can be used to store a value of this stamp.
*/
- public abstract PlatformKind getPlatformKind(PlatformKindTool tool);
+ public abstract LIRKind getLIRKind(LIRKindTool tool);
/**
* Returns the union of this stamp and the given stamp. Typically used to create stamps for phi
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampProvider.java
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/VoidStamp.java
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/VoidStamp.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/VoidStamp.java Mon Jun 30 12:02:19 2014 +0200
@@ -45,7 +45,7 @@
}
@Override
- public PlatformKind getPlatformKind(PlatformKindTool tool) {
+ public LIRKind getLIRKind(LIRKindTool tool) {
throw GraalInternalError.shouldNotReachHere("void stamp has no value");
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/GraalKernelTester.java
--- a/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/GraalKernelTester.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/GraalKernelTester.java Mon Jun 30 12:02:19 2014 +0200
@@ -152,13 +152,17 @@
return true;
}
+ HotSpotNmethod installedCode;
+
@Override
protected void dispatchKernelOkra(int range, Object... args) {
HSAILHotSpotBackend backend = getHSAILBackend();
if (backend.isDeviceInitialized()) {
try {
- HotSpotNmethod code = backend.compileAndInstallKernel(testMethod);
- backend.executeKernel(code, range, args);
+ if (installedCode == null) {
+ installedCode = backend.compileAndInstallKernel(testMethod);
+ }
+ backend.executeKernel(installedCode, range, args);
} catch (InvalidInstalledCodeException e) {
Debug.log("WARNING:Invalid installed code: " + e);
e.printStackTrace();
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/AtomicIntGetAndAddTest.java
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/AtomicIntGetAndAddTest.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/AtomicIntGetAndAddTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -45,11 +45,6 @@
}
@Override
- protected boolean supportsRequiredCapabilities() {
- return (canDeoptimize());
- }
-
- @Override
public void runTest() {
setupArrays();
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/AtomicIntGetAndSetTest.java
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/AtomicIntGetAndSetTest.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/AtomicIntGetAndSetTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -45,11 +45,6 @@
}
@Override
- protected boolean supportsRequiredCapabilities() {
- return (canDeoptimize());
- }
-
- @Override
public void runTest() {
setupArrays();
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/AtomicLongGetAndAddTest.java
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/AtomicLongGetAndAddTest.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/AtomicLongGetAndAddTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -45,11 +45,6 @@
}
@Override
- protected boolean supportsRequiredCapabilities() {
- return (canDeoptimize());
- }
-
- @Override
public void runTest() {
setupArrays();
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/AtomicLongGetAndSetTest.java
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/AtomicLongGetAndSetTest.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/AtomicLongGetAndSetTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -45,11 +45,6 @@
}
@Override
- protected boolean supportsRequiredCapabilities() {
- return (canDeoptimize());
- }
-
- @Override
public void runTest() {
setupArrays();
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchMost20000StressGCTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchMost20000StressGCTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2009, 2012, 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.compiler.hsail.test;
+
+import org.junit.*;
+
+/**
+ * A version which is likely to get a GC while running the never_rans, and so is good for oops_do
+ * testing.
+ */
+public class BoundsCatchMost20000StressGCTest extends BoundsCatchManyBase {
+
+ @Override
+ int getGlobalSize() {
+ return 20000;
+ }
+
+ boolean isMyDeoptGid(int gid) {
+ return (gid > 100 && gid % 100 != 1);
+ }
+
+ int[] dummyArray;
+
+ // copied run routine here because otherwise polymorphic calls to isDeoptGid
+ @Override
+ public void run(int gid) {
+ int outval = getOutval(gid);
+ try {
+ int index = (isMyDeoptGid(gid) ? num + 1 : gid);
+ outArray[index] = outval;
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // set up so we can detect if we go thru here twice
+ outArray[gid] += outval;
+ // note: cannot record the exceptiongid here for many deopts in parallel
+
+ // allocate something so GCs happen more often
+ dummyArray = new int[1000];
+ }
+ }
+
+ @Override
+ public void runTest() {
+ setupArrays();
+
+ for (int i = 0; i < 10; i++) {
+ // we should not get an exception escaping from the kernel
+ dispatchMethodKernel(num);
+ }
+ }
+
+ @Test
+ public void test() {
+ testGeneratedHsail();
+ }
+}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewStringConcatTest.java
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewStringConcatTest.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewStringConcatTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -50,8 +50,7 @@
myOutArray[gid] = inArray[(gid + NUM / 2) % NUM] + inArray[gid];
}
- // Node implementing Lowerable not handled in HSAIL Backend: 6274|MonitorEnter
- @Ignore
+ @Ignore("emitDirectCall unimplemented")
@Test
public void test() {
try (DebugConfigScope s = disableIntercept()) {
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ArrayListGetTest.java
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ArrayListGetTest.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ArrayListGetTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -23,14 +23,11 @@
package com.oracle.graal.compiler.hsail.test.lambda;
-import static com.oracle.graal.debug.Debug.*;
-
import java.util.*;
import org.junit.*;
import com.oracle.graal.compiler.hsail.test.infra.*;
-import com.oracle.graal.debug.*;
/**
* Tests calling ArrayList.get().
@@ -58,13 +55,10 @@
});
}
- // NYI emitForeignCall charAlignedDisjointArraycopy
- @Test(expected = com.oracle.graal.compiler.common.GraalInternalError.class)
- @Ignore
+ @Ignore("emitDirectCall unimplemented")
+ @Test
public void testUsingLambdaMethod() {
- try (DebugConfigScope s = disableIntercept()) {
- testGeneratedHsailUsingLambdaMethod();
- }
+ testGeneratedHsailUsingLambdaMethod();
}
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ArrayListSetTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ArrayListSetTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2014, 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.compiler.hsail.test.lambda;
+
+import com.oracle.graal.compiler.hsail.test.infra.*;
+
+import org.junit.*;
+import java.util.*;
+
+/**
+ * Tests calling ArrayList.set().
+ */
+public class ArrayListSetTest extends GraalKernelTester {
+
+ final static int NUM = 50;
+ ArrayList aryList = new ArrayList<>();
+
+ @Override
+ public void runTest() {
+ for (int i = 0; i < NUM; i++) {
+ aryList.add(-1);
+ }
+ dispatchLambdaKernel(NUM, (gid) -> {
+ aryList.set(gid, gid);
+ });
+ }
+
+ @Override
+ protected boolean supportsRequiredCapabilities() {
+ return (canHandleObjectAllocation());
+ }
+
+ @Test
+ @Ignore
+ public void testUsingLambdaMethod() {
+ testGeneratedHsailUsingLambdaMethod();
+ }
+}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntAddAndGetGidTest.java
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntAddAndGetGidTest.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntAddAndGetGidTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -47,11 +47,6 @@
}
@Override
- protected boolean supportsRequiredCapabilities() {
- return (canDeoptimize());
- }
-
- @Override
public void runTest() {
setupArrays();
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntAddAndGetTest.java
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntAddAndGetTest.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntAddAndGetTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -44,11 +44,6 @@
}
@Override
- protected boolean supportsRequiredCapabilities() {
- return (canDeoptimize());
- }
-
- @Override
public void runTest() {
setupArrays();
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntDecAndGetTest.java
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntDecAndGetTest.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntDecAndGetTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -44,11 +44,6 @@
}
@Override
- protected boolean supportsRequiredCapabilities() {
- return (canDeoptimize());
- }
-
- @Override
public void runTest() {
setupArrays();
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntGetAndAddTest.java
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntGetAndAddTest.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntGetAndAddTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -44,11 +44,6 @@
}
@Override
- protected boolean supportsRequiredCapabilities() {
- return (canDeoptimize());
- }
-
- @Override
public void runTest() {
setupArrays();
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntGetAndDecTest.java
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntGetAndDecTest.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntGetAndDecTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -44,11 +44,6 @@
}
@Override
- protected boolean supportsRequiredCapabilities() {
- return (canDeoptimize());
- }
-
- @Override
public void runTest() {
setupArrays();
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntGetAndIncTest.java
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntGetAndIncTest.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntGetAndIncTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -44,11 +44,6 @@
}
@Override
- protected boolean supportsRequiredCapabilities() {
- return (canDeoptimize());
- }
-
- @Override
public void runTest() {
setupArrays();
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntIncAndGetTest.java
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntIncAndGetTest.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntIncAndGetTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -44,11 +44,6 @@
}
@Override
- protected boolean supportsRequiredCapabilities() {
- return (canDeoptimize());
- }
-
- @Override
public void runTest() {
setupArrays();
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicLongAddAndGetTest.java
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicLongAddAndGetTest.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicLongAddAndGetTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -46,11 +46,6 @@
}
@Override
- protected boolean supportsRequiredCapabilities() {
- return (canDeoptimize());
- }
-
- @Override
public void runTest() {
setupArrays();
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicLongGetAndAddTest.java
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicLongGetAndAddTest.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicLongGetAndAddTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -44,11 +44,6 @@
}
@Override
- protected boolean supportsRequiredCapabilities() {
- return (canDeoptimize());
- }
-
- @Override
public void runTest() {
setupArrays();
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicLongGetAndIncTest.java
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicLongGetAndIncTest.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicLongGetAndIncTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -44,11 +44,6 @@
}
@Override
- protected boolean supportsRequiredCapabilities() {
- return (canDeoptimize());
- }
-
- @Override
public void runTest() {
setupArrays();
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicLongIncAndGetTest.java
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicLongIncAndGetTest.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicLongIncAndGetTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -44,11 +44,6 @@
}
@Override
- protected boolean supportsRequiredCapabilities() {
- return (canDeoptimize());
- }
-
- @Override
public void runTest() {
setupArrays();
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ByteArrayCopyConjointTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ByteArrayCopyConjointTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2014, 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.compiler.hsail.test.lambda;
+
+import com.oracle.graal.compiler.hsail.test.infra.*;
+
+import org.junit.*;
+
+/**
+ * Tests copying a byte array where src and dest overlap.
+ */
+public class ByteArrayCopyConjointTest extends GraalKernelTester {
+
+ final static int MAXOUTSIZ = 100;
+ final static int NUM = 20;
+
+ @Result byte[][] outArray = new byte[NUM][MAXOUTSIZ];
+
+ @Override
+ public void runTest() {
+ for (int i = 0; i < NUM; i++) {
+ for (int j = 0; j < outArray[i].length; j++) {
+ outArray[i][j] = (byte) (i + j);
+ }
+ }
+ dispatchLambdaKernel(NUM, (gid) -> {
+ System.arraycopy(outArray[gid], 0, outArray[gid], gid % NUM, NUM);
+ });
+ }
+
+ @Test
+ public void testUsingLambdaMethod() {
+ testGeneratedHsailUsingLambdaMethod();
+ }
+}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ByteArrayCopyDisjointTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ByteArrayCopyDisjointTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2014, 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.compiler.hsail.test.lambda;
+
+import com.oracle.graal.compiler.hsail.test.infra.*;
+
+import org.junit.*;
+
+/**
+ * Tests copying a byte array where src and dest do not overlap.
+ */
+public class ByteArrayCopyDisjointTest extends GraalKernelTester {
+
+ final static int MAXOUTSIZ = 100;
+ final static int NUM = 20;
+
+ @Result byte[][] outArray = new byte[NUM][MAXOUTSIZ];
+ byte[] inArray = new byte[NUM + MAXOUTSIZ];
+
+ @Override
+ public void runTest() {
+ for (int i = 0; i < inArray.length; i++) {
+ inArray[i] = (byte) i;
+ }
+ dispatchLambdaKernel(NUM, (gid) -> {
+ System.arraycopy(inArray, gid, outArray[gid], 0, MAXOUTSIZ);
+ });
+ }
+
+ @Test
+ public void testUsingLambdaMethod() {
+ testGeneratedHsailUsingLambdaMethod();
+ }
+}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/CharArrayCopyConjointTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/CharArrayCopyConjointTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2014, 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.compiler.hsail.test.lambda;
+
+import com.oracle.graal.compiler.hsail.test.infra.*;
+
+import org.junit.*;
+
+/**
+ * Tests copying a char array where src and dest overlap.
+ */
+public class CharArrayCopyConjointTest extends GraalKernelTester {
+
+ final static int MAXOUTSIZ = 100;
+ final static int NUM = 20;
+
+ @Result char[][] outArray = new char[NUM][MAXOUTSIZ];
+
+ @Override
+ public void runTest() {
+ for (int i = 0; i < NUM; i++) {
+ for (int j = 0; j < outArray[i].length; j++) {
+ outArray[i][j] = (char) (i + j);
+ }
+ }
+ dispatchLambdaKernel(NUM, (gid) -> {
+ System.arraycopy(outArray[gid], 0, outArray[gid], gid % NUM, NUM);
+ });
+ }
+
+ @Test
+ public void testUsingLambdaMethod() {
+ testGeneratedHsailUsingLambdaMethod();
+ }
+}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/CharArrayCopyDisjointTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/CharArrayCopyDisjointTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2014, 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.compiler.hsail.test.lambda;
+
+import com.oracle.graal.compiler.hsail.test.infra.*;
+
+import org.junit.*;
+
+/**
+ * Tests copying a char array where src and dest do not overlap.
+ */
+public class CharArrayCopyDisjointTest extends GraalKernelTester {
+
+ final static int MAXOUTSIZ = 100;
+ final static int NUM = 20;
+
+ @Result char[][] outArray = new char[NUM][MAXOUTSIZ];
+ char[] inArray = new char[NUM + MAXOUTSIZ];
+
+ @Override
+ public void runTest() {
+ for (int i = 0; i < inArray.length; i++) {
+ inArray[i] = (char) i;
+ }
+ dispatchLambdaKernel(NUM, (gid) -> {
+ System.arraycopy(inArray, gid, outArray[gid], 0, MAXOUTSIZ);
+ });
+ }
+
+ @Test
+ public void testUsingLambdaMethod() {
+ testGeneratedHsailUsingLambdaMethod();
+ }
+}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/IntArrayCopyConjointTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/IntArrayCopyConjointTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2014, 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.compiler.hsail.test.lambda;
+
+import com.oracle.graal.compiler.hsail.test.infra.*;
+
+import org.junit.*;
+
+/**
+ * Tests copying a int array where src and dest overlap.
+ */
+public class IntArrayCopyConjointTest extends GraalKernelTester {
+
+ final static int MAXOUTSIZ = 100;
+ final static int NUM = 20;
+
+ @Result int[][] outArray = new int[NUM][MAXOUTSIZ];
+
+ @Override
+ public void runTest() {
+ for (int i = 0; i < NUM; i++) {
+ for (int j = 0; j < outArray[i].length; j++) {
+ outArray[i][j] = i + j;
+ }
+ }
+ dispatchLambdaKernel(NUM, (gid) -> {
+ System.arraycopy(outArray[gid], 0, outArray[gid], gid % NUM, NUM);
+ });
+ }
+
+ @Test
+ public void testUsingLambdaMethod() {
+ testGeneratedHsailUsingLambdaMethod();
+ }
+}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/IntArrayCopyDisjointTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/IntArrayCopyDisjointTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2014, 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.compiler.hsail.test.lambda;
+
+import com.oracle.graal.compiler.hsail.test.infra.*;
+
+import org.junit.*;
+
+/**
+ * Tests copying a int array where src and dest do not overlap.
+ */
+public class IntArrayCopyDisjointTest extends GraalKernelTester {
+
+ final static int MAXOUTSIZ = 100;
+ final static int NUM = 20;
+
+ @Result int[][] outArray = new int[NUM][MAXOUTSIZ];
+ int[] inArray = new int[NUM + MAXOUTSIZ];
+
+ @Override
+ public void runTest() {
+ for (int i = 0; i < inArray.length; i++) {
+ inArray[i] = i;
+ }
+ dispatchLambdaKernel(NUM, (gid) -> {
+ System.arraycopy(inArray, gid, outArray[gid], 0, MAXOUTSIZ);
+ });
+ }
+
+ @Test
+ public void testUsingLambdaMethod() {
+ testGeneratedHsailUsingLambdaMethod();
+ }
+}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/LongArrayCopyConjointTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/LongArrayCopyConjointTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2014, 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.compiler.hsail.test.lambda;
+
+import com.oracle.graal.compiler.hsail.test.infra.*;
+
+import org.junit.*;
+
+/**
+ * Tests copying a long array where src and dest overlap.
+ */
+public class LongArrayCopyConjointTest extends GraalKernelTester {
+
+ final static int MAXOUTSIZ = 100;
+ final static int NUM = 20;
+
+ @Result long[][] outArray = new long[NUM][MAXOUTSIZ];
+
+ @Override
+ public void runTest() {
+ for (int i = 0; i < NUM; i++) {
+ for (int j = 0; j < outArray[i].length; j++) {
+ outArray[i][j] = i + j;
+ }
+ }
+ dispatchLambdaKernel(NUM, (gid) -> {
+ System.arraycopy(outArray[gid], 0, outArray[gid], gid % NUM, NUM);
+ });
+ }
+
+ @Test
+ public void testUsingLambdaMethod() {
+ testGeneratedHsailUsingLambdaMethod();
+ }
+}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/LongArrayCopyDisjointTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/LongArrayCopyDisjointTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2014, 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.compiler.hsail.test.lambda;
+
+import com.oracle.graal.compiler.hsail.test.infra.*;
+
+import org.junit.*;
+
+/**
+ * Tests copying a long array where src and dest do not overlap.
+ */
+public class LongArrayCopyDisjointTest extends GraalKernelTester {
+
+ final static int MAXOUTSIZ = 100;
+ final static int NUM = 20;
+
+ @Result long[][] outArray = new long[NUM][MAXOUTSIZ];
+ long[] inArray = new long[NUM + MAXOUTSIZ];
+
+ @Override
+ public void runTest() {
+ for (int i = 0; i < inArray.length; i++) {
+ inArray[i] = i;
+ }
+ dispatchLambdaKernel(NUM, (gid) -> {
+ System.arraycopy(inArray, gid, outArray[gid], 0, MAXOUTSIZ);
+ });
+ }
+
+ @Test
+ public void testUsingLambdaMethod() {
+ testGeneratedHsailUsingLambdaMethod();
+ }
+}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/NewStringEqualsTest.java
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/NewStringEqualsTest.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/NewStringEqualsTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -52,6 +52,12 @@
setupArrays();
String base = "ABCDEFGHIJ";
+ // Resolving StringIndexOutOfBoundsException causes compilation of the
+ // lambda to fail as. Combined with use of InlineEverything and RemoveNeverExecutedCode
+ // the inlining budget is blown before String.equals can be inlined leaving
+ // a DirectCallTargetNode in the graph which cannot be lowered by HSAIL.
+ new StringIndexOutOfBoundsException().fillInStackTrace();
+
dispatchLambdaKernel(NUM, (gid) -> {
outArray[gid] = new String(chars, 0, 10 + (gid % 3)).equals(base);
});
@@ -63,8 +69,7 @@
return (canHandleObjectAllocation());
}
- // NYI emitForeignCall charAlignedDisjointArraycopy
- @Ignore
+ @Ignore("see comment in runTest")
@Test
public void test() {
try (DebugConfigScope s = disableIntercept()) {
@@ -72,7 +77,7 @@
}
}
- @Ignore
+ @Ignore("see comment in runTest")
@Test
public void testUsingLambdaMethod() {
try (DebugConfigScope s = disableIntercept()) {
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ObjArrayCopyConjointTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ObjArrayCopyConjointTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2014, 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.compiler.hsail.test.lambda;
+
+import com.oracle.graal.compiler.hsail.test.infra.*;
+
+import org.junit.*;
+
+/**
+ * Tests {@link System#arraycopy} for object arrays where dest and src type are same, and overlap.
+ */
+public class ObjArrayCopyConjointTest extends GraalKernelTester {
+
+ final static int MAXOUTSIZ = 100;
+ final static int NUM = 20;
+
+ @Result String[][] outArray = new String[NUM][MAXOUTSIZ];
+
+ @Override
+ public void runTest() {
+ for (int i = 0; i < NUM; i++) {
+ for (int j = 0; j < outArray[i].length; j++) {
+ outArray[i][j] = Integer.toString(i * 100 + j);
+ }
+ }
+ dispatchLambdaKernel(NUM, (gid) -> {
+ System.arraycopy(outArray[gid], 0, outArray[gid], gid % NUM, NUM);
+ });
+ }
+
+ @Test
+ public void testUsingLambdaMethod() {
+ testGeneratedHsailUsingLambdaMethod();
+ }
+}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ObjArrayCopyDisjointNonExactTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ObjArrayCopyDisjointNonExactTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2014, 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.compiler.hsail.test.lambda;
+
+import com.oracle.graal.compiler.hsail.test.infra.*;
+
+import org.junit.*;
+
+/**
+ * Tests {@link System#arraycopy} for object arrays where dest is a superclass of src.
+ */
+public class ObjArrayCopyDisjointNonExactTest extends GraalKernelTester {
+
+ final static int MAXOUTSIZ = 100;
+ final static int NUM = 20;
+
+ @Result Object[][] outArray = new Object[NUM][MAXOUTSIZ];
+ String[] inArray = new String[NUM + MAXOUTSIZ];
+
+ @Override
+ public void runTest() {
+ for (int i = 0; i < inArray.length; i++) {
+ inArray[i] = Integer.toString(i * 1111);
+ }
+ dispatchLambdaKernel(NUM, (gid) -> {
+ System.arraycopy(inArray, gid, outArray[gid], 0, MAXOUTSIZ);
+ });
+ }
+
+ // this fails because we do not have a pure java snippet for this case
+ // see ArrayCopySnippets.arrayCopy(Object, int, Object, int, int)
+ @Test(expected = com.oracle.graal.compiler.common.GraalInternalError.class)
+ public void testUsingLambdaMethod() {
+ testGeneratedHsailUsingLambdaMethod();
+ }
+}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ObjArrayCopyDisjointTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ObjArrayCopyDisjointTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2014, 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.compiler.hsail.test.lambda;
+
+import com.oracle.graal.compiler.hsail.test.infra.*;
+
+import org.junit.*;
+
+/**
+ * Tests {@link System#arraycopy} for object arrays where dest and src type are same, no overlap.
+ */
+public class ObjArrayCopyDisjointTest extends GraalKernelTester {
+
+ final static int MAXOUTSIZ = 100;
+ final static int NUM = 20;
+
+ @Result String[][] outArray = new String[NUM][MAXOUTSIZ];
+ String[] inArray = new String[NUM + MAXOUTSIZ];
+
+ @Override
+ public void runTest() {
+ for (int i = 0; i < inArray.length; i++) {
+ inArray[i] = Integer.toString(i * 1111);
+ }
+ dispatchLambdaKernel(NUM, (gid) -> {
+ System.arraycopy(inArray, gid, outArray[gid], 0, MAXOUTSIZ);
+ });
+ }
+
+ @Test
+ public void testUsingLambdaMethod() {
+ testGeneratedHsailUsingLambdaMethod();
+ }
+}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ReduceMaxTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ReduceMaxTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2014, 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.compiler.hsail.test.lambda;
+
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.runtime;
+import com.oracle.graal.hotspot.HotSpotVMConfig;
+import static org.junit.Assert.*;
+import org.junit.*;
+
+import java.util.*;
+import java.util.stream.IntStream;
+
+public class ReduceMaxTest {
+ // The length of the input array
+ static int jobSize = 1027 * 1023 * 13;
+ static int loops = 1;
+
+ // The source array
+ int bigArray[] = null;
+
+ // result for baseline single threaded stream
+ int resultStream = 0;
+ // result for parallel CPU and offloaded streams
+ int resultOffload = 0;
+
+ int evaluate(boolean doParallelStream) {
+ int result = 0;
+ for (int i = 0; i < loops; i++) {
+ IntStream s = Arrays.stream(bigArray);
+ if (doParallelStream == true) {
+ OptionalInt resultParallel = s.parallel().reduce(Integer::max);
+ result = resultParallel.getAsInt();
+ } else {
+ result = s.reduce(Integer::max).getAsInt();
+ }
+ }
+ return result;
+ }
+
+ int evaluateWithIdentity(boolean doParallelStream) {
+ int result = 0;
+ for (int i = 0; i < loops; i++) {
+ IntStream s = Arrays.stream(bigArray);
+ if (doParallelStream == true) {
+ result = s.parallel().reduce(0, Integer::max);
+ } else {
+ result = s.reduce(0, Integer::max);
+ }
+ }
+ return result;
+ }
+
+ @Test
+ public void testReduce() {
+ // Handmade reduce does not support +UseCompressedOops
+ HotSpotVMConfig config = runtime().getConfig();
+ if (config.useCompressedOops == true || config.useHSAILDeoptimization == true) {
+ return;
+ }
+
+ bigArray = new int[jobSize];
+ for (int i = 0; i < jobSize; i++) {
+ // bigArray[i] = i + 1;
+ bigArray[i] = -1024 + i + 1;
+ }
+
+ // Get non parallel baseline
+ resultStream = evaluate(false);
+
+ // Get OptionalInt version kernel
+ resultOffload = evaluate(true);
+ assertTrue(resultStream == resultOffload);
+
+ // Do identity version kernel
+ // Get non parallel baseline
+ resultStream = evaluateWithIdentity(false);
+
+ resultOffload = evaluateWithIdentity(true);
+ assertTrue(resultStream == resultOffload);
+ }
+}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ReduceMinTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ReduceMinTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2014, 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.compiler.hsail.test.lambda;
+
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.runtime;
+import com.oracle.graal.hotspot.HotSpotVMConfig;
+import static org.junit.Assert.*;
+import org.junit.*;
+
+import java.util.*;
+import java.util.stream.IntStream;
+
+public class ReduceMinTest {
+ // The length of the input array
+ static int jobSize = 1027 * 1023 * 13;
+ static int loops = 1;
+
+ // The input array to the kernel
+ int bigArray[] = null;
+
+ // result for baseline single threaded stream
+ int resultStream = 0;
+ // result for parallel CPU and offloaded streams
+ int resultOffload = 0;
+
+ int evaluate(boolean doParallelStream) {
+ int result = 0;
+ for (int i = 0; i < loops; i++) {
+ IntStream s = Arrays.stream(bigArray);
+ if (doParallelStream == true) {
+ OptionalInt resultParallel = s.parallel().reduce(Integer::min);
+ result = resultParallel.getAsInt();
+ } else {
+ result = s.reduce(Integer::min).getAsInt();
+ }
+ }
+ return result;
+ }
+
+ int evaluateWithIdentity(boolean doParallelStream) {
+ int result = 0;
+ for (int i = 0; i < loops; i++) {
+ IntStream s = Arrays.stream(bigArray);
+ if (doParallelStream == true) {
+ result = s.parallel().reduce(0, Integer::min);
+ } else {
+ result = s.reduce(0, Integer::min);
+ }
+ }
+ return result;
+ }
+
+ @Test
+ public void testReduce() {
+ // Handmade reduce does not support +UseCompressedOops
+ HotSpotVMConfig config = runtime().getConfig();
+ if (config.useCompressedOops == true || config.useHSAILDeoptimization == true) {
+ return;
+ }
+
+ bigArray = new int[jobSize];
+ for (int i = 0; i < jobSize; i++) {
+ bigArray[i] = -1024 + i + 1;
+ }
+
+ // Get non parallel baseline
+ resultStream = evaluate(false);
+
+ // Get OptionalInt version kernel
+ resultOffload = evaluate(true);
+ assertTrue(resultStream == resultOffload);
+
+ // Do identity version kernel
+ // Get non parallel baseline
+ resultStream = evaluateWithIdentity(false);
+
+ resultOffload = evaluateWithIdentity(true);
+ assertTrue(resultStream == resultOffload);
+ }
+}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ReduceSumTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ReduceSumTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2014, 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.compiler.hsail.test.lambda;
+
+//import com.oracle.graal.compiler.common.GraalInternalError;
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.runtime;
+import com.oracle.graal.hotspot.HotSpotVMConfig;
+import org.junit.*;
+
+import java.util.*;
+import java.util.stream.IntStream;
+
+public class ReduceSumTest {
+ // The length of the input array
+ static int jobSize = 1027 * 1023 * 13;
+ static int loops = 1;
+
+ // The array to be summed
+ int bigArray[] = null;
+
+ // sum for baseline single threaded stream
+ int sumStream = 0;
+ // sum for parallel CPU and offloaded streams
+ int sumOffload = 0;
+
+ int evaluate(boolean doParallelStream) {
+ int sum = 0;
+ for (int i = 0; i < loops; i++) {
+ IntStream s = Arrays.stream(bigArray);
+ if (doParallelStream == true) {
+ OptionalInt resultParallel = s.parallel().reduce(Integer::sum);
+ sum = resultParallel.getAsInt();
+ } else {
+ OptionalInt resultStream = s.reduce(Integer::sum);
+ sum = resultStream.getAsInt();
+ }
+ }
+ return sum;
+ }
+
+ int evaluateWithIdentity(boolean doParallelStream) {
+ int sum = 0;
+ for (int i = 0; i < loops; i++) {
+ IntStream s = Arrays.stream(bigArray);
+ if (doParallelStream == true) {
+ sum = s.parallel().reduce(0, Integer::sum);
+ } else {
+ sum = s.reduce(0, Integer::sum);
+ }
+ }
+ return sum;
+ }
+
+ @Test
+ public void testReduce() {
+ // Handmade reduce does not support +UseCompressedOops
+ HotSpotVMConfig config = runtime().getConfig();
+ if (config.useCompressedOops == true || config.useHSAILDeoptimization == true) {
+ return;
+ }
+
+ bigArray = new int[jobSize];
+ for (int i = 0; i < jobSize; i++) {
+ bigArray[i] = -1024 + i + 1;
+ }
+
+ // Get non parallel baseline
+ sumStream = evaluate(false);
+
+ // Get OptionalInt version kernel
+ sumOffload = evaluate(true);
+ assert sumStream == sumOffload : "Offload sum is wrong, stream:" + sumStream + " != offload:" + sumOffload;
+
+ // Get identity version kernel
+ sumOffload = evaluateWithIdentity(true);
+ assert sumStream == sumOffload : "Offload sum is wrong, stream:" + sumStream + " != offload:" + sumOffload;
+ }
+}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/StringBuilderTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/StringBuilderTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2014, 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.compiler.hsail.test.lambda;
+
+import com.oracle.graal.compiler.hsail.test.infra.*;
+
+import org.junit.*;
+
+/**
+ * Tests creating a new String using StringBuilder (relies on {@link System#arraycopy}).
+ */
+public class StringBuilderTest extends GraalKernelTester {
+
+ final static int NUM = 20;
+ StringBuilder[] builders = new StringBuilder[NUM];
+ @Result String[] resultString = new String[NUM];
+
+ @Override
+ public void runTest() {
+ for (int i = 0; i < NUM; i++) {
+ builders[i] = new StringBuilder().append(i).append("abc");
+ }
+ dispatchLambdaKernel(NUM, (gid) -> {
+ resultString[gid] = builders[gid].append(gid * 1234).toString();
+ });
+ }
+
+ @Override
+ protected boolean supportsRequiredCapabilities() {
+ return (canHandleObjectAllocation());
+ }
+
+ @Test
+ public void testUsingLambdaMethod() {
+ testGeneratedHsailUsingLambdaMethod();
+ }
+}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/StringSubsequenceTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/StringSubsequenceTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2014, 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.compiler.hsail.test.lambda;
+
+import com.oracle.graal.compiler.hsail.test.infra.*;
+
+import org.junit.*;
+
+/**
+ * Tests creating a new {@link CharSequence} using {@link String#subSequence(int, int)}.
+ */
+public class StringSubsequenceTest extends GraalKernelTester {
+
+ final static int NUM = 50;
+ String inputString;
+ @Result CharSequence[] resultSequence = new String[NUM];
+
+ @Override
+ public void runTest() {
+ StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < NUM + 10; i++) {
+ builder.append(i);
+ }
+ inputString = builder.toString();
+ dispatchLambdaKernel(NUM, (gid) -> {
+ resultSequence[gid] = inputString.subSequence(gid, gid + 10);
+ });
+
+ // for (int i = 0; i < NUM; i++) {
+ // System.out.println(resultSequence[i]);
+ // }
+ }
+
+ @Ignore("emitDirectCall unimplemented")
+ @Test
+ public void testUsingLambdaMethod() {
+ testGeneratedHsailUsingLambdaMethod();
+ }
+}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/StringSubstringTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/StringSubstringTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2014, 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.compiler.hsail.test.lambda;
+
+import com.oracle.graal.compiler.hsail.test.infra.*;
+
+import org.junit.*;
+
+/**
+ * Tests creating a new String using {@link String#substring(int, int)}.
+ */
+public class StringSubstringTest extends GraalKernelTester {
+
+ final static int NUM = 50;
+ String inputString;
+ @Result String[] resultString = new String[NUM];
+
+ @Override
+ public void runTest() {
+ StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < NUM + 10; i++) {
+ builder.append(i);
+ }
+ inputString = builder.toString();
+ dispatchLambdaKernel(NUM, (gid) -> {
+ resultString[gid] = inputString.substring(gid, gid + 10);
+ });
+ }
+
+ @Ignore("emitDirectCall unimplemented")
+ @Test
+ public void testUsingLambdaMethod() {
+ testGeneratedHsailUsingLambdaMethod();
+ }
+}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/CompileAndDispatch.java
--- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/CompileAndDispatch.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/CompileAndDispatch.java Mon Jun 30 12:02:19 2014 +0200
@@ -32,4 +32,12 @@
Object createKernel(Class> consumerClass);
boolean dispatchKernel(Object kernel, int jobSize, Object[] args);
+
+ Object createKernelFromHsailString(String code, String methodName);
+
+ String getIntegerReduceIntrinsic(String reducerName);
+
+ Integer offloadIntReduceImpl(Object kernel, int identity, int[] streamSource);
+
+ String getIntReduceTargetName(Class> opClass);
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java
--- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java Mon Jun 30 12:02:19 2014 +0200
@@ -81,7 +81,7 @@
@Override
public Variable emitMove(Value input) {
- Variable result = newVariable(input.getPlatformKind());
+ Variable result = newVariable(input.getLIRKind());
emitMove(result, input);
return result;
}
@@ -149,7 +149,9 @@
}
}
}
- return new HSAILAddressValue(target().wordKind, baseRegister, finalDisp);
+
+ LIRKind resultKind = getAddressKind(base, displacement, index);
+ return new HSAILAddressValue(resultKind, baseRegister, finalDisp);
}
@Override
@@ -184,7 +186,7 @@
double trueDestinationProbability) {
// We don't have to worry about mirroring the condition on HSAIL.
Condition finalCondition = cond;
- Variable result = newVariable(left.getKind());
+ Variable result = newVariable(left.getLIRKind());
Kind kind = left.getKind().getStackKind();
switch (kind) {
case Int:
@@ -209,14 +211,14 @@
@Override
public void emitIntegerTestBranch(Value left, Value right, LabelRef trueDestination, LabelRef falseDestination, double trueDestinationProbability) {
Variable result = emitAnd(left, right);
- Variable dummyResult = newVariable(left.getKind());
+ Variable dummyResult = newVariable(left.getLIRKind());
append(new CompareBranchOp(mapKindToCompareOp(left.getKind()), Condition.EQ, result, Constant.forInt(0), dummyResult, dummyResult, trueDestination, falseDestination, false));
}
@Override
public Variable emitConditionalMove(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
Condition finalCondition = cond;
- Variable result = newVariable(trueValue.getKind());
+ Variable result = newVariable(trueValue.getLIRKind());
Kind kind = left.getKind().getStackKind();
switch (kind) {
case Int:
@@ -247,7 +249,7 @@
*/
@Override
public Variable emitNegate(Value input) {
- Variable result = newVariable(input.getKind());
+ Variable result = newVariable(input.getLIRKind());
switch (input.getKind()) {
case Int:
// Note: The Int case also handles the negation of shorts, bytes, and chars because
@@ -278,7 +280,7 @@
*/
@Override
public Variable emitNot(Value input) {
- Variable result = newVariable(input.getKind());
+ Variable result = newVariable(input.getLIRKind());
switch (input.getKind()) {
case Int:
// Note: The Int case also covers other primitive integral types smaller than an int
@@ -296,7 +298,7 @@
}
public Variable emitTestAddressAdd(Value a, Value b) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
switch (a.getKind()) {
case Int:
append(new Op2Reg(IADD, result, a, loadNonConst(b)));
@@ -321,7 +323,7 @@
@Override
public Variable emitAdd(Value a, Value b) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
switch (a.getKind()) {
case Int:
append(new Op2Reg(IADD, result, a, loadNonConst(b)));
@@ -346,7 +348,7 @@
@Override
public Variable emitSub(Value a, Value b) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
switch (a.getKind()) {
case Int:
append(new Op2Reg(ISUB, result, a, loadNonConst(b)));
@@ -368,7 +370,7 @@
@Override
public Variable emitMul(Value a, Value b) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
switch (a.getKind()) {
case Int:
append(new Op2Reg(IMUL, result, a, loadNonConst(b)));
@@ -389,7 +391,7 @@
}
public Variable emitUMul(Value a, Value b) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
switch (a.getKind()) {
case Int:
append(new Op2Reg(LUMUL, result, a, loadNonConst(b)));
@@ -415,7 +417,7 @@
@Override
public Value emitDiv(Value a, Value b, LIRFrameState state) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
switch (a.getKind()) {
case Int:
append(new Op2Reg(IDIV, result, a, loadNonConst(b)));
@@ -438,7 +440,7 @@
@Override
public Value emitRem(Value a, Value b, LIRFrameState state) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
switch (a.getKind()) {
case Int:
append(new Op2Reg(IREM, result, a, loadNonConst(b)));
@@ -470,7 +472,7 @@
@Override
public Variable emitAnd(Value a, Value b) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
switch (a.getKind()) {
case Int:
append(new Op2Reg(IAND, result, a, loadNonConst(b)));
@@ -486,7 +488,7 @@
@Override
public Variable emitOr(Value a, Value b) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
switch (a.getKind()) {
case Int:
append(new Op2Reg(IOR, result, a, loadNonConst(b)));
@@ -502,7 +504,7 @@
@Override
public Variable emitXor(Value a, Value b) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
switch (a.getKind()) {
case Int:
append(new Op2Reg(IXOR, result, a, loadNonConst(b)));
@@ -525,7 +527,7 @@
*/
@Override
public Variable emitShl(Value a, Value b) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
switch (a.getKind()) {
case Int:
// Note: The Int case also covers the shifting of bytes, shorts and chars because
@@ -550,7 +552,7 @@
*/
@Override
public Variable emitShr(Value a, Value b) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
switch (a.getKind()) {
case Int:
// Note: The Int case also covers the shifting of bytes, shorts and chars because
@@ -575,7 +577,7 @@
*/
@Override
public Variable emitUShr(Value a, Value b) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
switch (a.getKind()) {
case Int:
append(new ShiftOp(IUSHR, result, a, b));
@@ -623,24 +625,24 @@
case D2I:
case F2I:
to = "s32";
- result = newVariable(Kind.Int);
+ result = newVariable(LIRKind.value(Kind.Int));
break;
case D2L:
case F2L:
to = "s64";
- result = newVariable(Kind.Long);
+ result = newVariable(LIRKind.value(Kind.Long));
break;
case F2D:
case I2D:
case L2D:
to = "f64";
- result = newVariable(Kind.Double);
+ result = newVariable(LIRKind.value(Kind.Double));
break;
case D2F:
case I2F:
case L2F:
to = "f32";
- result = newVariable(Kind.Float);
+ result = newVariable(LIRKind.value(Kind.Float));
break;
default:
throw GraalInternalError.shouldNotReachHere();
@@ -653,7 +655,7 @@
@Override
public Value emitNarrow(Value inputVal, int bits) {
Variable input = load(inputVal);
- Variable result = newVariable(bits > 32 ? Kind.Long : Kind.Int);
+ Variable result = newVariable(LIRKind.value(bits > 32 ? Kind.Long : Kind.Int));
append(new ConvertOp(result, input, "s" + bits, input.getKind() == Kind.Long ? "s64" : "s32"));
return result;
}
@@ -661,7 +663,7 @@
@Override
public Value emitSignExtend(Value inputVal, int fromBits, int toBits) {
Variable input = load(inputVal);
- Variable result = newVariable(toBits > 32 ? Kind.Long : Kind.Int);
+ Variable result = newVariable(LIRKind.value(toBits > 32 ? Kind.Long : Kind.Int));
append(new ConvertOp(result, input, "s" + toBits, "s" + fromBits));
return result;
}
@@ -669,13 +671,13 @@
@Override
public Value emitZeroExtend(Value inputVal, int fromBits, int toBits) {
Variable input = load(inputVal);
- Variable result = newVariable(toBits > 32 ? Kind.Long : Kind.Int);
+ Variable result = newVariable(LIRKind.value(toBits > 32 ? Kind.Long : Kind.Int));
append(new ConvertOp(result, input, "u" + toBits, "u" + fromBits));
return result;
}
@Override
- public Value emitReinterpret(PlatformKind to, Value inputVal) {
+ public Value emitReinterpret(LIRKind to, Value inputVal) {
Variable result = newVariable(to);
emitMove(result, inputVal);
return result;
@@ -693,21 +695,23 @@
}
@Override
- public void emitBitCount(Variable result, Value value) {
+ public Value emitBitCount(Value value) {
+ Variable result = newVariable(LIRKind.value(Kind.Int));
if (value.getKind().getStackKind() == Kind.Int) {
append(new HSAILBitManipulationOp(IPOPCNT, result, value));
} else {
append(new HSAILBitManipulationOp(LPOPCNT, result, value));
}
+ return result;
}
@Override
- public void emitBitScanForward(Variable result, Value value) {
+ public Value emitBitScanForward(Value value) {
throw GraalInternalError.unimplemented();
}
@Override
- public void emitBitScanReverse(Variable result, Value value) {
+ public Value emitBitScanReverse(Value value) {
throw GraalInternalError.unimplemented();
}
@@ -719,7 +723,7 @@
*/
@Override
public Value emitMathAbs(Value input) {
- Variable result = newVariable(input.getPlatformKind());
+ Variable result = newVariable(input.getLIRKind());
append(new Op1Reg(ABS, result, input));
return result;
}
@@ -731,7 +735,7 @@
* @return Value representing the result of the operation
*/
public Value emitMathCeil(Value input) {
- Variable result = newVariable(input.getPlatformKind());
+ Variable result = newVariable(input.getLIRKind());
append(new Op1Reg(CEIL, result, input));
return result;
}
@@ -743,7 +747,7 @@
* @return Value representing the result of the operation
*/
public Value emitMathFloor(Value input) {
- Variable result = newVariable(input.getPlatformKind());
+ Variable result = newVariable(input.getLIRKind());
append(new Op1Reg(FLOOR, result, input));
return result;
}
@@ -755,7 +759,7 @@
* @return Value representing the result of the operation
*/
public Value emitMathRint(Value input) {
- Variable result = newVariable(input.getPlatformKind());
+ Variable result = newVariable(input.getLIRKind());
append(new Op1Reg(RINT, result, input));
return result;
}
@@ -768,7 +772,7 @@
*/
@Override
public Value emitMathSqrt(Value input) {
- Variable result = newVariable(input.getPlatformKind());
+ Variable result = newVariable(input.getLIRKind());
append(new Op1Reg(SQRT, result, input));
return result;
}
@@ -794,12 +798,12 @@
}
@Override
- public void emitByteSwap(Variable result, Value input) {
+ public Value emitByteSwap(Value input) {
throw GraalInternalError.unimplemented();
}
@Override
- public void emitArrayEquals(Kind kind, Variable result, Value array1, Value array2, Value length) {
+ public Value emitArrayEquals(Kind kind, Value array1, Value array2, Value length) {
// TODO Auto-generated method stub
throw GraalInternalError.unimplemented();
}
@@ -808,7 +812,7 @@
public void emitReturn(Value input) {
AllocatableValue operand = Value.ILLEGAL;
if (input != null) {
- operand = resultOperandFor(input.getKind());
+ operand = resultOperandFor(input.getLIRKind());
emitMove(operand, input);
}
append(new ReturnOp(operand));
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILNodeLIRBuilder.java
--- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILNodeLIRBuilder.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILNodeLIRBuilder.java Mon Jun 30 12:02:19 2014 +0200
@@ -47,12 +47,12 @@
@Override
protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) {
- throw GraalInternalError.unimplemented();
+ throw GraalInternalError.unimplemented(MetaUtil.format("direct call to %H.%n(%p)", callTarget.target()));
}
@Override
protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) {
- throw GraalInternalError.unimplemented();
+ throw GraalInternalError.unimplemented(MetaUtil.format("direct call to %H.%n(%p)", callTarget.target()));
}
@Override
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java
--- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Mon Jun 30 12:02:19 2014 +0200
@@ -24,7 +24,6 @@
package com.oracle.graal.compiler.ptx;
import static com.oracle.graal.api.code.ValueUtil.*;
-import static com.oracle.graal.api.meta.Value.*;
import static com.oracle.graal.lir.ptx.PTXArithmetic.*;
import static com.oracle.graal.lir.ptx.PTXBitManipulationOp.IntrinsicOpcode.*;
import static com.oracle.graal.lir.ptx.PTXCompare.*;
@@ -112,24 +111,9 @@
}
}
- protected static AllocatableValue toParamKind(AllocatableValue value) {
- if (value.getKind().getStackKind() != value.getKind()) {
- // We only have stack-kinds in the LIR, so convert the operand kind for values from the
- // calling convention.
- if (isRegister(value)) {
- return asRegister(value).asValue(value.getKind().getStackKind());
- } else if (isStackSlot(value)) {
- return StackSlot.get(value.getKind().getStackKind(), asStackSlot(value).getRawOffset(), asStackSlot(value).getRawAddFrameSize());
- } else {
- throw GraalInternalError.shouldNotReachHere();
- }
- }
- return value;
- }
-
public Variable emitWarpParam(Kind kind, Warp annotation) {
- Variable result = newVariable(kind);
- Variable tid = newVariable(Kind.Char);
+ Variable result = newVariable(target().getLIRKind(kind));
+ Variable tid = newVariable(LIRKind.value(Kind.Char));
switch (annotation.dimension()) {
case X:
@@ -149,7 +133,7 @@
@Override
public Variable emitMove(Value input) {
- Variable result = newVariable(input.getKind());
+ Variable result = newVariable(input.getLIRKind());
emitMove(result, input);
return result;
}
@@ -208,14 +192,15 @@
if (baseRegister.equals(Value.ILLEGAL)) {
baseRegister = asAllocatable(indexRegister);
} else {
- Variable longBaseRegister = newVariable(Kind.Long);
+ Variable longBaseRegister = newVariable(LIRKind.value(Kind.Long));
emitMove(longBaseRegister, baseRegister);
baseRegister = emitAdd(longBaseRegister, indexRegister);
}
}
}
- return new PTXAddressValue(target().wordKind, baseRegister, finalDisp);
+ LIRKind resultKind = getAddressKind(base, displacement, index);
+ return new PTXAddressValue(resultKind, baseRegister, finalDisp);
}
private PTXAddressValue asAddress(Value address) {
@@ -229,18 +214,18 @@
}
@Override
- public Variable emitLoad(PlatformKind kind, Value address, LIRFrameState state) {
+ public Variable emitLoad(LIRKind kind, Value address, LIRFrameState state) {
PTXAddressValue loadAddress = asAddress(address);
Variable result = newVariable(kind);
- append(new LoadOp((Kind) kind, result, loadAddress, state));
+ append(new LoadOp((Kind) kind.getPlatformKind(), result, loadAddress, state));
return result;
}
@Override
- public void emitStore(PlatformKind kind, Value address, Value inputVal, LIRFrameState state) {
+ public void emitStore(LIRKind kind, Value address, Value inputVal, LIRFrameState state) {
PTXAddressValue storeAddress = asAddress(address);
Variable input = load(inputVal);
- append(new StoreOp((Kind) kind, storeAddress, input, state));
+ append(new StoreOp((Kind) kind.getPlatformKind(), storeAddress, input, state));
}
@Override
@@ -301,7 +286,7 @@
emitCompare(finalCondition, left, right);
- Variable result = newVariable(trueValue.getKind());
+ Variable result = newVariable(trueValue.getLIRKind());
switch (left.getKind().getStackKind()) {
case Int:
case Long:
@@ -366,7 +351,7 @@
@Override
public Variable emitIntegerTestMove(Value left, Value right, Value trueValue, Value falseValue) {
emitIntegerTest(left, right);
- Variable result = newVariable(trueValue.getKind());
+ Variable result = newVariable(trueValue.getLIRKind());
append(new CondMoveOp(result, Condition.EQ, load(trueValue), loadNonConst(falseValue), nextPredRegNum));
nextPredRegNum++;
@@ -385,7 +370,7 @@
@Override
public Variable emitNegate(Value input) {
- Variable result = newVariable(input.getKind());
+ Variable result = newVariable(input.getLIRKind());
switch (input.getKind()) {
case Int:
append(new Op1Stack(INEG, result, input));
@@ -404,7 +389,7 @@
@Override
public Variable emitNot(Value input) {
- Variable result = newVariable(input.getKind());
+ Variable result = newVariable(input.getLIRKind());
switch (input.getKind()) {
case Int:
append(new Op1Stack(INOT, result, input));
@@ -420,7 +405,7 @@
@Override
public Variable emitAdd(Value a, Value b) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
switch (a.getKind()) {
case Int:
append(new Op2Stack(IADD, result, a, loadNonConst(b)));
@@ -442,7 +427,7 @@
@Override
public Variable emitSub(Value a, Value b) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
switch (a.getKind()) {
case Int:
append(new Op2Stack(ISUB, result, a, loadNonConst(b)));
@@ -464,7 +449,7 @@
@Override
public Variable emitMul(Value a, Value b) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
switch (a.getKind()) {
case Int:
append(new Op2Reg(IMUL, result, a, loadNonConst(b)));
@@ -496,7 +481,7 @@
@Override
public Value emitDiv(Value a, Value b, LIRFrameState state) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
switch (a.getKind()) {
case Int:
append(new Op2Reg(IDIV, result, a, loadNonConst(b)));
@@ -518,7 +503,7 @@
@Override
public Value emitRem(Value a, Value b, LIRFrameState state) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
switch (a.getKind()) {
case Int:
append(new Op2Reg(IREM, result, a, loadNonConst(b)));
@@ -544,7 +529,7 @@
@Override
public Variable emitAnd(Value a, Value b) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
switch (a.getKind()) {
case Int:
append(new Op2Stack(IAND, result, a, loadNonConst(b)));
@@ -560,7 +545,7 @@
@Override
public Variable emitOr(Value a, Value b) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
switch (a.getKind()) {
case Int:
append(new Op2Stack(IOR, result, a, loadNonConst(b)));
@@ -576,7 +561,7 @@
@Override
public Variable emitXor(Value a, Value b) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
switch (a.getKind()) {
case Int:
append(new Op2Stack(IXOR, result, a, loadNonConst(b)));
@@ -592,7 +577,7 @@
@Override
public Variable emitShl(Value a, Value b) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
switch (a.getKind()) {
case Int:
append(new Op2Stack(ISHL, result, a, loadNonConst(b)));
@@ -608,7 +593,7 @@
@Override
public Variable emitShr(Value a, Value b) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
switch (a.getKind()) {
case Int:
append(new Op2Stack(ISHR, result, a, loadNonConst(b)));
@@ -624,7 +609,7 @@
@Override
public Variable emitUShr(Value a, Value b) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
switch (a.getKind()) {
case Int:
append(new ShiftOp(IUSHR, result, a, b));
@@ -640,7 +625,7 @@
public Variable emitConvertOp(Kind from, Kind to, Value inputVal) {
Variable input = load(inputVal);
- Variable result = newVariable(to);
+ Variable result = newVariable(LIRKind.value(to));
append(new ConvertOp(result, input, to, from));
return result;
}
@@ -723,17 +708,17 @@
return inputVal;
} else if (fromBits > 32) {
assert inputVal.getKind() == Kind.Long;
- Variable result = newVariable(Kind.Long);
+ Variable result = newVariable(LIRKind.value(Kind.Long));
long mask = IntegerStamp.defaultMask(fromBits);
append(new Op2Stack(LAND, result, inputVal, Constant.forLong(mask)));
return result;
} else {
assert inputVal.getKind() == Kind.Int;
- Variable result = newVariable(Kind.Int);
+ Variable result = newVariable(LIRKind.value(Kind.Int));
int mask = (int) IntegerStamp.defaultMask(fromBits);
append(new Op2Stack(IAND, result, inputVal, Constant.forInt(mask)));
if (toBits > 32) {
- Variable longResult = newVariable(Kind.Long);
+ Variable longResult = newVariable(LIRKind.value(Kind.Long));
emitMove(longResult, result);
return longResult;
} else {
@@ -743,7 +728,7 @@
}
@Override
- public Value emitReinterpret(PlatformKind to, Value inputVal) {
+ public Value emitReinterpret(LIRKind to, Value inputVal) {
Variable result = newVariable(to);
emitMove(result, inputVal);
return result;
@@ -765,21 +750,23 @@
}
@Override
- public void emitBitCount(Variable result, Value value) {
+ public Value emitBitCount(Value value) {
+ Variable result = newVariable(LIRKind.value(Kind.Int));
if (value.getKind().getStackKind() == Kind.Int) {
append(new PTXBitManipulationOp(IPOPCNT, result, value));
} else {
append(new PTXBitManipulationOp(LPOPCNT, result, value));
}
+ return result;
}
@Override
- public void emitBitScanForward(Variable result, Value value) {
+ public Value emitBitScanForward(Value value) {
throw GraalInternalError.unimplemented("PTXLIRGenerator.emitBitScanForward()");
}
@Override
- public void emitBitScanReverse(Variable result, Value value) {
+ public Value emitBitScanReverse(Value value) {
throw GraalInternalError.unimplemented("PTXLIRGenerator.emitBitScanReverse()");
}
@@ -814,12 +801,12 @@
}
@Override
- public void emitByteSwap(Variable result, Value input) {
+ public Value emitByteSwap(Value input) {
throw GraalInternalError.unimplemented("PTXLIRGenerator.emitByteSwap()");
}
@Override
- public void emitArrayEquals(Kind kind, Variable result, Value array1, Value array2, Value length) {
+ public Value emitArrayEquals(Kind kind, Value array1, Value array2, Value length) {
// TODO Auto-generated method stub
throw GraalInternalError.unimplemented();
}
@@ -827,7 +814,7 @@
@Override
public void emitReturn(Value input) {
if (input != null) {
- AllocatableValue operand = resultOperandFor(input.getKind());
+ AllocatableValue operand = resultOperandFor(input.getLIRKind());
// Load the global memory address from return parameter
Variable loadVar = emitLoadReturnAddress(operand.getKind(), operand, null);
// Store input in global memory whose location is loadVar
@@ -843,7 +830,7 @@
@Override
public void emitStrategySwitch(SwitchStrategy strategy, Variable key, LabelRef[] keyTargets, LabelRef defaultTarget) {
boolean needsTemp = key.getKind() == Kind.Object;
- append(new StrategySwitchOp(strategy, keyTargets, defaultTarget, key, needsTemp ? newVariable(key.getKind()) : Value.ILLEGAL, nextPredRegNum++));
+ append(new StrategySwitchOp(strategy, keyTargets, defaultTarget, key, needsTemp ? newVariable(key.getLIRKind()) : Value.ILLEGAL, nextPredRegNum++));
}
@Override
@@ -851,7 +838,7 @@
// Making a copy of the switch value is necessary because jump table destroys the input
// value
Variable tmp = emitMove(key);
- append(new TableSwitchOp(lowKey, defaultTarget, targets, tmp, newVariable(target().wordKind), nextPredRegNum++));
+ append(new TableSwitchOp(lowKey, defaultTarget, targets, tmp, newVariable(LIRKind.value(target().wordKind)), nextPredRegNum++));
}
@Override
@@ -862,7 +849,7 @@
public Variable emitLoadParam(Kind kind, Value address, LIRFrameState state) {
PTXAddressValue loadAddress = asAddress(address);
- Variable result = newVariable(kind);
+ Variable result = newVariable(target().getLIRKind(kind));
append(new LoadParamOp(kind, result, loadAddress, state));
return result;
@@ -873,13 +860,13 @@
Variable result;
switch (kind) {
case Float:
- result = newVariable(Kind.Int);
+ result = newVariable(LIRKind.value(Kind.Int));
break;
case Double:
- result = newVariable(Kind.Long);
+ result = newVariable(LIRKind.value(Kind.Long));
break;
default:
- result = newVariable(kind);
+ result = newVariable(target().getLIRKind(kind));
}
append(new LoadReturnAddrOp(kind, result, loadAddress, state));
@@ -893,10 +880,7 @@
}
@Override
- public AllocatableValue resultOperandFor(Kind kind) {
- if (kind == Kind.Void) {
- return ILLEGAL;
- }
+ public AllocatableValue resultOperandFor(LIRKind kind) {
return (new Variable(kind, 0));
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Mon Jun 30 12:02:19 2014 +0200
@@ -90,7 +90,7 @@
@Override
public Variable emitMove(Value input) {
- Variable result = newVariable(input.getKind());
+ Variable result = newVariable(input.getLIRKind());
emitMove(result, input);
return result;
}
@@ -177,14 +177,15 @@
if (finalDisp == 0) {
// Nothing to do. Just use the base register.
} else {
- Variable longBaseRegister = newVariable(Kind.Long);
+ Variable longBaseRegister = newVariable(LIRKind.derivedReference(Kind.Long));
emitMove(longBaseRegister, baseRegister);
baseRegister = emitAdd(longBaseRegister, Constant.forLong(finalDisp));
}
}
}
- return new SPARCAddressValue(target().wordKind, baseRegister, indexRegister, displacementInt);
+ LIRKind resultKind = getAddressKind(base, displacement, index);
+ return new SPARCAddressValue(resultKind, baseRegister, indexRegister, displacementInt);
}
protected SPARCAddressValue asAddressValue(Value address) {
@@ -197,7 +198,7 @@
@Override
public Value emitAddress(StackSlot address) {
- Variable result = newVariable(target().wordKind);
+ Variable result = newVariable(LIRKind.value(target().wordKind));
append(new StackLoadAddressOp(result, address));
return result;
}
@@ -206,7 +207,7 @@
public void emitReturn(Value input) {
AllocatableValue operand = Value.ILLEGAL;
if (input != null) {
- operand = resultOperandFor(input.getKind());
+ operand = resultOperandFor(input.getLIRKind());
emitMove(operand, input);
}
append(new ReturnOp(operand));
@@ -268,7 +269,7 @@
boolean mirrored = emitCompare(left, right);
Condition finalCondition = mirrored ? cond.mirror() : cond;
- Variable result = newVariable(trueValue.getKind());
+ Variable result = newVariable(trueValue.getLIRKind());
Kind kind = left.getKind().getStackKind();
switch (kind) {
case Int:
@@ -332,7 +333,7 @@
@Override
public Variable emitIntegerTestMove(Value left, Value right, Value trueValue, Value falseValue) {
emitIntegerTest(left, right);
- Variable result = newVariable(trueValue.getKind());
+ Variable result = newVariable(trueValue.getLIRKind());
Kind kind = left.getKind().getStackKind();
append(new CondMoveOp(kind, result, Condition.EQ, load(trueValue), loadNonConst(falseValue)));
return result;
@@ -352,7 +353,7 @@
public void emitStrategySwitch(SwitchStrategy strategy, Variable key, LabelRef[] keyTargets, LabelRef defaultTarget) {
// a temp is needed for loading long and object constants
boolean needsTemp = key.getKind() == Kind.Long || key.getKind() == Kind.Object;
- append(new StrategySwitchOp(strategy, keyTargets, defaultTarget, key, needsTemp ? newVariable(key.getKind()) : Value.ILLEGAL));
+ append(new StrategySwitchOp(strategy, keyTargets, defaultTarget, key, needsTemp ? newVariable(key.getLIRKind()) : Value.ILLEGAL));
}
@Override
@@ -360,88 +361,96 @@
// Making a copy of the switch value is necessary because jump table destroys the input
// value
Variable tmp = emitMove(key);
- append(new TableSwitchOp(lowKey, defaultTarget, targets, tmp, newVariable(target().wordKind)));
+ append(new TableSwitchOp(lowKey, defaultTarget, targets, tmp, newVariable(LIRKind.value(target().wordKind))));
}
@Override
- public void emitBitCount(Variable result, Value operand) {
+ public Value emitBitCount(Value operand) {
+ Variable result = newVariable(LIRKind.value(Kind.Int));
if (operand.getKind().getStackKind() == Kind.Int) {
append(new SPARCBitManipulationOp(IPOPCNT, result, asAllocatable(operand), this));
} else {
append(new SPARCBitManipulationOp(LPOPCNT, result, asAllocatable(operand), this));
}
+ return result;
}
@Override
- public void emitBitScanForward(Variable result, Value operand) {
+ public Value emitBitScanForward(Value operand) {
+ Variable result = newVariable(LIRKind.value(Kind.Int));
append(new SPARCBitManipulationOp(BSF, result, asAllocatable(operand), this));
+ return result;
}
@Override
- public void emitBitScanReverse(Variable result, Value operand) {
+ public Value emitBitScanReverse(Value operand) {
+ Variable result = newVariable(LIRKind.value(Kind.Int));
if (operand.getKind().getStackKind() == Kind.Int) {
append(new SPARCBitManipulationOp(IBSR, result, asAllocatable(operand), this));
} else {
append(new SPARCBitManipulationOp(LBSR, result, asAllocatable(operand), this));
}
+ return result;
}
@Override
public Value emitMathAbs(Value input) {
- Variable result = newVariable(input.getPlatformKind());
+ Variable result = newVariable(input.getLIRKind());
append(new BinaryRegConst(DAND, result, asAllocatable(input), Constant.forDouble(Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL))));
return result;
}
@Override
public Value emitMathSqrt(Value input) {
- Variable result = newVariable(input.getPlatformKind());
+ Variable result = newVariable(input.getLIRKind());
append(new SPARCMathIntrinsicOp(SQRT, result, asAllocatable(input)));
return result;
}
@Override
public Value emitMathLog(Value input, boolean base10) {
- Variable result = newVariable(input.getPlatformKind());
+ Variable result = newVariable(input.getLIRKind());
append(new SPARCMathIntrinsicOp(LOG, result, asAllocatable(input)));
return result;
}
@Override
public Value emitMathCos(Value input) {
- Variable result = newVariable(input.getPlatformKind());
+ Variable result = newVariable(input.getLIRKind());
append(new SPARCMathIntrinsicOp(COS, result, asAllocatable(input)));
return result;
}
@Override
public Value emitMathSin(Value input) {
- Variable result = newVariable(input.getPlatformKind());
+ Variable result = newVariable(input.getLIRKind());
append(new SPARCMathIntrinsicOp(SIN, result, asAllocatable(input)));
return result;
}
@Override
public Value emitMathTan(Value input) {
- Variable result = newVariable(input.getPlatformKind());
+ Variable result = newVariable(input.getLIRKind());
append(new SPARCMathIntrinsicOp(TAN, result, asAllocatable(input)));
return result;
}
@Override
- public void emitByteSwap(Variable result, Value input) {
+ public Value emitByteSwap(Value input) {
+ Variable result = newVariable(input.getLIRKind());
append(new SPARCByteSwapOp(result, input));
+ return result;
}
@Override
- public void emitArrayEquals(Kind kind, Variable result, Value array1, Value array2, Value length) {
+ public Value emitArrayEquals(Kind kind, Value array1, Value array2, Value length) {
// TODO Auto-generated method stub
throw GraalInternalError.unimplemented();
}
@Override
public Value emitNegate(Value input) {
- Variable result = newVariable(input.getKind());
+ Variable result = newVariable(input.getLIRKind());
switch (input.getKind().getStackKind()) {
case Long:
append(new Op1Stack(LNEG, result, input));
@@ -463,7 +472,7 @@
@Override
public Value emitNot(Value input) {
- Variable result = newVariable(input.getKind());
+ Variable result = newVariable(input.getLIRKind());
switch (input.getKind().getStackKind()) {
case Int:
append(new Op1Stack(INOT, result, input));
@@ -502,7 +511,7 @@
case IMUL:
case LMUL:
if (NumUtil.isInt(b.asLong())) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
append(new BinaryRegConst(op, result, a, b));
return result;
}
@@ -513,7 +522,7 @@
}
private Variable emitBinaryVar(SPARCArithmetic op, boolean commutative, AllocatableValue a, AllocatableValue b) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
if (commutative) {
append(new BinaryCommutative(op, result, a, b));
} else {
@@ -540,7 +549,7 @@
@Override
public Variable emitSub(Value a, Value b) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
switch (a.getKind().getStackKind()) {
case Int:
append(new Op2Stack(ISUB, result, a, loadNonConst(b)));
@@ -562,7 +571,7 @@
@Override
public Variable emitMul(Value a, Value b) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
switch (a.getKind().getStackKind()) {
case Int:
append(new BinaryRegReg(IMUL, result, a, loadNonConst(b)));
@@ -594,13 +603,13 @@
@Override
public Value emitDiv(Value a, Value b, LIRFrameState state) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
switch (a.getKind().getStackKind()) {
case Int:
append(new BinaryRegReg(IDIV, result, a, loadNonConst(b)));
break;
case Long:
- append(new BinaryRegReg(LDIV, result, a, loadNonConst(b), state));
+ append(new BinaryRegReg(LDIV, result, a, loadNonConst(b)));
break;
case Float:
append(new Op2Stack(FDIV, result, a, loadNonConst(b)));
@@ -616,7 +625,7 @@
@Override
public Value emitRem(Value a, Value b, LIRFrameState state) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
Variable q = null;
switch (a.getKind().getStackKind()) {
case Int:
@@ -626,7 +635,7 @@
append(new RemOp(LREM, result, a, loadNonConst(b), state, this));
break;
case Float:
- q = newVariable(Kind.Float);
+ q = newVariable(LIRKind.value(Kind.Float));
append(new Op2Stack(FDIV, q, a, b));
append(new Unary2Op(F2I, q, q));
append(new Unary2Op(I2F, q, q));
@@ -634,7 +643,7 @@
append(new Op2Stack(FSUB, result, a, q));
break;
case Double:
- q = newVariable(Kind.Double);
+ q = newVariable(LIRKind.value(Kind.Double));
append(new Op2Stack(DDIV, q, a, b));
append(new Unary2Op(D2L, q, q));
append(new Unary2Op(L2D, q, q));
@@ -679,7 +688,7 @@
@Override
public Variable emitAnd(Value a, Value b) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
switch (a.getKind().getStackKind()) {
case Int:
append(new Op2Stack(IAND, result, a, loadNonConst(b)));
@@ -696,7 +705,7 @@
@Override
public Variable emitOr(Value a, Value b) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
switch (a.getKind().getStackKind()) {
case Int:
append(new Op2Stack(IOR, result, a, loadNonConst(b)));
@@ -712,7 +721,7 @@
@Override
public Variable emitXor(Value a, Value b) {
- Variable result = newVariable(a.getKind());
+ Variable result = newVariable(a.getLIRKind());
switch (a.getKind().getStackKind()) {
case Int:
append(new Op2Stack(IXOR, result, a, loadNonConst(b)));
@@ -727,7 +736,7 @@
}
private Variable emitShift(SPARCArithmetic op, Value a, Value b) {
- Variable result = newVariable(a.getPlatformKind());
+ Variable result = newVariable(a.getLIRKind());
AllocatableValue input = asAllocatable(a);
if (isConstant(b)) {
append(new BinaryRegConst(op, result, input, asConstant(b)));
@@ -773,13 +782,13 @@
}
}
- private AllocatableValue emitConvertMove(PlatformKind kind, AllocatableValue input) {
+ private AllocatableValue emitConvertMove(LIRKind kind, AllocatableValue input) {
Variable result = newVariable(kind);
emitMove(result, input);
return result;
}
- private AllocatableValue emitConvert2Op(PlatformKind kind, SPARCArithmetic op, AllocatableValue input) {
+ private AllocatableValue emitConvert2Op(LIRKind kind, SPARCArithmetic op, AllocatableValue input) {
Variable result = newVariable(kind);
append(new Unary2Op(op, result, input));
return result;
@@ -793,14 +802,14 @@
SPARCArithmetic conversionInstruction = null;
switch (op) {
case D2F:
- return emitConvert2Op(Kind.Float, D2F, input);
+ return emitConvert2Op(LIRKind.value(Kind.Float), D2F, input);
case D2I:
fromRegisterKind = Kind.Double;
toRegisterKind = Kind.Int;
conversionInstruction = D2I;
break;
case F2L:
- Variable v = newVariable(Kind.Double);
+ Variable v = newVariable(LIRKind.value(Kind.Double));
emitMove(v, input);
input = v;
case D2L:
@@ -809,26 +818,26 @@
conversionInstruction = D2L;
break;
case F2D:
- return emitConvert2Op(Kind.Double, F2D, input);
+ return emitConvert2Op(LIRKind.value(Kind.Double), F2D, input);
case F2I:
fromRegisterKind = Kind.Float;
toRegisterKind = Kind.Int;
conversionInstruction = F2I;
break;
case I2D:
- return emitConvert2Op(Kind.Double, L2D, emitConvert2Op(Kind.Long, I2L, input));
+ return emitConvert2Op(LIRKind.value(Kind.Double), I2D, input);
case I2F:
- return emitConvert2Op(Kind.Float, I2F, input);
+ return emitConvert2Op(LIRKind.value(Kind.Float), I2F, input);
case L2D:
- return emitConvert2Op(Kind.Double, L2D, input);
+ return emitConvert2Op(LIRKind.value(Kind.Double), L2D, input);
case L2F:
- return emitConvert2Op(Kind.Float, D2F, emitConvert2Op(Kind.Double, L2D, input));
+ return emitConvert2Op(LIRKind.value(Kind.Float), L2F, input);
default:
throw GraalInternalError.shouldNotReachHere();
}
if (fromRegisterKind != null) {
- AllocatableValue var = newVariable(toRegisterKind);
- emitMove(var, emitConvert2Op(fromRegisterKind, conversionInstruction, input));
+ AllocatableValue var = newVariable(LIRKind.value(toRegisterKind));
+ emitMove(var, emitConvert2Op(LIRKind.value(fromRegisterKind), conversionInstruction, input));
return var;
} else {
throw GraalInternalError.shouldNotReachHere();
@@ -838,7 +847,7 @@
@Override
public Value emitNarrow(Value inputVal, int bits) {
if (inputVal.getKind() == Kind.Long && bits <= 32) {
- return emitConvert2Op(Kind.Int, L2I, asAllocatable(inputVal));
+ return emitConvert2Op(LIRKind.value(Kind.Int), L2I, asAllocatable(inputVal));
} else {
return inputVal;
}
@@ -853,11 +862,11 @@
// sign extend to 64 bits
switch (fromBits) {
case 8:
- return emitConvert2Op(Kind.Long, B2L, asAllocatable(inputVal));
+ return emitConvert2Op(LIRKind.value(Kind.Long), B2L, asAllocatable(inputVal));
case 16:
- return emitConvert2Op(Kind.Long, S2L, asAllocatable(inputVal));
+ return emitConvert2Op(LIRKind.value(Kind.Long), S2L, asAllocatable(inputVal));
case 32:
- return emitConvert2Op(Kind.Long, I2L, asAllocatable(inputVal));
+ return emitConvert2Op(LIRKind.value(Kind.Long), I2L, asAllocatable(inputVal));
default:
throw GraalInternalError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)");
}
@@ -865,9 +874,9 @@
// sign extend to 32 bits (smaller values are internally represented as 32 bit values)
switch (fromBits) {
case 8:
- return emitConvert2Op(Kind.Int, B2I, asAllocatable(inputVal));
+ return emitConvert2Op(LIRKind.value(Kind.Int), B2I, asAllocatable(inputVal));
case 16:
- return emitConvert2Op(Kind.Int, S2I, asAllocatable(inputVal));
+ return emitConvert2Op(LIRKind.value(Kind.Int), S2I, asAllocatable(inputVal));
case 32:
return inputVal;
default:
@@ -882,25 +891,25 @@
if (fromBits == toBits) {
return inputVal;
} else if (fromBits > 32) {
- assert inputVal.getKind() == Kind.Long : inputVal.getKind();
- Variable result = newVariable(Kind.Long);
+ assert inputVal.getKind() == Kind.Long;
+ Variable result = newVariable(LIRKind.value(Kind.Long));
long mask = IntegerStamp.defaultMask(fromBits);
append(new BinaryRegConst(SPARCArithmetic.LAND, result, asAllocatable(inputVal), Constant.forLong(mask)));
return result;
} else {
assert inputVal.getKind() == Kind.Int || inputVal.getKind() == Kind.Short || inputVal.getKind() == Kind.Byte : inputVal.getKind();
- Variable result = newVariable(Kind.Int);
+ Variable result = newVariable(LIRKind.value(Kind.Int));
int mask = (int) IntegerStamp.defaultMask(fromBits);
Constant constant = Constant.forInt(mask);
if (canInlineConstant(constant)) {
append(new BinaryRegConst(SPARCArithmetic.IAND, result, asAllocatable(inputVal), constant));
} else {
- Variable maskVar = newVariable(Kind.Int);
+ Variable maskVar = newVariable(LIRKind.value(Kind.Int));
emitMove(maskVar, constant);
append(new BinaryRegReg(IAND, result, maskVar, (inputVal)));
}
if (toBits > 32) {
- Variable longResult = newVariable(Kind.Long);
+ Variable longResult = newVariable(LIRKind.value(Kind.Long));
emitMove(longResult, result);
return longResult;
} else {
@@ -910,12 +919,12 @@
}
@Override
- public AllocatableValue emitReinterpret(PlatformKind to, Value inputVal) {
+ public AllocatableValue emitReinterpret(LIRKind to, Value inputVal) {
Kind from = inputVal.getKind();
AllocatableValue input = asAllocatable(inputVal);
// These cases require a move between CPU and FPU registers:
- switch ((Kind) to) {
+ switch ((Kind) to.getPlatformKind()) {
case Int:
switch (from) {
case Float:
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/AllocSpy.java
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/AllocSpy.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/AllocSpy.java Mon Jun 30 12:02:19 2014 +0200
@@ -39,11 +39,11 @@
* trace is governed by the value of the "AllocSpy.ContextSize" system property (default is 5).
*
* Using this facility requires using -javaagent on the command line. For example:
- *
+ *
*
* mx --vm server unittest -javaagent:lib/java-allocation-instrumenter.jar -dsa -DAllocSpy.ContextSize=6 BC_iadd2
*
- *
+ *
* @see #SampleBytes
* @see #SampleInstances
* @see #HistogramLimit
@@ -237,8 +237,8 @@
} else {
if (!excludeFrame(className)) {
sb.append("type=").append(desc);
- if (count != 1) {
- sb.append("[]");
+ if (count != -1) {
+ sb.append('[').append(count).append(']');
}
append(sb.append('\n'), e);
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java Mon Jun 30 12:02:19 2014 +0200
@@ -27,6 +27,7 @@
import java.io.*;
import java.lang.reflect.*;
import java.util.*;
+import java.util.concurrent.*;
import java.util.zip.*;
import org.junit.*;
@@ -34,6 +35,8 @@
import com.oracle.graal.api.code.*;
import com.oracle.graal.api.meta.*;
import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.compiler.CompilerThreadFactory.DebugConfigAccess;
import com.oracle.graal.debug.*;
import com.oracle.graal.java.*;
import com.oracle.graal.nodes.*;
@@ -42,6 +45,7 @@
import com.oracle.graal.phases.tiers.*;
import com.oracle.graal.phases.util.*;
import com.oracle.graal.phases.verify.*;
+import com.oracle.graal.printer.*;
import com.oracle.graal.runtime.*;
import com.oracle.graal.test.*;
@@ -97,7 +101,15 @@
String property = System.getProperty(CheckGraalInvariants.class.getName() + ".filters");
String[] filters = property == null ? null : property.split(",");
- List errors = new ArrayList<>();
+ CompilerThreadFactory factory = new CompilerThreadFactory("CheckInvariantsThread", new DebugConfigAccess() {
+ public GraalDebugConfig getDebugConfig() {
+ return DebugEnvironment.initialize(System.out);
+ }
+ });
+ int availableProcessors = Runtime.getRuntime().availableProcessors();
+ ThreadPoolExecutor executor = new ThreadPoolExecutor(availableProcessors, availableProcessors, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), factory);
+
+ List errors = Collections.synchronizedList(new ArrayList<>());
for (String className : classNames) {
try {
Class> c = Class.forName(className, false, CheckGraalInvariants.class.getClassLoader());
@@ -107,22 +119,24 @@
} else {
String methodName = className + "." + m.getName();
if (matches(filters, methodName)) {
- StructuredGraph graph = new StructuredGraph(metaAccess.lookupJavaMethod(m));
- try (DebugConfigScope s = Debug.setConfig(new DelegatingDebugConfig().disable(INTERCEPT))) {
- graphBuilderSuite.apply(graph, context);
- checkGraph(context, graph);
- } catch (VerificationError e) {
- errors.add(e.getMessage());
- } catch (LinkageError e) {
- // suppress linkages errors resulting from eager resolution
- } catch (BailoutException e) {
- // Graal bail outs on certain patterns in Java bytecode (e.g.,
- // unbalanced monitors introduced by jacoco).
- } catch (Throwable e) {
- StringWriter sw = new StringWriter();
- e.printStackTrace(new PrintWriter(sw));
- errors.add(String.format("Error while checking %s:%n%s", methodName, sw));
- }
+ executor.execute(() -> {
+ StructuredGraph graph = new StructuredGraph(metaAccess.lookupJavaMethod(m));
+ try (DebugConfigScope s = Debug.setConfig(new DelegatingDebugConfig().disable(INTERCEPT))) {
+ graphBuilderSuite.apply(graph, context);
+ checkGraph(context, graph);
+ } catch (VerificationError e) {
+ errors.add(e.getMessage());
+ } catch (LinkageError e) {
+ // suppress linkages errors resulting from eager resolution
+ } catch (BailoutException e) {
+ // Graal bail outs on certain patterns in Java bytecode (e.g.,
+ // unbalanced monitors introduced by jacoco).
+ } catch (Throwable e) {
+ StringWriter sw = new StringWriter();
+ e.printStackTrace(new PrintWriter(sw));
+ errors.add(String.format("Error while checking %s:%n%s", methodName, sw));
+ }
+ });
}
}
}
@@ -131,6 +145,13 @@
e.printStackTrace();
}
}
+ executor.shutdown();
+ try {
+ executor.awaitTermination(1, TimeUnit.HOURS);
+ } catch (InterruptedException e1) {
+ throw new RuntimeException(e1);
+ }
+
if (!errors.isEmpty()) {
StringBuilder msg = new StringBuilder();
String nl = String.format("%n");
@@ -153,6 +174,7 @@
new VerifyUsageWithEquals(JavaType.class).apply(graph, context);
new VerifyUsageWithEquals(JavaMethod.class).apply(graph, context);
new VerifyUsageWithEquals(JavaField.class).apply(graph, context);
+ new VerifyUsageWithEquals(LIRKind.class).apply(graph, context);
new VerifyDebugUsage().apply(graph, context);
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -103,7 +103,7 @@
IntegerTestNode test = (IntegerTestNode) conditional.condition();
ParameterNode param0 = graph.getParameter(0);
ParameterNode param1 = graph.getParameter(1);
- assertTrue((test.x() == param0 && test.y() == param1) || (test.x() == param1 && test.y() == param0));
+ assertTrue((test.getX() == param0 && test.getY() == param1) || (test.getX() == param1 && test.getY() == param0));
}
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatOptimizationTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatOptimizationTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2014, 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.compiler.test;
+
+import org.junit.*;
+
+/**
+ * Check for incorrect elimination of 0.0 and -0.0 from computations. They can affect the sign of
+ * the result of an add or substract.
+ */
+public class FloatOptimizationTest extends GraalCompilerTest {
+
+ @Test
+ public void test1() {
+ test("test1Snippet", -0.0);
+ }
+
+ @SuppressWarnings("all")
+ public static double test1Snippet(double x) {
+ return x + 0.0;
+ }
+
+ @Test
+ public void test2() {
+ test("test2Snippet", -0.0f);
+ }
+
+ @SuppressWarnings("all")
+ public static double test2Snippet(float x) {
+ return x + 0.0f;
+ }
+
+ @Test
+ public void test3() {
+ test("test3Snippet", -0.0);
+ }
+
+ @SuppressWarnings("all")
+ public static double test3Snippet(double x) {
+ return x - -0.0;
+ }
+
+ @Test
+ public void test4() {
+ test("test4Snippet", -0.0f);
+ }
+
+ @SuppressWarnings("all")
+ public static double test4Snippet(float x) {
+ return x - -0.0f;
+ }
+
+ @Override
+ protected void assertDeepEquals(String message, Object expected, Object actual, double delta) {
+ if (expected instanceof Double && actual instanceof Double) {
+ double e = (double) expected;
+ double a = (double) actual;
+ if (Double.doubleToRawLongBits(a) != Double.doubleToRawLongBits(e)) {
+ Assert.fail((message == null ? "" : message) + "raw double bits not equal " + Double.doubleToRawLongBits(a) + " != " + Double.doubleToRawLongBits(e));
+ }
+ } else {
+ super.assertDeepEquals(message, expected, actual, delta);
+ }
+ }
+}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FlowSenReduTest.java
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FlowSenReduTest.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FlowSenReduTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -384,7 +384,7 @@
public StructuredGraph visualize(StructuredGraph graph, String title) {
DebugConfig debugConfig = DebugScope.getConfig();
- DebugConfig fixedConfig = Debug.fixedConfig(false, true, false, false, false, debugConfig.dumpHandlers(), debugConfig.output());
+ DebugConfig fixedConfig = Debug.fixedConfig(false, true, false, false, false, false, debugConfig.dumpHandlers(), debugConfig.verifyHandlers(), debugConfig.output());
try (DebugConfigScope s = Debug.setConfig(fixedConfig)) {
Debug.dump(graph, title);
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FlowSensitiveReductionTest.java
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FlowSensitiveReductionTest.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FlowSensitiveReductionTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -148,9 +148,7 @@
new FlowSensitiveReductionPhase(getMetaAccess()).apply(graph, context);
new CanonicalizerPhase(true).apply(graph, context);
for (ConstantNode constant : getConstantNodes(graph)) {
- if (ConstantNodeRecordsUsages || !constant.gatherUsages(graph).isEmpty()) {
- assertTrue("unexpected constant: " + constant, constant.asConstant().isNull() || constant.asConstant().asInt() > 0);
- }
+ assertTrue("unexpected constant: " + constant, constant.asConstant().isNull() || constant.asConstant().asInt() > 0);
}
}
@@ -186,9 +184,7 @@
new FlowSensitiveReductionPhase(getMetaAccess()).apply(graph, new PhaseContext(getProviders(), null));
new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null));
for (ConstantNode constant : getConstantNodes(graph)) {
- if (ConstantNodeRecordsUsages || !constant.gatherUsages(graph).isEmpty()) {
- assertTrue("unexpected constant: " + constant, constant.asConstant().isNull() || constant.asConstant().asInt() > 0);
- }
+ assertTrue("unexpected constant: " + constant, constant.asConstant().isNull() || constant.asConstant().asInt() > 0);
}
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -213,14 +213,8 @@
protected int countUnusedConstants(StructuredGraph graph) {
int total = 0;
for (ConstantNode node : getConstantNodes(graph)) {
- if (!ConstantNodeRecordsUsages) {
- if (node.gatherUsages(graph).isEmpty()) {
- total++;
- }
- } else {
- if (node.usages().isEmpty()) {
- total++;
- }
+ if (node.usages().isEmpty()) {
+ total++;
}
}
return total;
@@ -275,7 +269,7 @@
}
result.append("\n");
for (Node node : schedule.getBlockToNodesMap().get(block)) {
- if (node.recordsUsages()) {
+ if (node.isAlive() && node.recordsUsages()) {
if (!excludeVirtual || !(node instanceof VirtualObjectNode || node instanceof ProxyNode)) {
int id;
if (canonicalId.get(node) != null) {
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -651,7 +651,7 @@
MidTierContext midContext = new MidTierContext(getProviders(), assumptions, getCodeCache().getTarget(), OptimisticOptimizations.ALL, graph.method().getProfilingInfo(), null);
new GuardLoweringPhase().apply(graph, midContext);
new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, midContext);
- new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, midContext);
+ new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.LOW_TIER).apply(graph, midContext);
SchedulePhase schedule = new SchedulePhase(schedulingStrategy, memsched);
schedule.apply(graph);
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MonitorGraphTest.java
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MonitorGraphTest.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MonitorGraphTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -85,9 +85,11 @@
private StructuredGraph parseAndProcess(String snippet) {
StructuredGraph graph = parse(snippet);
ParameterNode param = graph.getNodes(ParameterNode.class).first();
- ConstantNode constant = ConstantNode.forInt(0, graph);
- for (Node n : param.usages().filter(isNotA(FrameState.class)).snapshot()) {
- n.replaceFirstInput(param, constant);
+ if (param != null) {
+ ConstantNode constant = ConstantNode.forInt(0, graph);
+ for (Node n : param.usages().filter(isNotA(FrameState.class)).snapshot()) {
+ n.replaceFirstInput(param, constant);
+ }
}
Map hints = new HashMap<>();
for (Invoke invoke : graph.getInvokes()) {
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -80,18 +80,20 @@
}
}
- private void collectStats(final LIRInstruction instr) {
- instr.forEachOutput(new ValueProcedure() {
+ private ValueProcedure collectStatsProc = new ValueProcedure() {
- @Override
- public Value doValue(Value value) {
- if (ValueUtil.isRegister(value)) {
- final Register reg = ValueUtil.asRegister(value);
- registers.add(reg);
- }
- return value;
+ @Override
+ public Value doValue(Value value) {
+ if (ValueUtil.isRegister(value)) {
+ final Register reg = ValueUtil.asRegister(value);
+ registers.add(reg);
}
- });
+ return value;
+ }
+ };
+
+ private void collectStats(final LIRInstruction instr) {
+ instr.forEachOutput(collectStatsProc);
if (instr instanceof MoveOp) {
MoveOp move = (MoveOp) instr;
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -25,10 +25,9 @@
import org.junit.*;
import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.common.type.*;
import com.oracle.graal.graph.*;
import com.oracle.graal.loop.phases.*;
-import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.extended.*;
import com.oracle.graal.nodes.virtual.*;
import com.oracle.graal.phases.common.*;
import com.oracle.graal.phases.schedule.*;
@@ -279,7 +278,7 @@
@SuppressWarnings("unused")
public static void testNewNodeSnippet() {
- new IntegerAddNode(new IntegerStamp(32, Integer.MIN_VALUE, Integer.MAX_VALUE, 0, 0xFFFFFFFF), null, null);
+ new ValueAnchorNode(null);
}
/**
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Mon Jun 30 12:02:19 2014 +0200
@@ -42,6 +42,8 @@
public static final OptionValue Dump = new OptionValue<>(null);
@Option(help = "Pattern for scope(s) to in which metering is enabled (see DebugFilter and Debug.metric)")
public static final OptionValue Meter = new OptionValue<>(null);
+ @Option(help = "Pattern for scope(s) to in which verification is enabled (see DebugFilter and Debug.verify)")
+ public static final OptionValue Verify = new OptionValue<>(null);
@Option(help = "Pattern for scope(s) to in which memory use tracking is enabled (see DebugFilter and Debug.metric)")
public static final OptionValue TrackMemUse = new OptionValue<>(null);
@Option(help = "Pattern for scope(s) to in which timing is enabled (see DebugFilter and Debug.timer)")
@@ -89,18 +91,21 @@
private final DebugFilter trackMemUseFilter;
private final DebugFilter timerFilter;
private final DebugFilter dumpFilter;
+ private final DebugFilter verifyFilter;
private final MethodFilter[] methodFilter;
private final List dumpHandlers;
+ private final List verifyHandlers;
private final PrintStream output;
private final Set
+ * This method sets in motion the inlining machinery.
*
- *
- * The stack grows and shrinks as choices are made among the alternatives below:
- *
- *
- * not worth inlining: pop any remaining graphs not yet delved into, pop the current invocation.
- *
- *
- * process next invoke: delve into one of the callsites hosted in the current candidate graph,
- * determine whether any inlining should be performed in it
- *
- * try to inline: move past the current inlining candidate (remove it from the topmost element).
- * If that was the last one then try to inline the callsite that is (still) in the topmost
- * element of {@link com.oracle.graal.phases.common.inlining.walker.InliningData}, and then
- * remove such callsite.
- *
- *
- *
- *
- * Some facts about the alternatives above:
- *
- *
- * the first step amounts to backtracking, the 2nd one to delving, and the 3rd one also involves
- * backtracking (however after may-be inlining).
- *
- * the choice of abandon-and-backtrack or delve-into is depends on
- * {@link InliningPolicy#isWorthInlining} and {@link InliningPolicy#continueInlining}.
- *
- * the 3rd choice is picked when both of the previous ones aren't picked
- *
- * as part of trying-to-inline, {@link InliningPolicy#isWorthInlining} again sees use, but
- * that's another story.
- *
- *
+ * @see InliningData
+ * @see InliningData#moveForward()
*
*/
@Override
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java Mon Jun 30 12:02:19 2014 +0200
@@ -223,8 +223,10 @@
* @param inlineGraph the graph that the invoke will be replaced with
* @param receiverNullCheck true if a null check needs to be generated for non-static inlinings,
* false if no such check is required
+ * @param canonicalizedNodes if non-null then append to this list any nodes which should be
+ * canonicalized after inlining
*/
- public static Map inline(Invoke invoke, StructuredGraph inlineGraph, boolean receiverNullCheck) {
+ public static Map inline(Invoke invoke, StructuredGraph inlineGraph, boolean receiverNullCheck, List canonicalizedNodes) {
final NodeInputList parameters = invoke.callTarget().arguments();
FixedNode invokeNode = invoke.asNode();
StructuredGraph graph = invokeNode.graph();
@@ -289,7 +291,6 @@
stateAtExceptionEdge = obj.stateAfter();
UnwindNode unwindDuplicate = (UnwindNode) duplicates.get(unwindNode);
obj.replaceAtUsages(unwindDuplicate.exception());
- unwindDuplicate.clearInputs();
Node n = obj.next();
obj.setNext(null);
unwindDuplicate.replaceAndDelete(n);
@@ -332,7 +333,6 @@
ReturnNode returnNode = (ReturnNode) duplicates.get(returnNodes.get(0));
Node returnValue = returnNode.result();
invokeNode.replaceAtUsages(returnValue);
- returnNode.clearInputs();
returnNode.replaceAndDelete(n);
} else {
ArrayList returnDuplicates = new ArrayList<>(returnNodes.size());
@@ -341,7 +341,7 @@
}
MergeNode merge = graph.add(new MergeNode());
merge.setStateAfter(stateAfter);
- ValueNode returnValue = mergeReturns(merge, returnDuplicates);
+ ValueNode returnValue = mergeReturns(merge, returnDuplicates, canonicalizedNodes);
invokeNode.replaceAtUsages(returnValue);
merge.setNext(n);
}
@@ -440,7 +440,7 @@
}
}
- public static ValueNode mergeReturns(MergeNode merge, List extends ReturnNode> returnNodes) {
+ public static ValueNode mergeReturns(MergeNode merge, List extends ReturnNode> returnNodes, List canonicalizedNodes) {
PhiNode returnValuePhi = null;
for (ReturnNode returnNode : returnNodes) {
@@ -451,10 +451,12 @@
if (returnNode.result() != null) {
if (returnValuePhi == null) {
returnValuePhi = merge.graph().addWithoutUnique(new ValuePhiNode(returnNode.result().stamp().unrestricted(), merge));
+ if (canonicalizedNodes != null) {
+ canonicalizedNodes.add(returnValuePhi);
+ }
}
returnValuePhi.addInput(returnNode.result());
}
- returnNode.clearInputs();
returnNode.replaceAndDelete(endNode);
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/AbstractInlineInfo.java
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/AbstractInlineInfo.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/AbstractInlineInfo.java Mon Jun 30 12:02:19 2014 +0200
@@ -28,10 +28,12 @@
import com.oracle.graal.api.meta.ResolvedJavaMethod;
import com.oracle.graal.graph.*;
import com.oracle.graal.nodes.*;
+import com.oracle.graal.phases.common.CanonicalizerPhase;
import com.oracle.graal.phases.common.inlining.InliningUtil;
import com.oracle.graal.phases.common.inlining.info.elem.Inlineable;
import com.oracle.graal.phases.common.inlining.info.elem.InlineableMacroNode;
import com.oracle.graal.phases.common.inlining.info.elem.InlineableGraph;
+import com.oracle.graal.phases.tiers.HighTierContext;
public abstract class AbstractInlineInfo implements InlineInfo {
@@ -52,22 +54,22 @@
}
protected static Collection inline(Invoke invoke, ResolvedJavaMethod concrete, Inlineable inlineable, Assumptions assumptions, boolean receiverNullCheck) {
- Collection parameterUsages = new ArrayList<>();
+ List canonicalizeNodes = new ArrayList<>();
if (inlineable instanceof InlineableGraph) {
StructuredGraph calleeGraph = ((InlineableGraph) inlineable).getGraph();
- Map duplicateMap = InliningUtil.inline(invoke, calleeGraph, receiverNullCheck);
- getInlinedParameterUsages(parameterUsages, calleeGraph, duplicateMap);
+ Map duplicateMap = InliningUtil.inline(invoke, calleeGraph, receiverNullCheck, canonicalizeNodes);
+ getInlinedParameterUsages(canonicalizeNodes, calleeGraph, duplicateMap);
} else {
assert inlineable instanceof InlineableMacroNode;
Class extends FixedWithNextNode> macroNodeClass = ((InlineableMacroNode) inlineable).getMacroNodeClass();
FixedWithNextNode macroNode = InliningUtil.inlineMacroNode(invoke, concrete, macroNodeClass);
- parameterUsages.add(macroNode);
+ canonicalizeNodes.add(macroNode);
}
InliningUtil.InlinedBytecodes.add(concrete.getCodeSize());
assumptions.recordMethodContents(concrete);
- return parameterUsages;
+ return canonicalizeNodes;
}
public static void getInlinedParameterUsages(Collection parameterUsages, StructuredGraph calleeGraph, Map duplicateMap) {
@@ -80,4 +82,22 @@
}
}
}
+
+ public final void populateInlinableElements(HighTierContext context, Assumptions calleeAssumptions, CanonicalizerPhase canonicalizer) {
+ for (int i = 0; i < numberOfMethods(); i++) {
+ Inlineable elem = Inlineable.getInlineableElement(methodAt(i), invoke, context.replaceAssumptions(calleeAssumptions), canonicalizer);
+ setInlinableElement(i, elem);
+ }
+ }
+
+ public final int determineNodeCount() {
+ int nodes = 0;
+ for (int i = 0; i < numberOfMethods(); i++) {
+ Inlineable elem = inlineableElementAt(i);
+ if (elem != null) {
+ nodes += elem.getNodeCount();
+ }
+ }
+ return nodes;
+ }
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/InlineInfo.java
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/InlineInfo.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/InlineInfo.java Mon Jun 30 12:02:19 2014 +0200
@@ -30,7 +30,9 @@
import com.oracle.graal.graph.*;
import com.oracle.graal.nodes.Invoke;
import com.oracle.graal.nodes.StructuredGraph;
+import com.oracle.graal.phases.common.CanonicalizerPhase;
import com.oracle.graal.phases.common.inlining.info.elem.Inlineable;
+import com.oracle.graal.phases.tiers.HighTierContext;
import com.oracle.graal.phases.util.Providers;
/**
@@ -82,4 +84,8 @@
void tryToDevirtualizeInvoke(MetaAccessProvider metaAccess, Assumptions assumptions);
boolean shouldInline();
+
+ void populateInlinableElements(HighTierContext context, Assumptions calleeAssumptions, CanonicalizerPhase canonicalizer);
+
+ int determineNodeCount();
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java Mon Jun 30 12:02:19 2014 +0200
@@ -222,9 +222,7 @@
ArrayList replacementNodes = new ArrayList<>();
- Collection parameterUsages = new ArrayList<>();
-
- // do the actual inlining for every invoke
+ // prepare the anchors for the invokes
for (int i = 0; i < numberOfMethods; i++) {
BeginNode node = successors[i];
Invoke invokeForInlining = (Invoke) node.next();
@@ -241,8 +239,7 @@
GuardedValueNode anchoredReceiver = InliningUtil.createAnchoredReceiver(graph, node, commonType, receiver, exact);
invokeForInlining.callTarget().replaceFirstInput(receiver, anchoredReceiver);
- parameterUsages.addAll(inline(invokeForInlining, methodAt(i), inlineableElementAt(i), assumptions, false));
-
+ assert !anchoredReceiver.isDeleted() : anchoredReceiver;
replacementNodes.add(anchoredReceiver);
}
if (shouldFallbackToInvoke()) {
@@ -274,7 +271,17 @@
TailDuplicationPhase.tailDuplicate(returnMerge, TailDuplicationPhase.TRUE_DECISION, replacementNodes, phaseContext, canonicalizer);
}
}
- return parameterUsages;
+
+ Collection canonicalizeNodes = new ArrayList<>();
+ // do the actual inlining for every invoke
+ for (int i = 0; i < numberOfMethods; i++) {
+ Invoke invokeForInlining = (Invoke) successors[i].next();
+ canonicalizeNodes.addAll(inline(invokeForInlining, methodAt(i), inlineableElementAt(i), assumptions, false));
+ }
+ if (returnValuePhi != null) {
+ canonicalizeNodes.add(returnValuePhi);
+ }
+ return canonicalizeNodes;
}
private int getTypeCount(int concreteMethodIndex) {
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/Inlineable.java
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/Inlineable.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/Inlineable.java Mon Jun 30 12:02:19 2014 +0200
@@ -32,6 +32,8 @@
public interface Inlineable {
static Inlineable getInlineableElement(final ResolvedJavaMethod method, Invoke invoke, HighTierContext context, CanonicalizerPhase canonicalizer) {
+ assert method != null;
+ assert invoke != null;
Class extends FixedWithNextNode> macroNodeClass = InliningUtil.getMacroNodeClass(context.getReplacements(), method);
if (macroNodeClass != null) {
return new InlineableMacroNode(macroNodeClass);
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java Mon Jun 30 12:02:19 2014 +0200
@@ -32,11 +32,26 @@
import com.oracle.graal.nodes.*;
import com.oracle.graal.phases.common.CanonicalizerPhase;
import com.oracle.graal.phases.common.DeadCodeEliminationPhase;
+import com.oracle.graal.phases.common.cfs.FlowUtil;
import com.oracle.graal.phases.common.inlining.InliningUtil;
import com.oracle.graal.phases.tiers.HighTierContext;
import static com.oracle.graal.compiler.common.GraalOptions.OptCanonicalizer;
+/**
+ *
+ * Represents a feasible concrete target for inlining, whose graph has been copied already and thus
+ * can be modified without affecting the original (usually cached) version.
+ *
+ *
+ *
+ * Instances of this class don't make sense in isolation but as part of an
+ * {@link com.oracle.graal.phases.common.inlining.info.InlineInfo InlineInfo}.
+ *
+ *
+ * @see com.oracle.graal.phases.common.inlining.walker.InliningData#moveForward()
+ * @see com.oracle.graal.phases.common.inlining.walker.CallsiteHolderExplorable
+ */
public class InlineableGraph implements Inlineable {
private final StructuredGraph graph;
@@ -73,6 +88,7 @@
try (Debug.Scope s = Debug.scope("InlineGraph", graph)) {
ArrayList parameterUsages = replaceParamsWithMoreInformativeArguments(invoke, context);
+ parameterUsages = rewireParamsForDuplicateArguments(invoke, parameterUsages);
if (parameterUsages != null && OptCanonicalizer.getValue()) {
assert !parameterUsages.isEmpty() : "The caller didn't have more information about arguments after all";
canonicalizer.applyIncremental(graph, context, parameterUsages);
@@ -89,16 +105,62 @@
}
}
- private static boolean isArgMoreInformativeThanParam(ValueNode arg, ParameterNode param) {
- if (arg.isConstant()) {
- return true;
- } else {
- Stamp joinedStamp = param.stamp().join(arg.stamp());
- if (joinedStamp != null && !joinedStamp.equals(param.stamp())) {
- return true;
+ /**
+ * This method detects duplicate arguments (therefore corresponding to different
+ * {@link ParameterNode}s) and updates the graph to make all of their usages refer to the first
+ * one of them.
+ *
+ * @return a (possibly updated) list of nodes for incremental canonicalization.
+ */
+ private ArrayList rewireParamsForDuplicateArguments(Invoke invoke, ArrayList parameterUsages0) {
+ ArrayList parameterUsages = parameterUsages0;
+ ArrayList params = new ArrayList<>();
+ List originalArgs = invoke.callTarget().arguments();
+ List argsInEffect = new ArrayList<>();
+ // some param-nodes might have been deleted by replaceParamsWithMoreInformativeArguments()
+ // that's why we obtain an up-to-date list
+ for (ParameterNode p : graph.getNodes(ParameterNode.class)) {
+ if (!FlowUtil.lacksUsages(p)) {
+ params.add(p);
+ argsInEffect.add(originalArgs.get(p.index()));
}
}
- return false;
+ // argsInEffect and params paired by position
+ assert params.size() == argsInEffect.size();
+ int argIdx = 0;
+ for (ValueNode arg : argsInEffect) {
+ int firstOccurrrence = argsInEffect.indexOf(arg);
+ assert firstOccurrrence >= 0;
+ if (firstOccurrrence < argIdx) {
+ ParameterNode survivingParam = params.get(firstOccurrrence);
+ assert survivingParam.isAlive();
+ ParameterNode duplicateParam = params.get(argIdx);
+ assert duplicateParam.isAlive();
+ assert survivingParam != duplicateParam;
+ assert !isArgMoreInformativeThanParam(arg, survivingParam);
+ parameterUsages = trackParameterUsages(duplicateParam, parameterUsages);
+ // replaceFloating() deletes the duplicate param, unlike replaceAtUsages()
+ graph.replaceFloating(duplicateParam, survivingParam);
+ }
+ argIdx++;
+ }
+ return parameterUsages;
+ }
+
+ private static boolean isArgMoreInformativeThanParam(ValueNode arg, ParameterNode param) {
+ return arg.isConstant() || canStampBeImproved(arg, param);
+ }
+
+ private static boolean canStampBeImproved(ValueNode arg, ParameterNode param) {
+ return improvedStamp(arg, param) != null;
+ }
+
+ private static Stamp improvedStamp(ValueNode arg, ParameterNode param) {
+ Stamp joinedStamp = param.stamp().join(arg.stamp());
+ if (joinedStamp == null || joinedStamp.equals(param.stamp())) {
+ return null;
+ }
+ return joinedStamp;
}
/**
@@ -140,9 +202,9 @@
graph.replaceFloating(param, ConstantNode.forConstant(constant, context.getMetaAccess(), graph));
// param-node gone, leaving a gap in the sequence given by param.index()
} else {
- Stamp joinedStamp = param.stamp().join(arg.stamp());
- if (joinedStamp != null && !joinedStamp.equals(param.stamp())) {
- param.setStamp(joinedStamp);
+ Stamp impro = improvedStamp(arg, param);
+ if (impro != null) {
+ param.setStamp(impro);
parameterUsages = trackParameterUsages(param, parameterUsages);
} else {
assert !isArgMoreInformativeThanParam(arg, param);
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/policy/AbstractInliningPolicy.java
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/policy/AbstractInliningPolicy.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/policy/AbstractInliningPolicy.java Mon Jun 30 12:02:19 2014 +0200
@@ -100,17 +100,6 @@
return size;
}
- protected static int determineNodeCount(InlineInfo info) {
- int nodes = 0;
- for (int i = 0; i < info.numberOfMethods(); i++) {
- Inlineable elem = info.inlineableElementAt(i);
- if (elem != null) {
- nodes += elem.getNodeCount();
- }
- }
- return nodes;
- }
-
protected static double determineInvokeProbability(ToDoubleFunction probabilities, InlineInfo info) {
double invokeProbability = 0;
for (int i = 0; i < info.numberOfMethods(); i++) {
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/policy/GreedyInliningPolicy.java
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/policy/GreedyInliningPolicy.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/policy/GreedyInliningPolicy.java Mon Jun 30 12:02:19 2014 +0200
@@ -30,6 +30,7 @@
import com.oracle.graal.nodes.spi.Replacements;
import com.oracle.graal.phases.common.inlining.InliningUtil;
import com.oracle.graal.phases.common.inlining.info.InlineInfo;
+import com.oracle.graal.phases.common.inlining.walker.MethodInvocation;
import java.util.Map;
import java.util.function.ToDoubleFunction;
@@ -54,8 +55,12 @@
}
@Override
- public boolean isWorthInlining(ToDoubleFunction probabilities, Replacements replacements, InlineInfo info, int inliningDepth, double probability, double relevance,
- boolean fullyProcessed) {
+ public boolean isWorthInlining(ToDoubleFunction probabilities, Replacements replacements, MethodInvocation invocation, int inliningDepth, boolean fullyProcessed) {
+
+ final InlineInfo info = invocation.callee();
+ final double probability = invocation.probability();
+ final double relevance = invocation.relevance();
+
if (InlineEverything.getValue()) {
InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "inline everything");
return true;
@@ -72,7 +77,7 @@
}
double inliningBonus = getInliningBonus(info);
- int nodes = determineNodeCount(info);
+ int nodes = info.determineNodeCount();
int lowLevelGraphSize = previousLowLevelGraphSize(info);
if (SmallCompiledLowLevelGraphSize.getValue() > 0 && lowLevelGraphSize > SmallCompiledLowLevelGraphSize.getValue() * inliningBonus) {
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/policy/InlineEverythingPolicy.java
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/policy/InlineEverythingPolicy.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/policy/InlineEverythingPolicy.java Mon Jun 30 12:02:19 2014 +0200
@@ -26,7 +26,7 @@
import com.oracle.graal.nodes.FixedNode;
import com.oracle.graal.nodes.StructuredGraph;
import com.oracle.graal.nodes.spi.Replacements;
-import com.oracle.graal.phases.common.inlining.info.InlineInfo;
+import com.oracle.graal.phases.common.inlining.walker.MethodInvocation;
import java.util.function.ToDoubleFunction;
@@ -41,8 +41,7 @@
return true;
}
- public boolean isWorthInlining(ToDoubleFunction probabilities, Replacements replacements, InlineInfo info, int inliningDepth, double probability, double relevance,
- boolean fullyProcessed) {
+ public boolean isWorthInlining(ToDoubleFunction probabilities, Replacements replacements, MethodInvocation invocation, int inliningDepth, boolean fullyProcessed) {
return true;
}
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/policy/InliningPolicy.java
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/policy/InliningPolicy.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/policy/InliningPolicy.java Mon Jun 30 12:02:19 2014 +0200
@@ -25,7 +25,7 @@
import com.oracle.graal.nodes.FixedNode;
import com.oracle.graal.nodes.StructuredGraph;
import com.oracle.graal.nodes.spi.Replacements;
-import com.oracle.graal.phases.common.inlining.info.InlineInfo;
+import com.oracle.graal.phases.common.inlining.walker.MethodInvocation;
import java.util.function.ToDoubleFunction;
@@ -33,5 +33,5 @@
boolean continueInlining(StructuredGraph graph);
- boolean isWorthInlining(ToDoubleFunction probabilities, Replacements replacements, InlineInfo info, int inliningDepth, double probability, double relevance, boolean fullyProcessed);
+ boolean isWorthInlining(ToDoubleFunction probabilities, Replacements replacements, MethodInvocation invocation, int inliningDepth, boolean fullyProcessed);
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/CallsiteHolder.java
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/CallsiteHolder.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/CallsiteHolder.java Mon Jun 30 12:02:19 2014 +0200
@@ -22,105 +22,31 @@
*/
package com.oracle.graal.phases.common.inlining.walker;
-import com.oracle.graal.api.meta.MetaUtil;
import com.oracle.graal.api.meta.ResolvedJavaMethod;
-import com.oracle.graal.nodes.FixedNode;
-import com.oracle.graal.nodes.Invoke;
import com.oracle.graal.nodes.StructuredGraph;
-import com.oracle.graal.phases.graph.FixedNodeProbabilityCache;
-
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.function.ToDoubleFunction;
-
-import static com.oracle.graal.compiler.common.GraalOptions.CapInheritedRelevance;
/**
* Information about a graph that will potentially be inlined. This includes tracking the
* invocations in graph that will subject to inlining themselves.
*/
-public class CallsiteHolder {
-
- private final StructuredGraph graph;
- private final LinkedList remainingInvokes;
- private final double probability;
- private final double relevance;
-
- private final ToDoubleFunction probabilities;
- private final ComputeInliningRelevance computeInliningRelevance;
-
- public CallsiteHolder(StructuredGraph graph, double probability, double relevance) {
- this.graph = graph;
- this.probability = probability;
- this.relevance = relevance;
- if (graph == null) {
- remainingInvokes = new LinkedList<>();
- probabilities = null;
- computeInliningRelevance = null;
- } else {
- remainingInvokes = new InliningIterator(graph).apply();
- assert remainingInvokes.size() == count(graph.getInvokes());
- if (remainingInvokes.isEmpty()) {
- probabilities = null;
- computeInliningRelevance = null;
- } else {
- probabilities = new FixedNodeProbabilityCache();
- computeInliningRelevance = new ComputeInliningRelevance(graph, probabilities);
- computeProbabilities();
- }
- }
- }
-
- private static int count(Iterable invokes) {
- int count = 0;
- Iterator iterator = invokes.iterator();
- while (iterator.hasNext()) {
- iterator.next();
- count++;
- }
- return count;
- }
+public abstract class CallsiteHolder {
/**
* Gets the method associated with the {@linkplain #graph() graph} represented by this object.
*/
- public ResolvedJavaMethod method() {
- return graph == null ? null : graph.method();
- }
+ public abstract ResolvedJavaMethod method();
- public boolean hasRemainingInvokes() {
- return !remainingInvokes.isEmpty();
- }
+ /**
+ * The stack realized by {@link InliningData} grows upon {@link InliningData#moveForward()}
+ * deciding to explore (depth-first) a callsite of the graph associated to this
+ * {@link CallsiteHolder}. The list of not-yet-considered callsites is managed by
+ * {@link CallsiteHolderExplorable}, and this method reports whether any such candidates remain.
+ */
+ public abstract boolean hasRemainingInvokes();
/**
* The graph about which this object contains inlining information.
*/
- public StructuredGraph graph() {
- return graph;
- }
-
- public Invoke popInvoke() {
- return remainingInvokes.removeFirst();
- }
-
- public void pushInvoke(Invoke invoke) {
- remainingInvokes.push(invoke);
- }
+ public abstract StructuredGraph graph();
- public void computeProbabilities() {
- computeInliningRelevance.compute();
- }
-
- public double invokeProbability(Invoke invoke) {
- return probability * probabilities.applyAsDouble(invoke.asNode());
- }
-
- public double invokeRelevance(Invoke invoke) {
- return Math.min(CapInheritedRelevance.getValue(), relevance) * computeInliningRelevance.getRelevance(invoke);
- }
-
- @Override
- public String toString() {
- return (graph != null ? MetaUtil.format("%H.%n(%p)", method()) : "") + remainingInvokes;
- }
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/CallsiteHolderDummy.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/CallsiteHolderDummy.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,61 @@
+/*
+ * 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.phases.common.inlining.walker;
+
+import com.oracle.graal.api.meta.ResolvedJavaMethod;
+import com.oracle.graal.nodes.StructuredGraph;
+
+import com.oracle.graal.phases.common.inlining.info.elem.InlineableMacroNode;
+
+/**
+ * A {@link CallsiteHolder} that stands for an {@link InlineableMacroNode} in the stack realized by
+ * {@link InliningData}.
+ */
+public final class CallsiteHolderDummy extends CallsiteHolder {
+
+ public static final CallsiteHolderDummy DUMMY_CALLSITE_HOLDER = new CallsiteHolderDummy();
+
+ private CallsiteHolderDummy() {
+ // no instances other than the singleton
+ }
+
+ @Override
+ public ResolvedJavaMethod method() {
+ return null;
+ }
+
+ @Override
+ public boolean hasRemainingInvokes() {
+ return false;
+ }
+
+ @Override
+ public StructuredGraph graph() {
+ return null;
+ }
+
+ @Override
+ public String toString() {
+ return "";
+ }
+}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/CallsiteHolderExplorable.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/CallsiteHolderExplorable.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,214 @@
+/*
+ * 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.phases.common.inlining.walker;
+
+import com.oracle.graal.api.meta.MetaUtil;
+import com.oracle.graal.api.meta.ResolvedJavaMethod;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.phases.graph.FixedNodeProbabilityCache;
+
+import java.util.*;
+import java.util.function.ToDoubleFunction;
+
+import static com.oracle.graal.compiler.common.GraalOptions.CapInheritedRelevance;
+
+/**
+ *
+ * A {@link CallsiteHolder} whose graph has been copied already and thus can be modified without
+ * affecting the original (usually cached) version.
+ *
+ *
+ *
+ * An instance of this class is derived from an
+ * {@link com.oracle.graal.phases.common.inlining.info.elem.InlineableGraph InlineableGraph} and
+ * contains a subset of the information there: just the {@link Invoke} nodes from it. Such nodes are
+ * candidates for depth-first search of further inlining opportunities (thus the adjective
+ * "explorable" given to this class)
+ *
+ *
+ * @see InliningData#moveForward()
+ */
+public final class CallsiteHolderExplorable extends CallsiteHolder {
+
+ /**
+ * Graph in which inlining may be performed at one or more of the callsites containined in
+ * {@link #remainingInvokes}
+ */
+ private final StructuredGraph graph;
+
+ private final LinkedList remainingInvokes;
+ private final double probability;
+ private final double relevance;
+
+ /**
+ * @see #getFixedParams()
+ */
+ private final Set fixedParams;
+
+ private final ToDoubleFunction probabilities;
+ private final ComputeInliningRelevance computeInliningRelevance;
+
+ public CallsiteHolderExplorable(StructuredGraph graph, double probability, double relevance, BitSet freshlyInstantiatedArguments) {
+ assert graph != null;
+ this.graph = graph;
+ this.probability = probability;
+ this.relevance = relevance;
+ this.fixedParams = fixedParamsAt(freshlyInstantiatedArguments);
+ remainingInvokes = new InliningIterator(graph).apply();
+ if (remainingInvokes.isEmpty()) {
+ probabilities = null;
+ computeInliningRelevance = null;
+ } else {
+ probabilities = new FixedNodeProbabilityCache();
+ computeInliningRelevance = new ComputeInliningRelevance(graph, probabilities);
+ computeProbabilities();
+ }
+ assert repOK();
+ }
+
+ /**
+ * @see #getFixedParams()
+ */
+ @SuppressWarnings("unchecked")
+ private Set fixedParamsAt(BitSet freshlyInstantiatedArguments) {
+ if (freshlyInstantiatedArguments == null || freshlyInstantiatedArguments.isEmpty()) {
+ return Collections.EMPTY_SET;
+ }
+ Set result = new HashSet<>();
+ for (ParameterNode p : graph.getNodes(ParameterNode.class)) {
+ if (freshlyInstantiatedArguments.get(p.index())) {
+ result.add(p);
+ }
+ }
+ return result;
+ }
+
+ /**
+ *
+ * Parameters for which the callsite targeting {@link #graph()} provides "fixed" arguments. That
+ * callsite isn't referenced by this instance. Instead, it belongs to the graph of the caller of
+ * this {@link CallsiteHolderExplorable}
+ *
+ *
+ *
+ * Constant arguments don't contribute to fixed-params: those params have been removed already,
+ * see {@link com.oracle.graal.phases.common.inlining.info.elem.InlineableGraph}.
+ *
+ *
+ *
+ * Instead, fixed-params are those receiving freshly instantiated arguments (possibly
+ * instantiated several levels up in the call-hierarchy)
+ *
+ * */
+ public Set getFixedParams() {
+ return fixedParams;
+ }
+
+ public boolean repOK() {
+ for (Invoke invoke : remainingInvokes) {
+ if (!invoke.asNode().isAlive() || !containsInvoke(invoke)) {
+ assert false;
+ return false;
+ }
+ if (!allArgsNonNull(invoke)) {
+ assert false;
+ return false;
+ }
+ }
+ for (ParameterNode fixedParam : fixedParams) {
+ if (!containsParam(fixedParam)) {
+ assert false;
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public ResolvedJavaMethod method() {
+ return graph == null ? null : graph.method();
+ }
+
+ @Override
+ public boolean hasRemainingInvokes() {
+ return !remainingInvokes.isEmpty();
+ }
+
+ @Override
+ public StructuredGraph graph() {
+ return graph;
+ }
+
+ public Invoke popInvoke() {
+ return remainingInvokes.removeFirst();
+ }
+
+ public void pushInvoke(Invoke invoke) {
+ remainingInvokes.push(invoke);
+ }
+
+ public static boolean allArgsNonNull(Invoke invoke) {
+ for (ValueNode arg : invoke.callTarget().arguments()) {
+ if (arg == null) {
+ assert false;
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public boolean containsInvoke(Invoke invoke) {
+ for (Invoke i : graph().getInvokes()) {
+ if (i == invoke) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean containsParam(ParameterNode param) {
+ for (ParameterNode p : graph.getNodes(ParameterNode.class)) {
+ if (p == param) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void computeProbabilities() {
+ computeInliningRelevance.compute();
+ }
+
+ public double invokeProbability(Invoke invoke) {
+ return probability * probabilities.applyAsDouble(invoke.asNode());
+ }
+
+ public double invokeRelevance(Invoke invoke) {
+ return Math.min(CapInheritedRelevance.getValue(), relevance) * computeInliningRelevance.getRelevance(invoke);
+ }
+
+ @Override
+ public String toString() {
+ return (graph != null ? MetaUtil.format("%H.%n(%p)", method()) : "") + remainingInvokes;
+ }
+}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java Mon Jun 30 12:02:19 2014 +0200
@@ -34,7 +34,10 @@
import com.oracle.graal.graph.Graph;
import com.oracle.graal.graph.Node;
import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.AbstractNewObjectNode;
import com.oracle.graal.nodes.java.MethodCallTargetNode;
+import com.oracle.graal.nodes.virtual.AllocatedObjectNode;
+import com.oracle.graal.nodes.virtual.VirtualObjectNode;
import com.oracle.graal.phases.OptimisticOptimizations;
import com.oracle.graal.phases.common.CanonicalizerPhase;
import com.oracle.graal.phases.common.inlining.InliningUtil;
@@ -51,14 +54,37 @@
import java.util.function.ToDoubleFunction;
import static com.oracle.graal.compiler.common.GraalOptions.*;
+import static com.oracle.graal.phases.common.inlining.walker.CallsiteHolderDummy.DUMMY_CALLSITE_HOLDER;
/**
- * Holds the data for building the callee graphs recursively: graphs and invocations (each
- * invocation can have multiple graphs).
+ *
+ * The space of inlining decisions is explored depth-first with the help of a stack realized by
+ * {@link InliningData}. At any point in time, the topmost element of that stack consists of:
+ *
+ *
the callsite under consideration is tracked as a {@link MethodInvocation}.
+ *
+ * one or more {@link CallsiteHolder}s, all of them associated to the callsite above. Why more than
+ * one? Depending on the type-profile for the receiver more than one concrete method may be feasible
+ * target.
+ *
+ *
+ *
+ *
+ * The bottom element in the stack consists of:
+ *
+ *
+ * a single {@link MethodInvocation} (the
+ * {@link com.oracle.graal.phases.common.inlining.walker.MethodInvocation#isRoot root} one, ie the
+ * unknown caller of the root graph)
+ *
+ * a single {@link CallsiteHolder} (the root one, for the method on which inlining was called)
+ * to inline at the callsite given by calleeInvocation, where that callsite belongs
+ * to the {@link CallsiteHolderExplorable} at the top of the {@link #graphQueue} maintained in
+ * this class.
+ *
+ * otherwise, to devirtualize the callsite in question.
+ *
+ *
* @return true iff inlining was actually performed
*/
- private boolean tryToInline(CallsiteHolder callerCallsiteHolder, MethodInvocation calleeInvocation, MethodInvocation parentInvocation, int inliningDepth) {
+ private boolean tryToInline(MethodInvocation calleeInvocation, MethodInvocation parentInvocation, int inliningDepth) {
+ CallsiteHolderExplorable callerCallsiteHolder = (CallsiteHolderExplorable) currentGraph();
InlineInfo calleeInfo = calleeInvocation.callee();
- assert iterContains(callerCallsiteHolder.graph().getInvokes(), calleeInfo.invoke());
+ assert callerCallsiteHolder.containsInvoke(calleeInfo.invoke());
Assumptions callerAssumptions = parentInvocation.assumptions();
metricInliningConsidered.increment();
- if (inliningPolicy.isWorthInlining(probabilities, context.getReplacements(), calleeInfo, inliningDepth, calleeInvocation.probability(), calleeInvocation.relevance(), true)) {
+ if (inliningPolicy.isWorthInlining(probabilities, context.getReplacements(), calleeInvocation, inliningDepth, true)) {
doInline(callerCallsiteHolder, calleeInvocation, callerAssumptions);
return true;
}
@@ -396,62 +438,94 @@
return false;
}
- private static boolean iterContains(Iterable in, T elem) {
- for (T i : in) {
- if (i == elem) {
- return true;
- }
- }
- return false;
- }
-
/**
- * Process the next invoke and enqueue all its graphs for processing.
+ * This method picks one of the callsites belonging to the current
+ * {@link CallsiteHolderExplorable}. Provided the callsite qualifies to be analyzed for
+ * inlining, this method prepares a new stack top in {@link InliningData} for such callsite,
+ * which comprises:
+ *
+ *
preparing a summary of feasible targets, ie preparing an {@link InlineInfo}
+ *
based on it, preparing the stack top proper which consists of:
+ *
+ *
one {@link MethodInvocation}
+ *
a {@link CallsiteHolder} for each feasible target
+ *
+ *
+ *
+ *
+ * The thus prepared "stack top" is needed by {@link #moveForward()} to explore the space of
+ * inlining decisions (each decision one of: backtracking, delving, inlining).
+ *
+ *
+ *
+ * The {@link InlineInfo} used to get things rolling is kept around in the
+ * {@link MethodInvocation}, it will be needed in case of inlining, see
+ * {@link InlineInfo#inline(Providers, Assumptions)}
+ *
+ * A freshly instantiated argument is either:
+ *
+ *
an {@link InliningData#isFreshInstantiation(com.oracle.graal.nodes.ValueNode)}
+ *
a fixed-param, ie a {@link ParameterNode} receiving a freshly instantiated argument
+ *
+ *
+ *
+ * @return the positions of freshly instantiated arguments in the argument list of the
+ * invoke, or null if no such positions exist.
+ */
+ public static BitSet freshlyInstantiatedArguments(Invoke invoke, Set fixedParams) {
+ assert fixedParams != null;
+ assert paramsAndInvokeAreInSameGraph(invoke, fixedParams);
+ BitSet result = null;
+ int argIdx = 0;
+ for (ValueNode arg : invoke.callTarget().arguments()) {
+ assert arg != null;
+ if (isFreshInstantiation(arg) || fixedParams.contains(arg)) {
+ if (result == null) {
+ result = new BitSet();
+ }
+ result.set(argIdx);
+ }
+ argIdx++;
}
- for (int i = 0; i < info.numberOfMethods(); i++) {
- Inlineable elem = Inlineable.getInlineableElement(info.methodAt(i), info.invoke(), context.replaceAssumptions(calleeAssumptions), canonicalizer);
- info.setInlinableElement(i, elem);
+ return result;
+ }
+
+ private static boolean paramsAndInvokeAreInSameGraph(Invoke invoke, Set fixedParams) {
+ if (fixedParams.isEmpty()) {
+ return true;
}
- return info;
+ for (ParameterNode p : fixedParams) {
+ if (p.graph() != invoke.asNode().graph()) {
+ return false;
+ }
+ }
+ return true;
}
public int graphCount() {
return graphQueue.size();
}
- private void pushGraph(StructuredGraph graph, double probability, double relevance) {
- assert graph != null;
- assert !contains(graph);
- graphQueue.push(new CallsiteHolder(graph, probability, relevance));
- assert graphQueue.size() <= maxGraphs;
- }
-
- private void pushDummyGraph() {
- graphQueue.push(DUMMY_CALLSITE_HOLDER);
- assert graphQueue.size() <= maxGraphs;
- }
-
public boolean hasUnprocessedGraphs() {
return !graphQueue.isEmpty();
}
@@ -498,16 +572,11 @@
InlineInfo info = methodInvocation.callee();
maxGraphs += info.numberOfMethods();
assert graphQueue.size() <= maxGraphs;
- double invokeProbability = methodInvocation.probability();
- double invokeRelevance = methodInvocation.relevance();
for (int i = 0; i < info.numberOfMethods(); i++) {
- Inlineable elem = info.inlineableElementAt(i);
- if (elem instanceof InlineableGraph) {
- pushGraph(((InlineableGraph) elem).getGraph(), invokeProbability * info.probabilityAt(i), invokeRelevance * info.relevanceAt(i));
- } else {
- assert elem instanceof InlineableMacroNode;
- pushDummyGraph();
- }
+ CallsiteHolder ch = methodInvocation.buildCallsiteHolderForElement(i);
+ assert (ch == DUMMY_CALLSITE_HOLDER) || !contains(ch.graph());
+ graphQueue.push(ch);
+ assert graphQueue.size() <= maxGraphs;
}
}
@@ -555,6 +624,7 @@
}
private boolean contains(StructuredGraph graph) {
+ assert graph != null;
for (CallsiteHolder info : graphQueue) {
if (info.graph() == graph) {
return true;
@@ -564,14 +634,56 @@
}
/**
+ *
+ * The stack realized by {@link InliningData} grows and shrinks as choices are made among the
+ * alternatives below:
+ *
+ *
+ * not worth inlining: pop stack top, which comprises:
+ *
+ *
pop any remaining graphs not yet delved into
+ *
pop the current invocation
+ *
+ *
+ *
+ * {@link #processNextInvoke() delve} into one of the callsites hosted in the current graph,
+ * such callsite is explored next by {@link #moveForward()}
+ *
+ * {@link #tryToInline(MethodInvocation, MethodInvocation, int) try to inline}: move past the
+ * current graph (remove it from the topmost element).
+ *
+ *
+ * If that was the last one then {@link #tryToInline(MethodInvocation, MethodInvocation, int)
+ * try to inline} the callsite under consideration (ie, the "current invocation").
+ *
+ * Whether inlining occurs or not, that callsite is removed from the top of {@link InliningData}
+ * .
+ *
+ *
+ *
+ *
+ *
+ *
+ * Some facts about the alternatives above:
+ *
+ *
+ * the first step amounts to backtracking, the 2nd one to depth-search, and the 3rd one also
+ * involves backtracking (however possibly after inlining).
+ *
+ * the choice of abandon-and-backtrack or delve-into depends on
+ * {@link InliningPolicy#isWorthInlining} and {@link InliningPolicy#continueInlining}.
+ *
+ * the 3rd choice is picked whenever none of the previous choices are made
+ * An instance of this class denotes a callsite being analyzed for inlining.
+ *
+ *
+ * Each element of the {@link InliningData} stack contains one such instance, the accompanying
+ * {@link CallsiteHolder}s in that element represent feasible targets for the callsite in question.
+ *
+ *
+ * @see InliningData#moveForward()
+ */
public class MethodInvocation {
private final InlineInfo callee;
@@ -38,11 +54,39 @@
private int processedGraphs;
- public MethodInvocation(InlineInfo info, Assumptions assumptions, double probability, double relevance) {
+ /**
+ *
+ * The immutable positions of freshly instantiated arguments (ie, positions in
+ * callee.invoke.callTarget.arguments).
+ *
+ *
+ *
+ * A freshly instantiated argument is either:
+ *
+ *
an {@link InliningData#isFreshInstantiation(com.oracle.graal.nodes.ValueNode)}
+ *
a fixed-param of the graph containing the callsite (ie, of callee.graph()
+ * that contains callee.invoke)
+ *
+ *
+ *
+ *
+ * Given those positions, the
+ * {@link com.oracle.graal.phases.common.inlining.walker.CallsiteHolderExplorable} instantiated
+ * in {@link #buildCallsiteHolderForElement(int)} can determine which of its parameters
+ * are fixed.
+ *
+ */
+ private final BitSet freshlyInstantiatedArguments;
+
+ private final int sizeFreshArgs;
+
+ public MethodInvocation(InlineInfo info, Assumptions assumptions, double probability, double relevance, BitSet freshlyInstantiatedArguments) {
this.callee = info;
this.assumptions = assumptions;
this.probability = probability;
this.relevance = relevance;
+ this.freshlyInstantiatedArguments = freshlyInstantiatedArguments;
+ this.sizeFreshArgs = freshlyInstantiatedArguments == null ? 0 : freshlyInstantiatedArguments.cardinality();
}
public void incrementProcessedGraphs() {
@@ -79,6 +123,27 @@
return callee == null;
}
+ public BitSet getFreshlyInstantiatedArguments() {
+ return freshlyInstantiatedArguments;
+ }
+
+ public int getSizeFreshArgs() {
+ return sizeFreshArgs;
+ }
+
+ public CallsiteHolder buildCallsiteHolderForElement(int index) {
+ Inlineable elem = callee.inlineableElementAt(index);
+ if (elem instanceof InlineableGraph) {
+ InlineableGraph ig = (InlineableGraph) elem;
+ final double invokeProbability = probability * callee.probabilityAt(index);
+ final double invokeRelevance = relevance * callee.relevanceAt(index);
+ return new CallsiteHolderExplorable(ig.getGraph(), invokeProbability, invokeRelevance, freshlyInstantiatedArguments);
+ } else {
+ assert elem instanceof InlineableMacroNode;
+ return CallsiteHolderDummy.DUMMY_CALLSITE_HOLDER;
+ }
+ }
+
@Override
public String toString() {
if (isRoot()) {
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/util/HashSetNodeChangeListener.java
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/util/HashSetNodeChangeListener.java Mon Jun 30 08:50:26 2014 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2013, 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.phases.common.util;
-
-import java.util.*;
-
-import com.oracle.graal.graph.Graph.NodeChangedListener;
-import com.oracle.graal.graph.*;
-
-/**
- * A simple {@link NodeChangedListener} implementation that accumulates the changed nodes in a
- * {@link HashSet}.
- */
-public class HashSetNodeChangeListener implements NodeChangedListener {
-
- private final Set changedNodes;
-
- public HashSetNodeChangeListener() {
- this.changedNodes = new HashSet<>();
- }
-
- @Override
- public void nodeChanged(Node node) {
- changedNodes.add(node);
- }
-
- public Set getChangedNodes() {
- return changedNodes;
- }
-}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/util/HashSetNodeEventListener.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/util/HashSetNodeEventListener.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2013, 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.phases.common.util;
+
+import java.util.*;
+
+import com.oracle.graal.graph.Graph.NodeEventListener;
+import com.oracle.graal.graph.*;
+
+/**
+ * A simple {@link NodeEventListener} implementation that accumulates event nodes in a
+ * {@link HashSet}.
+ */
+public class HashSetNodeEventListener implements NodeEventListener {
+
+ /**
+ * Accumulates all node events except for {@link NodeEventListener#nodeAdded(Node) node
+ * additions}.
+ */
+ public static class ExceptForAddedNodes extends HashSetNodeEventListener {
+ @Override
+ public void nodeAdded(Node node) {
+ }
+ }
+
+ private final Set nodes;
+
+ public HashSetNodeEventListener() {
+ this.nodes = new HashSet<>();
+ }
+
+ public void nodeAdded(Node node) {
+ nodes.add(node);
+ }
+
+ public void inputChanged(Node node) {
+ nodes.add(node);
+ }
+
+ public void usagesDroppedToZero(Node node) {
+ nodes.add(node);
+ }
+
+ /**
+ * Gets the set of nodes that were communicated to this listener.
+ */
+ public Set getNodes() {
+ return nodes;
+ }
+}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java Mon Jun 30 12:02:19 2014 +0200
@@ -94,12 +94,15 @@
public final void apply(final StructuredGraph graph, final C context, final boolean dumpGraph) {
try (TimerCloseable a = timer.start(); Scope s = Debug.scope(getClass(), this); Closeable c = memUseTracker.start()) {
- BasePhase.this.run(graph, context);
+ this.run(graph, context);
executionCount.increment();
inputNodesCount.add(graph.getNodeCount());
if (dumpGraph && Debug.isDumpEnabled()) {
Debug.dump(graph, "After phase %s", getName());
}
+ if (Debug.isVerifyEnabled()) {
+ Debug.verify(graph, this, "After phase " + getName());
+ }
assert graph.verify();
} catch (Throwable t) {
throw Debug.handle(t);
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyUsageWithEquals.java
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyUsageWithEquals.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyUsageWithEquals.java Mon Jun 30 12:02:19 2014 +0200
@@ -67,8 +67,8 @@
protected boolean verify(StructuredGraph graph, PhaseContext context) {
for (ObjectEqualsNode cn : graph.getNodes().filter(ObjectEqualsNode.class)) {
// bail out if we compare an object of type klass with == or != (except null checks)
- if (checkUsage(cn.x(), cn.y(), context.getMetaAccess()) && checkUsage(cn.y(), cn.x(), context.getMetaAccess())) {
- throw new VerificationError("Verification of " + klass.getName() + " usage failed: Comparing " + cn.x() + " and " + cn.y() + " in " + graph.method() +
+ if (checkUsage(cn.getX(), cn.getY(), context.getMetaAccess()) && checkUsage(cn.getY(), cn.getX(), context.getMetaAccess())) {
+ throw new VerificationError("Verification of " + klass.getName() + " usage failed: Comparing " + cn.getX() + " and " + cn.getY() + " in " + graph.method() +
" must use .equals() for object equality, not '==' or '!='");
}
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014, 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
@@ -299,6 +299,7 @@
for (Position pos : directInputPositions) {
writeByte(pos.getSubIndex() == NodeClass.NOT_ITERABLE ? 0 : 1);
writePoolObject(nodeClass.getName(pos));
+ writePoolObject(nodeClass.getInputType(pos));
}
Collection directSuccessorPositions = nodeClass.getFirstLevelSuccessorPositions();
writeShort((char) directSuccessorPositions.size());
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2014, 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
@@ -532,7 +532,7 @@
}
private void printInterval(Interval interval) {
- out.printf("%s %s ", interval.operand, (isRegister(interval.operand) ? "fixed" : interval.kind().name()));
+ out.printf("%s %s ", interval.operand, (isRegister(interval.operand) ? "fixed" : interval.kind()));
if (isRegister(interval.operand)) {
out.printf("\"[%s|%c]\"", interval.operand, interval.operand.getKind().getTypeChar());
} else {
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java Mon Jun 30 12:02:19 2014 +0200
@@ -34,10 +34,17 @@
public class DebugEnvironment {
+ @SuppressWarnings("all")
+ private static boolean assertionsEnabled() {
+ boolean assertionsEnabled = false;
+ assert assertionsEnabled = true;
+ return assertionsEnabled;
+ }
+
public static GraalDebugConfig initialize(PrintStream log) {
// Ensure Graal runtime is initialized prior to Debug being initialized as the former
- // included processing command line options used by the latter.
+ // may include processing command line options used by the latter.
Graal.getRuntime();
if (!Debug.isEnabled()) {
@@ -55,7 +62,16 @@
if (DecompileAfterPhase.getValue() != null) {
dumpHandlers.add(new DecompilerDebugDumpHandler());
}
- GraalDebugConfig debugConfig = new GraalDebugConfig(Log.getValue(), Meter.getValue(), TrackMemUse.getValue(), Time.getValue(), Dump.getValue(), MethodFilter.getValue(), log, dumpHandlers);
+ List verifyHandlers = new ArrayList<>();
+ String verifyFilter = Verify.getValue();
+ if (verifyFilter == null && assertionsEnabled()) {
+ verifyFilter = "";
+ }
+ if (verifyFilter != null) {
+ verifyHandlers.add(new NoDeadCodeVerifyHandler());
+ }
+ GraalDebugConfig debugConfig = new GraalDebugConfig(Log.getValue(), Meter.getValue(), TrackMemUse.getValue(), Time.getValue(), Dump.getValue(), verifyFilter, MethodFilter.getValue(), log,
+ dumpHandlers, verifyHandlers);
Debug.setConfig(debugConfig);
return debugConfig;
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/NoDeadCodeVerifyHandler.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/NoDeadCodeVerifyHandler.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2014, 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.printer;
+
+import static com.oracle.graal.printer.NoDeadCodeVerifyHandler.Options.*;
+
+import java.util.*;
+import java.util.concurrent.*;
+
+import com.oracle.graal.compiler.common.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.options.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.common.*;
+
+/**
+ * Verifies that graphs have no dead code.
+ */
+public class NoDeadCodeVerifyHandler implements DebugVerifyHandler {
+
+ // The options below will be removed once all phases clean up their own dead code.
+
+ private static final int OFF = 0;
+ private static final int INFO = 1;
+ private static final int VERBOSE = 2;
+ private static final int FATAL = 3;
+
+ static class Options {
+ // @formatter:off
+ @Option(help = "Run level for NoDeadCodeVerifyHandler (0 = off, 1 = info, 2 = verbose, 3 = fatal)")
+ public static final OptionValue NDCV = new OptionValue<>(0);
+ // @formatter:on
+ }
+
+ private static final Map, Boolean> discovered = new ConcurrentHashMap<>();
+
+ public void verify(Object object, Object... context) {
+ if (NDCV.getValue() != OFF) {
+ StructuredGraph graph = extract(StructuredGraph.class, object);
+ BasePhase> phase = extract(BasePhase.class, context);
+ assert phase != null : "a Phase context is required by " + getClass().getSimpleName();
+ if (graph != null) {
+ List before = graph.getNodes().snapshot();
+ new DeadCodeEliminationPhase().run(graph);
+ List after = graph.getNodes().snapshot();
+ assert after.size() <= before.size();
+ if (before.size() != after.size()) {
+ before.removeAll(after);
+ if (discovered.put(phase.getClass(), Boolean.TRUE) == null) {
+ String message = extract(String.class, context);
+ String prefix = message == null ? "" : message + ": ";
+ String phaseClass = phase.getClass().getName();
+ GraalInternalError error = new GraalInternalError("%sfound dead nodes in %s (phase class=%s): %s", prefix, graph, phaseClass, before);
+ if (NDCV.getValue() == INFO) {
+ System.out.println(error.getMessage());
+ } else if (NDCV.getValue() == VERBOSE) {
+ error.printStackTrace(System.out);
+ } else {
+ assert NDCV.getValue() == FATAL;
+ throw error;
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.ptx/src/com/oracle/graal/ptx/PTX.java
--- a/graal/com.oracle.graal.ptx/src/com/oracle/graal/ptx/PTX.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.ptx/src/com/oracle/graal/ptx/PTX.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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
@@ -197,12 +197,12 @@
}
@Override
- public boolean canStoreValue(RegisterCategory category, PlatformKind platformKind) {
- if (!(platformKind instanceof Kind)) {
+ public boolean canStoreValue(RegisterCategory category, PlatformKind lirKind) {
+ if (!(lirKind instanceof Kind)) {
return false;
}
- Kind kind = (Kind) platformKind;
+ Kind kind = (Kind) lirKind;
if (category == REG) {
switch (kind) {
case Boolean:
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java
--- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java Mon Jun 30 12:02:19 2014 +0200
@@ -181,8 +181,8 @@
StructuredGraph graph = convert.graph();
Arguments args = new Arguments(key, graph.getGuardsStage(), tool.getLoweringStage());
- args.add("input", convert.getInput());
- args.add("result", graph.unique(new AMD64FloatConvertNode(convert.stamp(), convert.getOp(), convert.getInput())));
+ args.add("input", convert.getValue());
+ args.add("result", graph.unique(new AMD64FloatConvertNode(convert.stamp(), convert.getOp(), convert.getValue())));
SnippetTemplate template = template(args);
Debug.log("Lowering %s in %s: node=%s, template=%s, arguments=%s", convert.getOp(), graph, convert, template, args);
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64FloatConvertNode.java
--- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64FloatConvertNode.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64FloatConvertNode.java Mon Jun 30 12:02:19 2014 +0200
@@ -26,6 +26,7 @@
import com.oracle.graal.compiler.common.*;
import com.oracle.graal.compiler.common.calc.*;
import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.graph.spi.*;
import com.oracle.graal.lir.gen.*;
import com.oracle.graal.nodes.*;
import com.oracle.graal.nodes.calc.*;
@@ -36,15 +37,13 @@
* of the {@link FloatConvertNode} which, on AMD64 needs a {@link AMD64FloatConvertNode} plus some
* fixup code that handles the corner cases that differ between AMD64 and Java.
*/
-public class AMD64FloatConvertNode extends FloatingNode implements ArithmeticLIRLowerable {
+public class AMD64FloatConvertNode extends UnaryNode implements ArithmeticLIRLowerable {
private final FloatConvert op;
- @Input private ValueNode value;
public AMD64FloatConvertNode(Stamp stamp, FloatConvert op, ValueNode value) {
- super(stamp);
+ super(stamp, value);
this.op = op;
- this.value = value;
}
public Constant evalConst(Constant... inputs) {
@@ -52,7 +51,13 @@
throw GraalInternalError.shouldNotReachHere();
}
+ @Override
+ public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
+ // nothing to do
+ return this;
+ }
+
public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
- builder.setResult(this, gen.emitFloatConvert(op, builder.operand(value)));
+ builder.setResult(this, gen.emitFloatConvert(op, builder.operand(getValue())));
}
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements.hsail/src/com/oracle/graal/replacements/hsail/HSAILMathIntrinsicsNode.java
--- a/graal/com.oracle.graal.replacements.hsail/src/com/oracle/graal/replacements/hsail/HSAILMathIntrinsicsNode.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.replacements.hsail/src/com/oracle/graal/replacements/hsail/HSAILMathIntrinsicsNode.java Mon Jun 30 12:02:19 2014 +0200
@@ -123,7 +123,7 @@
@Override
public Node canonical(CanonicalizerTool tool) {
if (getParameter().isConstant()) {
- return ConstantNode.forPrimitive(evalConst(getParameter().asConstant()), graph());
+ return ConstantNode.forPrimitive(evalConst(getParameter().asConstant()));
}
return this;
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/BitOpNodesTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/BitOpNodesTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2012, 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.replacements.test;
+
+import org.junit.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.compiler.test.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.common.*;
+import com.oracle.graal.phases.common.inlining.*;
+import com.oracle.graal.phases.tiers.*;
+
+public class BitOpNodesTest extends GraalCompilerTest {
+
+ private static final int INT_CONSTANT_1 = 0x80100010;
+ private static final int INT_CONSTANT_2 = 0x00011110;
+ private static final int INT_CONSTANT_3 = 0x00000000;
+
+ private static final long LONG_CONSTANT_1 = 0x8000000000100010L;
+ private static final long LONG_CONSTANT_2 = 0x0000000000011110L;
+ private static final long LONG_CONSTANT_3 = 0x0000000000000000L;
+
+ public static long dummyField;
+
+ /*
+ * Tests for BitCountNode canonicalizations.
+ */
+
+ public static int bitCountIntConstantSnippet() {
+ return Integer.bitCount(INT_CONSTANT_1) + Integer.bitCount(INT_CONSTANT_2) + Integer.bitCount(INT_CONSTANT_3);
+ }
+
+ @Test
+ public void testBitCountIntConstant() {
+ ValueNode result = parseAndInline("bitCountIntConstantSnippet");
+ Assert.assertEquals(7, result.asConstant().asInt());
+ }
+
+ public static int bitCountLongConstantSnippet() {
+ return Long.bitCount(LONG_CONSTANT_1) + Long.bitCount(LONG_CONSTANT_2) + Long.bitCount(LONG_CONSTANT_3);
+ }
+
+ public static int bitCountIntSnippet(int v) {
+ return Integer.bitCount(v & 0xFFFFFF | 0xFF);
+ }
+
+ @Test
+ public void testBitCountInt() {
+ ValueNode result = parseAndInline("bitCountIntSnippet");
+ Assert.assertEquals(StampFactory.forInteger(Kind.Int, 8, 24), result.stamp());
+ }
+
+ public static int bitCountIntEmptySnippet(int v) {
+ return Integer.bitCount(v & 0xFFFFFF);
+ }
+
+ @Test
+ public void testBitCountIntEmpty() {
+ ValueNode result = parseAndInline("bitCountIntEmptySnippet");
+ Assert.assertEquals(StampFactory.forInteger(Kind.Int, 0, 24), result.stamp());
+ }
+
+ @Test
+ public void testBitCountLongConstant() {
+ ValueNode result = parseAndInline("bitCountLongConstantSnippet");
+ Assert.assertEquals(7, result.asConstant().asInt());
+ }
+
+ public static int bitCountLongSnippet(long v) {
+ return Long.bitCount(v & 0xFFFFFFFFFFL | 0xFFL);
+ }
+
+ @Test
+ public void testBitCountLong() {
+ ValueNode result = parseAndInline("bitCountLongSnippet");
+ Assert.assertEquals(StampFactory.forInteger(Kind.Int, 8, 40), result.stamp());
+ }
+
+ public static int bitCountLongEmptySnippet(long v) {
+ return Long.bitCount(v & 0xFFFFFFFFFFL);
+ }
+
+ @Test
+ public void testBitCountLongEmpty() {
+ ValueNode result = parseAndInline("bitCountLongEmptySnippet");
+ Assert.assertEquals(StampFactory.forInteger(Kind.Int, 0, 40), result.stamp());
+ }
+
+ /*
+ * Tests for BitScanForwardNode
+ */
+
+ public static int scanForwardIntConstantSnippet() {
+ return Integer.numberOfTrailingZeros(INT_CONSTANT_1) + Integer.numberOfTrailingZeros(INT_CONSTANT_2) + Integer.numberOfTrailingZeros(INT_CONSTANT_3);
+ }
+
+ @Test
+ public void testScanForwardIntConstant() {
+ ValueNode result = parseAndInline("scanForwardIntConstantSnippet");
+ Assert.assertEquals(40, result.asConstant().asInt());
+ }
+
+ public static int scanForwardIntSnippet(int v) {
+ return Integer.numberOfTrailingZeros(v & 0xFFF0 | 0xFF00);
+ }
+
+ @Test
+ public void testScanForwardInt() {
+ ValueNode result = parseAndInline("scanForwardIntSnippet");
+ Assert.assertEquals(StampFactory.forInteger(Kind.Int, 4, 8), result.stamp());
+ }
+
+ public static int scanForwardLongConstantSnippet() {
+ return Long.numberOfTrailingZeros(LONG_CONSTANT_1) + Long.numberOfTrailingZeros(LONG_CONSTANT_2) + Long.numberOfTrailingZeros(LONG_CONSTANT_3);
+ }
+
+ @Test
+ public void testScanForwardLongConstant() {
+ ValueNode result = parseAndInline("scanForwardLongConstantSnippet");
+ Assert.assertEquals(72, result.asConstant().asInt());
+ }
+
+ public static int scanForwardLongSnippet(long v) {
+ return Long.numberOfTrailingZeros(v & 0xFFFF000000L | 0xFF00000000L);
+ }
+
+ @Test
+ public void testScanForwardLong() {
+ ValueNode result = parseAndInline("scanForwardLongSnippet");
+ Assert.assertEquals(StampFactory.forInteger(Kind.Int, 24, 32), result.stamp());
+ }
+
+ public static int scanForwardLongEmptySnippet(long v) {
+ int result = Long.numberOfTrailingZeros(v & 0xFFFF000000L);
+ dummyField = result;
+ return result;
+ }
+
+ @Test
+ public void testScanForwardLongEmpty() {
+ ValueNode result = parseAndInline("scanForwardLongEmptySnippet");
+ Assert.assertEquals(StampFactory.forInteger(Kind.Int, -1, 64), result.stamp());
+ }
+
+ /*
+ * Tests for BitScanReverseNode
+ */
+
+ public static int scanReverseIntConstantSnippet() {
+ return Integer.numberOfLeadingZeros(INT_CONSTANT_1) + Integer.numberOfLeadingZeros(INT_CONSTANT_2) + Integer.numberOfLeadingZeros(INT_CONSTANT_3);
+ }
+
+ @Test
+ public void testScanReverseIntConstant() {
+ ValueNode result = parseAndInline("scanReverseIntConstantSnippet");
+ Assert.assertEquals(47, result.asConstant().asInt());
+ }
+
+ public static int scanReverseIntSnippet(int v) {
+ return Integer.numberOfLeadingZeros(v & 0xFFF0 | 0xFF0);
+ }
+
+ @Test
+ public void testScanReverseInt() {
+ ValueNode result = parseAndInline("scanReverseIntSnippet");
+ Assert.assertEquals(StampFactory.forInteger(Kind.Int, 16, 20), result.stamp());
+ }
+
+ public static int scanReverseLongConstantSnippet() {
+ return Long.numberOfLeadingZeros(LONG_CONSTANT_1) + Long.numberOfLeadingZeros(LONG_CONSTANT_2) + Long.numberOfLeadingZeros(LONG_CONSTANT_3);
+ }
+
+ @Test
+ public void testScanReverseLongConstant() {
+ ValueNode result = parseAndInline("scanReverseLongConstantSnippet");
+ Assert.assertEquals(111, result.asConstant().asInt());
+ }
+
+ public static int scanReverseLongSnippet(long v) {
+ int result = Long.numberOfLeadingZeros(v & 0xFFF0);
+ dummyField = result;
+ return result;
+ }
+
+ @Test
+ public void testScanReverseLong() {
+ ValueNode result = parseAndInline("scanReverseLongSnippet");
+ Assert.assertEquals(StampFactory.forInteger(Kind.Int, 48, 64), result.stamp());
+ }
+
+ public static int scanReverseLongEmptySnippet(long v) {
+ int result = Long.numberOfLeadingZeros(v & 0xFFFF000000L);
+ dummyField = result;
+ return result;
+ }
+
+ @Test
+ public void testScanReverseLongEmpty() {
+ ValueNode result = parseAndInline("scanReverseLongEmptySnippet");
+ Assert.assertEquals(StampFactory.forInteger(Kind.Int, 24, 64), result.stamp());
+ }
+
+ private ValueNode parseAndInline(String name) {
+ StructuredGraph graph = parse(name);
+ HighTierContext context = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.NONE);
+ CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true);
+ canonicalizer.apply(graph, context);
+ new InliningPhase(canonicalizer).apply(graph, context);
+ canonicalizer.apply(graph, context);
+ Assert.assertEquals(1, graph.getNodes(ReturnNode.class).count());
+ return graph.getNodes(ReturnNode.class).first().result();
+ }
+}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/InstanceOfTest.java
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/InstanceOfTest.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/InstanceOfTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -50,7 +50,7 @@
protected void replaceProfile(StructuredGraph graph, JavaTypeProfile profile) {
InstanceOfNode ion = graph.getNodes().filter(InstanceOfNode.class).first();
if (ion != null) {
- InstanceOfNode ionNew = graph.unique(new InstanceOfNode(ion.type(), ion.object(), profile));
+ InstanceOfNode ionNew = graph.unique(new InstanceOfNode(ion.type(), ion.getValue(), profile));
graph.replaceFloating(ion, ionNew);
}
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -114,7 +114,7 @@
SignExtendNode convert = (SignExtendNode) location.getIndex();
Assert.assertEquals(convert.getInputBits(), 32);
Assert.assertEquals(convert.getResultBits(), 64);
- Assert.assertEquals(graph.getParameter(1), convert.getInput());
+ Assert.assertEquals(graph.getParameter(1), convert.getValue());
} else {
Assert.assertEquals(graph.getParameter(1), location.getIndex());
}
@@ -138,7 +138,7 @@
SignExtendNode convert = (SignExtendNode) location.getIndex();
Assert.assertEquals(convert.getInputBits(), 32);
Assert.assertEquals(convert.getResultBits(), 64);
- Assert.assertEquals(graph.getParameter(1), convert.getInput());
+ Assert.assertEquals(graph.getParameter(1), convert.getValue());
} else {
Assert.assertEquals(graph.getParameter(1), location.getIndex());
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -125,7 +125,7 @@
SignExtendNode convert = (SignExtendNode) location.getIndex();
Assert.assertEquals(convert.getInputBits(), 32);
Assert.assertEquals(convert.getResultBits(), 64);
- Assert.assertEquals(graph.getParameter(1), convert.getInput());
+ Assert.assertEquals(graph.getParameter(1), convert.getValue());
} else {
Assert.assertEquals(graph.getParameter(1), location.getIndex());
}
@@ -154,7 +154,7 @@
SignExtendNode convert = (SignExtendNode) location.getIndex();
Assert.assertEquals(convert.getInputBits(), 32);
Assert.assertEquals(convert.getResultBits(), 64);
- Assert.assertEquals(graph.getParameter(1), convert.getInput());
+ Assert.assertEquals(graph.getParameter(1), convert.getValue());
} else {
Assert.assertEquals(graph.getParameter(1), location.getIndex());
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/NodeIntrinsicVerifier.java
--- a/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/NodeIntrinsicVerifier.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/NodeIntrinsicVerifier.java Mon Jun 30 12:02:19 2014 +0200
@@ -124,6 +124,7 @@
private void findConstructor(TypeElement nodeClass, TypeMirror[] signature, ExecutableElement intrinsicMethod, AnnotationMirror intrinsicAnnotation) {
List constructors = ElementFilter.constructorsIn(nodeClass.getEnclosedElements());
+ List failureReasons = new ArrayList<>();
nextConstructor: for (ExecutableElement constructor : constructors) {
int sIdx = 0;
@@ -141,13 +142,16 @@
TypeMirror varargsType = ((ArrayType) paramType).getComponentType();
while (sIdx < signature.length) {
if (!isTypeCompatible(varargsType, signature[sIdx++])) {
+ failureReasons.add(String.format("Constructor %s failed because the types of argument %d are incompatible: %s != %s", constructor, sIdx, varargsType, signature[sIdx - 1]));
continue nextConstructor;
}
}
} else if (sIdx >= signature.length) {
// too many arguments in intrinsic method
+ failureReasons.add(String.format("Too many arguments for %s", constructor));
continue nextConstructor;
} else if (!isTypeCompatible(paramType, signature[sIdx++])) {
+ failureReasons.add(String.format("Constructor %s failed because the types of argument %d are incompatible: %s != %s", constructor, sIdx, paramType, signature[sIdx - 1]));
continue nextConstructor;
}
}
@@ -158,10 +162,17 @@
}
// too many arguments in constructor
+ failureReasons.add(String.format("Not enough arguments for %s", constructor));
}
// not found
- env.getMessager().printMessage(Kind.ERROR, "Could not find matching constructor for node intrinsic.", intrinsicMethod, intrinsicAnnotation);
+ if (failureReasons.isEmpty()) {
+ env.getMessager().printMessage(Kind.ERROR, "Could not find matching constructor for node intrinsic.", intrinsicMethod, intrinsicAnnotation);
+ } else {
+ for (String reason : failureReasons) {
+ env.getMessager().printMessage(Kind.ERROR, reason, intrinsicMethod, intrinsicAnnotation);
+ }
+ }
}
private boolean isTypeCompatible(TypeMirror originalType, TypeMirror substitutionType) {
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ArraySubstitutions.java
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ArraySubstitutions.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ArraySubstitutions.java Mon Jun 30 12:02:19 2014 +0200
@@ -34,6 +34,11 @@
@MethodSubstitution
public static Object newInstance(Class> componentType, int length) throws NegativeArraySizeException {
+ // The error cases must be handled here since DynamicNewArrayNode can only deoptimize the
+ // caller in response to exceptions.
+ if (componentType == void.class) {
+ throw new IllegalArgumentException();
+ }
return DynamicNewArrayNode.newArray(GuardingPiNode.guardingNonNull(componentType), length);
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CollapseFrameForSingleSideEffectPhase.java
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CollapseFrameForSingleSideEffectPhase.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CollapseFrameForSingleSideEffectPhase.java Mon Jun 30 12:02:19 2014 +0200
@@ -22,6 +22,8 @@
*/
package com.oracle.graal.replacements;
+import static com.oracle.graal.api.code.BytecodeFrame.*;
+
import java.util.*;
import com.oracle.graal.api.code.*;
@@ -129,15 +131,15 @@
FrameState frameState = stateSplit.stateAfter();
if (frameState != null) {
if (stateSplit.hasSideEffect()) {
- stateSplit.setStateAfter(createInvalidFrameState(node));
+ setStateAfter(node.graph(), stateSplit, INVALID_FRAMESTATE_BCI, false);
state = state.addSideEffect(stateSplit);
} else if (currentState.invalid) {
- stateSplit.setStateAfter(createInvalidFrameState(node));
+ setStateAfter(node.graph(), stateSplit, INVALID_FRAMESTATE_BCI, false);
} else {
stateSplit.setStateAfter(null);
- }
- if (frameState.usages().isEmpty()) {
- GraphUtil.killWithUnusedFloatingInputs(frameState);
+ if (frameState.usages().isEmpty()) {
+ GraphUtil.killWithUnusedFloatingInputs(frameState);
+ }
}
}
}
@@ -176,18 +178,14 @@
for (Node returnSideEffect : returnSideEffects) {
if (!unwindSideEffects.contains(returnSideEffect) && !maskedSideEffects.contains(returnSideEffect)) {
StateSplit split = (StateSplit) returnSideEffect;
- if (split.stateAfter() != null) {
- split.setStateAfter(graph.add(new FrameState(BytecodeFrame.AFTER_BCI)));
- }
+ setStateAfter(graph, split, AFTER_BCI, true);
}
}
for (Node unwindSideEffect : unwindSideEffects) {
if (!returnSideEffects.contains(unwindSideEffect) && !maskedSideEffects.contains(unwindSideEffect)) {
StateSplit split = (StateSplit) unwindSideEffect;
- if (split.stateAfter() != null) {
- split.setStateAfter(graph.add(new FrameState(BytecodeFrame.AFTER_EXCEPTION_BCI)));
- }
+ setStateAfter(graph, split, AFTER_EXCEPTION_BCI, true);
}
}
}
@@ -207,15 +205,34 @@
}
if (isNowInvalid) {
- loop.setStateAfter(createInvalidFrameState(loop));
+ setStateAfter(loop.graph(), loop, INVALID_FRAMESTATE_BCI, false);
}
IterationState endState = IterationState.merge(loop, info.endStates.values(), isNowInvalid);
return ReentrantNodeIterator.processLoop(this, loop, endState).exitStates;
}
- private static FrameState createInvalidFrameState(FixedNode node) {
- return node.graph().add(new FrameState(BytecodeFrame.INVALID_FRAMESTATE_BCI));
+ /**
+ * Creates and sets a special frame state for a node. If the existing frame state is
+ * non-null and has no other usages, it is deleted via
+ * {@link GraphUtil#killWithUnusedFloatingInputs(Node)}.
+ *
+ * @param graph the graph context
+ * @param node the node whose frame state is updated
+ * @param bci {@link BytecodeFrame#AFTER_BCI}, {@link BytecodeFrame#AFTER_EXCEPTION_BCI} or
+ * {@link BytecodeFrame#INVALID_FRAMESTATE_BCI}
+ * @param replaceOnly only perform the update if the node currently has a non-null frame
+ * state
+ */
+ private static void setStateAfter(StructuredGraph graph, StateSplit node, int bci, boolean replaceOnly) {
+ assert bci == AFTER_BCI || bci == AFTER_EXCEPTION_BCI || bci == INVALID_FRAMESTATE_BCI;
+ FrameState currentStateAfter = node.stateAfter();
+ if (currentStateAfter != null || !replaceOnly) {
+ node.setStateAfter(graph.add(new FrameState(bci)));
+ if (currentStateAfter != null && currentStateAfter.usages().isEmpty()) {
+ GraphUtil.killWithUnusedFloatingInputs(currentStateAfter);
+ }
+ }
}
}
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java Mon Jun 30 12:02:19 2014 +0200
@@ -109,7 +109,7 @@
StructuredGraph graph = loadField.graph();
ResolvedJavaField field = loadField.field();
ValueNode object = loadField.isStatic() ? staticFieldBase(graph, field) : loadField.object();
- Stamp loadStamp = loadStamp(loadField.stamp(), field.getKind(), true);
+ Stamp loadStamp = loadStamp(loadField.stamp(), field.getKind());
ConstantLocationNode location = createFieldLocation(graph, field, false);
assert location != null : "Field that is loaded must not be eliminated";
@@ -158,7 +158,7 @@
StructuredGraph graph = loadIndexed.graph();
Kind elementKind = loadIndexed.elementKind();
LocationNode location = createArrayLocation(graph, elementKind, loadIndexed.index(), false);
- Stamp loadStamp = loadStamp(loadIndexed.stamp(), elementKind, true);
+ Stamp loadStamp = loadStamp(loadIndexed.stamp(), elementKind);
ReadNode memoryRead = graph.add(new ReadNode(loadIndexed.array(), location, loadStamp, BarrierType.NONE));
ValueNode readValue = implicitLoadConvert(graph, elementKind, memoryRead);
@@ -223,7 +223,7 @@
if (graph.getGuardsStage().ordinal() < StructuredGraph.GuardsStage.FIXED_DEOPTS.ordinal()) {
return;
}
- ValueNode hub = createReadHub(graph, loadHub.object(), loadHub.getGuard());
+ ValueNode hub = createReadHub(graph, loadHub.getValue(), loadHub.getGuard());
graph.replaceFloating(loadHub, hub);
}
@@ -273,7 +273,7 @@
}
protected ReadNode createUnsafeRead(StructuredGraph graph, UnsafeLoadNode load, GuardingNode guard) {
- boolean compressible = (!load.object().isNullConstant() && load.accessKind() == Kind.Object);
+ boolean compressible = load.accessKind() == Kind.Object;
Kind readKind = load.accessKind();
LocationNode location = createLocation(load);
Stamp loadStamp = loadStamp(load.stamp(), readKind, compressible);
@@ -503,6 +503,10 @@
protected abstract LocationIdentity initLocationIdentity();
+ public Stamp loadStamp(Stamp stamp, Kind kind) {
+ return loadStamp(stamp, kind, true);
+ }
+
protected Stamp loadStamp(Stamp stamp, Kind kind, @SuppressWarnings("unused") boolean compressible) {
switch (kind) {
case Boolean:
@@ -580,21 +584,21 @@
SignExtendNode extend = (SignExtendNode) offset;
if (extend.getResultBits() == 64) {
signExtend = true;
- offset = extend.getInput();
+ offset = extend.getValue();
}
}
if (offset instanceof IntegerAddNode) {
IntegerAddNode integerAddNode = (IntegerAddNode) offset;
- if (integerAddNode.y() instanceof ConstantNode) {
- displacement = integerAddNode.y().asConstant().asLong();
- offset = integerAddNode.x();
+ if (integerAddNode.getY() instanceof ConstantNode) {
+ displacement = integerAddNode.getY().asConstant().asLong();
+ offset = integerAddNode.getX();
}
}
if (offset instanceof LeftShiftNode) {
LeftShiftNode leftShiftNode = (LeftShiftNode) offset;
- if (leftShiftNode.y() instanceof ConstantNode) {
- long shift = leftShiftNode.y().asConstant().asLong();
+ if (leftShiftNode.getY() instanceof ConstantNode) {
+ long shift = leftShiftNode.getY().asConstant().asLong();
if (shift >= 1 && shift <= 3) {
if (shift == 1) {
indexScaling = 2;
@@ -603,7 +607,7 @@
} else {
indexScaling = 8;
}
- offset = leftShiftNode.x();
+ offset = leftShiftNode.getX();
}
}
}
@@ -622,13 +626,15 @@
protected GuardingNode createBoundsCheck(AccessIndexedNode n, LoweringTool tool) {
StructuredGraph graph = n.graph();
ValueNode array = n.array();
- ValueNode arrayLength = readArrayLength(n.graph(), array, tool.getConstantReflection());
+ ValueNode arrayLength = readArrayLength(array, tool.getConstantReflection());
if (arrayLength == null) {
Stamp stamp = StampFactory.positiveInt();
ReadNode readArrayLength = graph.add(new ReadNode(array, ConstantLocationNode.create(ARRAY_LENGTH_LOCATION, Kind.Int, arrayLengthOffset(), graph), stamp, BarrierType.NONE));
graph.addBeforeFixed(n, readArrayLength);
readArrayLength.setGuard(createNullCheck(array, readArrayLength, tool));
arrayLength = readArrayLength;
+ } else {
+ arrayLength = arrayLength.isAlive() ? arrayLength : graph.addOrUniqueWithInputs(arrayLength);
}
if (arrayLength.isConstant() && n.index().isConstant()) {
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraphKit.java
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraphKit.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraphKit.java Mon Jun 30 12:02:19 2014 +0200
@@ -208,7 +208,7 @@
ResolvedJavaMethod method = ((MethodCallTargetNode) invoke.callTarget()).targetMethod();
ReplacementsImpl repl = new ReplacementsImpl(providers, snippetReflection, new Assumptions(false), providers.getCodeCache().getTarget());
StructuredGraph calleeGraph = repl.makeGraph(method, null, method, null, FrameStateProcessing.CollapseFrameForSingleSideEffect);
- InliningUtil.inline(invoke, calleeGraph, false);
+ InliningUtil.inline(invoke, calleeGraph, false, null);
}
protected void pushStructure(Structure structure) {
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java Mon Jun 30 12:02:19 2014 +0200
@@ -141,7 +141,7 @@
assert testValue.isConstant();
return LogicConstantNode.forBoolean(result.asConstant().equals(testValue.asConstant()), result.graph());
}
- if (condition == null || condition.y() != testValue) {
+ if (condition == null || condition.getY() != testValue) {
// Re-use previously generated condition if the trueValue for the test is the same
condition = createCompareNode(result.graph(), Condition.EQ, result, testValue);
}
@@ -208,7 +208,7 @@
}
@Override
- public void replace(ValueNode oldNode, ValueNode newNode, MemoryMapNode mmap) {
+ public void replace(ValueNode oldNode, ValueNode newNode, MemoryMap mmap) {
assert newNode instanceof PhiNode;
assert oldNode == instanceOf;
newNode.inferStamp();
@@ -234,19 +234,17 @@
public void replaceUsingInstantiation() {
ValueNode newValue = instantiation.asMaterialization(usage.graph(), trueValue, falseValue);
usage.replaceAtUsages(newValue);
- usage.clearInputs();
assert usage.usages().isEmpty();
GraphUtil.killWithUnusedFloatingInputs(usage);
}
@Override
- public void replace(ValueNode oldNode, ValueNode newNode, MemoryMapNode mmap) {
+ public void replace(ValueNode oldNode, ValueNode newNode, MemoryMap mmap) {
assert newNode instanceof PhiNode;
assert oldNode == instanceOf;
newNode.inferStamp();
instantiation.initialize(newNode, trueValue, falseValue);
usage.replaceAtUsages(newNode);
- usage.clearInputs();
assert usage.usages().isEmpty();
GraphUtil.killWithUnusedFloatingInputs(usage);
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/IntegerSubstitutions.java
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/IntegerSubstitutions.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/IntegerSubstitutions.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, 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
@@ -23,6 +23,7 @@
package com.oracle.graal.replacements;
import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.nodes.calc.*;
import com.oracle.graal.replacements.nodes.*;
@ClassSubstitution(Integer.class)
@@ -53,4 +54,14 @@
public static int bitCount(int i) {
return BitCountNode.bitCount(i);
}
+
+ @MethodSubstitution
+ public static int divideUnsigned(int dividend, int divisor) {
+ return UnsignedDivNode.unsignedDivide(dividend, divisor);
+ }
+
+ @MethodSubstitution
+ public static int remainderUnsigned(int dividend, int divisor) {
+ return UnsignedRemNode.unsignedRemainder(dividend, divisor);
+ }
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/LongSubstitutions.java
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/LongSubstitutions.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/LongSubstitutions.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, 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
@@ -23,6 +23,7 @@
package com.oracle.graal.replacements;
import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.nodes.calc.*;
import com.oracle.graal.replacements.nodes.*;
@ClassSubstitution(Long.class)
@@ -53,4 +54,14 @@
public static int bitCount(long i) {
return BitCountNode.bitCount(i);
}
+
+ @MethodSubstitution
+ public static long divideUnsigned(long dividend, long divisor) {
+ return UnsignedDivNode.unsignedDivide(dividend, divisor);
+ }
+
+ @MethodSubstitution
+ public static long remainderUnsigned(long dividend, long divisor) {
+ return UnsignedRemNode.unsignedRemainder(dividend, divisor);
+ }
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Mon Jun 30 12:02:19 2014 +0200
@@ -483,7 +483,10 @@
if (!SnippetTemplate.hasConstantParameter(method)) {
NodeIntrinsificationVerificationPhase.verify(graph);
}
+ int sideEffectCount = 0;
+ assert (sideEffectCount = graph.getNodes().filter(e -> e instanceof StateSplit && ((StateSplit) e).hasSideEffect()).count()) >= 0;
new ConvertDeoptimizeToGuardPhase().apply(graph);
+ assert sideEffectCount == graph.getNodes().filter(e -> e instanceof StateSplit && ((StateSplit) e).hasSideEffect()).count() : "deleted side effecting node";
switch (frameStateProcessing) {
case Removal:
@@ -586,7 +589,7 @@
if (isInlinable(substitutedMethod)) {
final StructuredGraph originalGraph = buildInitialGraph(substitutedMethod);
Mark mark = graph.getMark();
- InliningUtil.inline(callTarget.invoke(), originalGraph, true);
+ InliningUtil.inline(callTarget.invoke(), originalGraph, true, null);
for (MethodCallTargetNode inlinedCallTarget : graph.getNewNodes(mark).filter(MethodCallTargetNode.class)) {
if (doNotInline == null) {
doNotInline = new HashSet<>();
@@ -620,7 +623,7 @@
targetGraph = parseGraph(callee, policy, inliningDepth + 1);
}
Object beforeInlineData = beforeInline(callTarget, targetGraph);
- InliningUtil.inline(callTarget.invoke(), targetGraph, true);
+ InliningUtil.inline(callTarget.invoke(), targetGraph, true, null);
Debug.dump(graph, "after inlining %s", callee);
afterInline(graph, targetGraph, beforeInlineData);
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsUtil.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsUtil.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2014, 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.replacements;
+
+import com.oracle.graal.replacements.nodes.*;
+
+public class ReplacementsUtil {
+ private ReplacementsUtil() {
+ // empty
+ }
+
+ private static final boolean REPLACEMENTS_ASSERTIONS_ENABLED;
+
+ static {
+ boolean assertionsEnabled = false;
+ assert (assertionsEnabled = true) != false;
+ REPLACEMENTS_ASSERTIONS_ENABLED = assertionsEnabled;
+ }
+
+ /**
+ * Asserts that condition evaluates to true by the time compilation is finished. This is
+ * intended to be used within snippets or stubs, and will lead to a compile error if the
+ * assertion fails.
+ */
+ public static void staticAssert(boolean condition, String message) {
+ if (REPLACEMENTS_ASSERTIONS_ENABLED) {
+ AssertionNode.assertion(true, condition, message);
+ }
+ }
+
+ /**
+ * Asserts that condition evaluates to true at runtime. This is intended to be used within
+ * snippets or stubs, and will lead to a VM error if it fails.
+ */
+ public static void runtimeAssert(boolean condition, String message) {
+ if (REPLACEMENTS_ASSERTIONS_ENABLED) {
+ AssertionNode.assertion(false, condition, message);
+ }
+ }
+}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Mon Jun 30 12:02:19 2014 +0200
@@ -35,6 +35,7 @@
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
+import java.util.stream.*;
import com.oracle.graal.api.code.*;
import com.oracle.graal.api.meta.*;
@@ -364,7 +365,7 @@
}
public ValueNode length() {
- return ConstantNode.forInt(varargs.length, graph());
+ return ConstantNode.forInt(varargs.length);
}
}
@@ -618,6 +619,7 @@
Mark mark = snippetCopy.getMark();
LoopTransformations.fullUnroll(loop, phaseContext, new CanonicalizerPhase(true));
new CanonicalizerPhase(true).applyIncremental(snippetCopy, phaseContext, mark);
+ loop.deleteUnusedNodes();
}
GraphUtil.removeFixedWithUnusedInputs(explodeLoop);
exploded = true;
@@ -676,38 +678,33 @@
Debug.dump(snippet, "SnippetTemplate after fixing memory anchoring");
- List returnNodes = new ArrayList<>(4);
- List memMaps = new ArrayList<>(4);
StartNode entryPointNode = snippet.start();
- boolean anchorUsed = false;
- for (ReturnNode retNode : snippet.getNodes(ReturnNode.class)) {
- MemoryMapNode memMap = retNode.getMemoryMap();
- anchorUsed |= memMap.replaceLastLocationAccess(snippetCopy.start(), memoryAnchor);
- memMaps.add(memMap);
- retNode.setMemoryMap(null);
- returnNodes.add(retNode);
- if (memMap.usages().isEmpty()) {
- memMap.safeDelete();
- }
- }
- if (memoryAnchor.usages().isEmpty() && !anchorUsed) {
+ if (memoryAnchor.usages().isEmpty()) {
memoryAnchor.safeDelete();
} else {
snippetCopy.addAfterFixed(snippetCopy.start(), memoryAnchor);
}
- assert snippet.getNodes().filter(MemoryMapNode.class).isEmpty();
+ List returnNodes = snippet.getNodes(ReturnNode.class).snapshot();
if (returnNodes.isEmpty()) {
this.returnNode = null;
this.memoryMap = null;
} else if (returnNodes.size() == 1) {
this.returnNode = returnNodes.get(0);
- this.memoryMap = memMaps.get(0);
+ this.memoryMap = returnNode.getMemoryMap();
} else {
MergeNode merge = snippet.add(new MergeNode());
- ValueNode returnValue = InliningUtil.mergeReturns(merge, returnNodes);
+ List memMaps = returnNodes.stream().map(n -> n.getMemoryMap()).collect(Collectors.toList());
+ ValueNode returnValue = InliningUtil.mergeReturns(merge, returnNodes, null);
this.returnNode = snippet.add(new ReturnNode(returnValue));
- this.memoryMap = FloatingReadPhase.mergeMemoryMaps(merge, memMaps);
+ MemoryMapImpl mmap = FloatingReadPhase.mergeMemoryMaps(merge, memMaps);
+ this.memoryMap = snippet.unique(new MemoryMapNode(mmap.getMap()));
merge.setNext(this.returnNode);
+
+ for (MemoryMapNode mm : memMaps) {
+ if (mm.isAlive()) {
+ mm.safeDelete();
+ }
+ }
}
this.sideEffectNodes = curSideEffectNodes;
@@ -797,7 +794,7 @@
private final ArrayList nodes;
/**
- * map of killing locations to memory checkpoints (nodes).
+ * Map of killing locations to memory checkpoints (nodes).
*/
private final MemoryMapNode memoryMap;
@@ -896,7 +893,7 @@
/**
* Replaces all usages of {@code oldNode} with direct or indirect usages of {@code newNode}.
*/
- void replace(ValueNode oldNode, ValueNode newNode, MemoryMapNode mmap);
+ void replace(ValueNode oldNode, ValueNode newNode, MemoryMap mmap);
}
/**
@@ -918,7 +915,7 @@
}
@Override
- public void replace(ValueNode oldNode, ValueNode newNode, MemoryMapNode mmap) {
+ public void replace(ValueNode oldNode, ValueNode newNode, MemoryMap mmap) {
if (mmap != null) {
for (Node usage : oldNode.usages().snapshot()) {
LocationIdentity identity = getLocationIdentity(usage);
@@ -960,12 +957,12 @@
// no floating reads yet, ignore locations created while lowering
return true;
}
- if (memoryMap == null || ((MemoryMapImpl) memoryMap).isEmpty()) {
- // there're no kills in the snippet graph
+ if (memoryMap == null || memoryMap.isEmpty()) {
+ // there are no kills in the snippet graph
return true;
}
- Set kills = new HashSet<>(((MemoryMapImpl) memoryMap).getLocations());
+ Set kills = new HashSet<>(memoryMap.getLocations());
if (replacee instanceof MemoryCheckpoint.Single) {
// check if some node in snippet graph also kills the same location
@@ -1009,10 +1006,10 @@
return true;
}
- private class DuplicateMapper extends MemoryMapNode {
+ private class DuplicateMapper implements MemoryMap {
private final Map duplicates;
- @Input private StartNode replaceeStart;
+ private StartNode replaceeStart;
public DuplicateMapper(Map duplicates, StartNode replaceeStart) {
this.duplicates = duplicates;
@@ -1032,14 +1029,9 @@
}
@Override
- public Set getLocations() {
+ public Collection getLocations() {
return memoryMap.getLocations();
}
-
- @Override
- public boolean replaceLastLocationAccess(MemoryNode oldNode, MemoryNode newNode) {
- throw GraalInternalError.shouldNotReachHere();
- }
}
/**
@@ -1133,7 +1125,7 @@
if (returnNode != null && !(replacee instanceof ControlSinkNode)) {
ReturnNode returnDuplicate = (ReturnNode) duplicates.get(returnNode);
returnValue = returnDuplicate.result();
- MemoryMapNode mmap = new DuplicateMapper(duplicates, replaceeGraph.start());
+ MemoryMap mmap = new DuplicateMapper(duplicates, replaceeGraph.start());
if (returnValue == null && replacee.usages().isNotEmpty() && replacee instanceof MemoryCheckpoint) {
replacer.replace(replacee, null, mmap);
} else {
@@ -1147,14 +1139,11 @@
next = fwn.next();
fwn.setNext(null);
}
- returnDuplicate.clearInputs();
returnDuplicate.replaceAndDelete(next);
}
}
// Remove the replacee from its graph
- replacee.clearInputs();
- replacee.replaceAtUsages(null);
GraphUtil.killCFG(replacee);
Debug.dump(replaceeGraph, "After lowering %s with %s", replacee, this);
@@ -1241,7 +1230,6 @@
replacer.replace(replacee, returnValue, new DuplicateMapper(duplicates, replaceeGraph.start()));
if (returnDuplicate.isAlive()) {
- returnDuplicate.clearInputs();
returnDuplicate.replaceAndDelete(next);
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/UnsignedMathSubstitutions.java
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/UnsignedMathSubstitutions.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/UnsignedMathSubstitutions.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014, 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
@@ -26,10 +26,7 @@
import static com.oracle.graal.nodes.calc.ConditionalNode.*;
import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
import com.oracle.graal.api.replacements.*;
-import com.oracle.graal.graph.Node.ConstantNodeParameter;
-import com.oracle.graal.graph.Node.NodeIntrinsic;
import com.oracle.graal.nodes.calc.*;
/**
@@ -101,7 +98,7 @@
*/
@MethodSubstitution
public static int divide(int a, int b) {
- return unsignedDivide(Kind.Int, a, b);
+ return UnsignedDivNode.unsignedDivide(a, b);
}
/**
@@ -109,7 +106,7 @@
*/
@MethodSubstitution
public static int remainder(int a, int b) {
- return unsignedRemainder(Kind.Int, a, b);
+ return UnsignedRemNode.unsignedRemainder(a, b);
}
/**
@@ -117,7 +114,7 @@
*/
@MethodSubstitution
public static long divide(long a, long b) {
- return unsignedDivide(Kind.Long, a, b);
+ return UnsignedDivNode.unsignedDivide(a, b);
}
/**
@@ -125,18 +122,6 @@
*/
@MethodSubstitution
public static long remainder(long a, long b) {
- return unsignedRemainder(Kind.Long, a, b);
+ return UnsignedRemNode.unsignedRemainder(a, b);
}
-
- @NodeIntrinsic(UnsignedDivNode.class)
- private static native int unsignedDivide(@ConstantNodeParameter Kind kind, int a, int b);
-
- @NodeIntrinsic(UnsignedDivNode.class)
- private static native long unsignedDivide(@ConstantNodeParameter Kind kind, long a, long b);
-
- @NodeIntrinsic(UnsignedRemNode.class)
- private static native int unsignedRemainder(@ConstantNodeParameter Kind kind, int a, int b);
-
- @NodeIntrinsic(UnsignedRemNode.class)
- private static native long unsignedRemainder(@ConstantNodeParameter Kind kind, long a, long b);
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ArrayEqualsNode.java
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ArrayEqualsNode.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ArrayEqualsNode.java Mon Jun 30 12:02:19 2014 +0200
@@ -26,7 +26,6 @@
import com.oracle.graal.compiler.common.type.*;
import com.oracle.graal.graph.*;
import com.oracle.graal.graph.spi.*;
-import com.oracle.graal.lir.*;
import com.oracle.graal.nodes.*;
import com.oracle.graal.nodes.spi.*;
import com.oracle.graal.nodes.util.*;
@@ -67,7 +66,7 @@
return null;
}
if (GraphUtil.unproxify(array1) == GraphUtil.unproxify(array2)) {
- return ConstantNode.forBoolean(true, graph());
+ return ConstantNode.forBoolean(true);
}
return this;
}
@@ -130,8 +129,7 @@
@Override
public void generate(NodeLIRBuilderTool gen) {
- Variable result = gen.newVariable(Kind.Int);
- gen.emitArrayEquals(kind, result, gen.operand(array1), gen.operand(array2), gen.operand(length));
+ Value result = gen.getLIRGeneratorTool().emitArrayEquals(kind, gen.operand(array1), gen.operand(array2), gen.operand(length));
gen.setResult(this, result);
}
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/AssertionNode.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/AssertionNode.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2014, 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.replacements.nodes;
+
+import com.oracle.graal.compiler.common.*;
+import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+
+/**
+ * Assertion nodes will go away as soon as the value evaluates to true. Compile-time assertions will
+ * fail if this has not happened by the time the node is lowered to LIR, while runtime assertions
+ * may need to insert a check.
+ */
+public class AssertionNode extends FixedWithNextNode implements Lowerable, Canonicalizable, LIRLowerable {
+
+ @Input private ValueNode value;
+
+ private final boolean compileTimeAssertion;
+ private final String message;
+
+ public AssertionNode(boolean compileTimeAssertion, ValueNode value, String message) {
+ super(StampFactory.forVoid());
+ this.value = value;
+ this.compileTimeAssertion = compileTimeAssertion;
+ this.message = message;
+ }
+
+ public ValueNode value() {
+ return value;
+ }
+
+ public String message() {
+ return message;
+ }
+
+ @Override
+ public Node canonical(CanonicalizerTool tool) {
+ if (value.isConstant() && value.asConstant().asInt() != 0) {
+ return null;
+ }
+ return this;
+ }
+
+ public void lower(LoweringTool tool) {
+ if (!compileTimeAssertion) {
+ tool.getLowerer().lower(this, tool);
+ }
+ }
+
+ public void generate(NodeLIRBuilderTool generator) {
+ assert compileTimeAssertion;
+ if (value.isConstant() && value.asConstant().asInt() == 0) {
+ throw new GraalInternalError("failed compile-time assertion: %s", message);
+ } else {
+ throw new GraalInternalError("failed compile-time assertion (value %s): %s", value, message);
+ }
+ }
+
+ @SuppressWarnings("unused")
+ @NodeIntrinsic
+ public static void assertion(@ConstantNodeParameter boolean compileTimeAssertion, boolean value, @ConstantNodeParameter String message) {
+ assert value : message;
+ }
+}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitCountNode.java
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitCountNode.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitCountNode.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, 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
@@ -24,31 +24,31 @@
import com.oracle.graal.api.meta.*;
import com.oracle.graal.compiler.common.type.*;
-import com.oracle.graal.graph.*;
import com.oracle.graal.graph.spi.*;
-import com.oracle.graal.lir.*;
import com.oracle.graal.nodes.*;
import com.oracle.graal.nodes.calc.*;
import com.oracle.graal.nodes.spi.*;
-public class BitCountNode extends FloatingNode implements LIRLowerable, Canonicalizable {
-
- @Input private ValueNode value;
+public class BitCountNode extends UnaryNode implements LIRLowerable {
public BitCountNode(ValueNode value) {
- super(StampFactory.forInteger(Kind.Int, 0, ((PrimitiveStamp) value.stamp()).getBits()));
- this.value = value;
+ super(StampFactory.forInteger(Kind.Int, 0, ((PrimitiveStamp) value.stamp()).getBits()), value);
+ assert value.getKind() == Kind.Int || value.getKind() == Kind.Long;
}
@Override
- public Node canonical(CanonicalizerTool tool) {
- if (value.isConstant()) {
- Constant c = value.asConstant();
- if (c.getKind() == Kind.Int) {
- return ConstantNode.forInt(Integer.bitCount(c.asInt()), graph());
- } else if (c.getKind() == Kind.Long) {
- return ConstantNode.forInt(Long.bitCount(c.asLong()), graph());
- }
+ public boolean inferStamp() {
+ IntegerStamp valueStamp = (IntegerStamp) getValue().stamp();
+ assert (valueStamp.downMask() & IntegerStamp.defaultMask(valueStamp.getBits())) == valueStamp.downMask();
+ assert (valueStamp.upMask() & IntegerStamp.defaultMask(valueStamp.getBits())) == valueStamp.upMask();
+ return updateStamp(StampFactory.forInteger(Kind.Int, bitCount(valueStamp.downMask()), bitCount(valueStamp.upMask())));
+ }
+
+ @Override
+ public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
+ if (forValue.isConstant()) {
+ Constant c = forValue.asConstant();
+ return ConstantNode.forInt(forValue.getKind() == Kind.Int ? bitCount(c.asInt()) : bitCount(c.asLong()));
}
return this;
}
@@ -65,8 +65,7 @@
@Override
public void generate(NodeLIRBuilderTool gen) {
- Variable result = gen.newVariable(Kind.Int);
- gen.emitBitCount(result, gen.operand(value));
+ Value result = gen.getLIRGeneratorTool().emitBitCount(gen.operand(getValue()));
gen.setResult(this, result);
}
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java Mon Jun 30 12:02:19 2014 +0200
@@ -24,31 +24,46 @@
import com.oracle.graal.api.meta.*;
import com.oracle.graal.compiler.common.type.*;
-import com.oracle.graal.graph.*;
import com.oracle.graal.graph.spi.*;
-import com.oracle.graal.lir.*;
import com.oracle.graal.nodes.*;
import com.oracle.graal.nodes.calc.*;
import com.oracle.graal.nodes.spi.*;
-public class BitScanForwardNode extends FloatingNode implements LIRLowerable, Canonicalizable {
-
- @Input private ValueNode value;
+/**
+ * Determines the index of the least significant "1" bit. Note that the result is undefined if the
+ * input is zero.
+ */
+public class BitScanForwardNode extends UnaryNode implements LIRLowerable {
public BitScanForwardNode(ValueNode value) {
- super(StampFactory.forInteger(Kind.Int, 0, ((PrimitiveStamp) value.stamp()).getBits()));
- this.value = value;
+ super(StampFactory.forInteger(Kind.Int, 0, ((PrimitiveStamp) value.stamp()).getBits()), value);
+ assert value.getKind() == Kind.Int || value.getKind() == Kind.Long;
}
@Override
- public Node canonical(CanonicalizerTool tool) {
- if (value.isConstant()) {
- Constant c = value.asConstant();
- if (c.getKind() == Kind.Int) {
- return ConstantNode.forInt(Integer.numberOfTrailingZeros(c.asInt()), graph());
- } else if (c.getKind() == Kind.Long) {
- return ConstantNode.forInt(Long.numberOfTrailingZeros(c.asLong()), graph());
- }
+ public boolean inferStamp() {
+ IntegerStamp valueStamp = (IntegerStamp) getValue().stamp();
+ int min;
+ int max;
+ long mask = IntegerStamp.defaultMask(valueStamp.getBits());
+ int firstAlwaysSetBit = scan(valueStamp.downMask() & mask);
+ if (firstAlwaysSetBit == -1) {
+ int lastMaybeSetBit = BitScanReverseNode.scan(valueStamp.upMask() & mask);
+ min = -1;
+ max = lastMaybeSetBit;
+ } else {
+ int firstMaybeSetBit = scan(valueStamp.upMask() & mask);
+ min = firstMaybeSetBit;
+ max = firstAlwaysSetBit;
+ }
+ return updateStamp(StampFactory.forInteger(Kind.Int, min, max));
+ }
+
+ @Override
+ public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
+ if (forValue.isConstant()) {
+ Constant c = forValue.asConstant();
+ return ConstantNode.forInt(forValue.getKind() == Kind.Int ? scan(c.asInt()) : scan(c.asLong()));
}
return this;
}
@@ -72,8 +87,7 @@
@Override
public void generate(NodeLIRBuilderTool gen) {
- Variable result = gen.newVariable(Kind.Int);
- gen.emitBitScanForward(result, gen.operand(value));
+ Value result = gen.getLIRGeneratorTool().emitBitScanForward(gen.operand(getValue()));
gen.setResult(this, result);
}
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java Mon Jun 30 12:02:19 2014 +0200
@@ -24,31 +24,44 @@
import com.oracle.graal.api.meta.*;
import com.oracle.graal.compiler.common.type.*;
-import com.oracle.graal.graph.*;
import com.oracle.graal.graph.spi.*;
-import com.oracle.graal.lir.*;
import com.oracle.graal.nodes.*;
import com.oracle.graal.nodes.calc.*;
import com.oracle.graal.nodes.spi.*;
-public class BitScanReverseNode extends FloatingNode implements LIRLowerable, Canonicalizable {
-
- @Input private ValueNode value;
+/**
+ * Determines the index of the most significant "1" bit. Note that the result is undefined if the
+ * input is zero.
+ */
+public class BitScanReverseNode extends UnaryNode implements LIRLowerable {
public BitScanReverseNode(ValueNode value) {
- super(StampFactory.forInteger(Kind.Int, 0, ((PrimitiveStamp) value.stamp()).getBits()));
- this.value = value;
+ super(StampFactory.forInteger(Kind.Int, 0, ((PrimitiveStamp) value.stamp()).getBits()), value);
+ assert value.getKind() == Kind.Int || value.getKind() == Kind.Long;
}
@Override
- public Node canonical(CanonicalizerTool tool) {
- if (value.isConstant()) {
- Constant c = value.asConstant();
- if (c.getKind() == Kind.Int) {
- return ConstantNode.forInt(31 - Integer.numberOfLeadingZeros(c.asInt()), graph());
- } else if (c.getKind() == Kind.Long) {
- return ConstantNode.forInt(63 - Long.numberOfLeadingZeros(c.asLong()), graph());
- }
+ public boolean inferStamp() {
+ IntegerStamp valueStamp = (IntegerStamp) getValue().stamp();
+ int min;
+ int max;
+ long mask = IntegerStamp.defaultMask(valueStamp.getBits());
+ int lastAlwaysSetBit = scan(valueStamp.downMask() & mask);
+ if (lastAlwaysSetBit == -1) {
+ min = -1;
+ } else {
+ min = lastAlwaysSetBit;
+ }
+ int lastMaybeSetBit = scan(valueStamp.upMask() & mask);
+ max = lastMaybeSetBit;
+ return updateStamp(StampFactory.forInteger(Kind.Int, min, max));
+ }
+
+ @Override
+ public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
+ if (forValue.isConstant()) {
+ Constant c = forValue.asConstant();
+ return ConstantNode.forInt(forValue.getKind() == Kind.Int ? scan(c.asInt()) : scan(c.asLong()));
}
return this;
}
@@ -79,8 +92,7 @@
@Override
public void generate(NodeLIRBuilderTool gen) {
- Variable result = gen.newVariable(Kind.Int);
- gen.getLIRGeneratorTool().emitBitScanReverse(result, gen.operand(value));
+ Value result = gen.getLIRGeneratorTool().emitBitScanReverse(gen.operand(getValue()));
gen.setResult(this, result);
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectReadNode.java
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectReadNode.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectReadNode.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, 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
@@ -45,9 +45,14 @@
this.readKind = readKind;
}
+ protected ValueNode getAddress() {
+ return address;
+ }
+
@Override
public void generate(NodeLIRBuilderTool gen) {
- gen.setResult(this, gen.getLIRGeneratorTool().emitLoad(readKind, gen.operand(address), null));
+ LIRKind kind = gen.getLIRGeneratorTool().target().getLIRKind(readKind);
+ gen.setResult(this, gen.getLIRGeneratorTool().emitLoad(kind, gen.operand(address), null));
}
@SuppressWarnings("unchecked")
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectStoreNode.java
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectStoreNode.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectStoreNode.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, 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
@@ -50,7 +50,16 @@
@Override
public void generate(NodeLIRBuilderTool gen) {
Value v = gen.operand(value);
- gen.getLIRGeneratorTool().emitStore(kind, gen.operand(address), v, null);
+ LIRKind lirKind = gen.getLIRGeneratorTool().target().getLIRKind(kind);
+ gen.getLIRGeneratorTool().emitStore(lirKind, gen.operand(address), v, null);
+ }
+
+ protected ValueNode getAddress() {
+ return address;
+ }
+
+ protected ValueNode getValue() {
+ return value;
}
/*
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/LoadSnippetVarargParameterNode.java
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/LoadSnippetVarargParameterNode.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/LoadSnippetVarargParameterNode.java Mon Jun 30 12:02:19 2014 +0200
@@ -35,18 +35,18 @@
@Input private ValueNode index;
- private final ParameterNode[] parameters;
+ @Input private final NodeInputList parameters;
public LoadSnippetVarargParameterNode(ParameterNode[] locals, ValueNode index, Stamp stamp) {
super(stamp);
this.index = index;
- this.parameters = locals;
+ this.parameters = new NodeInputList<>(this, locals);
}
@Override
public Node canonical(CanonicalizerTool tool) {
if (index.isConstant()) {
- return parameters[index.asConstant().asInt()];
+ return parameters.get(index.asConstant().asInt());
}
return this;
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java Mon Jun 30 12:02:19 2014 +0200
@@ -142,7 +142,7 @@
((Lowerable) nonNullReceiver).lower(tool);
}
}
- InliningUtil.inline(invoke, replacementGraph, false);
+ InliningUtil.inline(invoke, replacementGraph, false, null);
Debug.dump(graph(), "After inlining replacement %s", replacementGraph);
} else {
invoke.lower(tool);
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, 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
@@ -25,16 +25,14 @@
import com.oracle.graal.api.meta.*;
import com.oracle.graal.compiler.common.*;
import com.oracle.graal.compiler.common.type.*;
-import com.oracle.graal.graph.*;
import com.oracle.graal.graph.spi.*;
import com.oracle.graal.lir.gen.*;
import com.oracle.graal.nodes.*;
import com.oracle.graal.nodes.calc.*;
import com.oracle.graal.nodes.spi.*;
-public class MathIntrinsicNode extends FloatingNode implements Canonicalizable, ArithmeticLIRLowerable {
+public class MathIntrinsicNode extends UnaryNode implements ArithmeticLIRLowerable {
- @Input private ValueNode x;
private final Operation operation;
public enum Operation {
@@ -47,24 +45,19 @@
TAN
}
- public ValueNode x() {
- return x;
- }
-
public Operation operation() {
return operation;
}
- public MathIntrinsicNode(ValueNode x, Operation op) {
- super(StampFactory.forKind(Kind.Double));
- assert x.stamp() instanceof FloatStamp && PrimitiveStamp.getBits(x.stamp()) == 64;
- this.x = x;
+ public MathIntrinsicNode(ValueNode value, Operation op) {
+ super(StampFactory.forKind(Kind.Double), value);
+ assert value.stamp() instanceof FloatStamp && PrimitiveStamp.getBits(value.stamp()) == 64;
this.operation = op;
}
@Override
public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
- Value input = builder.operand(x());
+ Value input = builder.operand(getValue());
Value result;
switch (operation()) {
case ABS:
@@ -100,9 +93,9 @@
}
@Override
- public Node canonical(CanonicalizerTool tool) {
- if (x().isConstant()) {
- return ConstantNode.forPrimitive(evalConst(x().asConstant()), graph());
+ public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
+ if (forValue.isConstant()) {
+ return ConstantNode.forPrimitive(evalConst(forValue.asConstant()));
}
return this;
}
@@ -112,7 +105,7 @@
return doCompute(value, op);
}
- private static double doCompute(double value, Operation op) throws GraalInternalError {
+ private static double doCompute(double value, Operation op) {
switch (op) {
case ABS:
return Math.abs(value);
@@ -128,7 +121,8 @@
return Math.cos(value);
case TAN:
return Math.tan(value);
+ default:
+ throw new GraalInternalError("unknown op %s", op);
}
- throw new GraalInternalError("unknown op %s", op);
}
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/PureFunctionMacroNode.java
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/PureFunctionMacroNode.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/PureFunctionMacroNode.java Mon Jun 30 12:02:19 2014 +0200
@@ -52,7 +52,7 @@
if (param.isConstant()) {
Constant constant = evaluate(param.asConstant(), tool.getMetaAccess());
if (constant != null) {
- return ConstantNode.forConstant(constant, tool.getMetaAccess(), graph());
+ return ConstantNode.forConstant(constant, tool.getMetaAccess());
}
}
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReadRegisterNode.java
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReadRegisterNode.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReadRegisterNode.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, 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
@@ -75,7 +75,8 @@
@Override
public void generate(NodeLIRBuilderTool generator) {
- Value result = register.asValue(getKind());
+ LIRKind kind = generator.getLIRGeneratorTool().getLIRKind(stamp());
+ Value result = register.asValue(kind);
if (incoming) {
generator.getLIRGeneratorTool().emitIncomingValues(new Value[]{result});
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReverseBytesNode.java
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReverseBytesNode.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReverseBytesNode.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, 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
@@ -24,32 +24,39 @@
import com.oracle.graal.api.meta.*;
import com.oracle.graal.compiler.common.type.*;
-import com.oracle.graal.graph.*;
import com.oracle.graal.graph.spi.*;
-import com.oracle.graal.lir.*;
import com.oracle.graal.nodes.*;
import com.oracle.graal.nodes.calc.*;
import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
-public class ReverseBytesNode extends FloatingNode implements LIRLowerable, Canonicalizable {
-
- @Input private ValueNode value;
+public class ReverseBytesNode extends UnaryNode implements LIRLowerable {
public ReverseBytesNode(ValueNode value) {
- super(StampFactory.forKind(value.getKind()));
- assert getKind().isNumericInteger();
- this.value = value;
+ super(StampFactory.forKind(value.getKind()), value);
+ assert getKind() == Kind.Int || getKind() == Kind.Long;
}
@Override
- public Node canonical(CanonicalizerTool tool) {
- if (value.isConstant()) {
- long v = value.asConstant().asLong();
- if (getKind().getStackKind() == Kind.Int) {
- return ConstantNode.forInt(Integer.reverseBytes((int) v), graph());
- } else if (getKind() == Kind.Long) {
- return ConstantNode.forLong(Long.reverseBytes(v), graph());
- }
+ public boolean inferStamp() {
+ IntegerStamp valueStamp = (IntegerStamp) getValue().stamp();
+ Stamp newStamp;
+ if (getKind() == Kind.Int) {
+ long mask = IntegerStamp.defaultMask(Kind.Int.getBitCount());
+ newStamp = StampTool.stampForMask(valueStamp.getBits(), reverse((int) valueStamp.downMask()) & mask, reverse((int) valueStamp.upMask()) & mask);
+ } else if (getKind() == Kind.Long) {
+ newStamp = StampTool.stampForMask(valueStamp.getBits(), reverse(valueStamp.downMask()), reverse(valueStamp.upMask()));
+ } else {
+ return false;
+ }
+ return updateStamp(newStamp);
+ }
+
+ @Override
+ public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
+ if (forValue.isConstant()) {
+ Constant c = forValue.asConstant();
+ return ConstantNode.forIntegerKind(getKind(), getKind() == Kind.Int ? reverse(c.asInt()) : reverse(c.asLong()));
}
return this;
}
@@ -66,8 +73,7 @@
@Override
public void generate(NodeLIRBuilderTool gen) {
- Variable result = gen.newVariable(value.getKind());
- gen.getLIRGeneratorTool().emitByteSwap(result, gen.operand(value));
+ Value result = gen.getLIRGeneratorTool().emitByteSwap(gen.operand(getValue()));
gen.setResult(this, result);
}
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/WriteRegisterNode.java
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/WriteRegisterNode.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/WriteRegisterNode.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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
@@ -54,7 +54,7 @@
@Override
public void generate(NodeLIRBuilderTool generator) {
Value val = generator.operand(value);
- generator.getLIRGeneratorTool().emitMove(register.asValue(val.getKind()), val);
+ generator.getLIRGeneratorTool().emitMove(register.asValue(val.getLIRKind()), val);
}
@Override
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java
--- a/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java Mon Jun 30 12:02:19 2014 +0200
@@ -36,7 +36,6 @@
public class SPARC extends Architecture {
public static final RegisterCategory CPU = new RegisterCategory("CPU");
- public static final RegisterCategory FPU = new RegisterCategory("FPU");
// General purpose registers
public static final Register r0 = new Register(0, 0, "g0", CPU);
@@ -123,6 +122,8 @@
};
// @formatter:on
+ public static final RegisterCategory FPU = new RegisterCategory("FPU", cpuRegisters.length);
+
// Floating point registers
public static final Register f0 = new Register(32, 0, "f0", FPU);
public static final Register f1 = new Register(33, 1, "f1", FPU);
@@ -194,12 +195,12 @@
}
@Override
- public boolean canStoreValue(RegisterCategory category, PlatformKind platformKind) {
- if (!(platformKind instanceof Kind)) {
+ public boolean canStoreValue(RegisterCategory category, PlatformKind lirKind) {
+ if (!(lirKind instanceof Kind)) {
return false;
}
- Kind kind = (Kind) platformKind;
+ Kind kind = (Kind) lirKind;
if (category == CPU) {
switch (kind) {
case Boolean:
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Mon Jun 30 12:02:19 2014 +0200
@@ -246,9 +246,7 @@
@SlowPath
public Iterable getStackTrace() {
- if (stackIntrospection == null) {
- stackIntrospection = Graal.getRequiredCapability(StackIntrospection.class);
- }
+ initStackIntrospection();
final Iterator frames = stackIntrospection.getStackTrace(anyFrameMethod, anyFrameMethod, 1).iterator();
class FrameIterator implements Iterator {
@@ -276,10 +274,15 @@
};
}
- public FrameInstance getCurrentFrame() {
+ private void initStackIntrospection() {
if (stackIntrospection == null) {
stackIntrospection = Graal.getRequiredCapability(StackIntrospection.class);
}
+ }
+
+ @SlowPath
+ public FrameInstance getCurrentFrame() {
+ initStackIntrospection();
Iterator frames = stackIntrospection.getStackTrace(callTargetMethod, callTargetMethod, 0).iterator();
if (frames.hasNext()) {
return new HotSpotFrameInstance.CallTargetFrame(frames.next(), true);
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -120,6 +120,7 @@
}
}
}
+ loopsData.deleteUnusedNodes();
} while (unrolled);
}
@@ -138,7 +139,7 @@
@Override
public int compare(LoopEx o1, LoopEx o2) {
- return o2.lirLoop().getDepth() - o1.lirLoop().getDepth();
+ return o2.loop().getDepth() - o1.loop().getDepth();
}
});
return sortedLoops;
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultInliningPolicy.java
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultInliningPolicy.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultInliningPolicy.java Mon Jun 30 12:02:19 2014 +0200
@@ -34,9 +34,8 @@
return profile.getFrequency() / profile.getDeepNodeCount();
}
- public boolean isAllowed(TruffleInliningProfile profile, int currentBudgetLeft) {
+ public boolean isAllowed(TruffleInliningProfile profile, int currentNodeCount) {
if (profile.isRecursiveCall()) {
- // recursive call found
profile.setFailedReason(REASON_RECURSION);
return false;
}
@@ -45,7 +44,7 @@
return true;
}
- if (currentBudgetLeft - profile.getDeepNodeCount() < 0) {
+ if (currentNodeCount + profile.getDeepNodeCount() > TruffleInliningMaxCallerSize.getValue()) {
profile.setFailedReason(REASON_MAXIMUM_TOTAL_NODE_COUNT);
return false;
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Mon Jun 30 12:02:19 2014 +0200
@@ -121,6 +121,7 @@
@Override
public void invalidate() {
this.runtime.invalidateInstalledCode(this);
+ invalidateInlining();
}
protected void invalidate(Node oldNode, Node newNode, CharSequence reason) {
@@ -133,6 +134,23 @@
cancelInstalledTask(oldNode, newNode, reason);
}
+ public void invalidateInlining() {
+ if (inliningPerformed) {
+ inliningPerformed = false;
+ getRootNode().accept(new NodeVisitor() {
+ public boolean visit(Node node) {
+ if (node instanceof OptimizedDirectCallNode) {
+ OptimizedDirectCallNode callNode = (OptimizedDirectCallNode) node;
+ if (callNode.isInlined()) {
+ callNode.resetInlining();
+ }
+ }
+ return true;
+ }
+ });
+ }
+ }
+
private void cancelInstalledTask(Node oldNode, Node newNode, CharSequence reason) {
if (this.runtime.cancelInstalledTask(this)) {
logOptimizingUnqueued(this, oldNode, newNode, reason);
@@ -242,19 +260,19 @@
return;
}
TruffleInliningHandler handler = new TruffleInliningHandler(new DefaultInliningPolicy());
- TruffleInliningResult result = handler.decideInlining(this, 0);
+ TruffleInliningDecision result = handler.decideInlining(this, 0);
performInlining(result);
logInliningDecision(result);
}
- private static void performInlining(TruffleInliningResult result) {
+ private static void performInlining(TruffleInliningDecision result) {
if (result.getCallTarget().inliningPerformed) {
return;
}
result.getCallTarget().inliningPerformed = true;
for (TruffleInliningProfile profile : result) {
profile.getCallNode().inline();
- TruffleInliningResult recursiveResult = profile.getRecursiveResult();
+ TruffleInliningDecision recursiveResult = profile.getRecursiveResult();
if (recursiveResult != null) {
performInlining(recursiveResult);
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetLog.java
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetLog.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetLog.java Mon Jun 30 12:02:19 2014 +0200
@@ -53,7 +53,7 @@
private OptimizedCallTargetLog() {
}
- public static void logInliningDecision(TruffleInliningResult result) {
+ public static void logInliningDecision(TruffleInliningDecision result) {
if (!TraceTruffleInlining.getValue()) {
return;
}
@@ -63,7 +63,7 @@
logInliningDone(result.getCallTarget());
}
- private static void logInliningDecisionRecursive(TruffleInliningResult result, int depth) {
+ private static void logInliningDecisionRecursive(TruffleInliningDecision result, int depth) {
List callNodes = searchCallNodes(result.getCallTarget());
for (OptimizedDirectCallNode callNode : callNodes) {
TruffleInliningProfile profile = result.getProfiles().get(callNode);
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedDirectCallNode.java
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedDirectCallNode.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedDirectCallNode.java Mon Jun 30 12:02:19 2014 +0200
@@ -72,6 +72,14 @@
}
}
+ public void resetInlining() {
+ CompilerAsserts.neverPartOfCompilation();
+ if (inlined) {
+ inlined = false;
+ getCurrentCallTarget().invalidateInlining();
+ }
+ }
+
@Override
public boolean isInlinable() {
return true;
@@ -219,4 +227,5 @@
public static OptimizedDirectCallNode create(OptimizedCallTarget target) {
return new OptimizedDirectCallNode(target);
}
+
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Mon Jun 30 12:02:19 2014 +0200
@@ -214,7 +214,7 @@
expansionLogger.preExpand(methodCallTargetNode, inlineGraph);
}
List canonicalizedNodes = methodCallTargetNode.invoke().asNode().usages().snapshot();
- Map inlined = InliningUtil.inline(methodCallTargetNode.invoke(), inlineGraph, false);
+ Map inlined = InliningUtil.inline(methodCallTargetNode.invoke(), inlineGraph, false, canonicalizedNodes);
if (TraceTruffleExpansion.getValue()) {
expansionLogger.postExpand(inlined);
}
@@ -280,6 +280,7 @@
break;
}
}
+ loopsData.deleteUnusedNodes();
} while (unrolled);
} catch (Throwable e) {
throw Debug.handle(e);
@@ -297,7 +298,7 @@
@Override
public int compare(LoopEx o1, LoopEx o2) {
- return o2.lirLoop().getDepth() - o1.lirLoop().getDepth();
+ return o2.loop().getDepth() - o1.loop().getDepth();
}
});
return sortedLoops;
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java Mon Jun 30 12:02:19 2014 +0200
@@ -49,7 +49,7 @@
loadFieldNode.field().getAnnotation(CompilerDirectives.CompilationFinal.class) != null) {
Constant constant = loadFieldNode.field().readValue(loadFieldNode.object().asConstant());
assert verifyFieldValue(loadFieldNode.field(), constant);
- return ConstantNode.forConstant(constant, metaAccess, loadFieldNode.graph());
+ return ConstantNode.forConstant(constant, metaAccess);
}
}
} else if (node instanceof LoadIndexedNode) {
@@ -59,7 +59,7 @@
Constant constant = constantReflection.readArrayElement(loadIndexedNode.array().asConstant(), index);
if (constant != null) {
- return ConstantNode.forConstant(constant, metaAccess, loadIndexedNode.graph());
+ return ConstantNode.forConstant(constant, metaAccess);
}
}
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java Mon Jun 30 12:02:19 2014 +0200
@@ -64,7 +64,12 @@
private final HashMap, StructuredGraph> cache = new HashMap<>();
private final HashMap, Long> lastUsed = new HashMap<>();
private final StructuredGraph markerGraph = new StructuredGraph();
+
private final ResolvedJavaType stringBuilderClass;
+ private final ResolvedJavaType runtimeExceptionClass;
+ private final ResolvedJavaType assertionErrorClass;
+ private final ResolvedJavaType controlFlowExceptionClass;
+
private final ResolvedJavaMethod callBoundaryMethod;
private long counter;
@@ -73,7 +78,12 @@
this.config = config;
this.configForRootGraph = configForRootGraph;
this.optimisticOptimizations = optimisticOptimizations;
+
this.stringBuilderClass = providers.getMetaAccess().lookupJavaType(StringBuilder.class);
+ this.runtimeExceptionClass = providers.getMetaAccess().lookupJavaType(RuntimeException.class);
+ this.assertionErrorClass = providers.getMetaAccess().lookupJavaType(AssertionError.class);
+ this.controlFlowExceptionClass = providers.getMetaAccess().lookupJavaType(ControlFlowException.class);
+
try {
callBoundaryMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallTarget.class.getDeclaredMethod("callRoot", Object[].class));
} catch (NoSuchMethodException ex) {
@@ -244,15 +254,17 @@
", must annotate such calls with @CompilerDirectives.SlowPath!"));
}
Invoke invoke = methodCallTargetNode.invoke();
- InliningUtil.inline(invoke, inlineGraph, true);
+ InliningUtil.inline(invoke, inlineGraph, true, null);
}
private boolean tryCutOffRuntimeExceptions(MethodCallTargetNode methodCallTargetNode) {
if (methodCallTargetNode.targetMethod().isConstructor()) {
- ResolvedJavaType runtimeException = providers.getMetaAccess().lookupJavaType(RuntimeException.class);
- ResolvedJavaType controlFlowException = providers.getMetaAccess().lookupJavaType(ControlFlowException.class);
+ ResolvedJavaType declaringClass = methodCallTargetNode.targetMethod().getDeclaringClass();
ResolvedJavaType exceptionType = Objects.requireNonNull(StampTool.typeOrNull(methodCallTargetNode.receiver().stamp()));
- if (runtimeException.isAssignableFrom(methodCallTargetNode.targetMethod().getDeclaringClass()) && !controlFlowException.isAssignableFrom(exceptionType)) {
+
+ boolean removeAllocation = runtimeExceptionClass.isAssignableFrom(declaringClass) || assertionErrorClass.isAssignableFrom(declaringClass);
+ boolean isCFGException = controlFlowExceptionClass.isAssignableFrom(exceptionType);
+ if (removeAllocation && !isCFGException) {
DeoptimizeNode deoptNode = methodCallTargetNode.graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.UnreachedCode));
FixedNode invokeNode = methodCallTargetNode.invoke().asNode();
invokeNode.replaceAtPredecessor(deoptNode);
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Mon Jun 30 12:02:19 2014 +0200
@@ -50,6 +50,7 @@
import com.oracle.graal.truffle.nodes.*;
import com.oracle.truffle.api.*;
import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.api.source.*;
/**
* Implementation of the Truffle compiler using Graal.
@@ -110,8 +111,11 @@
public void compileMethodImpl(final OptimizedCallTarget compilable) {
final StructuredGraph graph;
- if (TraceTruffleCompilation.getValue()) {
+ if (TraceTruffleCompilation.getValue() || TraceTruffleCompilationAST.getValue()) {
OptimizedCallTargetLog.logOptimizingStart(compilable);
+ if (TraceTruffleCompilationAST.getValue()) {
+ NodeUtil.printCompactTree(OptimizedCallTarget.OUT, compilable.getRootNode());
+ }
}
long timeCompilationStarted = System.nanoTime();
@@ -150,7 +154,7 @@
}
private static String formatSourceSection(SourceSection sourceSection) {
- return sourceSection != null ? sourceSection.toString() : "n/a";
+ return sourceSection != null ? sourceSection.getShortDescription() : "n/a";
}
public CompilationResult compileMethodHelper(StructuredGraph graph, Assumptions assumptions, String name, SpeculationLog speculationLog, InstalledCode predefinedInstalledCode) {
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java Mon Jun 30 12:02:19 2014 +0200
@@ -87,6 +87,8 @@
public static final OptionValue TraceTruffleCompilationHistogram = new OptionValue<>(false);
@Option(help = "Prints out all polymorphic and generic nodes after compilation.")
public static final OptionValue TraceTruffleCompilationPolymorphism = new OptionValue<>(false);
+ @Option(help = "Prints out all polymorphic and generic nodes after compilation.")
+ public static final OptionValue TraceTruffleCompilationAST = new OptionValue<>(false);
@Option(help = "")
public static final OptionValue TraceTruffleExpansion = new OptionValue<>(false);
@Option(help = "")
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleExpansionLogger.java
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleExpansionLogger.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleExpansionLogger.java Mon Jun 30 12:02:19 2014 +0200
@@ -50,7 +50,7 @@
int sourceMethodBci = callTarget.invoke().bci();
ResolvedJavaMethod targetMethod = callTarget.targetMethod();
ResolvedJavaType targetReceiverType = null;
- if (!sourceMethod.isStatic() && callTarget.receiver().isConstant()) {
+ if (!sourceMethod.isStatic() && callTarget.receiver() != null && callTarget.receiver().isConstant()) {
targetReceiverType = providers.getMetaAccess().lookupJavaType(callTarget.arguments().first().asConstant());
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningDecision.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningDecision.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2013, 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.truffle;
+
+import java.util.*;
+
+public final class TruffleInliningDecision implements Iterable {
+
+ private final OptimizedCallTarget callTarget;
+ private final Map profiles;
+ private final Set inlined;
+ private final int nodeCount;
+
+ public TruffleInliningDecision(OptimizedCallTarget callTarget, List profiles, Set inlined, int nodeCount) {
+ this.callTarget = callTarget;
+ this.profiles = new HashMap<>();
+ for (TruffleInliningProfile profile : profiles) {
+ this.profiles.put(profile.getCallNode(), profile);
+ }
+ this.nodeCount = nodeCount;
+ this.inlined = inlined;
+ }
+
+ public Map getProfiles() {
+ return profiles;
+ }
+
+ public int getNodeCount() {
+ return nodeCount;
+ }
+
+ public OptimizedCallTarget getCallTarget() {
+ return callTarget;
+ }
+
+ public boolean isInlined(OptimizedDirectCallNode path) {
+ return inlined.contains(profiles.get(path));
+ }
+
+ public int size() {
+ return inlined.size();
+ }
+
+ public Iterator iterator() {
+ return Collections.unmodifiableSet(inlined).iterator();
+ }
+
+ @Override
+ public String toString() {
+ return inlined.toString();
+ }
+}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningHandler.java
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningHandler.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningHandler.java Mon Jun 30 12:02:19 2014 +0200
@@ -31,68 +31,62 @@
private static final int MAXIMUM_RECURSIVE_DEPTH = 15;
private static final ProfileScoreComparator INLINING_SCORE = new ProfileScoreComparator();
private final TruffleInliningPolicy policy;
- private final Map resultCache;
+ private final Map resultCache;
public TruffleInliningHandler(TruffleInliningPolicy policy) {
this.policy = policy;
this.resultCache = new HashMap<>();
}
- public TruffleInliningResult decideInlining(OptimizedCallTarget target, int depth) {
+ public TruffleInliningDecision decideInlining(OptimizedCallTarget target, int depth) {
if (resultCache.containsKey(target)) {
return resultCache.get(target);
}
- resultCache.put(target, null);
- TruffleInliningResult result = decideInliningImpl(target, depth);
+ resultCache.put(target, null); // important for recursion detection
+ TruffleInliningDecision result = createInliningDecision(target, depth);
resultCache.put(target, result);
return result;
}
- private TruffleInliningResult decideInliningImpl(OptimizedCallTarget target, int depth) {
- List profiles = lookupProfiles(target, depth);
+ private TruffleInliningDecision createInliningDecision(OptimizedCallTarget target, int depth) {
+ List profiles = createProfiles(target, depth);
Set inlined = new HashSet<>();
Collections.sort(profiles, INLINING_SCORE);
- int budget = TruffleCompilerOptions.TruffleInliningMaxCallerSize.getValue() - OptimizedCallUtils.countNonTrivialNodes(target, true);
+ int deepNodeCount = OptimizedCallUtils.countNonTrivialNodes(target, true);
int index = 0;
+
for (TruffleInliningProfile profile : profiles) {
profile.setQueryIndex(index++);
- if (policy.isAllowed(profile, budget)) {
+ if (policy.isAllowed(profile, deepNodeCount)) {
inlined.add(profile);
- budget -= profile.getDeepNodeCount();
+ deepNodeCount += profile.getDeepNodeCount();
}
}
- int deepNodeCount = TruffleCompilerOptions.TruffleInliningMaxCallerSize.getValue() - budget;
- return new TruffleInliningResult(target, profiles, inlined, deepNodeCount);
+ return new TruffleInliningDecision(target, profiles, inlined, deepNodeCount);
}
- private List lookupProfiles(final OptimizedCallTarget target, int depth) {
- final List callNodes = new ArrayList<>();
+ private List createProfiles(final OptimizedCallTarget target, final int depth) {
+ final List profiles = new ArrayList<>();
target.getRootNode().accept(new NodeVisitor() {
public boolean visit(Node node) {
if (node instanceof OptimizedDirectCallNode) {
- callNodes.add((OptimizedDirectCallNode) node);
+ profiles.add(createProfile(target, (OptimizedDirectCallNode) node, depth));
}
return true;
}
});
- final List profiles = new ArrayList<>();
- for (OptimizedDirectCallNode callNode : callNodes) {
- profiles.add(lookupProfile(target, callNode, depth));
- }
return profiles;
}
- public TruffleInliningProfile lookupProfile(OptimizedCallTarget parentTarget, OptimizedDirectCallNode ocn, int depth) {
+ public TruffleInliningProfile createProfile(OptimizedCallTarget parentTarget, OptimizedDirectCallNode ocn, int depth) {
OptimizedCallTarget target = ocn.getCurrentCallTarget();
- int callSites = ocn.getCurrentCallTarget().getKnownCallSiteCount();
int nodeCount = OptimizedCallUtils.countNonTrivialNodes(target, false);
double frequency = calculateFrequency(parentTarget, ocn);
- boolean forced = ocn.isInliningForced();
int deepNodeCount;
- TruffleInliningResult recursiveResult;
+ TruffleInliningDecision recursiveResult;
boolean recursiveCall = false;
if (target.inliningPerformed || depth > MAXIMUM_RECURSIVE_DEPTH) {
deepNodeCount = OptimizedCallUtils.countNonTrivialNodes(target, true);
@@ -107,7 +101,7 @@
}
}
- TruffleInliningProfile profile = new TruffleInliningProfile(ocn, callSites, nodeCount, deepNodeCount, frequency, forced, recursiveCall, recursiveResult);
+ TruffleInliningProfile profile = new TruffleInliningProfile(ocn, nodeCount, deepNodeCount, frequency, recursiveCall, recursiveResult);
profile.setScore(policy.calculateScore(profile));
return profile;
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningPolicy.java
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningPolicy.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningPolicy.java Mon Jun 30 12:02:19 2014 +0200
@@ -24,7 +24,7 @@
public interface TruffleInliningPolicy {
- boolean isAllowed(TruffleInliningProfile profile, int currentBudgetLeft);
+ boolean isAllowed(TruffleInliningProfile profile, int currentNodeCount);
double calculateScore(TruffleInliningProfile profile);
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningProfile.java
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningProfile.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningProfile.java Mon Jun 30 12:02:19 2014 +0200
@@ -29,25 +29,20 @@
private final OptimizedDirectCallNode callNode;
private final int nodeCount;
private final int deepNodeCount;
- private final int callSites;
private final double frequency;
- private final boolean forced;
private final boolean recursiveCall;
- private final TruffleInliningResult recursiveResult;
+ private final TruffleInliningDecision recursiveResult;
private String failedReason;
private int queryIndex = -1;
private double score;
- public TruffleInliningProfile(OptimizedDirectCallNode callNode, int callSites, int nodeCount, int deepNodeCount, double frequency, boolean forced, boolean recursiveCall,
- TruffleInliningResult recursiveResult) {
+ public TruffleInliningProfile(OptimizedDirectCallNode callNode, int nodeCount, int deepNodeCount, double frequency, boolean recursiveCall, TruffleInliningDecision recursiveResult) {
this.callNode = callNode;
- this.callSites = callSites;
this.nodeCount = nodeCount;
this.deepNodeCount = deepNodeCount;
this.frequency = frequency;
this.recursiveCall = recursiveCall;
- this.forced = forced;
this.recursiveResult = recursiveResult;
}
@@ -60,14 +55,14 @@
}
public int getCallSites() {
- return callSites;
+ return callNode.getCurrentCallTarget().getKnownCallSiteCount();
}
public int getNodeCount() {
return nodeCount;
}
- public TruffleInliningResult getRecursiveResult() {
+ public TruffleInliningDecision getRecursiveResult() {
return recursiveResult;
}
@@ -96,7 +91,7 @@
}
public boolean isForced() {
- return forced;
+ return callNode.isInliningForced();
}
public double getFrequency() {
@@ -112,7 +107,7 @@
properties.put("nodeCount", String.format("%5d/%5d", deepNodeCount, nodeCount));
properties.put("frequency", frequency);
properties.put("score", String.format("%8.4f", getScore()));
- properties.put(String.format("index=%3d, force=%s, callSites=%2d", queryIndex, (forced ? "Y" : "N"), callSites), "");
+ properties.put(String.format("index=%3d, force=%s, callSites=%2d", queryIndex, (isForced() ? "Y" : "N"), getCallSites()), "");
properties.put("reason", failedReason);
return properties;
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningResult.java
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningResult.java Mon Jun 30 08:50:26 2014 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2013, 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.truffle;
-
-import java.util.*;
-
-public final class TruffleInliningResult implements Iterable {
-
- private final OptimizedCallTarget callTarget;
- private final Map profiles;
- private final Set inlined;
- private final int nodeCount;
-
- public TruffleInliningResult(OptimizedCallTarget callTarget, List profiles, Set inlined, int nodeCount) {
- this.callTarget = callTarget;
- this.profiles = new HashMap<>();
- for (TruffleInliningProfile profile : profiles) {
- this.profiles.put(profile.getCallNode(), profile);
- }
- this.nodeCount = nodeCount;
- this.inlined = inlined;
- }
-
- public Map getProfiles() {
- return profiles;
- }
-
- public int getNodeCount() {
- return nodeCount;
- }
-
- public OptimizedCallTarget getCallTarget() {
- return callTarget;
- }
-
- public boolean isInlined(OptimizedDirectCallNode path) {
- return inlined.contains(profiles.get(path));
- }
-
- public int size() {
- return inlined.size();
- }
-
- public Iterator iterator() {
- return Collections.unmodifiableSet(inlined).iterator();
- }
-
- @Override
- public String toString() {
- return inlined.toString();
- }
-}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/LoadIndexedFinalNode.java
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/LoadIndexedFinalNode.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/LoadIndexedFinalNode.java Mon Jun 30 12:02:19 2014 +0200
@@ -38,7 +38,7 @@
/**
* Creates a new {@link LoadIndexedFinalNode}.
- *
+ *
* @param array the instruction producing the array
* @param index the instruction producing the index
* @param elementKind the element type
@@ -52,7 +52,7 @@
if (array().isConstant() && index().isConstant()) {
Constant constant = tool.getConstantReflection().readArrayElement(array().asConstant(), index().asConstant().asInt());
if (constant != null) {
- return ConstantNode.forConstant(constant, tool.getMetaAccess(), graph());
+ return ConstantNode.forConstant(constant, tool.getMetaAccess());
}
}
return this;
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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
@@ -24,7 +24,6 @@
import com.oracle.graal.api.meta.*;
import com.oracle.graal.compiler.common.type.*;
-import com.oracle.graal.graph.*;
import com.oracle.graal.graph.spi.*;
import com.oracle.graal.nodes.*;
import com.oracle.graal.nodes.calc.*;
@@ -36,42 +35,42 @@
* Node representing an exact integer addition that will throw an {@link ArithmeticException} in
* case the addition would overflow the 32 bit range.
*/
-public class IntegerAddExactNode extends IntegerAddNode implements Canonicalizable, IntegerExactArithmeticNode {
+public class IntegerAddExactNode extends IntegerAddNode implements IntegerExactArithmeticNode {
public IntegerAddExactNode(ValueNode x, ValueNode y) {
- super(x.stamp().unrestricted(), x, y);
+ super(x, y);
assert x.stamp().isCompatible(y.stamp()) && x.stamp() instanceof IntegerStamp;
}
@Override
public boolean inferStamp() {
- // TODO Should probably use a specialised version which understands that it can't overflow
- return updateStamp(StampTool.add(x().stamp(), y().stamp()));
+ // TODO Should probably use a specialized version which understands that it can't overflow
+ return updateStamp(StampTool.add(getX().stamp(), getY().stamp()));
}
@Override
- public Node canonical(CanonicalizerTool tool) {
- if (x().isConstant() && !y().isConstant()) {
- return graph().unique(new IntegerAddExactNode(y(), x()));
+ public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+ if (forX.isConstant() && !forY.isConstant()) {
+ return new IntegerAddExactNode(forY, forX);
}
- if (x().isConstant()) {
- Constant xConst = x().asConstant();
- Constant yConst = y().asConstant();
+ if (forX.isConstant()) {
+ Constant xConst = forX.asConstant();
+ Constant yConst = forY.asConstant();
assert xConst.getKind() == yConst.getKind();
try {
if (xConst.getKind() == Kind.Int) {
- return ConstantNode.forInt(ExactMath.addExact(xConst.asInt(), yConst.asInt()), graph());
+ return ConstantNode.forInt(ExactMath.addExact(xConst.asInt(), yConst.asInt()));
} else {
assert xConst.getKind() == Kind.Long;
- return ConstantNode.forLong(ExactMath.addExact(xConst.asLong(), yConst.asLong()), graph());
+ return ConstantNode.forLong(ExactMath.addExact(xConst.asLong(), yConst.asLong()));
}
} catch (ArithmeticException ex) {
// The operation will result in an overflow exception, so do not canonicalize.
}
- } else if (y().isConstant()) {
- long c = y().asConstant().asLong();
+ } else if (forY.isConstant()) {
+ long c = forY.asConstant().asLong();
if (c == 0) {
- return x();
+ return forX;
}
}
return this;
@@ -79,7 +78,7 @@
@Override
public IntegerExactArithmeticSplitNode createSplit(BeginNode next, BeginNode deopt) {
- return graph().add(new IntegerAddExactSplitNode(stamp(), x(), y(), next, deopt));
+ return graph().add(new IntegerAddExactSplitNode(stamp(), getX(), getY(), next, deopt));
}
@Override
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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
@@ -24,7 +24,6 @@
import com.oracle.graal.api.meta.*;
import com.oracle.graal.compiler.common.type.*;
-import com.oracle.graal.graph.*;
import com.oracle.graal.graph.spi.*;
import com.oracle.graal.nodes.*;
import com.oracle.graal.nodes.calc.*;
@@ -35,39 +34,39 @@
* Node representing an exact integer multiplication that will throw an {@link ArithmeticException}
* in case the addition would overflow the 32 bit range.
*/
-public class IntegerMulExactNode extends IntegerMulNode implements Canonicalizable, IntegerExactArithmeticNode {
+public class IntegerMulExactNode extends IntegerMulNode implements IntegerExactArithmeticNode {
public IntegerMulExactNode(ValueNode x, ValueNode y) {
- super(x.stamp().unrestricted(), x, y);
+ super(x, y);
assert x.stamp().isCompatible(y.stamp()) && x.stamp() instanceof IntegerStamp;
}
@Override
- public Node canonical(CanonicalizerTool tool) {
- if (x().isConstant() && !y().isConstant()) {
- return graph().unique(new IntegerMulExactNode(y(), x()));
+ public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+ if (forX.isConstant() && !forY.isConstant()) {
+ return new IntegerMulExactNode(forY, forX);
}
- if (x().isConstant()) {
- Constant xConst = x().asConstant();
- Constant yConst = y().asConstant();
+ if (forX.isConstant()) {
+ Constant xConst = forX.asConstant();
+ Constant yConst = forY.asConstant();
assert xConst.getKind() == yConst.getKind();
try {
if (xConst.getKind() == Kind.Int) {
- return ConstantNode.forInt(ExactMath.multiplyExact(xConst.asInt(), yConst.asInt()), graph());
+ return ConstantNode.forInt(ExactMath.multiplyExact(xConst.asInt(), yConst.asInt()));
} else {
assert xConst.getKind() == Kind.Long;
- return ConstantNode.forLong(ExactMath.multiplyExact(xConst.asLong(), yConst.asLong()), graph());
+ return ConstantNode.forLong(ExactMath.multiplyExact(xConst.asLong(), yConst.asLong()));
}
} catch (ArithmeticException ex) {
// The operation will result in an overflow exception, so do not canonicalize.
}
- } else if (y().isConstant()) {
- long c = y().asConstant().asLong();
+ } else if (forY.isConstant()) {
+ long c = forY.asConstant().asLong();
if (c == 1) {
- return x();
+ return forX;
}
if (c == 0) {
- return ConstantNode.forIntegerStamp(stamp(), 0, graph());
+ return ConstantNode.forIntegerStamp(stamp(), 0);
}
}
return this;
@@ -75,7 +74,7 @@
@Override
public IntegerExactArithmeticSplitNode createSplit(BeginNode next, BeginNode deopt) {
- return graph().add(new IntegerMulExactSplitNode(stamp(), x(), y(), next, deopt));
+ return graph().add(new IntegerMulExactSplitNode(stamp(), getX(), getY(), next, deopt));
}
@Override
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulHighNode.java
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulHighNode.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulHighNode.java Mon Jun 30 12:02:19 2014 +0200
@@ -22,10 +22,13 @@
*/
package com.oracle.graal.truffle.nodes.arithmetic;
+import java.util.function.*;
+
import com.oracle.graal.api.meta.*;
import com.oracle.graal.compiler.common.*;
import com.oracle.graal.compiler.common.type.*;
import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
import com.oracle.graal.lir.gen.*;
import com.oracle.graal.nodes.*;
import com.oracle.graal.nodes.calc.*;
@@ -56,10 +59,45 @@
}
}
+ /**
+ * Determines the minimum and maximum result of this node for the given inputs and returns the
+ * result of the given BiFunction on the minimum and maximum values.
+ */
+ private T processExtremes(ValueNode forX, ValueNode forY, BiFunction op) {
+ IntegerStamp xStamp = (IntegerStamp) forX.stamp();
+ IntegerStamp yStamp = (IntegerStamp) forY.stamp();
+
+ Kind kind = getKind();
+ assert kind == Kind.Int || kind == Kind.Long;
+ long[] xExtremes = {xStamp.lowerBound(), xStamp.upperBound()};
+ long[] yExtremes = {yStamp.lowerBound(), yStamp.upperBound()};
+ long min = Long.MAX_VALUE;
+ long max = Long.MIN_VALUE;
+ for (long a : xExtremes) {
+ for (long b : yExtremes) {
+ long result = kind == Kind.Int ? ExactMath.multiplyHigh((int) a, (int) b) : ExactMath.multiplyHigh(a, b);
+ min = Math.min(min, result);
+ max = Math.max(max, result);
+ }
+ }
+ return op.apply(min, max);
+ }
+
+ @Override
+ public boolean inferStamp() {
+ return updateStamp(processExtremes(getX(), getY(), (min, max) -> StampFactory.forInteger(getKind(), min, max)));
+ }
+
+ @SuppressWarnings("cast")
+ @Override
+ public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+ return processExtremes(forX, forY, (min, max) -> min == (long) max ? ConstantNode.forIntegerKind(getKind(), min) : this);
+ }
+
@Override
public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
- Value a = builder.operand(x());
- Value b = builder.operand(y());
+ Value a = builder.operand(getX());
+ Value b = builder.operand(getY());
builder.setResult(this, gen.emitMulHigh(a, b));
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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
@@ -24,54 +24,54 @@
import com.oracle.graal.api.meta.*;
import com.oracle.graal.compiler.common.type.*;
-import com.oracle.graal.graph.*;
import com.oracle.graal.graph.spi.*;
import com.oracle.graal.nodes.*;
import com.oracle.graal.nodes.calc.*;
import com.oracle.graal.nodes.spi.*;
import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.nodes.util.*;
import com.oracle.truffle.api.*;
/**
* Node representing an exact integer substraction that will throw an {@link ArithmeticException} in
* case the addition would overflow the 32 bit range.
*/
-public class IntegerSubExactNode extends IntegerSubNode implements Canonicalizable, IntegerExactArithmeticNode {
+public class IntegerSubExactNode extends IntegerSubNode implements IntegerExactArithmeticNode {
public IntegerSubExactNode(ValueNode x, ValueNode y) {
- super(StampTool.sub(x.stamp(), y.stamp()), x, y);
+ super(x, y);
assert x.stamp().isCompatible(y.stamp()) && x.stamp() instanceof IntegerStamp;
}
@Override
public boolean inferStamp() {
- // TODO Should probably use a specialised version which understands that it can't overflow
- return updateStamp(StampTool.sub(x().stamp(), y().stamp()));
+ // TODO Should probably use a specialized version which understands that it can't overflow
+ return updateStamp(StampTool.sub(getX().stamp(), getY().stamp()));
}
@Override
- public Node canonical(CanonicalizerTool tool) {
- if (x() == y()) {
- return ConstantNode.forIntegerStamp(stamp(), 0, graph());
+ public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+ if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
+ return ConstantNode.forIntegerStamp(stamp(), 0);
}
- if (x().isConstant() && y().isConstant()) {
- Constant xConst = x().asConstant();
- Constant yConst = y().asConstant();
+ if (forX.isConstant() && forY.isConstant()) {
+ Constant xConst = forX.asConstant();
+ Constant yConst = forY.asConstant();
assert xConst.getKind() == yConst.getKind();
try {
if (xConst.getKind() == Kind.Int) {
- return ConstantNode.forInt(ExactMath.subtractExact(xConst.asInt(), yConst.asInt()), graph());
+ return ConstantNode.forInt(ExactMath.subtractExact(xConst.asInt(), yConst.asInt()));
} else {
assert xConst.getKind() == Kind.Long;
- return ConstantNode.forLong(ExactMath.subtractExact(xConst.asLong(), yConst.asLong()), graph());
+ return ConstantNode.forLong(ExactMath.subtractExact(xConst.asLong(), yConst.asLong()));
}
} catch (ArithmeticException ex) {
// The operation will result in an overflow exception, so do not canonicalize.
}
- } else if (y().isConstant()) {
- long c = y().asConstant().asLong();
+ } else if (forY.isConstant()) {
+ long c = forY.asConstant().asLong();
if (c == 0) {
- return x();
+ return forX;
}
}
return this;
@@ -79,7 +79,7 @@
@Override
public IntegerExactArithmeticSplitNode createSplit(BeginNode next, BeginNode deopt) {
- return graph().add(new IntegerSubExactSplitNode(stamp(), x(), y(), next, deopt));
+ return graph().add(new IntegerSubExactSplitNode(stamp(), getX(), getY(), next, deopt));
}
@Override
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/UnsignedMulHighNode.java
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/UnsignedMulHighNode.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/UnsignedMulHighNode.java Mon Jun 30 12:02:19 2014 +0200
@@ -22,10 +22,13 @@
*/
package com.oracle.graal.truffle.nodes.arithmetic;
+import java.util.function.*;
+
import com.oracle.graal.api.meta.*;
import com.oracle.graal.compiler.common.*;
import com.oracle.graal.compiler.common.type.*;
import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
import com.oracle.graal.lir.gen.*;
import com.oracle.graal.nodes.*;
import com.oracle.graal.nodes.calc.*;
@@ -56,10 +59,49 @@
}
}
+ /**
+ * Determines the minimum and maximum result of this node for the given inputs and returns the
+ * result of the given BiFunction on the minimum and maximum values. Note that the minima and
+ * maxima are calculated using signed min/max functions, while the values themselves are
+ * unsigned.
+ */
+ private T processExtremes(ValueNode forX, ValueNode forY, BiFunction op) {
+ IntegerStamp xStamp = (IntegerStamp) forX.stamp();
+ IntegerStamp yStamp = (IntegerStamp) forY.stamp();
+
+ Kind kind = getKind();
+ assert kind == Kind.Int || kind == Kind.Long;
+ long[] xExtremes = {xStamp.lowerBound(), xStamp.upperBound()};
+ long[] yExtremes = {yStamp.lowerBound(), yStamp.upperBound()};
+ long min = Long.MAX_VALUE;
+ long max = Long.MIN_VALUE;
+ for (long a : xExtremes) {
+ for (long b : yExtremes) {
+ long result = kind == Kind.Int ? ExactMath.multiplyHighUnsigned((int) a, (int) b) : ExactMath.multiplyHighUnsigned(a, b);
+ min = Math.min(min, result);
+ max = Math.max(max, result);
+ }
+ }
+ return op.apply(min, max);
+ }
+
+ @SuppressWarnings("cast")
+ @Override
+ public boolean inferStamp() {
+ // if min is negative, then the value can reach into the unsigned range
+ return updateStamp(processExtremes(getX(), getY(), (min, max) -> (min == (long) max || min >= 0) ? StampFactory.forInteger(getKind(), min, max) : StampFactory.forKind(getKind())));
+ }
+
+ @SuppressWarnings("cast")
+ @Override
+ public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+ return processExtremes(forX, forY, (min, max) -> min == (long) max ? ConstantNode.forIntegerKind(getKind(), min) : this);
+ }
+
@Override
public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
- Value a = builder.operand(x());
- Value b = builder.operand(y());
+ Value a = builder.operand(getX());
+ Value b = builder.operand(getY());
builder.setResult(this, gen.emitUMulHigh(a, b));
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java Mon Jun 30 12:02:19 2014 +0200
@@ -59,7 +59,7 @@
public Node canonical(CanonicalizerTool tool) {
if (object.isConstant() && !object.isNullConstant() && offset.isConstant() && condition.isConstant() && condition.asConstant().asInt() == 1) {
Constant constant = tool.getConstantReflection().readUnsafeConstant(accessKind, object.asConstant(), offset.asConstant().asLong());
- return ConstantNode.forConstant(constant, tool.getMetaAccess(), graph());
+ return ConstantNode.forConstant(constant, tool.getMetaAccess());
}
return this;
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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
@@ -62,10 +62,9 @@
} else {
locationIdentity = ObjectLocationIdentity.create(locationArgument.asConstant());
}
- CompareNode compare = CompareNode.createCompareNode(graph(), Condition.EQ, conditionArgument, ConstantNode.forBoolean(true, graph()));
+ CompareNode compare = CompareNode.createCompareNode(Condition.EQ, conditionArgument, ConstantNode.forBoolean(true));
Kind returnKind = this.getTargetMethod().getSignature().getReturnKind();
- Node result = graph().add(new UnsafeLoadNode(objectArgument, offsetArgument, returnKind, locationIdentity, compare));
- return result;
+ return new UnsafeLoadNode(objectArgument, offsetArgument, returnKind, locationIdentity, compare);
}
return this;
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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
@@ -61,10 +61,7 @@
locationIdentity = ObjectLocationIdentity.create(locationArgument.asConstant());
}
- UnsafeStoreNode unsafeStoreNode = graph().add(
- new UnsafeStoreNode(objectArgument, offsetArgument, valueArgument, this.getTargetMethod().getSignature().getParameterKind(VALUE_ARGUMENT_INDEX), locationIdentity));
- unsafeStoreNode.setStateAfter(this.stateAfter());
- return unsafeStoreNode;
+ return new UnsafeStoreNode(objectArgument, offsetArgument, valueArgument, this.getTargetMethod().getSignature().getParameterKind(VALUE_ARGUMENT_INDEX), locationIdentity, stateAfter());
}
return this;
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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
@@ -25,17 +25,17 @@
import com.oracle.graal.api.meta.*;
import com.oracle.graal.compiler.common.calc.*;
import com.oracle.graal.compiler.common.type.*;
-import com.oracle.graal.graph.*;
import com.oracle.graal.graph.spi.*;
import com.oracle.graal.nodes.*;
import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.util.*;
import com.oracle.graal.truffle.nodes.asserts.*;
import com.oracle.truffle.api.*;
/**
* Macro node for method {@link CompilerDirectives#unsafeCast(Object, Class, boolean, boolean)}.
*/
-public class UnsafeTypeCastMacroNode extends NeverPartOfCompilationNode implements Canonicalizable {
+public class UnsafeTypeCastMacroNode extends NeverPartOfCompilationNode implements Simplifiable {
private static final int OBJECT_ARGUMENT_INDEX = 0;
private static final int CLASS_ARGUMENT_INDEX = 1;
@@ -49,22 +49,25 @@
}
@Override
- public Node canonical(CanonicalizerTool tool) {
+ public void simplify(SimplifierTool tool) {
ValueNode classArgument = arguments.get(CLASS_ARGUMENT_INDEX);
ValueNode nonNullArgument = arguments.get(NONNULL_ARGUMENT_INDEX);
if (classArgument.isConstant() && nonNullArgument.isConstant()) {
ValueNode objectArgument = arguments.get(OBJECT_ARGUMENT_INDEX);
ValueNode conditionArgument = arguments.get(CONDITION_ARGUMENT_INDEX);
ResolvedJavaType lookupJavaType = tool.getConstantReflection().asJavaType(classArgument.asConstant());
+ tool.addToWorkList(usages());
if (lookupJavaType == null) {
- return objectArgument;
+ replaceAtUsages(objectArgument);
+ GraphUtil.removeFixedWithUnusedInputs(this);
+ } else {
+ Stamp stamp = StampFactory.declared(lookupJavaType, nonNullArgument.asConstant().asInt() != 0);
+ ConditionAnchorNode valueAnchorNode = graph().add(
+ new ConditionAnchorNode(CompareNode.createCompareNode(graph(), Condition.EQ, conditionArgument, ConstantNode.forBoolean(true, graph()))));
+ PiNode piCast = graph().unique(new PiNode(objectArgument, stamp, valueAnchorNode));
+ replaceAtUsages(piCast);
+ graph().replaceFixedWithFixed(this, valueAnchorNode);
}
- Stamp stamp = StampFactory.declared(lookupJavaType, nonNullArgument.asConstant().asInt() != 0);
- ConditionAnchorNode valueAnchorNode = graph().add(new ConditionAnchorNode(CompareNode.createCompareNode(graph(), Condition.EQ, conditionArgument, ConstantNode.forBoolean(true, graph()))));
- PiNode piCast = graph().unique(new PiNode(objectArgument, stamp, valueAnchorNode));
- this.replaceAtUsages(piCast);
- return valueAnchorNode;
}
- return this;
}
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/ReplaceIntrinsicsPhase.java
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/ReplaceIntrinsicsPhase.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/ReplaceIntrinsicsPhase.java Mon Jun 30 12:02:19 2014 +0200
@@ -54,7 +54,7 @@
} else {
StructuredGraph inlineGraph = replacements.getMethodSubstitution(methodCallTarget.targetMethod());
if (inlineGraph != null) {
- InliningUtil.inline(methodCallTarget.invoke(), inlineGraph, true);
+ InliningUtil.inline(methodCallTarget.invoke(), inlineGraph, true, null);
Debug.dump(graph, "After inlining %s", methodCallTarget.targetMethod().toString());
}
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerAssertsSubstitutions.java
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerAssertsSubstitutions.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerAssertsSubstitutions.java Mon Jun 30 12:02:19 2014 +0200
@@ -33,6 +33,9 @@
@MacroSubstitution(macro = NeverPartOfCompilationNode.class, isStatic = true)
public static native void neverPartOfCompilation();
+ @MacroSubstitution(macro = NeverPartOfCompilationNode.class, isStatic = true)
+ public static native void neverPartOfCompilation(String message);
+
@MacroSubstitution(macro = CompilationConstantNode.class, isStatic = true)
public static native boolean compilationConstant(boolean value);
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java Mon Jun 30 12:02:19 2014 +0200
@@ -29,6 +29,7 @@
import com.oracle.graal.debug.*;
import com.oracle.graal.debug.Debug.Scope;
import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.Graph.*;
import com.oracle.graal.graph.spi.*;
import com.oracle.graal.nodes.*;
import com.oracle.graal.nodes.cfg.*;
@@ -90,12 +91,10 @@
}
// apply the effects collected during this iteration
- HashSetNodeChangeListener listener = new HashSetNodeChangeListener();
- graph.trackInputChange(listener);
- graph.trackUsagesDroppedZero(listener);
- closure.applyEffects();
- graph.stopTrackingInputChange();
- graph.stopTrackingUsagesDroppedZero();
+ HashSetNodeEventListener listener = new HashSetNodeEventListener.ExceptForAddedNodes();
+ try (NodeEventScope nes = graph.trackNodeEvents(listener)) {
+ closure.applyEffects();
+ }
if (Debug.isDumpEnabled()) {
Debug.dump(graph, "after " + getName() + " iteration");
@@ -103,7 +102,7 @@
new DeadCodeEliminationPhase().apply(graph);
- Set changedNodes = listener.getChangedNodes();
+ Set changedNodes = listener.getNodes();
for (Node node : graph.getNodes()) {
if (node instanceof Simplifiable) {
changedNodes.add(node);
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java Mon Jun 30 12:02:19 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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
@@ -71,7 +71,12 @@
assert getKind() != input.getKind();
assert generator.getLIRGeneratorTool().target().getSizeInBytes(getKind()) == generator.getLIRGeneratorTool().target().getSizeInBytes(input.getKind());
- AllocatableValue result = generator.getLIRGeneratorTool().newVariable(getKind());
+ LIRKind kind = generator.getLIRGeneratorTool().getLIRKind(stamp());
+ if (kind.isValue()) {
+ kind = kind.makeDerivedReference();
+ }
+
+ AllocatableValue result = generator.getLIRGeneratorTool().newVariable(kind);
generator.getLIRGeneratorTool().emitMove(result, generator.operand(input));
generator.setResult(this, result);
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Mon Jun 30 12:02:19 2014 +0200
@@ -134,9 +134,9 @@
* Fold constant field reads, e.g. enum constants.
*/
protected void rewriteLoadField(StructuredGraph graph, LoadFieldNode node) {
- ConstantNode constant = node.asConstant(metaAccess);
+ ConstantNode constant = node.asConstant(metaAccess, node.object());
if (constant != null) {
- node.replaceAtUsages(constant);
+ node.replaceAtUsages(graph.unique(constant));
graph.removeFixed(node);
}
}
@@ -199,7 +199,7 @@
ValueNode left = arguments.get(0);
ValueNode right = operation.rightOperandIsInt() ? toUnsigned(graph, arguments.get(1), Kind.Int) : fromSigned(graph, arguments.get(1));
- ValueNode replacement = graph.addOrUnique(createBinaryNodeInstance(operation.node(), wordKind, left, right));
+ ValueNode replacement = graph.addOrUnique(createBinaryNodeInstance(operation.node(), left, right));
if (replacement instanceof FixedWithNextNode) {
graph.addBeforeFixed(invoke.asNode(), (FixedWithNextNode) replacement);
}
@@ -213,7 +213,7 @@
case NOT:
assert arguments.size() == 1;
- replace(invoke, graph.unique(new XorNode(StampFactory.forKind(wordKind), arguments.get(0), ConstantNode.forIntegerKind(wordKind, -1, graph))));
+ replace(invoke, graph.unique(new XorNode(arguments.get(0), ConstantNode.forIntegerKind(wordKind, -1, graph))));
break;
case READ_POINTER:
@@ -333,10 +333,10 @@
* called for all Word operations which are annotated with @Operation(node = ...) and
* encapsulates the reflective allocation of the node.
*/
- private static ValueNode createBinaryNodeInstance(Class extends ValueNode> nodeClass, Kind kind, ValueNode left, ValueNode right) {
+ private static ValueNode createBinaryNodeInstance(Class extends ValueNode> nodeClass, ValueNode left, ValueNode right) {
try {
- Constructor extends ValueNode> constructor = nodeClass.getConstructor(Stamp.class, ValueNode.class, ValueNode.class);
- return constructor.newInstance(StampFactory.forKind(kind), left, right);
+ Constructor extends ValueNode> constructor = nodeClass.getConstructor(ValueNode.class, ValueNode.class);
+ return constructor.newInstance(left, right);
} catch (Throwable ex) {
throw new GraalInternalError(ex).addContext(nodeClass.getName());
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java Mon Jun 30 12:02:19 2014 +0200
@@ -86,8 +86,8 @@
MethodCallTargetNode callTarget = (MethodCallTargetNode) usage;
verifyInvoke(node, callTarget);
} else if (usage instanceof ObjectEqualsNode) {
- verify(!isWord(node) || ((ObjectEqualsNode) usage).x() != node, node, usage, "cannot use word type in comparison");
- verify(!isWord(node) || ((ObjectEqualsNode) usage).y() != node, node, usage, "cannot use word type in comparison");
+ verify(!isWord(node) || ((ObjectEqualsNode) usage).getX() != node, node, usage, "cannot use word type in comparison");
+ verify(!isWord(node) || ((ObjectEqualsNode) usage).getY() != node, node, usage, "cannot use word type in comparison");
} 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 ValuePhiNode) {
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/SourceTextTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/SourceTextTest.java Mon Jun 30 12:02:19 2014 +0200
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2013, 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.truffle.api.test.utilities;
+
+import static org.junit.Assert.*;
+
+import org.junit.*;
+
+import com.oracle.truffle.api.source.*;
+
+public class SourceTextTest {
+
+ private final Source emptySource = Source.fromText("", null);
+
+ private final Source emptyLineSource = Source.fromText("\n", null);
+
+ private final Source shortSource = Source.fromText("01", null);
+
+ private final Source longSource = Source.fromText("01234\n67\n9\n", null);
+
+ @Test
+ public void emptyTextTest0() {
+ assertEquals(emptySource.getLineCount(), 0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void emptyTextTest1() {
+ emptySource.getLineNumber(0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void emptyTextTest2() {
+ emptySource.getColumnNumber(0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void emptyTextTest3() {
+ emptySource.getLineNumber(-1);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void emptyTextTest4() {
+ emptySource.getLineStartOffset(0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void emptyTextTest5() {
+ emptySource.getLineStartOffset(1);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void emptyTextTest6() {
+ emptySource.getLineLength(1);
+ }
+
+ @Test
+ public void emptyLineTest0() {
+ assertEquals(emptyLineSource.getLineCount(), 1);
+ assertEquals(emptyLineSource.getLineNumber(0), 1);
+ assertEquals(emptyLineSource.getLineStartOffset(1), 0);
+ assertEquals(emptyLineSource.getColumnNumber(0), 1);
+ assertEquals(emptyLineSource.getLineLength(1), 0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void emptyLineTest1() {
+ emptyLineSource.getLineNumber(1);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void emptyLineTest2() {
+ emptyLineSource.getLineStartOffset(2);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void emptyLineTest3() {
+ emptyLineSource.getColumnNumber(1);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void emptyLineTest4() {
+ emptyLineSource.getLineLength(2);
+ }
+
+ @Test
+ public void shortTextTest0() {
+
+ assertEquals(shortSource.getLineCount(), 1);
+
+ assertEquals(shortSource.getLineNumber(0), 1);
+ assertEquals(shortSource.getLineStartOffset(1), 0);
+ assertEquals(shortSource.getColumnNumber(0), 1);
+
+ assertEquals(shortSource.getLineNumber(1), 1);
+ assertEquals(shortSource.getColumnNumber(1), 2);
+
+ assertEquals(shortSource.getLineLength(1), 2);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void shortTextTest1() {
+ shortSource.getLineNumber(-1);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void shortTextTest2() {
+ shortSource.getColumnNumber(-1);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void shortTextTest3() {
+ shortSource.getLineNumber(2);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void shortTextTest4() {
+ shortSource.getColumnNumber(2);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void shortTextTest5() {
+ shortSource.getLineLength(2);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void shortTextTest6() {
+ shortSource.getLineLength(2);
+ }
+
+ @Test
+ public void longTextTest0() {
+
+ assertEquals(longSource.getLineCount(), 3);
+
+ assertEquals(longSource.getLineNumber(0), 1);
+ assertEquals(longSource.getLineStartOffset(1), 0);
+ assertEquals(longSource.getColumnNumber(0), 1);
+
+ assertEquals(longSource.getLineNumber(4), 1);
+ assertEquals(longSource.getColumnNumber(4), 5);
+
+ assertEquals(longSource.getLineNumber(5), 1); // newline
+ assertEquals(longSource.getColumnNumber(5), 6); // newline
+ assertEquals(longSource.getLineLength(1), 5);
+
+ assertEquals(longSource.getLineNumber(6), 2);
+ assertEquals(longSource.getLineStartOffset(2), 6);
+ assertEquals(longSource.getColumnNumber(6), 1);
+
+ assertEquals(longSource.getLineNumber(7), 2);
+ assertEquals(longSource.getColumnNumber(7), 2);
+
+ assertEquals(longSource.getLineNumber(8), 2); // newline
+ assertEquals(longSource.getLineNumber(8), 2); // newline
+ assertEquals(longSource.getLineLength(2), 2);
+
+ assertEquals(longSource.getLineNumber(9), 3);
+ assertEquals(longSource.getLineStartOffset(3), 9);
+ assertEquals(longSource.getColumnNumber(9), 1);
+
+ assertEquals(longSource.getLineNumber(10), 3); // newline
+ assertEquals(longSource.getColumnNumber(10), 2); // newline
+ assertEquals(longSource.getLineLength(3), 1);
+
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void longTextTest1() {
+ longSource.getLineNumber(11);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void longTextTest2() {
+ longSource.getColumnNumber(11);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void longTextTest3() {
+ longSource.getLineStartOffset(4);
+ }
+
+}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/TextMapTest.java
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/utilities/TextMapTest.java Mon Jun 30 08:50:26 2014 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,202 +0,0 @@
-/*
- * Copyright (c) 2013, 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.truffle.api.test.utilities;
-
-import static org.junit.Assert.*;
-
-import org.junit.*;
-
-import com.oracle.truffle.api.source.*;
-
-public class TextMapTest {
-
- final TextMap emptyTextMap = new TextMap("");
-
- final TextMap emptyLineMap = new TextMap("\n");
-
- private final TextMap shortMap = new TextMap("01");
-
- private final TextMap longMap = new TextMap("01234\n67\n9\n");
-
- @Test
- public void emptyTextTest0() {
- assertEquals(emptyTextMap.lineCount(), 0);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void emptyTextTest1() {
- emptyTextMap.offsetToLine(0);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void emptyTextTest2() {
- emptyTextMap.offsetToCol(0);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void emptyTextTest3() {
- emptyTextMap.lineStartOffset(-1);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void emptyTextTest4() {
- emptyTextMap.lineStartOffset(0);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void emptyTextTest5() {
- emptyTextMap.lineStartOffset(1);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void emptyTextTest6() {
- emptyTextMap.lineLength(1);
- }
-
- @Test
- public void emptyLineTest0() {
- assertEquals(emptyLineMap.lineCount(), 1);
- assertEquals(emptyLineMap.offsetToLine(0), 1);
- assertEquals(emptyLineMap.lineStartOffset(1), 0);
- assertEquals(emptyLineMap.offsetToCol(0), 1);
- assertEquals(emptyLineMap.lineLength(1), 0);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void emptyLineTest1() {
- emptyLineMap.offsetToLine(1);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void emptyLineTest2() {
- emptyLineMap.lineStartOffset(2);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void emptyLineTest3() {
- emptyLineMap.offsetToCol(1);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void emptyLineTest4() {
- emptyLineMap.lineLength(2);
- }
-
- @Test
- public void shortTextTest0() {
-
- assertEquals(shortMap.lineCount(), 1);
-
- assertEquals(shortMap.offsetToLine(0), 1);
- assertEquals(shortMap.lineStartOffset(1), 0);
- assertEquals(shortMap.offsetToCol(0), 1);
-
- assertEquals(shortMap.offsetToLine(1), 1);
- assertEquals(shortMap.offsetToCol(1), 2);
-
- assertEquals(shortMap.lineLength(1), 2);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void shortTextTest1() {
- shortMap.offsetToLine(-1);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void shortTextTest2() {
- shortMap.offsetToCol(-1);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void shortTextTest3() {
- shortMap.offsetToLine(2);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void shortTextTest4() {
- shortMap.offsetToCol(2);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void shortTextTest5() {
- shortMap.lineStartOffset(2);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void shortTextTest6() {
- shortMap.lineLength(2);
- }
-
- @Test
- public void longTextTest0() {
-
- assertEquals(longMap.lineCount(), 3);
-
- assertEquals(longMap.offsetToLine(0), 1);
- assertEquals(longMap.lineStartOffset(1), 0);
- assertEquals(longMap.offsetToCol(0), 1);
-
- assertEquals(longMap.offsetToLine(4), 1);
- assertEquals(longMap.offsetToCol(4), 5);
-
- assertEquals(longMap.offsetToLine(5), 1); // newline
- assertEquals(longMap.offsetToCol(5), 6); // newline
- assertEquals(longMap.lineLength(1), 5);
-
- assertEquals(longMap.offsetToLine(6), 2);
- assertEquals(longMap.lineStartOffset(2), 6);
- assertEquals(longMap.offsetToCol(6), 1);
-
- assertEquals(longMap.offsetToLine(7), 2);
- assertEquals(longMap.offsetToCol(7), 2);
-
- assertEquals(longMap.offsetToLine(8), 2); // newline
- assertEquals(longMap.offsetToLine(8), 2); // newline
- assertEquals(longMap.lineLength(2), 2);
-
- assertEquals(longMap.offsetToLine(9), 3);
- assertEquals(longMap.lineStartOffset(3), 9);
- assertEquals(longMap.offsetToCol(9), 1);
-
- assertEquals(longMap.offsetToLine(10), 3); // newline
- assertEquals(longMap.offsetToCol(10), 2); // newline
- assertEquals(longMap.lineLength(3), 1);
-
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void longTextTest1() {
- longMap.offsetToLine(11);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void longTextTest2() {
- longMap.offsetToCol(11);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void longTextTest3() {
- longMap.lineStartOffset(4);
- }
-
-}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerAsserts.java
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerAsserts.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerAsserts.java Mon Jun 30 12:02:19 2014 +0200
@@ -29,7 +29,7 @@
* either executed in the interpreter or in the compiled code. The assertions are checked during
* code generation and the Truffle compiler produces for failing assertions a stack trace that
* identifies the code position of the assertion in the context of the current compilation.
- *
+ *
*/
public class CompilerAsserts {
@@ -42,9 +42,12 @@
public static void neverPartOfCompilation() {
}
+ public static void neverPartOfCompilation(@SuppressWarnings("unused") String message) {
+ }
+
/**
* Assertion that the corresponding value is reduced to a constant during compilation.
- *
+ *
* @param value the value that must be constant during compilation
* @return the value given as parameter
*/
@@ -54,7 +57,7 @@
/**
* Assertion that the corresponding value is reduced to a constant during compilation.
- *
+ *
* @param value the value that must be constant during compilation
* @return the value given as parameter
*/
@@ -64,7 +67,7 @@
/**
* Assertion that the corresponding value is reduced to a constant during compilation.
- *
+ *
* @param value the value that must be constant during compilation
* @return the value given as parameter
*/
@@ -74,7 +77,7 @@
/**
* Assertion that the corresponding value is reduced to a constant during compilation.
- *
+ *
* @param value the value that must be constant during compilation
* @return the value given as parameter
*/
@@ -84,7 +87,7 @@
/**
* Assertion that the corresponding value is reduced to a constant during compilation.
- *
+ *
* @param value the value that must be constant during compilation
* @return the value given as parameter
*/
@@ -94,7 +97,7 @@
/**
* Assertion that the corresponding value is reduced to a constant during compilation.
- *
+ *
* @param value the value that must be constant during compilation
* @return the value given as parameter
*/
@@ -104,7 +107,7 @@
/**
* Assertion that the corresponding value is reduced to a constant during compilation.
- *
+ *
* @param value the value that must be constant during compilation
* @return the value given as parameter
*/
@@ -114,7 +117,7 @@
/**
* Assertion that the corresponding value is reduced to a constant during compilation.
- *
+ *
* @param value the value that must be constant during compilation
* @return the value given as parameter
*/
@@ -124,7 +127,7 @@
/**
* Assertion that the corresponding value is reduced to a constant during compilation.
- *
+ *
* @param value the value that must be constant during compilation
* @return the value given as parameter
*/
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/ExecutionContext.java
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/ExecutionContext.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/ExecutionContext.java Mon Jun 30 12:02:19 2014 +0200
@@ -109,6 +109,16 @@
}
/**
+ * Has a {@link Probe} been created that is uniquely associated with a particular source code
+ * location.
+ *
+ * @return a probe uniquely associated with an extent of guest language source code.
+ */
+ public final boolean hasProbe(SourceSection sourceSection) {
+ return probeManager.hasProbe(sourceSection);
+ }
+
+ /**
* Returns all existing probes with specific tag, or all probes if {@code tag = null}; empty
* collection if no probes found.
*/
@@ -120,7 +130,7 @@
* Returns all existing probes with first character on a specified line; empty collection if no
* probes found.
*/
- public final Collection findProbesByLine(SourceLineLocation lineLocation) {
+ public final Collection findProbesByLine(LineLocation lineLocation) {
return probeManager.findProbesByLine(lineLocation);
}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/NullSourceSection.java
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/NullSourceSection.java Mon Jun 30 08:50:26 2014 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2014, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.truffle.api;
-
-/**
- * Marker for a special flavor of {@link SourceSection} that has no content and can be ignored.
- */
-public interface NullSourceSection extends SourceSection {
-
-}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/Source.java
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/Source.java Mon Jun 30 08:50:26 2014 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,159 +0,0 @@
-/*
- * Copyright (c) 2013, 2014, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.truffle.api;
-
-import java.io.*;
-
-import com.oracle.truffle.api.source.*;
-
-/**
- * Represents a unit (typically a file) of guest language source code.
- */
-public interface Source {
-
- /**
- * Returns the name of this resource holding a guest language program. An example would be the
- * name of a guest language source code file.
- *
- * @return the name of the guest language program
- */
- String getName();
-
- /**
- * Returns a short version of the name of the resource holding a guest language program (as
- * described in @getName). For example, this could be just the name of the file, rather than a
- * full path.
- *
- * @return the short name of the guest language program
- */
- String getShortName();
-
- /**
- * The normalized, canonical name of the file.
- */
- String getPath();
-
- /**
- * Access to the source contents.
- */
- Reader getReader();
-
- /**
- * Access to the source contents.
- */
- InputStream getInputStream();
-
- /**
- * Return the complete text of the code.
- */
- String getCode();
-
- /**
- * Given a 1-based line number, return the text in the line, not including a possible
- * terminating newline.
- */
- String getCode(int lineNumber);
-
- /**
- * The number of text lines in the source, including empty lines; characters at the end of the
- * source without a terminating newline count as a line.
- */
- int getLineCount();
-
- /**
- * Given a 0-based character offset, return the 1-based number of the line that includes the
- * position.
- */
- int getLineNumber(int offset);
-
- /**
- * Given a 1-based line number, return the 0-based offset of the first character in the line.
- */
- int getLineStartOffset(int lineNumber);
-
- /**
- * The number of characters (not counting a possible terminating newline) in a (1-based)
- * numbered line.
- */
- int getLineLength(int lineNumber);
-
- /**
- * Creates a representation of a contiguous region of text in the source. Computes the
- * {@code (startLine, startColumn)} values by building a {@linkplain TextMap map} of lines in
- * the source.
- *
- * Checks the position arguments for consistency with the source.
- *
- * The resulting representation defines hash/equality around equivalent location, presuming that
- * {@link Source} representations are cannonical.
- *
- *
- * @param identifier terse description of the region
- * @param charIndex 0-based position of the first character in the section
- * @param length the number of characters in the section
- * @return newly created object representing the specified region
- * @throws IllegalArgumentException if either of the arguments are outside the text of the
- * source
- * @throws IllegalStateException if the source is one of the "null" instances
- */
- SourceSection createSection(String identifier, int charIndex, int length) throws IllegalArgumentException, IllegalStateException;
-
- /**
- * Creates a representation of a contiguous region of text in the source. Computes the
- * {@code charIndex} value by building a {@linkplain TextMap map} of lines in the source.
- *
- * Checks the position arguments for consistency with the source.
- *
- * The resulting representation defines hash/equality around equivalent location, presuming that
- * {@link Source} representations are cannonical.
- *
- * @param identifier terse description of the region
- * @param startLine 1-based line number of the first character in the section
- * @param startColumn 1-based column number of the first character in the section
- * @param length the number of characters in the section
- * @return newly created object representing the specified region
- * @throws IllegalArgumentException if arguments are outside the text of the source
- * @throws IllegalStateException if the source is one of the "null" instances
- */
- SourceSection createSection(String identifier, int startLine, int startColumn, int length);
-
- /**
- * Creates a representation of a contiguous region of text in the source.
- *
- * This method performs no checks on the validity of the arguments.
- *
- * The resulting representation defines hash/equality around equivalent location, presuming that
- * {@link Source} representations are cannonical.
- *
- * @param identifier terse description of the region
- * @param startLine 1-based line number of the first character in the section
- * @param startColumn 1-based column number of the first character in the section
- * @param charIndex the 0-based index of the first character of the section
- * @param length the number of characters in the section
- * @return newly created object representing the specified region
- */
- SourceSection createSection(String identifier, int startLine, int startColumn, int charIndex, int length);
-
-}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/SourceSection.java
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/SourceSection.java Mon Jun 30 08:50:26 2014 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,171 +0,0 @@
-/*
- * Copyright (c) 2013, 2014, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.truffle.api;
-
-/**
- * Description of contiguous section of text within a {@link Source} of program code.
- *
- * The starting location of the section can be described using two different coordinates:
- *
- *
{@code (startLine, startColumn)}: rows and columns are 1-based, so the first character in a
- * source file is at position {@code (1,1)}. {@code Tab} characters are counted as occupying one
- * column.
- *
character index: 0-based offset of the character from the beginning of the source, so
- * the first character in a file is at index {@code 0}.
- *
- * The {@code Newline} that terminates each line counts as a single character for the purpose of a
- * character index and when counting the length of text. The {@code (line,column)} coordinates of a
- * {@code Newline} should never appear in a text section.
- *
- * If the final character of source is not a {@code Newline}, the final characters of the text are
- * still considered to be a line ("unterminated").
- *
- *
- * @see Source#createSection(String, int, int, int, int)
- * @see Source#createSection(String, int, int, int)
- * @see Source#createSection(String, int, int)
- */
-public interface SourceSection {
-
- // TODO support alternate text representations/encodings
-
- /**
- * Representation of the source program that contains this section.
- *
- * @return the source object
- */
- Source getSource();
-
- /**
- * Returns 1-based line number of the first character in this section (inclusive).
- *
- * @return the starting line number
- */
- int getStartLine();
-
- /**
- * Returns the 1-based column number of the first character in this section (inclusive).
- *
- * @return the starting column number
- */
- int getStartColumn();
-
- /**
- * Returns the 0-based index of the first character in this section.
- *
- * @return the starting character index
- */
- int getCharIndex();
-
- /**
- * Returns the length of this section in characters.
- *
- * @return the number of characters in the section
- */
- int getCharLength();
-
- /**
- * Returns the index of the text position immediately following the last character in the
- * section.
- *
- * @return the end position of the section
- */
- int getCharEndIndex();
-
- /**
- * Returns terse text describing this source section, typically used for printing the section.
- *
- * @return the identifier of the section
- */
- String getIdentifier();
-
- /**
- * Returns text described by this section.
- *
- * @return the code as a String object
- */
- String getCode();
-
- /**
- * Returns a short description of the source section, using just the file name, rather than its
- * full path.
- *
- * @return a short description of the source section
- */
- String getShortDescription();
-
- /**
- * Singleton instance with no content.
- */
- SourceSection NULL = new NullSourceSection() {
-
- @Override
- public Source getSource() {
- return null;
- }
-
- @Override
- public int getStartLine() {
- return 0;
- }
-
- @Override
- public int getStartColumn() {
- return 0;
- }
-
- @Override
- public int getCharIndex() {
- return 0;
- }
-
- @Override
- public int getCharLength() {
- return 0;
- }
-
- @Override
- public int getCharEndIndex() {
- return 0;
- }
-
- @Override
- public String getIdentifier() {
- return null;
- }
-
- @Override
- public String getCode() {
- return null;
- }
-
- @Override
- public String getShortDescription() {
- return "short";
- }
-
- };
-
-}
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleOptions.java
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleOptions.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleOptions.java Mon Jun 30 12:02:19 2014 +0200
@@ -72,6 +72,13 @@
*/
public static NodeCost TraceRewritesFilterToCost = parseNodeInfoKind(System.getProperty("truffle.TraceRewritesFilterToCost"));
+ /**
+ * Enables the dumping of Node creations and AST rewrites in JSON format.
+ *
+ * Can be set with {@code -Dtruffle.TraceASTJSON=true}.
+ */
+ public static final boolean TraceASTJSON = Boolean.getBoolean("truffle.TraceASTJSON");
+
private static NodeCost parseNodeInfoKind(String kind) {
if (kind == null) {
return null;
diff -r 51f392557124 -r 5f01f7c48d40 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameDescriptor.java
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameDescriptor.java Mon Jun 30 08:50:26 2014 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameDescriptor.java Mon Jun 30 12:02:19 2014 +0200
@@ -57,6 +57,7 @@
}
public FrameSlot addFrameSlot(Object identifier, FrameSlotKind kind) {
+ CompilerAsserts.neverPartOfCompilation("interpreter-only. includes hashmap operations.");
assert !identifierToSlotMap.containsKey(identifier);
FrameSlot slot = new FrameSlot(this, identifier, slots.size(), kind);
slots.add(slot);
@@ -87,6 +88,7 @@
}
public void removeFrameSlot(Object identifier) {
+ CompilerAsserts.neverPartOfCompilation("interpreter-only. includes hashmap operations.");
assert identifierToSlotMap.containsKey(identifier);
slots.remove(identifierToSlotMap.get(identifier));
identifierToSlotMap.remove(identifier);
@@ -104,7 +106,7 @@
/**
* Retrieve the list of all the identifiers associated with this frame descriptor.
- *
+ *
* @return the list of all the identifiers in this frame descriptor
*/
public Set