changeset 9663:822adbb2ee7b

CFGVerifier: verify post-dominator calculation verified against changeset 902a974d55c8, where post-dominator calculation was bogus.
author Bernhard Urban <bernhard.urban@jku.at>
date Mon, 13 May 2013 15:55:41 +0200
parents eade47d311a3
children 843dde5a83af f9a65a0e626b
files graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SimpleCFGTest.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/CFGVerifier.java
diffstat 2 files changed, 49 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SimpleCFGTest.java	Mon May 13 14:17:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SimpleCFGTest.java	Mon May 13 15:55:41 2013 +0200
@@ -22,14 +22,23 @@
  */
 package com.oracle.graal.compiler.test;
 
-import static org.junit.Assert.*;
-
 import org.junit.*;
 
+import com.oracle.graal.debug.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.cfg.*;
 
-public class SimpleCFGTest {
+public class SimpleCFGTest extends GraalCompilerTest {
+
+    private static void dumpGraph(final StructuredGraph graph) {
+        Debug.scope("SimpleCFGTest", new Runnable() {
+
+            @Override
+            public void run() {
+                Debug.dump(graph, "Graph");
+            }
+        });
+    }
 
     @Test
     public void testImplies() {
@@ -52,6 +61,8 @@
         ReturnNode returnNode = graph.add(new ReturnNode(null));
         merge.setNext(returnNode);
 
+        dumpGraph(graph);
+
         ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, true, true);
 
         Block[] blocks = cfg.getBlocks();
@@ -88,15 +99,15 @@
     }
 
     public static void assertDominator(Block block, Block expectedDominator) {
-        assertEquals("dominator of " + block, expectedDominator, block.getDominator());
+        Assert.assertEquals("dominator of " + block, expectedDominator, block.getDominator());
     }
 
     public static void assertDominatedSize(Block block, int size) {
-        assertEquals("number of dominated blocks of " + block, size, block.getDominated().size());
+        Assert.assertEquals("number of dominated blocks of " + block, size, block.getDominated().size());
     }
 
     public static void assertPostdominator(Block block, Block expectedPostdominator) {
-        assertEquals("postdominator of " + block, expectedPostdominator, block.getPostdominator());
+        Assert.assertEquals("postdominator of " + block, expectedPostdominator, block.getPostdominator());
     }
 
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/CFGVerifier.java	Mon May 13 14:17:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/CFGVerifier.java	Mon May 13 15:55:41 2013 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.nodes.cfg;
 
+import java.util.*;
+
 public class CFGVerifier {
 
     public static boolean verify(ControlFlowGraph cfg) {
@@ -48,6 +50,36 @@
                 assert dominated.getDominator() == block;
             }
 
+            Block postDominatorBlock = block.getPostdominator();
+            if (postDominatorBlock != null) {
+                assert block.getSuccessorCount() > 0 : "block has post-dominator block, but no successors";
+
+                BlockMap<Boolean> visitedBlocks = new BlockMap<>(cfg);
+                visitedBlocks.put(block, true);
+
+                Deque<Block> stack = new ArrayDeque<>();
+                for (Block sux : block.getSuccessors()) {
+                    visitedBlocks.put(sux, true);
+                    stack.push(sux);
+                }
+
+                while (stack.size() > 0) {
+                    Block tos = stack.pop();
+                    assert tos.getId() <= postDominatorBlock.getId();
+                    if (tos == postDominatorBlock) {
+                        continue; // found a valid path
+                    }
+                    assert tos.getSuccessorCount() > 0 : "no path found";
+
+                    for (Block sux : tos.getSuccessors()) {
+                        if (visitedBlocks.get(sux) == null) {
+                            visitedBlocks.put(sux, true);
+                            stack.push(sux);
+                        }
+                    }
+                }
+            }
+
             assert cfg.getLoops() == null || !block.isLoopHeader() || block.getLoop().header == block : block.beginNode;
         }