changeset 6398:bced4f3a4174

removed old EscapeAnalysisPhase
author Lukas Stadler <lukas.stadler@jku.at>
date Fri, 14 Sep 2012 15:16:50 +0200
parents b30dde62f44c
children 6ad5bf2efb5e
files graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EscapeAnalysisTest.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/EscapeAnalysisPhase.java graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/MonitorTest.java
diffstat 5 files changed, 2 insertions(+), 524 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EscapeAnalysisTest.java	Fri Sep 14 10:03:38 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,151 +0,0 @@
-/*
- * Copyright (c) 2011, 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.compiler.test;
-
-import junit.framework.Assert;
-
-import org.junit.Test;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.*;
-import com.oracle.graal.compiler.phases.*;
-import com.oracle.graal.debug.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.java.*;
-
-/**
- * In these test cases the probability of all invokes is set to a high value, such that an InliningPhase should inline them all.
- * After that, the EscapeAnalysisPhase is expected to remove all allocations and return the correct values.
- */
-public class EscapeAnalysisTest extends GraalCompilerTest {
-
-    @Test
-    public void test1() {
-        test("test1Snippet", Constant.forInt(101));
-    }
-
-    @SuppressWarnings("all")
-    public static int test1Snippet(int a) {
-        Integer x = new Integer(101);
-        return x.intValue();
-    }
-
-    @Test
-    public void test2() {
-        test("test2Snippet", Constant.forInt(0));
-    }
-
-    @SuppressWarnings("all")
-    public static int test2Snippet(int a) {
-        Integer[] x = new Integer[0];
-        return x.length;
-    }
-
-    @Test
-    public void test3() {
-        test("test3Snippet", Constant.forObject(null));
-    }
-
-    @SuppressWarnings("all")
-    public static Object test3Snippet(int a) {
-        Integer[] x = new Integer[1];
-        return x[0];
-    }
-
-    @Test
-    public void testMonitor() {
-        test("testMonitorSnippet", Constant.forInt(0));
-    }
-
-    private static native void notInlineable();
-
-    @SuppressWarnings("all")
-    public static int testMonitorSnippet(int a) {
-        Integer x = new Integer(0);
-        Integer[] y = new Integer[0];
-        Integer[] z = new Integer[1];
-        synchronized (x) {
-            synchronized (y) {
-                synchronized (z) {
-                    notInlineable();
-                }
-            }
-        }
-        return x.intValue();
-    }
-
-    @Test
-    public void testMonitor2() {
-        test("testMonitor2Snippet", Constant.forInt(0));
-    }
-
-    /**
-     * This test case differs from the last one in that it requires inlining within a synchronized region.
-     */
-    @SuppressWarnings("all")
-    public static int testMonitor2Snippet(int a) {
-        Integer x = new Integer(0);
-        Integer[] y = new Integer[0];
-        Integer[] z = new Integer[1];
-        synchronized (x) {
-            synchronized (y) {
-                synchronized (z) {
-                    notInlineable();
-                    return x.intValue();
-                }
-            }
-        }
-    }
-
-    private void test(final String snippet, final Constant expectedResult) {
-        Debug.scope("EscapeAnalysisTest", new DebugDumpScope(snippet), new Runnable() {
-            public void run() {
-                StructuredGraph graph = parse(snippet);
-                for (Invoke n : graph.getInvokes()) {
-                    n.node().setProbability(100000);
-                }
-
-                new InliningPhase(null, runtime(), null, null, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph);
-                new DeadCodeEliminationPhase().apply(graph);
-                Debug.dump(graph, "Graph");
-                new EscapeAnalysisPhase(null, runtime(), null).apply(graph);
-                Debug.dump(graph, "Graph");
-                int retCount = 0;
-                for (ReturnNode ret : graph.getNodes(ReturnNode.class)) {
-                    Assert.assertTrue(ret.result().isConstant());
-                    Assert.assertEquals(ret.result().asConstant(), expectedResult);
-                    retCount++;
-                }
-                Assert.assertEquals(1, retCount);
-                int newInstanceCount = 0;
-                for (@SuppressWarnings("unused") NewInstanceNode n : graph.getNodes(NewInstanceNode.class)) {
-                    newInstanceCount++;
-                }
-                for (@SuppressWarnings("unused") NewObjectArrayNode n : graph.getNodes(NewObjectArrayNode.class)) {
-                    newInstanceCount++;
-                }
-                Assert.assertEquals(0, newInstanceCount);
-            }
-        });
-    }
-}
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Fri Sep 14 10:03:38 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Fri Sep 14 15:16:50 2012 +0200
@@ -153,9 +153,6 @@
             }
         }
 
