changeset 10848:4da2141fc40f

Canonicalize final field loads from a phi of constant objects.
author Andreas Woess <andreas.woess@jku.at>
date Mon, 22 Jul 2013 19:12:14 +0200
parents 669e3105804d
children cea4beb67bfd
files graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java
diffstat 1 files changed, 34 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java	Mon Jul 22 19:17:17 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java	Mon Jul 22 19:12:14 2013 +0200
@@ -22,8 +22,11 @@
  */
 package com.oracle.graal.nodes.java;
 
+import java.lang.reflect.*;
+
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -57,11 +60,15 @@
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
         MetaAccessProvider runtime = tool.runtime();
-        if (tool.canonicalizeReads()) {
+        if (tool.canonicalizeReads() && runtime != null) {
             ConstantNode constant = asConstant(runtime);
             if (constant != null) {
                 return constant;
             }
+            PhiNode phi = asPhi(runtime);
+            if (phi != null) {
+                return phi;
+            }
         }
         return this;
     }
@@ -70,16 +77,34 @@
      * Gets a constant value for this load if possible.
      */
     public ConstantNode asConstant(MetaAccessProvider runtime) {
-        if (runtime != null) {
-            Constant constant = null;
-            if (isStatic()) {
-                constant = field().readConstantValue(null);
-            } else if (object().isConstant() && !object().isNullConstant()) {
-                constant = field().readConstantValue(object().asConstant());
+        Constant constant = null;
+        if (isStatic()) {
+            constant = field().readConstantValue(null);
+        } else if (object().isConstant() && !object().isNullConstant()) {
+            constant = field().readConstantValue(object().asConstant());
+        }
+        if (constant != null) {
+            return ConstantNode.forConstant(constant, runtime, graph());
+        }
+        return null;
+    }
+
+    private PhiNode asPhi(MetaAccessProvider runtime) {
+        if (!isStatic() && Modifier.isFinal(field.getModifiers()) && object() instanceof PhiNode && ((PhiNode) object()).values().filter(NodePredicates.isNotA(ConstantNode.class)).isEmpty()) {
+            PhiNode phi = (PhiNode) object();
+            Constant[] constants = new Constant[phi.valueCount()];
+            for (int i = 0; i < phi.valueCount(); i++) {
+                Constant constantValue = field().readConstantValue(phi.valueAt(i).asConstant());
+                if (constantValue == null) {
+                    return null;
+                }
+                constants[i] = constantValue;
             }
-            if (constant != null) {
-                return ConstantNode.forConstant(constant, runtime, graph());
+            PhiNode newPhi = graph().add(new PhiNode(stamp(), phi.merge()));
+            for (int i = 0; i < phi.valueCount(); i++) {
+                newPhi.addInput(ConstantNode.forConstant(constants[i], runtime, graph()));
             }
+            return newPhi;
         }
         return null;
     }