Mercurial > hg > graal-jvmci-8
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