changeset 21094:56668f0816f7

Merge.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Thu, 23 Apr 2015 13:37:27 +0200
parents a11325faa4d9 (current diff) 00b66fc966b1 (diff)
children 9212e6b75c07
files
diffstat 6 files changed, 69 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java	Thu Apr 23 13:37:11 2015 +0200
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java	Thu Apr 23 13:37:27 2015 +0200
@@ -402,7 +402,7 @@
         }
     }
 
-    @MatchRule("(Write Narrow=narrow location value)")
+    @MatchRule("(Write object location Narrow=narrow)")
     public ComplexMatchResult writeNarrow(WriteNode root, NarrowNode narrow) {
         return builder -> {
             LIRKind writeKind = getLIRGeneratorTool().getLIRKind(root.value().stamp());
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/util/FrequencyEncoder.java	Thu Apr 23 13:37:11 2015 +0200
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/util/FrequencyEncoder.java	Thu Apr 23 13:37:27 2015 +0200
@@ -46,6 +46,7 @@
     }
 
     protected final Map<T, Entry<T>> map;
+    protected boolean containsNull;
 
     /**
      * Creates an encoder that uses object identity.
@@ -69,17 +70,17 @@
      * Adds an object to the array.
      */
     public void addObject(T object) {
+        if (object == null) {
+            containsNull = true;
+            return;
+        }
+
         Entry<T> entry = map.get(object);
         if (entry == null) {
             entry = new Entry<>(object);
             map.put(object, entry);
         }
-        if (object == null) {
-            /* null must get index 0, so sort it up. */
-            entry.frequency = Integer.MAX_VALUE;
-        } else {
-            entry.frequency++;
-        }
+        entry.frequency++;
     }
 
     /**
@@ -87,6 +88,10 @@
      * {@link #addObject(Object) added} before.
      */
     public int getIndex(Object object) {
+        if (object == null) {
+            assert containsNull;
+            return 0;
+        }
         Entry<T> entry = map.get(object);
         assert entry != null && entry.index >= 0;
         return entry.index;
@@ -96,7 +101,7 @@
      * Returns the number of distinct objects that have been added, i.e., the length of the array.
      */
     public int getLength() {
-        return map.size();
+        return map.size() + (containsNull ? 1 : 0);
     }
 
     /**
@@ -104,14 +109,21 @@
      * correct length}.
      */
     public T[] encodeAll(T[] allObjects) {
-        assert allObjects.length == map.size();
+        assert allObjects.length == getLength();
         List<Entry<T>> sortedEntries = new ArrayList<>(map.values());
         sortedEntries.sort((e1, e2) -> -Integer.compare(e1.frequency, e2.frequency));
+
+        int offset = 0;
+        if (containsNull) {
+            allObjects[0] = null;
+            offset = 1;
+        }
         for (int i = 0; i < sortedEntries.size(); i++) {
             Entry<T> entry = sortedEntries.get(i);
-            entry.index = i;
-            allObjects[i] = entry.object;
-            assert entry.object != null || entry.index == 0;
+            int index = i + offset;
+            entry.index = index;
+            allObjects[index] = entry.object;
+            assert entry.object != null;
         }
         return allObjects;
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java	Thu Apr 23 13:37:11 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java	Thu Apr 23 13:37:27 2015 +0200
@@ -31,6 +31,8 @@
 import com.oracle.graal.hotspot.phases.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.lir.phases.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.StructuredGraph.*;
 import com.oracle.graal.options.*;
 import com.oracle.graal.options.DerivedOptionValue.OptionSupplier;
 import com.oracle.graal.phases.*;
@@ -104,10 +106,34 @@
         PhaseSuite<HighTierContext> suite = new PhaseSuite<>();
         GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault(plugins);
         suite.appendPhase(new GraphBuilderPhase(config));
+        assert appendGraphEncoderTest(suite);
         return suite;
     }
 
     /**
+     * When assertions are enabled, we encode and decode every parsed graph, to ensure that the
+     * encoding and decoding process work correctly. The decoding performs canonicalization during
+     * decoding, so the decoded graph can be different than the encoded graph - we cannot check them
+     * for equality here. However, the encoder {@link GraphEncoder#verifyEncoding verifies the
+     * encoding itself}, i.e., performs a decoding without canoncialization and checks the graphs
+     * for equality.
+     */
+    private boolean appendGraphEncoderTest(PhaseSuite<HighTierContext> suite) {
+        suite.appendPhase(new BasePhase<HighTierContext>() {
+            @Override
+            protected void run(StructuredGraph graph, HighTierContext context) {
+                EncodedGraph encodedGraph = GraphEncoder.encodeSingleGraph(graph, runtime.getTarget().arch);
+
+                SimplifyingGraphDecoder graphDecoder = new SimplifyingGraphDecoder(context.getMetaAccess(), context.getConstantReflection(), context.getStampProvider(), !ImmutableCode.getValue(),
+                                runtime.getTarget().arch);
+                StructuredGraph targetGraph = new StructuredGraph(graph.method(), AllowAssumptions.YES);
+                graphDecoder.decode(targetGraph, encodedGraph);
+            }
+        });
+        return true;
+    }
+
+    /**
      * Modifies the {@link GraphBuilderConfiguration} to build extra
      * {@linkplain DebugInfoMode#Simple debug info} if the VM
      * {@linkplain CompilerToVM#shouldDebugNonSafepoints() requests} it.
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GraphDecoder.java	Thu Apr 23 13:37:11 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GraphDecoder.java	Thu Apr 23 13:37:27 2015 +0200
@@ -303,7 +303,6 @@
              */
             FixedNode detectLoopsStart = startNode.predecessor() != null ? (FixedNode) startNode.predecessor() : startNode;
             cleanupGraph(methodScope, start);
-            Debug.dump(methodScope.graph, "Before loop detection");
             detectLoops(methodScope.graph, detectLoopsStart);
         }
     }
