changeset 3008:53dcb0794619

Added node verification (and tentative interface for VerificationListener). Fixed regression in dead code elimination.
author Thomas Wuerthinger <thomas@wuerthinger.net>
date Thu, 16 Jun 2011 17:39:29 +0200
parents de3ac4888421
children 6264ecd38bc2
files graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/EndNode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/Phase.java graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Graph.java graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Node.java graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeArray.java graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/VerificationListener.java
diffstat 9 files changed, 92 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java	Thu Jun 16 16:41:22 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java	Thu Jun 16 17:39:29 2011 +0200
@@ -28,6 +28,7 @@
 import com.oracle.max.graal.compiler.globalstub.*;
 import com.oracle.max.graal.compiler.observer.*;
 import com.oracle.max.graal.compiler.target.*;
+import com.oracle.max.graal.graph.*;
 import com.sun.cri.ci.*;
 import com.sun.cri.ri.*;
 import com.sun.cri.xir.*;
@@ -58,6 +59,8 @@
 
     public final RiRegisterConfig globalStubRegisterConfig;
 
+    private GraalCompilation currentCompilation;
+
     public GraalCompiler(RiRuntime runtime, CiTarget target, RiXirGenerator xirGen, RiRegisterConfig globalStubRegisterConfig) {
         this.runtime = runtime;
         this.target = target;
@@ -65,6 +68,17 @@
         this.globalStubRegisterConfig = globalStubRegisterConfig;
         this.backend = Backend.create(target.arch, this);
         init();
+
+        Graph.verificationListeners.add(new VerificationListener() {
+            @Override
+            public void verificationFailed(Node n) {
+                GraalCompiler.this.fireCompilationEvent(new CompilationEvent(currentCompilation, "Verification Error on Node " + n.id(), currentCompilation.graph, true, false));
+                for (Node p : n.predecessors()) {
+                    TTY.println("predecessor: " + p);
+                }
+                assert false : "Verification of node " + n + " failed";
+            }
+        });
     }
 
     public CiResult compileMethod(RiMethod method, int osrBCI, RiXirGenerator xirGenerator, CiStatistics stats) {
@@ -78,6 +92,7 @@
         CiResult result = null;
         TTY.Filter filter = new TTY.Filter(GraalOptions.PrintFilter, method);
         GraalCompilation compilation = new GraalCompilation(this, method, osrBCI, stats);
+        currentCompilation = compilation;
         try {
             result = compilation.compile();
         } finally {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/EndNode.java	Thu Jun 16 16:41:22 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/EndNode.java	Thu Jun 16 17:39:29 2011 +0200
@@ -57,4 +57,13 @@
             return (Merge) usages().get(0);
         }
     }
+
+    @Override
+    public boolean verify() {
+        assertTrue(inputs().size() == 0);
+        assertTrue(successors().size() == 0);
+        assertTrue(usages().size() <= 1);
+        assertTrue(predecessors().size() <= 1);
+        return true;
+    }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java	Thu Jun 16 16:41:22 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java	Thu Jun 16 17:39:29 2011 +0200
@@ -68,7 +68,7 @@
     }
 
     private static boolean isCFG(Node n) {
-        return n != null && ((n instanceof Instruction) || n == n.graph().start());
+        return n != null && ((n instanceof Instruction) || (n instanceof ControlSplit) || n == n.graph().start());
     }
 
     private void iterateSuccessors() {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java	Thu Jun 16 16:41:22 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java	Thu Jun 16 17:39:29 2011 +0200
@@ -26,6 +26,7 @@
 import java.util.*;
 
 import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.compiler.debug.*;
 import com.oracle.max.graal.compiler.graph.*;
 import com.oracle.max.graal.compiler.ir.*;
 import com.oracle.max.graal.compiler.value.*;
@@ -309,8 +310,9 @@
             }
             Node returnDuplicate = duplicates.get(returnNode);
             returnDuplicate.inputs().clearAll();
-            returnDuplicate.replace(invoke.next());
+            Node n = invoke.next();
             invoke.setNext(null);
