Canonicalize array access
Rémi Forax
forax at univ-mlv.fr
Tue Apr 3 03:14:17 PDT 2012
On 04/02/2012 12:10 PM, Douglas Simon wrote:
> Hi Remi,
>
> On Mar 30, 2012, at 7:13 PM, Rémi Forax wrote:
>
>> Hi guys,
>> I've played a little with Graal and I've some questions (a lot in fact but I will send several messages :)
> We're ready for your questions - fire away ;-)
A small contribution.
This code canonicalizes array access if the array and the index are a
constant.
cheers,
Rémi
diff --git
a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java
b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java
---
a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java
+++
b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java
@@ -32,7 +32,7 @@
/**
* The {@code LoadIndexedNode} represents a read from an element of an
array.
*/
-public final class LoadIndexedNode extends AccessIndexedNode implements
Lowerable, Node.IterableNodeType {
+public final class LoadIndexedNode extends AccessIndexedNode implements
Canonicalizable, Lowerable, Node.IterableNodeType {
/**
* Creates a new LoadIndexedNode.
@@ -62,4 +62,17 @@
public void lower(CiLoweringTool tool) {
tool.getRuntime().lower(this, tool);
}
+
+ @Override
+ public ValueNode canonical(CanonicalizerTool tool) {
+ if (index().isConstant() && array().isConstant() &&
!array().isNullConstant()) {
+ int arrayIndex = index().asConstant().asInt();
+ CiConstant constArray = array().asConstant();
+ if (arrayIndex >= 0 && arrayIndex <
tool.runtime().getArrayLength(constArray)) {
+ CiConstant constant =
elementKind().readUnsafeArrayConstant(constArray.asObject(), arrayIndex);
+ return ConstantNode.forCiConstant(constant,
tool.runtime(), graph());
+ }
+ }
+ return this;
+ }
}
diff --git
a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiKind.java
b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiKind.java
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiKind.java
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiKind.java
@@ -337,5 +337,33 @@
return null;
}
}
+
+ public CiConstant readUnsafeArrayConstant(Object value, long index) {
+ assert value != null;
+ Unsafe u = Unsafe.getUnsafe();
+ switch(this) {
+ case Boolean:
+ return CiConstant.forBoolean(u.getBoolean(value,
Unsafe.ARRAY_BOOLEAN_BASE_OFFSET + index *
Unsafe.ARRAY_BOOLEAN_INDEX_SCALE));
+ case Byte:
+ return CiConstant.forByte(u.getByte(value,
Unsafe.ARRAY_BYTE_BASE_OFFSET + index * Unsafe.ARRAY_BYTE_INDEX_SCALE));
+ case Char:
+ return CiConstant.forChar(u.getChar(value,
Unsafe.ARRAY_CHAR_BASE_OFFSET + index * Unsafe.ARRAY_CHAR_INDEX_SCALE));
+ case Short:
+ return CiConstant.forShort(u.getShort(value,
Unsafe.ARRAY_SHORT_BASE_OFFSET + index * Unsafe.ARRAY_SHORT_INDEX_SCALE));
+ case Int:
+ return CiConstant.forInt(u.getInt(value,
Unsafe.ARRAY_INT_BASE_OFFSET + index * Unsafe.ARRAY_INT_INDEX_SCALE));
+ case Long:
+ return CiConstant.forLong(u.getLong(value,
Unsafe.ARRAY_LONG_BASE_OFFSET + index * Unsafe.ARRAY_LONG_INDEX_SCALE));
+ case Float:
+ return CiConstant.forFloat(u.getFloat(value,
Unsafe.ARRAY_FLOAT_BASE_OFFSET + index * Unsafe.ARRAY_FLOAT_INDEX_SCALE));
+ case Double:
+ return CiConstant.forDouble(u.getDouble(value,
Unsafe.ARRAY_DOUBLE_BASE_OFFSET + index * Unsafe.ARRAY_DOUBLE_INDEX_SCALE));
+ case Object:
+ return CiConstant.forObject(u.getObject(value,
Unsafe.ARRAY_OBJECT_BASE_OFFSET + index * Unsafe.ARRAY_OBJECT_INDEX_SCALE));
+ default:
+ assert false : "unexpected kind: " + this;
+ return null;
+ }
+ }
}
More information about the graal-dev
mailing list