changeset 5011:5d0af6520f26

Do not use SchedulePhase in CFG printer
author Christian Wimmer <Christian.Wimmer@Oracle.com>
date Fri, 02 Mar 2012 09:12:54 -0800
parents f1cb5fa9a532
children feb4ad564664
files graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinter.java graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinterObserver.java
diffstat 2 files changed, 143 insertions(+), 74 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinter.java	Fri Mar 02 09:10:04 2012 -0800
+++ b/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinter.java	Fri Mar 02 09:12:54 2012 -0800
@@ -28,13 +28,11 @@
 import java.util.*;
 
 import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
 import com.oracle.max.criutils.*;
 import com.oracle.max.graal.alloc.util.*;
 import com.oracle.max.graal.compiler.alloc.*;
 import com.oracle.max.graal.compiler.alloc.Interval.UsePosList;
 import com.oracle.max.graal.compiler.gen.*;
-import com.oracle.max.graal.compiler.schedule.*;
 import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.graph.Node.Verbosity;
 import com.oracle.max.graal.graph.NodeClass.NodeClassIterator;
@@ -50,20 +48,18 @@
  */
 class CFGPrinter extends CompilationPrinter {
 
-    public final CiTarget target;
-    public final RiRuntime runtime;
-    public LIR lir;
-    public LIRGenerator lirGenerator;
+    protected CiTarget target;
+    protected LIR lir;
+    protected LIRGenerator lirGenerator;
+    protected ControlFlowGraph cfg;
 
     /**
      * Creates a control flow graph printer.
      *
      * @param buffer where the output generated via this printer shown be written
      */
-    public CFGPrinter(OutputStream out, CiTarget target, RiRuntime runtime) {
+    public CFGPrinter(OutputStream out) {
         super(out);
-        this.target = target;
-        this.runtime = runtime;
     }
 
     /**
@@ -119,22 +115,78 @@
     }
 
 
+    private NodeMap<Block> latestScheduling;
+    private NodeBitMap printedNodes;
+
+    private boolean inFixedSchedule(Node node) {
+        return lir != null || node.isDeleted() || cfg.getNodeToBlock().get(node) != null;
+    }
+
     /**
      * Prints the specified list of blocks.
      *
      * @param label A label describing the compilation phase that produced the control flow graph.
      * @param blocks The list of blocks to be printed.
      */
-    public void printCFG(String label, List<Block> blocks, SchedulePhase schedule) {
+    public void printCFG(String label, List<Block> blocks) {
+        if (lir == null) {
+            latestScheduling = new NodeMap<>(cfg.getNodeToBlock());
+            for (Block block : blocks) {
+                Node cur = block.getBeginNode();
+                while (true) {
+                    assert inFixedSchedule(cur) && latestScheduling.get(cur) == block;
+                    scheduleInputs(cur, block);
+
+                    if (cur == block.getEndNode()) {
+                        break;
+                    }
+                    assert cur.successors().count() == 1;
+                    cur = cur.successors().first();
+                }
+            }
+        }
+        printedNodes = new NodeBitMap(cfg.graph);
+
         begin("cfg");
         out.print("name \"").print(label).println('"');
         for (Block block : blocks) {
-            printBlock(block, schedule);
+            printBlock(block);
         }
         end("cfg");
+
+        latestScheduling = null;
+        printedNodes = null;
     }
 
-    private void printBlock(Block block, SchedulePhase schedule) {
+    private void scheduleInputs(Node node, Block nodeBlock) {
+        if (node instanceof PhiNode) {
+            PhiNode phi = (PhiNode) node;
+            assert nodeBlock.getBeginNode() == phi.merge();
+            for (Block pred : nodeBlock.getPredecessors()) {
+                schedule(phi.valueAt((EndNode) pred.getEndNode()), pred);
+            }
+
+        } else {
+            for (Node input : node.inputs()) {
+                schedule(input, nodeBlock);
+            }
+        }
+    }
+
+    private void schedule(Node input, Block block) {
+        if (!inFixedSchedule(input)) {
+            Block inputBlock = block;
+            if (latestScheduling.get(input) != null) {
+                inputBlock = ControlFlowGraph.commonDominator(inputBlock, latestScheduling.get(input));
+            }
+            if (inputBlock != latestScheduling.get(input)) {
+                latestScheduling.set(input, inputBlock);
+                scheduleInputs(input, inputBlock);
+            }
+        }
+    }
+
+    private void printBlock(Block block) {
         begin("block");
 
         out.print("name \"").print(blockToString(block)).println('"');
@@ -180,15 +232,12 @@
             out.print("loop_depth ").println(block.getLoop().depth);
         }
 
-        printNodes(block, schedule);
+        printNodes(block);
         printLIR(block);
         end("block");
     }
 
-    private void printNodes(Block block, SchedulePhase schedule) {
-        if (schedule == null) {
-            return;
-        }
+    private void printNodes(Block block) {
         begin("IR");
         out.println("HIR");
         out.disableIndentation();
@@ -196,25 +245,59 @@
         if (block.getPredecessors().size() == 0) {
             // Currently method parameters are not in the schedule, so print them separately here.
             for (ValueNode param : block.getBeginNode().graph().getNodes(LocalNode.class)) {
-                printNode(param);
+                printNode(param, false);
             }
         }
         if (block.getBeginNode() instanceof MergeNode) {
             // Currently phi functions are not in the schedule, so print them separately here.
             for (ValueNode phi : ((MergeNode) block.getBeginNode()).phis()) {
-                printNode(phi);
+                printNode(phi, false);
             }
         }
 
-        for (Node node : schedule.nodesFor(block)) {
-            printNode(node);
+        if (lir != null) {
+            for (Node node : lir.nodesFor(block)) {
+                printNode(node, false);
+            }
+        } else {
+            Node cur = block.getBeginNode();
+            while (true) {
+                printNode(cur, false);
+
+                if (cur == block.getEndNode()) {
+                    for (Map.Entry<Node, Block> entry : latestScheduling.entries()) {
+                        if (entry.getValue() == block && !inFixedSchedule(entry.getKey()) && !printedNodes.isMarked(entry.getKey())) {
+                            printNode(entry.getKey(), true);
+                        }
+                    }
+                    break;
+                }
+                assert cur.successors().count() == 1;
+                cur = cur.successors().first();
+            }
+
         }
+
         out.enableIndentation();
         end("IR");
     }
 
-    private void printNode(Node node) {
-        if (node instanceof FixedWithNextNode) {
+    private void printNode(Node node, boolean unscheduled) {
+        assert !printedNodes.isMarked(node);
+        printedNodes.mark(node);
+
+        if (!(node instanceof PhiNode)) {
+            for (Node input : node.inputs()) {
+                if (!inFixedSchedule(input) && !printedNodes.isMarked(input)) {
+                    printNode(input, true);
+                }
+            }
+        }
+
+        if (unscheduled) {
+            assert lir == null : "unscheduled nodes can only be present before LIR generation";
+            out.print("f ").print(HOVER_START).print("u").print(HOVER_SEP).print("unscheduled").print(HOVER_END).println(COLUMN_END);
+        } else if (node instanceof FixedWithNextNode) {
             out.print("f ").print(HOVER_START).print("#").print(HOVER_SEP).print("fixed with next").print(HOVER_END).println(COLUMN_END);
         } else if (node instanceof FixedNode) {
             out.print("f ").print(HOVER_START).print("*").print(HOVER_SEP).print("fixed").print(HOVER_END).println(COLUMN_END);
--- a/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinterObserver.java	Fri Mar 02 09:10:04 2012 -0800
+++ b/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinterObserver.java	Fri Mar 02 09:12:54 2012 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, 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
@@ -32,10 +32,11 @@
 import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.alloc.*;
 import com.oracle.max.graal.compiler.gen.*;
-import com.oracle.max.graal.compiler.schedule.*;
 import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.java.*;
 import com.oracle.max.graal.lir.*;
+import com.oracle.max.graal.lir.cfg.*;
 import com.oracle.max.graal.nodes.*;
 
 /**
@@ -45,30 +46,11 @@
 public class CFGPrinterObserver implements DebugDumpHandler {
 
     private CFGPrinter cfgPrinter;
-
-    private GraalCompiler compiler;
-    private RiResolvedMethod method;
-    private SchedulePhase schedule;
+    private Graph curGraph;
 
     @Override
-    public void dump(final Object object, final String message) {
-        Debug.sandbox("CFGPrinter", new Runnable() {
-            @Override
-            public void run() {
-                dumpSandboxed(object, message);
-            }
-        });
-    }
-
-    private void dumpSandboxed(final Object object, final String message) {
-        if (object instanceof GraalCompiler) {
-            compiler = (GraalCompiler) object;
-            return;
-        } else if (object instanceof SchedulePhase) {
-            schedule = (SchedulePhase) object;
-            return;
-        }
-
+    public void dump(Object object, String message) {
+        GraalCompiler compiler = Debug.contextLookup(GraalCompiler.class);
         if (compiler == null) {
             return;
         }
@@ -77,57 +59,61 @@
             File file = new File("compilations-" + System.currentTimeMillis() + ".cfg");
             try {
                 OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
-                cfgPrinter = new CFGPrinter(out, compiler.target, compiler.runtime);
+                cfgPrinter = new CFGPrinter(out);
             } catch (FileNotFoundException e) {
-                throw new InternalError("Could not open " + file.getAbsolutePath());
+                throw new GraalInternalError("Could not open " + file.getAbsolutePath());
             }
             TTY.println("CFGPrinter: Output to file %s", file);
         }
 
-        RiRuntime runtime = cfgPrinter.runtime;
-        if (object instanceof LIRGenerator) {
-            cfgPrinter.lirGenerator = (LIRGenerator) object;
-        } else if (object instanceof RiResolvedMethod) {
-            method = (RiResolvedMethod) object;
-            cfgPrinter.printCompilation(method);
+        StructuredGraph newGraph = Debug.contextLookup(StructuredGraph.class);
+        if (newGraph != curGraph) {
+            cfgPrinter.printCompilation(newGraph.method());
+            TTY.println("CFGPrinter: Dumping method %s", newGraph.method());
+            curGraph = newGraph;
+        }
 
-            cfgPrinter.lir = null;
-            cfgPrinter.lirGenerator = null;
-            schedule = null;
-            TTY.println("CFGPrinter: Dumping method %s", method);
+        cfgPrinter.target = compiler.target;
+        if (object instanceof LIR) {
+            cfgPrinter.lir = (LIR) object;
+        } else {
+            cfgPrinter.lir = Debug.contextLookup(LIR.class);
+        }
+        cfgPrinter.lirGenerator = Debug.contextLookup(LIRGenerator.class);
+        if (cfgPrinter.lir != null) {
+            cfgPrinter.cfg = cfgPrinter.lir.cfg;
+        }
 
-        } else if (object instanceof BciBlockMapping) {
+        RiRuntime runtime = compiler.runtime;
+
+        if (object instanceof BciBlockMapping) {
             BciBlockMapping blockMap = (BciBlockMapping) object;
             cfgPrinter.printCFG(message, blockMap);
             cfgPrinter.printBytecodes(runtime.disassemble(blockMap.method));
 
         } else if (object instanceof LIR) {
-            cfgPrinter.lir = (LIR) object;
-            cfgPrinter.printCFG(message, ((LIR) object).codeEmittingOrder(), schedule);
+            cfgPrinter.printCFG(message, cfgPrinter.lir.codeEmittingOrder());
 
         } else if (object instanceof StructuredGraph) {
-            SchedulePhase curSchedule = schedule;
-            if (curSchedule == null) {
-                try {
-                    curSchedule = new SchedulePhase();
-                    curSchedule.apply((StructuredGraph) object);
-                } catch (Throwable ex) {
-                    curSchedule = null;
-                    // ignore
-                }
+            if (cfgPrinter.cfg == null) {
+                cfgPrinter.cfg = ControlFlowGraph.compute((StructuredGraph) object, true, true, true, false);
             }
-            if (curSchedule != null && curSchedule.getCFG() != null) {
-                cfgPrinter.printCFG(message, Arrays.asList(curSchedule.getCFG().getBlocks()), curSchedule);
-            }
+            cfgPrinter.printCFG(message, Arrays.asList(cfgPrinter.cfg.getBlocks()));
 
         } else if (object instanceof CiTargetMethod) {
             cfgPrinter.printMachineCode(runtime.disassemble((CiTargetMethod) object), null);
+
         } else if (object instanceof Interval[]) {
             cfgPrinter.printIntervals(message, (Interval[]) object);
+
         } else if (object instanceof IntervalPrinter.Interval[]) {
             cfgPrinter.printIntervals(message, (IntervalPrinter.Interval[]) object);
         }
 
+        cfgPrinter.target = null;
+        cfgPrinter.lir = null;
+        cfgPrinter.lirGenerator = null;
+        cfgPrinter.cfg = null;
         cfgPrinter.flush();
     }
 }