# HG changeset patch # User Lukas Stadler # Date 1364206552 -3600 # Node ID ed38b01ce7bcdb1b4ddb21c2e6652f64482ab865 # Parent 31b7a648b4b3ed59ec265b86dda22cbeaf35487c changes to iterative inlining diff -r 31b7a648b4b3 -r ed38b01ce7bc graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java Mon Mar 25 11:15:52 2013 +0100 @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013, 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.ea; + +import static org.junit.Assert.*; + +import java.util.concurrent.*; + +import org.junit.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.compiler.test.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.java.*; +import com.oracle.graal.phases.*; +import com.oracle.graal.phases.common.*; +import com.oracle.graal.virtual.phases.ea.*; + +public class IterativeInliningTest extends GraalCompilerTest { + + private StructuredGraph graph; + + public static class TestObject { + + public Callable callable; + + public TestObject(Callable callable) { + this.callable = callable; + } + } + + public static class TestInt implements Callable { + + public int x; + public int y; + + public TestInt(int x, int y) { + this.x = x; + this.y = y; + } + + @Override + public Integer call() throws Exception { + return new Integer(x); + } + } + + @SuppressWarnings("all") + public static int testSimpleSnippet(int b) throws Exception { + TestObject a = new TestObject(null); + a.callable = new TestInt(b, 9); + return a.callable.call(); + } + + @Test + public void testSimple() { + ValueNode result = getReturn("testSimpleSnippet").result(); + assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty()); + assertEquals(graph.getLocal(0), result); + } + + @SuppressWarnings("all") + public static int testSimpleReadSnippet(TestObject a, int b) throws Exception { + a.callable = new TestInt(b, 9); + return a.callable.call(); + } + + @Ignore + @Test + public void testSimpleRead() { + ValueNode result = getReturn("testSimpleReadSnippet").result(); + assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty()); + assertEquals(graph.getLocal(1), result); + } + + final ReturnNode getReturn(String snippet) { + processMethod(snippet); + assertEquals(1, graph.getNodes(ReturnNode.class).count()); + return graph.getNodes(ReturnNode.class).first(); + } + + private void processMethod(final String snippet) { + graph = parse(snippet); + new ComputeProbabilityPhase().apply(graph); + GraalOptions.PEAReadCache = true; + new IterativeInliningPhase(runtime(), new Assumptions(false), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph); + } +} diff -r 31b7a648b4b3 -r ed38b01ce7bc graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java Mon Mar 25 11:06:45 2013 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java Mon Mar 25 11:15:52 2013 +0100 @@ -87,7 +87,7 @@ PartialEscapeClosure closure = new PartialEscapeClosure(graph.createNodeBitMap(), schedule, runtime, assumptions); ReentrantBlockIterator.apply(closure, schedule.getCFG().getStartBlock(), new BlockState(), null); - if (closure.getNewVirtualObjectCount() != 0) { + if (!closure.getEffects().isEmpty()) { // apply the effects collected during the escape analysis iteration ArrayList obsoleteNodes = new ArrayList<>(); for (Effect effect : closure.getEffects()) { @@ -103,11 +103,10 @@ new CanonicalizerPhase(runtime, assumptions, null, customCanonicalizer).apply(graph); } } + Map hints = GraalOptions.PEAInliningHints ? PartialEscapeAnalysisPhase.getHints(graph) : null; - InliningPhase inlining = new InliningPhase(runtime, GraalOptions.PEAInliningHints ? closure.getHints() : null, assumptions, cache, plan, optimisticOpts); - if (simple) { - inlining.setMaxMethodsPerInlining(1); - } + InliningPhase inlining = new InliningPhase(runtime, hints, assumptions, cache, plan, optimisticOpts); + inlining.setMaxMethodsPerInlining(simple ? 1 : Integer.MAX_VALUE); inlining.apply(graph); new DeadCodeEliminationPhase().apply(graph); @@ -116,7 +115,7 @@ new IterativeConditionalEliminationPhase(runtime, assumptions).apply(graph); } - if (!simple && closure.getNewVirtualObjectCount() == 0 && inlining.getInliningCount() == 0) { + if (closure.getEffects().isEmpty() && inlining.getInliningCount() == 0) { return false; } return true; diff -r 31b7a648b4b3 -r ed38b01ce7bc graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeAnalysisPhase.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeAnalysisPhase.java Mon Mar 25 11:06:45 2013 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeAnalysisPhase.java Mon Mar 25 11:15:52 2013 +0100 @@ -30,12 +30,14 @@ import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.common.CanonicalizerPhase.CustomCanonicalizer; import com.oracle.graal.phases.graph.*; import com.oracle.graal.phases.schedule.*; +import com.oracle.graal.virtual.nodes.*; import com.oracle.graal.virtual.phases.ea.EffectList.Effect; public class PartialEscapeAnalysisPhase extends Phase { @@ -93,7 +95,7 @@ PartialEscapeClosure closure = new PartialEscapeClosure(graph.createNodeBitMap(), schedule, runtime, assumptions); ReentrantBlockIterator.apply(closure, schedule.getCFG().getStartBlock(), new BlockState(), null); - if (closure.getNewVirtualObjectCount() == 0) { + if (closure.getEffects().isEmpty()) { return false; } @@ -196,4 +198,39 @@ } return success; } + + public static Map getHints(StructuredGraph graph) { + Map hints = null; + for (MaterializeObjectNode materialize : graph.getNodes(MaterializeObjectNode.class)) { + double sum = 0; + double invokeSum = 0; + for (Node usage : materialize.usages()) { + if (usage instanceof FixedNode) { + sum += ((FixedNode) usage).probability(); + } else { + if (usage instanceof MethodCallTargetNode) { + invokeSum += ((MethodCallTargetNode) usage).invoke().probability(); + } + for (Node secondLevelUage : materialize.usages()) { + if (secondLevelUage instanceof FixedNode) { + sum += ((FixedNode) secondLevelUage).probability(); + } + } + } + } + // TODO(lstadler) get rid of this magic number + if (sum > 100 && invokeSum > 0) { + for (Node usage : materialize.usages()) { + if (usage instanceof MethodCallTargetNode) { + if (hints == null) { + hints = new HashMap<>(); + } + Invoke invoke = ((MethodCallTargetNode) usage).invoke(); + hints.put(invoke, sum / invokeSum); + } + } + } + } + return hints; + } }