diff graal/GraalCompiler/src/com/sun/c1x/graph/IR.java @ 2868:6d24c27902a2

turned inlining into a phase, some node cloning fixes, added NodeWorklist
author Lukas Stadler <lukas.stadler@jku.at>
date Tue, 07 Jun 2011 19:19:14 +0200
parents 5c545fef2c81
children fc75fd3fa5e4
line wrap: on
line diff
--- a/graal/GraalCompiler/src/com/sun/c1x/graph/IR.java	Tue Jun 07 16:33:04 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/graph/IR.java	Tue Jun 07 19:19:14 2011 +0200
@@ -29,7 +29,6 @@
 import com.oracle.max.graal.schedule.*;
 import com.sun.c1x.*;
 import com.sun.c1x.debug.*;
-import com.sun.c1x.gen.*;
 import com.sun.c1x.ir.*;
 import com.sun.c1x.lir.*;
 import com.sun.c1x.observer.*;
@@ -157,6 +156,12 @@
         // Graph builder must set the startBlock and the osrEntryBlock
         new GraphBuilder(compilation, compilation.method, compilation.graph).build(false);
 
+//        CompilerGraph duplicate = new CompilerGraph();
+//        Map<Node, Node> replacements = new HashMap<Node, Node>();
+//        replacements.put(compilation.graph.start(), duplicate.start());
+//        duplicate.addDuplicate(compilation.graph.getNodes(), replacements);
+//        compilation.graph = duplicate;
+
         verifyAndPrint("After graph building");
 
         DeadCodeElimination dce = new DeadCodeElimination();
@@ -166,7 +171,7 @@
         }
 
         if (C1XOptions.Inline) {
-            inlineMethods();
+            new Inlining(compilation, this).apply(compilation.graph);
         }
 
         if (C1XOptions.PrintCompilation) {
@@ -174,241 +179,6 @@
         }
     }
 