-        if (GraalOptions.EscapeAnalysis && !plan.isPhaseDisabled(EscapeAnalysisPhase.class)) {
-            new EscapeAnalysisPhase(target, runtime, assumptions).apply(graph);
-        }
         if (GraalOptions.PartialEscapeAnalysis && !plan.isPhaseDisabled(PartialEscapeAnalysisPhase.class)) {
             new PartialEscapeAnalysisPhase(target, runtime, assumptions).apply(graph);
         }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java	Fri Sep 14 10:03:38 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java	Fri Sep 14 15:16:50 2012 +0200
@@ -69,7 +69,6 @@
     public static float   ProbabilityCapForInlining          = 1f;
 
     // escape analysis settings
-    public static boolean EscapeAnalysis                     = ____;
     public static boolean PartialEscapeAnalysis              = true;
 
     public static double TailDuplicationProbability          = 0.5;
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/EscapeAnalysisPhase.java	Fri Sep 14 10:03:38 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,367 +0,0 @@
-/*
- * Copyright (c) 2011, 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.compiler.phases;
-
-import java.util.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.*;
-import com.oracle.graal.compiler.graph.*;
-import com.oracle.graal.compiler.util.*;
-import com.oracle.graal.debug.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.PhiNode.PhiType;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.virtual.*;
-import com.oracle.max.criutils.*;
-
-public class EscapeAnalysisPhase extends Phase {
-
-    /**
-     * Encapsulates the state of the virtual object, which is updated while traversing the control flow graph.
-     */
-    public static class BlockExitState implements MergeableState<BlockExitState> {
-
-        public final ValueNode[] fieldState;
-        public final VirtualObjectNode virtualObject;
-        public final Graph graph;
-
-        public BlockExitState(EscapeField[] fields, VirtualObjectNode virtualObject) {
-            this.fieldState = new ValueNode[fields.length];
-            this.virtualObject = virtualObject;
-            this.graph = virtualObject.graph();
-            for (int i = 0; i < fields.length; i++) {
-                fieldState[i] = ConstantNode.defaultForKind(fields[i].type().kind(), virtualObject.graph());
-            }
-        }
-
-        public BlockExitState(BlockExitState state) {
-            this.fieldState = state.fieldState.clone();
-            this.virtualObject = state.virtualObject;
-            this.graph = state.graph;
-        }
-
-        @Override
-        public BlockExitState clone() {
-            return new BlockExitState(this);
-        }
-
-        @Override
-        public boolean merge(MergeNode merge, List<BlockExitState> withStates) {
-            PhiNode[] valuePhis = new PhiNode[fieldState.length];
-            for (BlockExitState other : withStates) {
-                for (int i2 = 0; i2 < fieldState.length; i2++) {
-                    if (fieldState[i2] != other.fieldState[i2] && valuePhis[i2] == null) {
-                        valuePhis[i2] = graph.add(new PhiNode(fieldState[i2].kind(), merge));
-                        valuePhis[i2].addInput(fieldState[i2]);
-                        fieldState[i2] = valuePhis[i2];
-                    }
-                }
-            }
-            for (BlockExitState other : withStates) {
-                for (int i2 = 0; i2 < fieldState.length; i2++) {
-                    if (valuePhis[i2] != null) {
-                        valuePhis[i2].addInput(other.fieldState[i2]);
-                    }
-                }
-            }
-            return true;
-        }
-
-        @Override
-        public void loopBegin(LoopBeginNode loopBegin) {
-            for (int i2 = 0; i2 < fieldState.length; i2++) {
-                PhiNode valuePhi = graph.add(new PhiNode(fieldState[i2].kind(), loopBegin));
-                valuePhi.addInput(fieldState[i2]);
-                fieldState[i2] = valuePhi;
-            }
-        }
-
-        @Override
-        public void loopEnds(LoopBeginNode loopBegin, List<BlockExitState> loopEndStates) {
-            for (BlockExitState loopEndState : loopEndStates) {
-                for (int i2 = 0; i2 < fieldState.length; i2++) {
-                    ((PhiNode) fieldState[i2]).addInput(loopEndState.fieldState[i2]);
-                }
-            }
-        }
-
-        @Override
-        public void afterSplit(FixedNode node) {
-            // nothing to do...
-        }
-    }
-
-    private static class EscapementFixup {
-
-        private final Map<Object, Integer> fields = new HashMap<>();
-        private final EscapeOp op;
-        private final StructuredGraph graph;
-        private final FixedWithNextNode node;
-        private EscapeField[] escapeFields;
-        private final int id;
-
-        public EscapementFixup(int id, EscapeOp op, StructuredGraph graph, FixedWithNextNode node) {
-            this.id = id;
-            this.op = op;
-            this.graph = graph;
-            this.node = node;
-        }
-
-        public void apply() {
-            if (node.usages().isEmpty()) {
-                graph.removeFixed(node);
-            } else {
-                process();
-                removeAllocation();
-            }
-        }
-
-        private void process() {
-            for (Node usage : node.usages().snapshot()) {
-                op.beforeUpdate(usage);
-            }
-        }
-
-        public void removeAllocation() {
-            escapeFields = op.fields();
-            for (int i = 0; i < escapeFields.length; i++) {
-                fields.put(escapeFields[i].representation(), i);
-            }
-            assert node.objectStamp().isExactType();
-            final VirtualObjectNode virtual = graph.add(new VirtualObjectNode(id, node.objectStamp().type(), escapeFields));
-            Debug.log("new virtual object: " + virtual);
-            node.replaceAtUsages(virtual);
-            FixedNode next = node.next();
-            graph.removeFixed(node);
-
-            List<ValueProxyNode> proxies;
-            while (!(proxies = virtual.usages().filter(ValueProxyNode.class).snapshot()).isEmpty()) {
-                for (ValueProxyNode vpn : proxies) {
-                    assert vpn.value() == virtual;
-                    graph.replaceFloating(vpn, virtual);
-                }
-            }
-
-            if (virtual.fields().length > 0) {
-                final BlockExitState startState = new BlockExitState(escapeFields, virtual);
-                new PostOrderNodeIterator<BlockExitState>(next, startState) {
-
-                    @Override
-                    protected void node(FixedNode curNode) {
-                        op.updateState(virtual, curNode, fields, state.fieldState);
-                        if (curNode instanceof LoopExitNode) {
-                            for (int i = 0; i < state.fieldState.length; i++) {
-                                state.fieldState[i] = graph.unique(new ValueProxyNode(state.fieldState[i], (LoopExitNode) curNode, PhiType.Value));
-                            }
-                        }
-                        if (!curNode.isDeleted() && curNode instanceof StateSplit && ((StateSplit) curNode).stateAfter() != null) {
-                            VirtualObjectState v = graph.add(new VirtualObjectState(virtual, state.fieldState));
-                            ((StateSplit) curNode).stateAfter().addVirtualObjectMapping(v);
-                        }
-                    }
-                }.apply();
-            }
-        }
-    }
-
-    private final TargetDescription target;
-    private final GraalCodeCacheProvider runtime;
-    private final Assumptions assumptions;
-
-    private int virtualIds = 0;
-
-    public EscapeAnalysisPhase(TargetDescription target, GraalCodeCacheProvider runtime, Assumptions assumptions) {
-        this.runtime = runtime;
-        this.target = target;
-        this.assumptions = assumptions;
-    }
-
-    @Override
-    protected void run(StructuredGraph graph) {
-        for (Node node : new GraphOrder(graph)) {
-            if (node != null && node instanceof FixedWithNextNode && node instanceof EscapeAnalyzable) {
-                FixedWithNextNode fixedNode = (FixedWithNextNode) node;
-                EscapeOp op = ((EscapeAnalyzable) node).getEscapeOp();
-                if (op != null) {
-                    try {
-                        performAnalysis(graph, fixedNode, op);
-                    } catch (GraalInternalError e) {
-                        throw e.addContext("escape analysis of node", node);
-                    }
-                }
-            }
-        }
-    }
-
-    private void performAnalysis(StructuredGraph graph, FixedWithNextNode node, EscapeOp op) {
-        if (!shouldAnalyze(node)) {
-            return;
-        }
-        HashSet<Node> exits = new HashSet<>();
-        HashSet<Invoke> invokes = new HashSet<>();
-
-        analyze(node, exits, invokes);
-        if (exits.isEmpty() && invokes.isEmpty()) {
-            Debug.log("!!!!!!!! non-escaping object: %s (%s)", node, node.stamp());
-            removeAllocation(graph, node, op);
-            Debug.dump(graph, "After escape", graph);
-        } else {
-            Debug.log("%n####### escaping object: %s (%s)", node, node.stamp());
-            if (GraalOptions.TraceEscapeAnalysis) {
-                TTY.print(" escapes at ", node);
-                for (Node n : exits) {
-                    TTY.print("%s, ", n);
-                }
-                for (Invoke n : invokes) {
-                    TTY.print("%s, ", n);
-                }
-                TTY.println();
-            }
-        }
-    }
-
-    protected void removeAllocation(StructuredGraph graph, FixedWithNextNode node, EscapeOp op) {
-        new EscapementFixup(virtualIds++, op, graph, node).apply();
-
-        for (PhiNode phi : node.graph().getNodes(PhiNode.class)) {
-            ValueNode simpleValue = phi;
-            boolean required = false;
-            for (ValueNode value : phi.values()) {
-                if (value != phi && value != simpleValue) {
-                    if (simpleValue != phi) {
-                        required = true;
-                        break;
-                    }
-                    simpleValue = value;
-                }
-            }
-            if (!required) {
-                graph.replaceFloating(phi, simpleValue);
-            }
-        }
-        new CanonicalizerPhase(target, runtime, assumptions).apply(graph);
-    }
-
-    protected boolean shouldAnalyze(@SuppressWarnings("unused") FixedWithNextNode node) {
-        return true;
-    }
-
-    private static void analyze(Node node, HashSet<Node> exits, HashSet<Invoke> invokes) {
-        for (Node usage : node.usages().snapshot()) {
-            boolean escapes = escape(node, usage);
-            if (escapes) {
-                if (usage instanceof VirtualState) {
-                    // nothing to do...
-                } else if (usage instanceof ValueProxyNode) {
-                    ValueProxyNode proxy = (ValueProxyNode) usage;
-                    for (Node proxyUsage : proxy.usages()) {
-                        if (!(proxyUsage instanceof VirtualObjectState)) {
-                            exits.add(usage);
-                            break;
-                        }
-                    }
-                } else if (usage instanceof MethodCallTargetNode) {
-                    if (usage.usages().isEmpty()) {
-                        usage.safeDelete();
-                    } else {
-                        invokes.add(((MethodCallTargetNode) usage).invoke());
-                    }
-                } else {
-                    exits.add(usage);
-                    break;
-                }
-            }
-        }
-    }
-
-    private static boolean escape(Node node, Node usage) {
-        if (usage instanceof IsNullNode) {
-            assert ((IsNullNode) usage).object() == node;
-            return false;
-        } else if (usage instanceof IsTypeNode) {
-            assert ((IsTypeNode) usage).objectClass() == node;
-            return false;
-        } else if (usage instanceof VirtualState) {
-            assert usage.inputs().contains(node);
-            return true;
-        } else if (usage instanceof AccessMonitorNode) {
-            assert ((AccessMonitorNode) usage).object() == node;
-            return false;
-        } else if (usage instanceof LoadFieldNode) {
-            assert ((LoadFieldNode) usage).object() == node;
-            return false;
-        } else if (usage instanceof StoreFieldNode) {
-            StoreFieldNode x = (StoreFieldNode) usage;
-            // self-references do escape
-            return x.value() == node; // TODO (thomaswue) Check if we can add this condition? && x.object() != node;
-        } else if (usage instanceof LoadIndexedNode) {
-            LoadIndexedNode x = (LoadIndexedNode) usage;
-            if (x.index() == node) {
-                return true;
-            } else {
-                assert x.array() == node;
-                return !isValidConstantIndex(x);
-            }
-        } else if (usage instanceof StoreIndexedNode) {
-            StoreIndexedNode x = (StoreIndexedNode) usage;
-            if (x.index() == node) {
-                return true;
-            } else {
-                assert x.array() == node || x.value() == node;
-                // in order to not escape the access needs to have a valid constant index and either a store into node
-                // or self-referencing
-                return !isValidConstantIndex(x) || x.value() == node && x.array() != node;
-            }
-        } else if (usage instanceof RegisterFinalizerNode) {
-            assert ((RegisterFinalizerNode) usage).object() == node;
-            return false;
-        } else if (usage instanceof ArrayLengthNode) {
-            assert ((ArrayLengthNode) usage).array() == node;
-            return false;
-        } else if (usage instanceof ValueProxyNode) {
-            for (Node vpnUsage : usage.usages().snapshot()) {
-                if (escape(usage, vpnUsage)) {
-                    return true;
-                }
-            }
-            return false;
-        } else {
-            return true;
-        }
-    }
-
-    public static boolean isValidConstantIndex(AccessIndexedNode x) {
-        Constant index = x.index().asConstant();
-        if (x.array() instanceof NewArrayNode) {
-            Constant length = ((NewArrayNode) x.array()).dimension(0).asConstant();
-            return index != null && length != null && index.asInt() >= 0 && index.asInt() < length.asInt();
-        } else {
-            return false;
-        }
-    }
-}
--- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/MonitorTest.java	Fri Sep 14 10:03:38 2012 +0200
+++ b/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/MonitorTest.java	Fri Sep 14 15:16:50 2012 +0200
@@ -24,7 +24,7 @@
 
 import org.junit.*;
 
-import com.oracle.graal.compiler.phases.*;
+import com.oracle.graal.compiler.phases.ea.*;
 import com.oracle.graal.compiler.test.*;
 
 public class MonitorTest extends GraalCompilerTest {
@@ -60,7 +60,7 @@
     }
 
     /**
-     * Tests monitor operations on {@link EscapeAnalysisPhase virtual objects}.
+     * Tests monitor operations on {@link PartialEscapeAnalysisPhase virtual objects}.
      */
     @Test
     public void test3() {