@@ -1020,7 +1019,6 @@
             }
         }
 
-        Debug.dump(currentGraph, "After loops detected");
         insertLoopEnds(currentGraph, startInstruction);
     }
 
@@ -1145,7 +1143,6 @@
     protected void cleanupGraph(MethodScope methodScope, Graph.Mark start) {
         assert verifyEdges(methodScope);
 
-        Debug.dump(methodScope.graph, "Before removing redundant merges");
         for (Node node : methodScope.graph.getNewNodes(start)) {
             if (node instanceof MergeNode) {
                 MergeNode mergeNode = (MergeNode) node;
@@ -1155,7 +1152,6 @@
             }
         }
 
-        Debug.dump(methodScope.graph, "Before removing redundant begins");
         for (Node node : methodScope.graph.getNewNodes(start)) {
             if (node instanceof BeginNode || node instanceof KillingBeginNode) {
                 if (!(node.predecessor() instanceof ControlSplitNode) && node.hasNoUsages()) {
@@ -1165,7 +1161,6 @@
             }
         }
 
-        Debug.dump(methodScope.graph, "Before removing unused non-fixed nodes");
         for (Node node : methodScope.graph.getNewNodes(start)) {
             if (!(node instanceof FixedNode) && node.hasNoUsages()) {
                 GraphUtil.killCFG(node);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java	Thu Apr 23 13:37:11 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java	Thu Apr 23 13:37:27 2015 +0200
@@ -70,9 +70,11 @@
             if (constant != null) {
                 return constant;
             }
-            PhiNode phi = asPhi(metaAccess, constantReflection, forObject);
-            if (phi != null) {
-                return phi;
+            if (tool.allUsagesAvailable()) {
+                PhiNode phi = asPhi(metaAccess, constantReflection, forObject);
+                if (phi != null) {
+                    return phi;
+                }
             }
         }
         if (!isStatic() && forObject.isNullConstant()) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Thu Apr 23 13:37:11 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Thu Apr 23 13:37:27 2015 +0200
@@ -238,14 +238,28 @@
      * </pre>
      */
     public static void normalizeLoops(StructuredGraph graph) {
+        boolean loopRemoved = false;
         for (LoopBeginNode begin : graph.getNodes(LoopBeginNode.TYPE)) {
             if (begin.loopEnds().isEmpty()) {
                 assert begin.forwardEndCount() == 1;
                 graph.reduceDegenerateLoopBegin(begin);
+                loopRemoved = true;
             } else {
                 normalizeLoopBegin(begin);
             }
         }
+
+        if (loopRemoved) {
+            /*
+             * Removing a degenerated loop can make non-loop phi functions unnecessary. Therefore,
+             * we re-check all phi functions and remove redundant ones.
+             */
+            for (Node node : graph.getNodes()) {
+                if (node instanceof PhiNode) {
+                    checkRedundantPhi((PhiNode) node);
+                }
+            }
+        }
     }
 
     private static void normalizeLoopBegin(LoopBeginNode begin) {