Mercurial > hg > truffle
changeset 14746:7544068e1a91
Perform de-virtualization of calls only in canonicalizer and not in graph builder
author | Christian Wimmer <christian.wimmer@oracle.com> |
---|---|
date | Tue, 25 Mar 2014 13:32:32 -0700 |
parents | 65b005b58825 |
children | a836fed0e270 |
files | graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java |
diffstat | 3 files changed, 25 insertions(+), 46 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java Tue Mar 25 11:50:57 2014 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java Tue Mar 25 13:32:32 2014 -0700 @@ -321,6 +321,7 @@ Assumptions assumptions = new Assumptions(false); HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); + canonicalizer.apply(graph, context); new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); if (loopPeeling) { new LoopTransformHighPhase().apply(graph);
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Tue Mar 25 11:50:57 2014 -0700 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Tue Mar 25 13:32:32 2014 -0700 @@ -1113,7 +1113,7 @@ private void genInvokeInterface(JavaMethod target) { if (target instanceof ResolvedJavaMethod) { ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(true), target.getSignature().getParameterCount(true)); - genInvokeIndirect(InvokeKind.Interface, (ResolvedJavaMethod) target, args); + appendInvoke(InvokeKind.Interface, (ResolvedJavaMethod) target, args); } else { handleUnresolvedInvoke(target, InvokeKind.Interface); } @@ -1148,7 +1148,7 @@ } ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(hasReceiver), target.getSignature().getParameterCount(hasReceiver)); if (hasReceiver) { - genInvokeIndirect(InvokeKind.Virtual, (ResolvedJavaMethod) target, args); + appendInvoke(InvokeKind.Virtual, (ResolvedJavaMethod) target, args); } else { appendInvoke(InvokeKind.Static, (ResolvedJavaMethod) target, args); } @@ -1163,47 +1163,12 @@ assert target != null; assert target.getSignature() != null; ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(true), target.getSignature().getParameterCount(true)); - invokeDirect((ResolvedJavaMethod) target, args); + appendInvoke(InvokeKind.Special, (ResolvedJavaMethod) target, args); } else { handleUnresolvedInvoke(target, InvokeKind.Special); } } - private void genInvokeIndirect(InvokeKind invokeKind, ResolvedJavaMethod target, ValueNode[] args) { - ValueNode receiver = args[0]; - // attempt to devirtualize the call - ResolvedJavaType klass = target.getDeclaringClass(); - - // 0. check for trivial cases - if (target.canBeStaticallyBound()) { - // check for trivial cases (e.g. final methods, nonvirtual methods) - invokeDirect(target, args); - return; - } - // 1. check if the exact type of the receiver can be determined - ResolvedJavaType exact = klass.asExactType(); - if (exact == null && receiver.stamp() instanceof ObjectStamp) { - ObjectStamp receiverStamp = (ObjectStamp) receiver.stamp(); - if (receiverStamp.isExactType()) { - exact = receiverStamp.type(); - } - } - if (exact != null) { - // either the holder class is exact, or the receiver object has an exact type - ResolvedJavaMethod exactMethod = exact.resolveMethod(target); - if (exactMethod != null) { - invokeDirect(exactMethod, args); - return; - } - } - // devirtualization failed, produce an actual invokevirtual - appendInvoke(invokeKind, target, args); - } - - private void invokeDirect(ResolvedJavaMethod target, ValueNode[] args) { - appendInvoke(InvokeKind.Special, target, args); - } - private void appendInvoke(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] args) { Kind resultType = targetMethod.getSignature().getReturnKind(); if (DeoptALot.getValue()) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Tue Mar 25 11:50:57 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Tue Mar 25 13:32:32 2014 -0700 @@ -126,15 +126,28 @@ @Override public Node canonical(CanonicalizerTool tool) { - if (!isStatic()) { + if (invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual) { + // attempt to devirtualize the call + + // check for trivial cases (e.g. final methods, nonvirtual methods) + if (targetMethod.canBeStaticallyBound()) { + invokeKind = InvokeKind.Special; + return this; + } + + // check if the exact type of the receiver can be determined ValueNode receiver = receiver(); - if (receiver != null && ObjectStamp.isExactType(receiver) && ObjectStamp.typeOrNull(receiver) != null) { - if (invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual) { - ResolvedJavaMethod method = ObjectStamp.typeOrNull(receiver).resolveMethod(targetMethod); - if (method != null) { - invokeKind = InvokeKind.Special; - targetMethod = method; - } + ResolvedJavaType exact = targetMethod.getDeclaringClass().asExactType(); + if (exact == null && ObjectStamp.isExactType(receiver)) { + exact = ObjectStamp.typeOrNull(receiver); + } + if (exact != null) { + // either the holder class is exact, or the receiver object has an exact type + ResolvedJavaMethod exactMethod = exact.resolveMethod(targetMethod); + if (exactMethod != null) { + invokeKind = InvokeKind.Special; + targetMethod = exactMethod; + return this; } } }