changeset 4387:1bd28959b8b8

Merge.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Sat, 28 Jan 2012 00:40:18 +0100
parents 217e0a60c711 (current diff) 5caca26cb1b9 (diff)
children b484ad70facb
files graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/simple/DataFlowAnalysis.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/FloatingReadPhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GlobalValueNumberingPhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/InliningUtil.java graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/GraphTest.java
diffstat 14 files changed, 189 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/simple/DataFlowAnalysis.java	Sat Jan 28 00:39:03 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/simple/DataFlowAnalysis.java	Sat Jan 28 00:40:18 2012 +0100
@@ -22,7 +22,7 @@
  */
 package com.oracle.max.graal.alloc.simple;
 
-import static com.oracle.max.graal.compiler.lir.LIRPhiMapping.*;
+import static com.oracle.max.cri.ci.CiValueUtil.*;
 import static com.oracle.max.graal.alloc.util.ValueUtil.*;
 
 import java.util.*;
@@ -34,6 +34,7 @@
 import com.oracle.max.graal.compiler.alloc.*;
 import com.oracle.max.graal.compiler.lir.*;
 import com.oracle.max.graal.compiler.lir.LIRInstruction.ValueProcedure;
+import com.oracle.max.graal.compiler.lir.LIRPhiMapping.PhiValueProcedure;
 import com.oracle.max.graal.compiler.schedule.*;
 
 public class DataFlowAnalysis {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java	Sat Jan 28 00:39:03 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java	Sat Jan 28 00:40:18 2012 +0100
@@ -129,7 +129,7 @@
 
     // Code generator settings
     public static boolean UseBranchPrediction                = true;
-    public static boolean UseExceptionProbability            = ____;
+    public static boolean UseExceptionProbability            = true;
     public static boolean AllowExplicitExceptionChecks       = true;
     public static boolean OmitHotExceptionStacktrace         = ____;
     public static int     MatureInvocationCount              = 100;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Sat Jan 28 00:39:03 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Sat Jan 28 00:40:18 2012 +0100
@@ -643,7 +643,7 @@
         if (writeBarrier != null) {
             emitXir(writeBarrier, null, null, false);
         }
-    }
+     }
 
     @SuppressWarnings("unused")
     protected void preGCWriteBarrier(CiValue addrOpr, boolean patch, LIRDebugInfo info) {
@@ -747,7 +747,7 @@
     private void emitInstanceOfBranch(InstanceOfNode x, LabelRef trueSuccessor, LabelRef falseSuccessor, LIRDebugInfo info) {
         XirArgument obj = toXirArgument(x.object());
         XirSnippet snippet = xir.genInstanceOf(site(x), obj, toXirArgument(x.targetClassInstruction()), x.targetClass());
-        emitXir(snippet, x, info, null, false, x.negated ? falseSuccessor : trueSuccessor, x.negated ? trueSuccessor : falseSuccessor);
+        emitXir(snippet, x, info, null, false, x.negated() ? falseSuccessor : trueSuccessor, x.negated() ? trueSuccessor : falseSuccessor);
     }
 
 
@@ -789,8 +789,8 @@
 
     private Variable emitInstanceOfConditional(InstanceOfNode x, CiValue trueValue, CiValue falseValue) {
         XirArgument obj = toXirArgument(x.object());
-        XirArgument trueArg = toXirArgument(x.negated ? falseValue : trueValue);
-        XirArgument falseArg = toXirArgument(x.negated ? trueValue : falseValue);
+        XirArgument trueArg = toXirArgument(x.negated() ? falseValue : trueValue);
+        XirArgument falseArg = toXirArgument(x.negated() ? trueValue : falseValue);
         XirSnippet snippet = xir.genMaterializeInstanceOf(site(x), obj, toXirArgument(x.targetClassInstruction()), trueArg, falseArg, x.targetClass());
         return (Variable) emitXir(snippet, null, null, false);
     }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/FloatingReadPhase.java	Sat Jan 28 00:39:03 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/FloatingReadPhase.java	Sat Jan 28 00:40:18 2012 +0100
@@ -30,7 +30,7 @@
 import com.oracle.max.graal.debug.*;
 import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.nodes.*;
-import com.oracle.max.graal.nodes.PhiNode.*;
+import com.oracle.max.graal.nodes.PhiNode.PhiType;
 import com.oracle.max.graal.nodes.extended.*;
 
 public class FloatingReadPhase extends Phase {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GlobalValueNumberingPhase.java	Sat Jan 28 00:39:03 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GlobalValueNumberingPhase.java	Sat Jan 28 00:40:18 2012 +0100
@@ -49,7 +49,9 @@
             if (n.getNodeClass().valueNumberable()) {
                 Node newNode = compilerGraph.findDuplicate(n);
                 if (newNode != null) {
-                    n.replaceAndDelete(newNode);
+                    assert !(n instanceof FixedNode || newNode instanceof FixedNode);
+                    n.replaceAtUsages(newNode);
+                    n.safeDelete();
                     metricGlobalValueNumberingHits.increment();
                     if (GraalOptions.TraceGVN) {
                         TTY.println("GVN applied and new node is " + newNode);
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/InliningUtil.java	Sat Jan 28 00:39:03 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/InliningUtil.java	Sat Jan 28 00:40:18 2012 +0100
@@ -405,7 +405,18 @@
         } else {
             if (unwindNode != null) {
                 UnwindNode unwindDuplicate = (UnwindNode) duplicates.get(unwindNode);
-                unwindDuplicate.replaceAndDelete(graph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile)));
+                DeoptimizeNode deoptimizeNode = new DeoptimizeNode(DeoptAction.InvalidateRecompile);
+                unwindDuplicate.replaceAndDelete(graph.add(deoptimizeNode));
+                // move the deopt upwards if there is a monitor exit that tries to use the "after exception" frame state
+                // (because there is no "after exception" frame state!)
+                if (deoptimizeNode.predecessor() instanceof MonitorExitNode) {
+                    MonitorExitNode monitorExit = (MonitorExitNode) deoptimizeNode.predecessor();
+                    if (monitorExit.stateAfter() != null && monitorExit.stateAfter().bci == FrameState.AFTER_EXCEPTION_BCI) {
+                        FrameState monitorFrameState = monitorExit.stateAfter();
+                        graph.removeFixed(monitorExit);
+                        monitorFrameState.safeDelete();
+                    }
+                }
             }
         }
 
@@ -428,8 +439,12 @@
                 } else if (frameState.bci == FrameState.AFTER_BCI) {
                     frameState.replaceAndDelete(stateAfter);
                 } else if (frameState.bci == FrameState.AFTER_EXCEPTION_BCI) {
-                    assert stateAtExceptionEdge != null;
-                    frameState.replaceAndDelete(stateAtExceptionEdge);
+                    if (frameState.isAlive()) {
+                        assert stateAtExceptionEdge != null;
+                        frameState.replaceAndDelete(stateAtExceptionEdge);
+                    } else {
+                        assert stateAtExceptionEdge == null;
+                    }
                 }
             }
         }
