changeset 8417:7e281cb9ea10

Merge.
author Doug Simon <doug.simon@oracle.com>
date Thu, 21 Mar 2013 09:44:47 +0100
parents 102b5249e97e (current diff) 743d0ac1fc81 (diff)
children ba659864f935
files graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java
diffstat 6 files changed, 192 insertions(+), 132 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Wed Mar 20 22:30:33 2013 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Thu Mar 21 09:44:47 2013 +0100
@@ -1073,7 +1073,11 @@
     }
 
     private static boolean optimizeMethodArgument(Value value) {
-        return isStackSlot(value) && asStackSlot(value).isInCallerFrame() && (GraalOptions.IncomingMethodArgumentsGCSafe || value.getKind() != Kind.Object);
+        /*
+         * Object method arguments that are passed on the stack are currently not optimized because
+         * this requires that the runtime visits method arguments during stack walking.
+         */
+        return isStackSlot(value) && asStackSlot(value).isInCallerFrame() && value.getKind() != Kind.Object;
     }
 
     /**
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java	Wed Mar 20 22:30:33 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java	Thu Mar 21 09:44:47 2013 +0100
@@ -77,4 +77,6 @@
     public Node node() {
         return this;
     }
+
+    public abstract Access asFixedNode();
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java	Wed Mar 20 22:30:33 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java	Thu Mar 21 09:44:47 2013 +0100
@@ -60,4 +60,9 @@
     public ValueNode canonical(CanonicalizerTool tool) {
         return ReadNode.canonicalizeRead(this, location(), object(), tool);
     }
+
+    @Override
+    public Access asFixedNode() {
+        return graph().add(new ReadNode(object(), nullCheckLocation(), stamp(), dependencies()));
+    }
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java	Wed Mar 20 22:30:33 2013 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java	Thu Mar 21 09:44:47 2013 +0100
@@ -37,123 +37,60 @@
 
 public class GuardLoweringPhase extends Phase {
 
-    private TargetDescription target;
+    private abstract static class ScheduledNodeIterator {
 
-    public GuardLoweringPhase(TargetDescription target) {
-        this.target = target;
-    }
+        private FixedWithNextNode lastFixed;
+        private FixedWithNextNode reconnect;
+        private ListIterator<ScheduledNode> iterator;
 
-    @Override
-    protected void run(StructuredGraph graph) {
-        SchedulePhase schedule = new SchedulePhase();
-        schedule.apply(graph);
+        public void processNodes(List<ScheduledNode> nodes, FixedWithNextNode begin) {
+            assert begin != null;
+            lastFixed = begin;
+            reconnect = null;
+            iterator = nodes.listIterator();
+            while (iterator.hasNext()) {
+                Node node = iterator.next();
+                if (!node.isAlive()) {
+                    continue;
+                }
+                if (reconnect != null && node instanceof FixedNode) {
+                    reconnect.setNext((FixedNode) node);
+                    reconnect = null;
+                }
+                if (node instanceof FixedWithNextNode) {
+                    lastFixed = (FixedWithNextNode) node;
+                }
+                processNode(node);
+            }
+        }
 
-        for (Block block : schedule.getCFG().getBlocks()) {
-            processBlock(block, schedule, graph, target);
+        protected void insert(FixedNode start, FixedWithNextNode end) {
+            this.lastFixed.setNext(start);
+            this.lastFixed = end;
+            this.reconnect = end;
         }
+
+        protected void replaceCurrent(FixedWithNextNode newNode) {
+            Node current = iterator.previous();
+            iterator.next(); // needed because of the previous() call
+            current.replaceAndDelete(newNode);
+            insert(newNode, newNode);
+            iterator.set(newNode);
+        }
+
+        protected abstract void processNode(Node node);
     }
 
-    private static void processBlock(Block block, SchedulePhase schedule, StructuredGraph graph, TargetDescription target) {
-        List<ScheduledNode> nodes = schedule.nodesFor(block);
-        if (GraalOptions.OptImplicitNullChecks && target.implicitNullCheckLimit > 0) {
-            useImplicitNullChecks(block.getBeginNode(), nodes, graph, target);
-        }
-        FixedWithNextNode lastFixed = block.getBeginNode();
-        FixedWithNextNode lastFastPath = null;
-        for (Node node : nodes) {
-            if (!node.isAlive()) {
-                continue;
-            }
-            if (lastFastPath != null && node instanceof FixedNode) {
-                lastFastPath.setNext((FixedNode) node);
-                lastFastPath = null;
-            }
-            if (node instanceof FixedWithNextNode) {
-                lastFixed = (FixedWithNextNode) node;
-            } else if (node instanceof GuardNode) {
-                GuardNode guard = (GuardNode) node;
-                if (guard.negated() && guard.condition() instanceof IsNullNode) {
-                    IsNullNode isNull = (IsNullNode) guard.condition();
-                    NullCheckNode nullCheck = graph.add(new NullCheckNode(isNull.object()));
-                    guard.replaceAndDelete(nullCheck);
-                    lastFixed.setNext(nullCheck);
-                    lastFixed = nullCheck;
-                    lastFastPath = nullCheck;
-                } else {
-                    BeginNode fastPath = graph.add(new BeginNode());
-                    BeginNode trueSuccessor;
-                    BeginNode falseSuccessor;
-                    DeoptimizeNode deopt = graph.add(new DeoptimizeNode(guard.action(), guard.reason()));
-                    BeginNode deoptBranch = BeginNode.begin(deopt);
-                    Loop loop = block.getLoop();
-                    while (loop != null) {
-                        LoopExitNode exit = graph.add(new LoopExitNode(loop.loopBegin()));
-                        graph.addBeforeFixed(deopt, exit);
-                        loop = loop.parent;
-                    }
-                    if (guard.negated()) {
-                        trueSuccessor = deoptBranch;
-                        falseSuccessor = fastPath;
-                    } else {
-                        trueSuccessor = fastPath;
-                        falseSuccessor = deoptBranch;
-                    }
-                    IfNode ifNode = graph.add(new IfNode(guard.condition(), trueSuccessor, falseSuccessor, trueSuccessor == fastPath ? 1 : 0));
-                    guard.replaceAndDelete(fastPath);
-                    lastFixed.setNext(ifNode);
-                    lastFixed = fastPath;
-                    lastFastPath = fastPath;
-                }
-            }
-        }
-    }
+    private class UseImplicitNullChecks extends ScheduledNodeIterator {
+
+        private final IdentityHashMap<ValueNode, GuardNode> nullGuarded = new IdentityHashMap<>();
 
-    private static void useImplicitNullChecks(BeginNode begin, List<ScheduledNode> nodes, StructuredGraph graph, TargetDescription target) {
-        ListIterator<ScheduledNode> iterator = nodes.listIterator();
-        IdentityHashMap<ValueNode, GuardNode> nullGuarded = new IdentityHashMap<>();
-        FixedWithNextNode lastFixed = begin;
-        FixedWithNextNode reconnect = null;
-        while (iterator.hasNext()) {
-            Node node = iterator.next();
-
-            if (reconnect != null && node instanceof FixedNode) {
-                reconnect.setNext((FixedNode) node);
-                reconnect = null;
-            }
-            if (node instanceof FixedWithNextNode) {
-                lastFixed = (FixedWithNextNode) node;
-            }
-
+        @Override
+        protected void processNode(Node node) {
             if (node instanceof GuardNode) {
-                GuardNode guard = (GuardNode) node;
-                if (guard.negated() && guard.condition() instanceof IsNullNode) {
-                    ValueNode obj = ((IsNullNode) guard.condition()).object();
-                    nullGuarded.put(obj, guard);
-                }
+                processGuard(node);
             } else if (node instanceof Access) {
-                Access access = (Access) node;
-                GuardNode guard = nullGuarded.get(access.object());
-                if (guard != null && isImplicitNullCheck(access.nullCheckLocation(), target)) {
-                    NodeInputList<ValueNode> dependencies = ((ValueNode) access).dependencies();
-                    dependencies.remove(guard);
-                    if (access instanceof FloatingReadNode) {
-                        ReadNode read = graph.add(new ReadNode(access.object(), access.nullCheckLocation(), ((FloatingReadNode) access).stamp(), dependencies));
-                        node.replaceAndDelete(read);
-                        access = read;
-                        lastFixed.setNext(read);
-                        lastFixed = read;
-                        reconnect = read;
-                        iterator.set(read);
-                    }
-                    assert access instanceof AccessNode;
-                    access.setNullCheck(true);
-                    LogicNode condition = guard.condition();
-                    guard.replaceAndDelete(access.node());
-                    if (condition.usages().isEmpty()) {
-                        GraphUtil.killWithUnusedFloatingInputs(condition);
-                    }
-                    nullGuarded.remove(access.object());
-                }
+                processAccess((Access) node);
             }
             if (node instanceof StateSplit && ((StateSplit) node).stateAfter() != null) {
                 nullGuarded.clear();
@@ -168,9 +105,119 @@
                 }
             }
         }
+
+        private void processAccess(Access access) {
+            GuardNode guard = nullGuarded.get(access.object());
+            if (guard != null && isImplicitNullCheck(access.nullCheckLocation())) {
+                NodeInputList<ValueNode> dependencies = ((ValueNode) access).dependencies();
+                dependencies.remove(guard);
+                Access fixedAccess = access;
+                if (access instanceof FloatingAccessNode) {
+                    fixedAccess = ((FloatingAccessNode) access).asFixedNode();
+                    replaceCurrent((FixedWithNextNode) fixedAccess.node());
+                }
+                assert fixedAccess instanceof FixedNode;
+                fixedAccess.setNullCheck(true);
+                LogicNode condition = guard.condition();
+                guard.replaceAndDelete(fixedAccess.node());
+                if (condition.usages().isEmpty()) {
+                    GraphUtil.killWithUnusedFloatingInputs(condition);
+                }
+                nullGuarded.remove(fixedAccess.object());
+            }
+        }
+
+        private void processGuard(Node node) {
+            GuardNode guard = (GuardNode) node;
+            if (guard.negated() && guard.condition() instanceof IsNullNode) {
+                ValueNode obj = ((IsNullNode) guard.condition()).object();
+                nullGuarded.put(obj, guard);
+            }
+        }
     }
 
-    private static boolean isImplicitNullCheck(LocationNode location, TargetDescription target) {
+    private class LowerGuards extends ScheduledNodeIterator {
+
+        private final Block block;
+
+        public LowerGuards(Block block) {
+            this.block = block;
+        }
+
+        @Override
+        protected void processNode(Node node) {
+            if (node instanceof GuardNode) {
+                GuardNode guard = (GuardNode) node;
+                if (guard.negated() && guard.condition() instanceof IsNullNode) {
+                    lowerToNullCheck(guard);
+                } else {
+                    lowerToIf(guard);
+                }
+            }
+        }
+
+        private void lowerToIf(GuardNode guard) {
+            StructuredGraph graph = (StructuredGraph) guard.graph();
+            BeginNode fastPath = graph.add(new BeginNode());
+            DeoptimizeNode deopt = graph.add(new DeoptimizeNode(guard.action(), guard.reason()));
+            BeginNode deoptBranch = BeginNode.begin(deopt);
+            BeginNode trueSuccessor;
+            BeginNode falseSuccessor;
+            insertLoopExits(deopt);
+            if (guard.negated()) {
+                trueSuccessor = deoptBranch;
+                falseSuccessor = fastPath;
+            } else {
+                trueSuccessor = fastPath;
+                falseSuccessor = deoptBranch;
+            }
+            IfNode ifNode = graph.add(new IfNode(guard.condition(), trueSuccessor, falseSuccessor, trueSuccessor == fastPath ? 1 : 0));
+            guard.replaceAndDelete(fastPath);
+            insert(ifNode, fastPath);
+        }
+
+        private void lowerToNullCheck(GuardNode guard) {
+            IsNullNode isNull = (IsNullNode) guard.condition();
+            NullCheckNode nullCheck = guard.graph().add(new NullCheckNode(isNull.object()));
+            replaceCurrent(nullCheck);
+        }
+
+        private void insertLoopExits(DeoptimizeNode deopt) {
+            Loop loop = block.getLoop();
+            StructuredGraph graph = (StructuredGraph) deopt.graph();
+            while (loop != null) {
+                LoopExitNode exit = graph.add(new LoopExitNode(loop.loopBegin()));
+                graph.addBeforeFixed(deopt, exit);
+                loop = loop.parent;
+            }
+        }
+    }
+
+    private TargetDescription target;
+
+    public GuardLoweringPhase(TargetDescription target) {
+        this.target = target;
+    }
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        SchedulePhase schedule = new SchedulePhase();
+        schedule.apply(graph);
+
+        for (Block block : schedule.getCFG().getBlocks()) {
+            processBlock(block, schedule);
+        }
+    }
+
+    private void processBlock(Block block, SchedulePhase schedule) {
+        List<ScheduledNode> nodes = schedule.nodesFor(block);
+        if (GraalOptions.OptImplicitNullChecks && target.implicitNullCheckLimit > 0) {
+            new UseImplicitNullChecks().processNodes(nodes, block.getBeginNode());
+        }
+        new LowerGuards(block).processNodes(nodes, block.getBeginNode());
+    }
+
+    private boolean isImplicitNullCheck(LocationNode location) {
         return !(location instanceof IndexedLocationNode) && location.displacement() < target.implicitNullCheckLimit;
     }
 }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Wed Mar 20 22:30:33 2013 +0100
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Thu Mar 21 09:44:47 2013 +0100
@@ -211,12 +211,6 @@
     public static boolean IntrinsifyAESMethods               = true;
 
     /**
-     * Method arguments that are passed on the stack can be optimized by the register allocator to avoid spilling 
-     * and reloading. However, this requires that the runtime visits method arguments during stack walking.  
-     */
-    public static boolean IncomingMethodArgumentsGCSafe      = true;
-
-    /**
      * Counts the various paths taken through snippets.
      */
     public static boolean SnippetCounters = false;
