changeset 15416:89ff116d8956

PEA: only merge objects at phi if this phi is the only reference
author Lukas Stadler <lukas.stadler@oracle.com>
date Mon, 28 Apr 2014 16:21:44 +0200
parents 2a83d2482625
children b2381f53c77f
files graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java
diffstat 1 files changed, 16 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Tue Apr 29 00:05:30 2014 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Mon Apr 28 16:21:44 2014 +0200
@@ -579,15 +579,29 @@
                 } else {
                     // all inputs are virtual: check if they're compatible and without identity
                     boolean compatible = true;
+                    boolean hasIdentity = false;
                     ObjectState firstObj = objStates[0];
                     for (int i = 0; i < objStates.length; i++) {
                         ObjectState obj = objStates[i];
-                        boolean hasIdentity = obj.virtual.hasIdentity() && mergedVirtualObjects.contains(obj.virtual);
-                        if (hasIdentity || !firstObj.virtual.type().equals(obj.virtual.type()) || firstObj.virtual.entryCount() != obj.virtual.entryCount() || !firstObj.locksEqual(obj)) {
+                        hasIdentity |= obj.virtual.hasIdentity();
+                        boolean identitySurvives = obj.virtual.hasIdentity() && mergedVirtualObjects.contains(obj.virtual);
+                        if (identitySurvives || !firstObj.virtual.type().equals(obj.virtual.type()) || firstObj.virtual.entryCount() != obj.virtual.entryCount() || !firstObj.locksEqual(obj)) {
                             compatible = false;
                             break;
                         }
                     }
+                    if (compatible && hasIdentity) {
+                        // we still need to check whether this value is referenced by any other phi
+                        outer: for (PhiNode otherPhi : merge.phis().filter(otherPhi -> otherPhi != phi)) {
+                            for (int i = 0; i < objStates.length; i++) {
+                                ObjectState otherPhiValueState = getObjectState(states.get(i), otherPhi.valueAt(i));
+                                if (Arrays.asList(objStates).contains(otherPhiValueState)) {
+                                    compatible = false;
+                                    break outer;
+                                }
+                            }
+                        }
+                    }
 
                     if (compatible) {
                         VirtualObjectNode virtual = getValueObjectVirtual(phi, getObjectState(states.get(0), phi.valueAt(0)).virtual);