@@ -452,7 +467,15 @@
             returnDuplicate.clearInputs();
             Node n = invoke.next();
             invoke.setNext(null);
-            returnDuplicate.replaceAndDelete(n);
+            if (n instanceof BeginNode) {
+                BeginNode begin = (BeginNode) n;
+                FixedNode next = begin.next();
+                begin.setNext(null);
+                returnDuplicate.replaceAndDelete(next);
+                begin.safeDelete();
+            } else {
+                returnDuplicate.replaceAndDelete(n);
+            }
         }
 
         invoke.node().clearInputs();
--- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/IfNode.java	Sat Jan 28 00:39:03 2012 +0100
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/IfNode.java	Sat Jan 28 00:40:18 2012 +0100
@@ -25,6 +25,7 @@
 import java.util.*;
 
 import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.nodes.spi.*;
 import com.oracle.max.graal.nodes.type.*;
 
@@ -86,7 +87,7 @@
      * @param istrue {@code true} if the true successor is requested, {@code false} otherwise
      * @return the corresponding successor
      */
-    public FixedNode successor(boolean istrue) {
+    public BeginNode successor(boolean istrue) {
         return blockSuccessor(istrue ? 0 : 1);
     }
 
--- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/StructuredGraph.java	Sat Jan 28 00:39:03 2012 +0100
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/StructuredGraph.java	Sat Jan 28 00:40:18 2012 +0100
@@ -28,6 +28,7 @@
 import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.nodes.calc.*;
 import com.oracle.max.graal.nodes.java.*;
+import com.oracle.max.graal.nodes.util.*;
 
 
 /**
@@ -191,12 +192,38 @@
         assert node != null;
         assert node.usages().isEmpty();
         assert survivingSuccessor >= 0 && survivingSuccessor < node.blockSuccessorCount() : "invalid surviving successor " + survivingSuccessor + " for " + node;
-        FixedNode next = node.blockSuccessor(survivingSuccessor);
+        BeginNode begin = node.blockSuccessor(survivingSuccessor);
+        FixedNode next = begin.next();
+        begin.setNext(null);
         for (int i = 0; i < node.blockSuccessorCount(); i++) {
             node.setBlockSuccessor(i, null);
         }
         node.replaceAtPredecessors(next);
         node.safeDelete();
+        begin.safeDelete();
+    }
+
+    public void removeSplitPropagate(ControlSplitNode node, int survivingSuccessor) {
+        assert node != null;
+        assert node.usages().isEmpty();
+        assert survivingSuccessor >= 0 && survivingSuccessor < node.blockSuccessorCount() : "invalid surviving successor " + survivingSuccessor + " for " + node;
+        BeginNode begin = node.blockSuccessor(survivingSuccessor);
+        FixedNode next = begin.next();
+        begin.setNext(null);
+        for (int i = 0; i < node.blockSuccessorCount(); i++) {
+            BeginNode successor = node.blockSuccessor(i);
+            node.setBlockSuccessor(i, null);
+            if (successor != begin && successor.isAlive()) {
+                GraphUtil.killCFG(successor);
+            }
+        }
+        if (next.isAlive()) {
+            node.replaceAtPredecessors(next);
+            node.safeDelete();
+            begin.safeDelete();
+        } else {
+            assert node.isDeleted();
+        }
     }
 
     public void replaceSplit(ControlSplitNode node, Node replacement, int survivingSuccessor) {
@@ -212,24 +239,30 @@
     public void replaceSplitWithFixed(ControlSplitNode node, FixedWithNextNode replacement, int survivingSuccessor) {
         assert node != null && replacement != null && node.isAlive() && replacement.isAlive() : "cannot replace " + node + " with " + replacement;
         assert survivingSuccessor >= 0 && survivingSuccessor < node.blockSuccessorCount() : "invalid surviving successor " + survivingSuccessor + " for " + node;
-        FixedNode next = node.blockSuccessor(survivingSuccessor);
+        BeginNode begin = node.blockSuccessor(survivingSuccessor);
+        FixedNode next = begin.next();
+        begin.setNext(null);
         for (int i = 0; i < node.blockSuccessorCount(); i++) {
             node.setBlockSuccessor(i, null);
         }
         replacement.setNext(next);
         node.replaceAndDelete(replacement);
+        begin.safeDelete();
     }
 
     public void replaceSplitWithFloating(ControlSplitNode node, FloatingNode replacement, int survivingSuccessor) {
         assert node != null && replacement != null && node.isAlive() && replacement.isAlive() : "cannot replace " + node + " with " + replacement;
         assert survivingSuccessor >= 0 && survivingSuccessor < node.blockSuccessorCount() : "invalid surviving successor " + survivingSuccessor + " for " + node;
-        FixedNode next = node.blockSuccessor(survivingSuccessor);
+        BeginNode begin = node.blockSuccessor(survivingSuccessor);
+        FixedNode next = begin.next();
+        begin.setNext(null);
         for (int i = 0; i < node.blockSuccessorCount(); i++) {
             node.setBlockSuccessor(i, null);
         }
         node.replaceAtPredecessors(next);
         node.replaceAtUsages(replacement);
         node.safeDelete();
+        begin.safeDelete();
     }
 
     public void addAfterFixed(FixedWithNextNode node, FixedWithNextNode newNode) {
--- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/LookupSwitchNode.java	Sat Jan 28 00:39:03 2012 +0100
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/LookupSwitchNode.java	Sat Jan 28 00:40:18 2012 +0100
@@ -41,6 +41,7 @@
      */
     public LookupSwitchNode(ValueNode value, BeginNode[] successors, int[] keys, double[] probability) {
         super(value, successors, probability);
+        assert successors.length == keys.length + 1;
         this.keys = keys;
     }
 
--- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/InstanceOfNode.java	Sat Jan 28 00:39:03 2012 +0100
+++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/InstanceOfNode.java	Sat Jan 28 00:40:18 2012 +0100
@@ -34,7 +34,11 @@
  */
 public final class InstanceOfNode extends TypeCheckNode implements Canonicalizable, LIRLowerable {
 
-    @Data public final boolean negated;
+    @Data private final boolean negated;
+
+    public boolean negated() {
+        return negated;
+    }
 
     /**
      * Constructs a new InstanceOfNode.
@@ -71,8 +75,7 @@
             if (constant.isNull()) {
                 return ConstantNode.forBoolean(negated, graph());
             } else {
-                // this should never happen - non-null constants are always expected to provide an exactType
-                assert false;
+                assert false : "non-null constants are always expected to provide an exactType";
             }
         }
         return this;
--- a/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/GraphTest.java	Sat Jan 28 00:39:03 2012 +0100
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/GraphTest.java	Sat Jan 28 00:40:18 2012 +0100
@@ -83,7 +83,31 @@
                 found = m;
             }
         }
-        return parse(found);
+        if (found != null) {
+            return parse(found);
+        } else {
+            throw new RuntimeException("method not found: " + methodName);
+        }
+    }
+
+    /**
+     * Parses a Java method to produce a graph.
+     *
+     * @param methodName the name of the method in {@code this.getClass()} to be parsed
+     */
+    protected StructuredGraph parseProfiled(String methodName) {
+        Method found = null;
+        for (Method m : this.getClass().getMethods()) {
+            if (m.getName().equals(methodName)) {
+                Assert.assertNull(found);
+                found = m;
+            }
+        }
+        if (found != null) {
+            return parseProfiled(found);
+        } else {
+            throw new RuntimeException("method not found: " + methodName);
+        }
     }
 
     /**
@@ -96,6 +120,16 @@
         return graph;
     }
 
+    /**
+     * Parses a Java method to produce a graph.
+     */
+    protected StructuredGraph parseProfiled(Method m) {
+        RiResolvedMethod riMethod = runtime.getRiMethod(m);
+        StructuredGraph graph = new StructuredGraph(riMethod);
+        new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault()).apply(graph);
+        return graph;
+    }
+
     protected PhasePlan getDefaultPhasePlan() {
         PhasePlan plan = new PhasePlan();
         plan.addPhase(PhasePosition.AFTER_PARSING, new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getSnippetDefault()));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/InvokeExceptionTest.java	Sat Jan 28 00:40:18 2012 +0100
@@ -0,0 +1,69 @@
+/*
+ * 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.max.graal.compiler.tests;
+
+import java.util.*;
+
+import org.junit.*;
+
+import com.oracle.max.graal.compiler.phases.*;
+import com.oracle.max.graal.nodes.*;
+
+public class InvokeExceptionTest extends GraphTest {
+
+    public static synchronized void throwException(int i) {
+        if (i == 1) {
+            throw new RuntimeException();
+        }
+    }
+
+    @Test
+    public void test1() {
+        // fill the profiling data...
+        for (int i = 0; i < 10000; i++) {
+            try {
+                throwException(i & 1);
+                test1Snippet(0);
+            } catch (Throwable t) {
+                // nothing to do...
+            }
+        }
+        test("test1Snippet");
+    }
+
+    @SuppressWarnings("all")
+    public static void test1Snippet(int a) {
+        throwException(a);
+    }
+
+    private void test(String snippet) {
+        StructuredGraph graph = parseProfiled(snippet);
+        Collection<Invoke> hints = new ArrayList<>();
+        for (Invoke invoke : graph.getInvokes()) {
+            hints.add(invoke);
+        }
+        new InliningPhase(null, runtime(), hints, null, getDefaultPhasePlan()).apply(graph);
+        new CanonicalizerPhase(null, runtime(), null).apply(graph);
+        new DeadCodeEliminationPhase().apply(graph);
+    }
+}
--- a/mx/eclipse-settings/org.eclipse.jdt.core.prefs	Sat Jan 28 00:39:03 2012 +0100
+++ b/mx/eclipse-settings/org.eclipse.jdt.core.prefs	Sat Jan 28 00:40:18 2012 +0100
@@ -167,7 +167,7 @@
 org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
 org.eclipse.jdt.core.formatter.comment.format_block_comments=true
 org.eclipse.jdt.core.formatter.comment.format_comments=true
-org.eclipse.jdt.core.formatter.comment.format_header=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
 org.eclipse.jdt.core.formatter.comment.format_html=true
 org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
 org.eclipse.jdt.core.formatter.comment.format_line_comments=true
--- a/mx/eclipse-settings/org.eclipse.jdt.ui.prefs	Sat Jan 28 00:39:03 2012 +0100
+++ b/mx/eclipse-settings/org.eclipse.jdt.ui.prefs	Sat Jan 28 00:40:18 2012 +0100
@@ -48,7 +48,7 @@
 cleanup_settings_version=2
 comment_clear_blank_lines=false
 comment_format_comments=true
-comment_format_header=true
+comment_format_header=false
 comment_format_html=true
 comment_format_source_code=true
 comment_indent_parameter_description=true