--- a/src/share/tools/IdealGraphVisualizer/Difference/src/com/sun/hotspot/igv/difference/Difference.java	Wed Mar 20 22:30:33 2013 +0100
+++ b/src/share/tools/IdealGraphVisualizer/Difference/src/com/sun/hotspot/igv/difference/Difference.java	Thu Mar 21 09:44:47 2013 +0100
@@ -207,12 +207,16 @@
             InputNode nodeTo = inputNodeMap.get(a.getNode(to));
             char fromIndex = e.getFromIndex();
             char toIndex = e.getToIndex();
-
-            InputEdge newEdge = new InputEdge(fromIndex, toIndex, nodeFrom.getId(), nodeTo.getId());
-            if (!newEdges.contains(newEdge)) {
-                markAsDeleted(newEdge);
-                newEdges.add(newEdge);
-                graph.addEdge(newEdge);
+            
+            if (nodeFrom == null || nodeTo == null) {
+                System.out.println("Unexpected edge : " + from + " -> " + to);
+            } else {
+                InputEdge newEdge = new InputEdge(fromIndex, toIndex, nodeFrom.getId(), nodeTo.getId());
+                if (!newEdges.contains(newEdge)) {
+                    markAsDeleted(newEdge);
+                    newEdges.add(newEdge);
+                    graph.addEdge(newEdge);
+                }
             }
         }
 