-    private void inlineMethods() {
-        int inliningSize = compilation.method.code().length;
-        boolean inlined;
-        int iterations = C1XOptions.MaximumRecursiveInlineLevel;
-        do {
-            inlined = false;
-
-            List<Invoke> trivialInline = new ArrayList<Invoke>();
-            List<Invoke> deoptInline = new ArrayList<Invoke>();
-            List<RiMethod> deoptMethods = new ArrayList<RiMethod>();
-            for (Node node : compilation.graph.getNodes()) {
-                if (node instanceof Invoke) {
-                    Invoke invoke = (Invoke) node;
-                    RiMethod target = invoke.target;
-                    if (target.isResolved() && !Modifier.isNative(target.accessFlags())) {
-                        if (target.canBeStaticallyBound()) {
-                            trivialInline.add(invoke);
-                        } else {
-                            RiMethod concrete = invoke.target.holder().uniqueConcreteMethod(invoke.target);
-                            if (concrete != null && concrete.isResolved() && !Modifier.isNative(concrete.accessFlags())) {
-                                deoptInline.add(invoke);
-                                deoptMethods.add(concrete);
-                            }
-                        }
-                    }
-                }
-            }
-
-            for (Invoke invoke : trivialInline) {
-                if (inlineMethod(invoke, invoke.target)) {
-                    inlined = true;
-                    inliningSize += invoke.target.code().length;
-                    if (inliningSize > C1XOptions.MaximumInstructionCount) {
-                        break;
-                    }
-                }
-            }
-
-            for (int i = 0; i < deoptInline.size(); i++) {
-                Invoke invoke = deoptInline.get(i);
-                RiMethod method = deoptMethods.get(i);
-                if (inlineMethod(invoke, method)) {
-                    if (C1XOptions.TraceInlining) {
-                        System.out.println("registering concrete method assumption...");
-                    }
-                    compilation.assumptions.recordConcreteMethod(invoke.target, method);
-                    inlined = true;
-                    inliningSize += method.code().length;
-                    if (inliningSize > C1XOptions.MaximumInstructionCount) {
-                        break;
-                    }
-                }
-            }
-
-            if (inlined) {
-                DeadCodeElimination dce = new DeadCodeElimination();
-                dce.apply(compilation.graph);
-                if (dce.deletedNodeCount > 0) {
-                    verifyAndPrint("After dead code elimination");
-                }
-                verifyAndPrint("After inlining iteration");
-            }
-
-            if (inliningSize > C1XOptions.MaximumInstructionCount) {
-                break;
-            }
-        } while(inlined && (--iterations > 0));
-    }
-
-    private boolean inlineMethod(Invoke invoke, RiMethod method) {
-        String name = invoke.id() + ": " + CiUtil.format("%H.%n(%p):%r", method, false) + " (" + method.code().length + " bytes)";
-        FrameState stateAfter = invoke.stateAfter();
-
-        if (method.code().length > C1XOptions.MaximumInlineSize) {
-            if (C1XOptions.TraceInlining) {
-                System.out.println("not inlining " + name + " because of code size");
-            }
-            return false;
-        }
-
-        if (invoke.predecessors().size() == 0) {
-            if (C1XOptions.TraceInlining) {
-                System.out.println("not inlining " + name + " because the invoke is dead code");
-            }
-            return false;
-        }
-
-        Instruction exceptionEdge = invoke.exceptionEdge();
-//        if (exceptionEdge != null) {
-//            if (C1XOptions.TraceInlining) {
-//                System.out.println("not inlining " + name + " because of exceptionEdge");
-//            }
-//            return false;
-//        }
-        if (!method.holder().isInitialized()) {
-            if (C1XOptions.TraceInlining) {
-                System.out.println("not inlining " + name + " because of non-initialized class");
-            }
-            return false;
-        }
-
-        if (C1XOptions.TraceInlining) {
-            System.out.printf("Building graph for %s, locals: %d, stack: %d\n", name, method.maxLocals(), method.maxStackSize());
-        }
-
-        CompilerGraph graph = new CompilerGraph();
-        new GraphBuilder(compilation, method, graph).build(true);
-
-        boolean withReceiver = !Modifier.isStatic(method.accessFlags());
-
-        int argumentCount = method.signature().argumentCount(false);
-        Value[] parameters = new Value[argumentCount + (withReceiver ? 1 : 0)];
-        int slot = withReceiver ? 1 : 0;
-        int param = withReceiver ? 1 : 0;
-        for (int i = 0; i < argumentCount; i++) {
-            parameters[param++] = invoke.argument(slot);
-            slot += method.signature().argumentKindAt(i).sizeInSlots();
-        }
-        if (withReceiver) {
-            parameters[0] = invoke.argument(0);
-        }
-
-        HashMap<Node, Node> replacements = new HashMap<Node, Node>();
-        ArrayList<Node> nodes = new ArrayList<Node>();
-        ArrayList<Node> frameStates = new ArrayList<Node>();
-        Return returnNode = null;
-        Unwind unwindNode = null;
-        StartNode startNode = graph.start();
-        for (Node node : graph.getNodes()) {
-            if (node != null) {
-                if (node instanceof StartNode) {
-                    assert startNode == node;
-                } else if (node instanceof Local) {
-                    replacements.put(node, parameters[((Local) node).index()]);
-                } else {
-                    nodes.add(node);
-                    if (node instanceof Return) {
-                        returnNode = (Return) node;
-                    } else if (node instanceof Unwind) {
-                        unwindNode = (Unwind) node;
-                    } else if (node instanceof FrameState) {
-                        frameStates.add(node);
-                    }
-                }
-            }
-        }
-
-        if (C1XOptions.TraceInlining) {
-            printGraph("Subgraph " + CiUtil.format("%H.%n(%p):%r", method, false), graph);
-            System.out.println("inlining " + name + ": " + frameStates.size() + " frame states, " + nodes.size() + " nodes");
-        }
-
-        assert invoke.predecessors().size() == 1 : "size: " + invoke.predecessors().size();
-        Instruction pred;
-        if (withReceiver) {
-            pred = new NullCheck(parameters[0], compilation.graph);
-        } else {
-            pred = new Merge(compilation.graph);
-        }
-        invoke.predecessors().get(0).successors().replace(invoke, pred);
-        replacements.put(startNode, pred);
-
-        Map<Node, Node> duplicates = compilation.graph.addDuplicate(nodes, replacements);
-
-        if (returnNode != null) {
-            List<Node> usages = new ArrayList<Node>(invoke.usages());
-            for (Node usage : usages) {
-                if (returnNode.result() instanceof Local) {
-                    usage.inputs().replace(invoke, replacements.get(returnNode.result()));
-                } else {
-                    usage.inputs().replace(invoke, duplicates.get(returnNode.result()));
-                }
-            }
-            Node returnDuplicate = duplicates.get(returnNode);
-            returnDuplicate.inputs().clearAll();
-
-            assert returnDuplicate.predecessors().size() == 1;
-            Node returnPred = returnDuplicate.predecessors().get(0);
-            int index = returnDuplicate.predecessorsIndex().get(0);
-            returnPred.successors().setAndClear(index, invoke, 0);
-            returnDuplicate.delete();
-        }
-
-//        if (invoke.next() instanceof Merge) {
-//            ((Merge) invoke.next()).removePhiPredecessor(invoke);
-//        }
-//        invoke.successors().clearAll();
-        invoke.inputs().clearAll();
-        invoke.setExceptionEdge(null);
-//        invoke.delete();
-
-
-        if (exceptionEdge != null) {
-            if (unwindNode != null) {
-                assert unwindNode.predecessors().size() == 1;
-                assert exceptionEdge.successors().size() == 1;
-                ExceptionObject obj = (ExceptionObject) exceptionEdge;
-
-                List<Node> usages = new ArrayList<Node>(obj.usages());
-                for (Node usage : usages) {
-                    if (replacements.containsKey(unwindNode.exception())) {
-                        usage.inputs().replace(obj, replacements.get(unwindNode.exception()));
-                    } else {
-                        usage.inputs().replace(obj, duplicates.get(unwindNode.exception()));
-                    }
-                }
-                Node unwindDuplicate = duplicates.get(unwindNode);
-                unwindDuplicate.inputs().clearAll();
-
-                assert unwindDuplicate.predecessors().size() == 1;
-                Node unwindPred = unwindDuplicate.predecessors().get(0);
-                int index = unwindDuplicate.predecessorsIndex().get(0);
-                unwindPred.successors().setAndClear(index, obj, 0);
-
-                obj.inputs().clearAll();
-                obj.delete();
-                unwindDuplicate.delete();
-
-            }
-        }
-
-        // adjust all frame states that were copied
-        if (frameStates.size() > 0) {
-            FrameState outerFrameState = stateAfter.duplicateModified(invoke.bci, invoke.kind);
-            for (Node frameState : frameStates) {
-                ((FrameState) duplicates.get(frameState)).setOuterFrameState(outerFrameState);
-            }
-        }
-
-        if (C1XOptions.TraceInlining) {
-            verifyAndPrint("After inlining " + CiUtil.format("%H.%n(%p):%r", method, false));
-        }
-        return true;
-    }
-
     /**
      * Gets the linear scan ordering of blocks as a list.
      * @return the blocks in linear scan order