# HG changeset patch # User Thomas Wuerthinger # Date 1308238769 -7200 # Node ID 53dcb07946194705666442be3dac24a530f7c9a8 # Parent de3ac4888421f45fa7846e66a512f19f350190fa Added node verification (and tentative interface for VerificationListener). Fixed regression in dead code elimination. diff -r de3ac4888421 -r 53dcb0794619 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java --- 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 { diff -r de3ac4888421 -r 53dcb0794619 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/EndNode.java --- 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; + } } diff -r de3ac4888421 -r 53dcb0794619 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java --- 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() { diff -r de3ac4888421 -r 53dcb0794619 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java --- 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); } } diff -r de3ac4888421 -r 53dcb0794619 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/Phase.java --- 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) } diff -r de3ac4888421 -r 53dcb0794619 graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Graph.java --- 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 verificationListeners = new ArrayList(4); + private final ArrayList 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 addDuplicate(Collection nodes, Map replacements) { Map newNodes = new HashMap(); // create node duplicates diff -r de3ac4888421 -r 53dcb0794619 graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Node.java --- 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; + } } diff -r de3ac4888421 -r 53dcb0794619 graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeArray.java --- 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; + } } } } diff -r de3ac4888421 -r 53dcb0794619 graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/VerificationListener.java --- /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); +}