changeset 8957:1af9b5d75139

Move framestate assignement to the hir
author Gilles Duboscq <duboscq@ssw.jku.at>
date Tue, 09 Apr 2013 16:28:19 +0200
parents 74725f2f6122
children 64d3d352f943 50c63b0d858e
files graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignementPhase.java graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java
diffstat 5 files changed, 142 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Tue Apr 09 16:27:59 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Tue Apr 09 16:28:19 2013 +0200
@@ -225,6 +225,8 @@
 
         new LoweringPhase(target, runtime, replacements, assumptions).apply(graph);
 
+        new FrameStateAssignementPhase().apply(graph);
+
         final SchedulePhase schedule = new SchedulePhase();
         schedule.apply(graph);
         Debug.dump(schedule, "final schedule");
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Tue Apr 09 16:27:59 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Tue Apr 09 16:28:19 2013 +0200
@@ -338,14 +338,7 @@
             if (instr instanceof StateSplit) {
                 stateAfter = ((StateSplit) instr).stateAfter();
             }
-            if (instr instanceof DeoptimizingNode) {
-                DeoptimizingNode deopt = (DeoptimizingNode) instr;
-                if (deopt.canDeoptimize() && deopt.getDeoptimizationState() == null) {
-                    deopt.setDeoptimizationState(lastState);
-                }
-            }
             if (instr instanceof ValueNode) {
-
                 ValueNode valueNode = (ValueNode) instr;
                 if (operand(valueNode) == null) {
                     if (!peephole(valueNode)) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java	Tue Apr 09 16:27:59 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java	Tue Apr 09 16:28:19 2013 +0200
@@ -70,7 +70,6 @@
     @Override
     public void generate(LIRGenerator gen) {
         assert lockDepth != -1;
-        assert stateAfter() != null;
         HotSpotLIRGenerator hsGen = (HotSpotLIRGenerator) gen;
         StackSlot slot = hsGen.getLockSlot(lockDepth);
         if (!eliminated) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignementPhase.java	Tue Apr 09 16:28:19 2013 +0200
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2013, 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.phases.common;
+
+import java.util.*;
+
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.iterators.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.cfg.*;
+import com.oracle.graal.nodes.util.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.graph.*;
+import com.oracle.graal.phases.graph.ReentrantBlockIterator.BlockIteratorClosure;
+
+public class FrameStateAssignementPhase extends Phase {
+
+    private static class FrameStateAssignementState {
+
+        private FrameState framestate;
+
+        public FrameStateAssignementState(FrameState framestate) {
+            this.framestate = framestate;
+        }
+
+        public FrameState getFramestate() {
+            return framestate;
+        }
+
+        public void setFramestate(FrameState framestate) {
+            assert framestate != null;
+            this.framestate = framestate;
+        }
+
+        @Override
+        public String toString() {
+            return "FrameStateAssignementState: " + framestate;
+        }
+    }
+
+    private static class FrameStateAssignementClosure extends BlockIteratorClosure<FrameStateAssignementState> {
+
+        @Override
+        protected void processBlock(Block block, FrameStateAssignementState currentState) {
+            FixedNode node = block.getBeginNode();
+            while (node != null) {
+                if (node instanceof DeoptimizingNode) {
+                    DeoptimizingNode deopt = (DeoptimizingNode) node;
+                    if (deopt.canDeoptimize() && deopt.getDeoptimizationState() == null) {
+                        deopt.setDeoptimizationState(currentState.getFramestate());
+                    }
+                }
+
+                if (node instanceof StateSplit) {
+                    StateSplit stateSplit = (StateSplit) node;
+                    if (stateSplit.stateAfter() != null) {
+                        currentState.setFramestate(stateSplit.stateAfter());
+                        stateSplit.setStateAfter(null);
+                    }
+                }
+
+                if (node instanceof FixedWithNextNode) {
+                    node = ((FixedWithNextNode) node).next();
+                } else {
+                    node = null;
+                }
+            }
+        }
+
+        @Override
+        protected FrameStateAssignementState merge(Block mergeBlock, List<FrameStateAssignementState> states) {
+            MergeNode merge = (MergeNode) mergeBlock.getBeginNode();
+            if (merge.stateAfter() != null) {
+                return new FrameStateAssignementState(merge.stateAfter());
+            }
+            return new FrameStateAssignementState(singleFrameState(states));
+        }
+
+        @Override
+        protected FrameStateAssignementState cloneState(FrameStateAssignementState oldState) {
+            return new FrameStateAssignementState(oldState.getFramestate());
+        }
+
+        @Override
+        protected List<FrameStateAssignementState> processLoop(Loop loop, FrameStateAssignementState initialState) {
+            return ReentrantBlockIterator.processLoop(this, loop, initialState).exitStates;
+        }
+
+    }
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        assert checkFixedDeopts(graph);
+        ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, false, false);
+        ReentrantBlockIterator.apply(new FrameStateAssignementClosure(), cfg.getStartBlock(), new FrameStateAssignementState(null), null);
+    }
+
+    private static boolean checkFixedDeopts(StructuredGraph graph) {
+        NodePredicate isFloatingNode = GraphUtil.isFloatingNode();
+        for (Node n : graph.getNodes().filterInterface(DeoptimizingNode.class)) {
+            if (((DeoptimizingNode) n).canDeoptimize() && isFloatingNode.apply(n)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private static FrameState singleFrameState(List<FrameStateAssignementState> states) {
+        Iterator<FrameStateAssignementState> it = states.iterator();
+        assert it.hasNext();
+        FrameState first = it.next().getFramestate();
+        while (it.hasNext()) {
+            if (first != it.next().getFramestate()) {
+                return null;
+            }
+        }
+        return first;
+    }
+}
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java	Tue Apr 09 16:27:59 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java	Tue Apr 09 16:28:19 2013 +0200
@@ -466,7 +466,7 @@
                     if (!(usage instanceof FrameState)) {
                         throw new SchedulingError(usage.toString());
                     }
-                    if (!(unscheduledUsage instanceof StateSplit)) {
+                    if (!(unscheduledUsage instanceof StateSplit || unscheduledUsage instanceof DeoptimizingNode)) {
                         throw new SchedulingError(unscheduledUsage.toString());
                     }
                     // Otherwise: Put the input into the same block as the usage.