+            returnDuplicate.replace(n);
         }
 
         if (exceptionEdge != null) {
@@ -325,7 +327,9 @@
                     usage.inputs().replace(obj, unwindDuplicate.exception());
                 }
                 unwindDuplicate.inputs().clearAll();
-                unwindDuplicate.replace(obj.next());
+                Node n = obj.next();
+                obj.setNext(null);
+                unwindDuplicate.replace(n);
             }
         }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/Phase.java	Thu Jun 16 16:41:22 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/Phase.java	Thu Jun 16 17:39:29 2011 +0200
@@ -41,7 +41,7 @@
     }
 
     public final void apply(Graph graph) {
-        assert graph != null;
+        assert graph != null && graph.verify();
 
         int startDeletedNodeCount = graph.getDeletedNodeCount();
         int startNodeCount = graph.getNodeCount();
@@ -74,6 +74,8 @@
             compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "After " + getName(), graph, true, false));
         }
 
+        assert graph.verify();
+
         // (Item|Graph|Phase|Value)
     }
 
--- a/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Graph.java	Thu Jun 16 16:41:22 2011 +0200
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Graph.java	Thu Jun 16 17:39:29 2011 +0200
@@ -33,6 +33,8 @@
 
 public class Graph {
 
+    public static final List<VerificationListener> verificationListeners = new ArrayList<VerificationListener>(4);
+
     private final ArrayList<Node> nodes;
     private final StartNode start;
     int nextId;
@@ -149,6 +151,13 @@
         return new NodeWorkList(this, fill, iterationLimitPerNode);
     }
 
+    public boolean verify() {
+        for (Node n : getNodes()) {
+            assert n == Node.Null || n.verify();
+        }
+        return true;
+    }
+
     public Map<Node, Node> addDuplicate(Collection<Node> nodes, Map<Node, Node> replacements) {
         Map<Node, Node> newNodes = new HashMap<Node, Node>();
         // create node duplicates
--- a/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Node.java	Thu Jun 16 16:41:22 2011 +0200
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Node.java	Thu Jun 16 17:39:29 2011 +0200
@@ -104,6 +104,7 @@
         usages.clear();
         predecessors.clear();
         delete();
+        assert other == null || other.verify();
         return other;
     }
 
@@ -124,7 +125,7 @@
 
     public void delete() {
         assert !isDeleted();
-        assert checkDeletion() : "Could not delete " + this;
+        assert checkDeletion() : "Could not delete " + this + " (usages: " + this.usages() + ", predecessors: " + this.predecessors() + ")";
 
         for (int i = 0; i < inputs.size(); ++i) {
             inputs.set(i, Null);
@@ -200,4 +201,19 @@
     public String toString() {
         return this.getClass().getSimpleName() + "-" + this.id();
     }
+
+    public boolean verify() {
+        return true;
+    }
+
+    public final void assertTrue(boolean cond) {
+        assert cond || assertionFailure();
+    }
+
+    public final boolean assertionFailure() {
+        for (VerificationListener l : Graph.verificationListeners) {
+            l.verificationFailed(this);
+        }
+        return true;
+    }
 }
--- a/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeArray.java	Thu Jun 16 16:41:22 2011 +0200
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeArray.java	Thu Jun 16 17:39:29 2011 +0200
@@ -143,16 +143,13 @@
             } else {
                 assert self().successors == this;
                 if (old != null) {
-                    for (int i = 0; i < old.predecessors.size(); ++i) {
-                        Node cur = old.predecessors.get(i);
-                        if (cur == self()) {
-                            old.predecessors.remove(i);
-                            break;
-                        }
-                    }
+                    old.predecessors.remove(self());
                 }
                 if (node != null) {
                     node.predecessors.add(self());
+                    if (node.predecessors.size() > 1 && node.getClass().getName().contains("EndNode")) {
+                        assert false;
+                    }
                 }
             }
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/VerificationListener.java	Thu Jun 16 17:39:29 2011 +0200
@@ -0,0 +1,28 @@
+/*
+ * 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.graph;
+
+
+public interface VerificationListener {
+    void verificationFailed(Node n);
+}