@@ -224,17 +228,21 @@
             char fromIndex = e.getFromIndex();
             char toIndex = e.getToIndex();
 
-            InputEdge newEdge = new InputEdge(fromIndex, toIndex, nodeFrom.getId(), nodeTo.getId());
-            if (!newEdges.contains(newEdge)) {
-                markAsNew(newEdge);
-                newEdges.add(newEdge);
-                graph.addEdge(newEdge);
+            if (nodeFrom == null || nodeTo == null) {
+                System.out.println("Unexpected edge : " + from + " -> " + to);
             } else {
-                newEdges.remove(newEdge);
-                graph.removeEdge(newEdge);
-                markAsSame(newEdge);
-                newEdges.add(newEdge);
-                graph.addEdge(newEdge);
+                InputEdge newEdge = new InputEdge(fromIndex, toIndex, nodeFrom.getId(), nodeTo.getId());
+                if (!newEdges.contains(newEdge)) {
+                    markAsNew(newEdge);
+                    newEdges.add(newEdge);
+                    graph.addEdge(newEdge);
+                } else {
+                    newEdges.remove(newEdge);
+                    graph.removeEdge(newEdge);
+                    markAsSame(newEdge);
+                    newEdges.add(newEdge);
+                    graph.addEdge(newEdge);
+                }
             }
         }