changeset 18793:ef51dadd50f7

Generalize ReinterpretNode to deal with arbitrary non-pointer types.
author Roland Schatz <roland.schatz@oracle.com>
date Wed, 07 Jan 2015 14:05:14 +0100
parents 7bb1abca2c0d
children c4fcd94dad19
files graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/PrimitiveConstant.java graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/SerializableConstant.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ArithmeticStamp.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/FloatStamp.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ReinterpretNode.java
diffstat 6 files changed, 139 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/PrimitiveConstant.java	Wed Jan 07 13:40:01 2015 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/PrimitiveConstant.java	Wed Jan 07 14:05:14 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2015, 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
@@ -22,11 +22,13 @@
  */
 package com.oracle.graal.api.meta;
 
+import java.nio.*;
+
 /**
  * Represents a primitive constant value, such as an integer or floating point number, within the
  * compiler and across the compiler/runtime interface.
  */
-public class PrimitiveConstant extends AbstractValue implements JavaConstant {
+public class PrimitiveConstant extends AbstractValue implements JavaConstant, SerializableConstant {
 
     private static final long serialVersionUID = 8787949721295655376L;
 
@@ -109,6 +111,41 @@
     }
 
     @Override
+    public int getSerializedSize() {
+        return getKind().getByteCount();
+    }
+
+    @Override
+    public void serialize(ByteBuffer buffer) {
+        switch (getKind()) {
+            case Byte:
+            case Boolean:
+                buffer.put((byte) primitive);
+                break;
+            case Short:
+                buffer.putShort((short) primitive);
+                break;
+            case Char:
+                buffer.putChar((char) primitive);
+                break;
+            case Int:
+                buffer.putInt(asInt());
+                break;
+            case Long:
+                buffer.putLong(asLong());
+                break;
+            case Float:
+                buffer.putFloat(asFloat());
+                break;
+            case Double:
+                buffer.putDouble(asDouble());
+                break;
+            default:
+                throw new IllegalArgumentException("unexpected kind " + getKind());
+        }
+    }
+
+    @Override
     public int hashCode() {
         return (int) (primitive ^ (primitive >>> 32)) * (getKind().ordinal() + 31);
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/SerializableConstant.java	Wed Jan 07 14:05:14 2015 +0100
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2014, 2015, 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;
+
+import java.nio.*;
+
+/**
+ * Represents a compile-time constant that can be converted to a byte array.
+ */
+public interface SerializableConstant extends Constant {
+
+    /**
+     * Return the size in bytes of the serialized representation of this constant.
+     */
+    int getSerializedSize();
+
+    /**
+     * Serialize the constant into the ByteBuffer. There must be at least
+     * {@link #getSerializedSize()} bytes available capacity in the buffer.
+     */
+    void serialize(ByteBuffer buffer);
+}
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ArithmeticStamp.java	Wed Jan 07 13:40:01 2015 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ArithmeticStamp.java	Wed Jan 07 14:05:14 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, 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
@@ -22,6 +22,10 @@
  */
 package com.oracle.graal.compiler.common.type;
 
+import java.nio.*;
+
+import com.oracle.graal.api.meta.*;
+
 /**
  * Type describing values that support arithmetic operations.
  */
@@ -37,6 +41,8 @@
         return ops;
     }
 
+    public abstract SerializableConstant deserialize(ByteBuffer buffer);
+
     @Override
     public int hashCode() {
         final int prime = 31;
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/FloatStamp.java	Wed Jan 07 13:40:01 2015 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/FloatStamp.java	Wed Jan 07 14:05:14 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, 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,6 +24,7 @@
 
 import static com.oracle.graal.compiler.common.calc.FloatConvert.*;
 
+import java.nio.*;
 import java.util.function.*;
 
 import com.oracle.graal.api.meta.*;
@@ -69,6 +70,18 @@
     }
 
     @Override
+    public SerializableConstant deserialize(ByteBuffer buffer) {
+        switch (getBits()) {
+            case 32:
+                return JavaConstant.forFloat(buffer.getFloat());
+            case 64:
+                return JavaConstant.forDouble(buffer.getDouble());
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    @Override
     public boolean isLegal() {
         return lowerBound <= upperBound || !nonNaN;
     }
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java	Wed Jan 07 13:40:01 2015 +0100
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java	Wed Jan 07 14:05:14 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, 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,6 +24,7 @@
 
 import static com.oracle.graal.compiler.common.calc.FloatConvert.*;
 
+import java.nio.*;
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
@@ -98,6 +99,24 @@
     }
 
     @Override
+    public SerializableConstant deserialize(ByteBuffer buffer) {
+        switch (getBits()) {
+            case 1:
+                return JavaConstant.forBoolean(buffer.get() != 0);
+            case 8:
+                return JavaConstant.forByte(buffer.get());
+            case 16:
+                return JavaConstant.forShort(buffer.getShort());
+            case 32:
+                return JavaConstant.forInt(buffer.getInt());
+            case 64:
+                return JavaConstant.forLong(buffer.getLong());
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    @Override
     public boolean isLegal() {
         return lowerBound <= upperBound;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ReinterpretNode.java	Wed Jan 07 13:40:01 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ReinterpretNode.java	Wed Jan 07 14:05:14 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, 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
@@ -22,8 +22,9 @@
  */
 package com.oracle.graal.nodes.calc;
 
+import java.nio.*;
+
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.lir.gen.*;
@@ -53,44 +54,27 @@
 
     protected ReinterpretNode(Stamp to, ValueNode value) {
         super(to, value);
-        assert to instanceof PrimitiveStamp;
+        assert to instanceof ArithmeticStamp;
     }
 
-    private JavaConstant evalConst(JavaConstant c) {
-        assert c.getKind().getBitCount() == ((PrimitiveStamp) stamp()).getBits();
-        switch (c.getKind()) {
-            case Int:
-                if (stamp() instanceof FloatStamp) {
-                    return JavaConstant.forFloat(Float.intBitsToFloat(c.asInt()));
-                } else {
-                    return c;
-                }
-            case Long:
-                if (stamp() instanceof FloatStamp) {
-                    return JavaConstant.forDouble(Double.longBitsToDouble(c.asLong()));
-                } else {
-                    return c;
-                }
-            case Float:
-                if (stamp() instanceof IntegerStamp) {
-                    return JavaConstant.forInt(Float.floatToRawIntBits(c.asFloat()));
-                } else {
-                    return c;
-                }
-            case Double:
-                if (stamp() instanceof IntegerStamp) {
-                    return JavaConstant.forLong(Double.doubleToRawLongBits(c.asDouble()));
-                } else {
-                    return c;
-                }
-        }
-        throw GraalInternalError.shouldNotReachHere();
+    private SerializableConstant evalConst(SerializableConstant c) {
+        /*
+         * We don't care about byte order here. Either would produce the correct result.
+         */
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[c.getSerializedSize()]).order(ByteOrder.nativeOrder());
+        c.serialize(buffer);
+
+        buffer.rewind();
+        SerializableConstant ret = ((ArithmeticStamp) stamp()).deserialize(buffer);
+
+        assert !buffer.hasRemaining();
+        return ret;
     }
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
         if (forValue.isConstant()) {
-            return ConstantNode.forConstant(evalConst(forValue.asJavaConstant()), null);
+            return ConstantNode.forConstant(stamp(), evalConst((SerializableConstant) forValue.asConstant()), null);
         }
         if (stamp().isCompatible(forValue.stamp())) {
             return forValue;