Mercurial > hg > graal-jvmci-8
changeset 19118:036c0b9bd4f5
Merge.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Wed, 04 Feb 2015 03:22:41 +0100 |
parents | 4f30f1e7e1e6 (diff) 02bfa2747729 (current diff) |
children | a5f47cb74b1b |
files | graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugins.java |
diffstat | 23 files changed, 276 insertions(+), 184 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java Wed Feb 04 01:31:23 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java Wed Feb 04 03:22:41 2015 +0100 @@ -67,7 +67,7 @@ StructuredGraph graph = new StructuredGraph(javaMethod); GraphBuilderConfiguration conf = GraphBuilderConfiguration.getSnippetDefault(); - new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), assumptions, conf, OptimisticOptimizations.ALL).apply(graph); + new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), assumptions, getProviders().getConstantReflection(), conf, OptimisticOptimizations.ALL).apply(graph); HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); new CanonicalizerPhase(true).apply(graph, context);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java Wed Feb 04 01:31:23 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java Wed Feb 04 03:22:41 2015 +0100 @@ -152,7 +152,8 @@ graph = new StructuredGraph(method); try (Scope s = Debug.scope(getClass(), graph, method, getCodeCache())) { Assumptions assumptions = new Assumptions(false); - new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), assumptions, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph); + new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), assumptions, getProviders().getConstantReflection(), GraphBuilderConfiguration.getEagerDefault(), + OptimisticOptimizations.ALL).apply(graph); context = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); new DeadCodeEliminationPhase().apply(graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/StaticAnalysis.java Wed Feb 04 01:31:23 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/StaticAnalysis.java Wed Feb 04 03:22:41 2015 +0100 @@ -238,7 +238,7 @@ OptimisticOptimizations optimisticOpts = OptimisticOptimizations.NONE; Assumptions assumptions = new Assumptions(false); - GraphBuilderPhase.Instance graphBuilder = new GraphBuilderPhase.Instance(metaAccess, stampProvider, assumptions, graphBuilderConfig, optimisticOpts); + GraphBuilderPhase.Instance graphBuilder = new GraphBuilderPhase.Instance(metaAccess, stampProvider, assumptions, null, graphBuilderConfig, optimisticOpts); graphBuilder.apply(graph); } catch (Throwable ex) { Debug.handle(ex);
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Wed Feb 04 01:31:23 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Wed Feb 04 03:22:41 2015 +0100 @@ -36,6 +36,7 @@ import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.debug.*; import com.oracle.graal.java.BciBlockMapping.BciBlock; +import com.oracle.graal.nodes.*; import com.oracle.graal.options.*; import com.oracle.graal.phases.*; @@ -687,7 +688,10 @@ Kind kind = field.getKind(); T receiver = frameState.apop(); if ((field instanceof ResolvedJavaField) && ((ResolvedJavaField) field).getDeclaringClass().isInitialized()) { - appendOptimizedLoadField(kind, genLoadField(receiver, (ResolvedJavaField) field)); + GraphBuilderPlugins.LoadFieldPlugin loadFieldPlugin = this.graphBuilderConfig.getLoadFieldPlugin(); + if (loadFieldPlugin == null || !loadFieldPlugin.apply((GraphBuilderContext) this, (ValueNode) receiver, (ResolvedJavaField) field)) { + appendOptimizedLoadField(kind, genLoadField(receiver, (ResolvedJavaField) field)); + } } else { handleUnresolvedLoadField(field, receiver); }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderConfiguration.java Wed Feb 04 01:31:23 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderConfiguration.java Wed Feb 04 03:22:41 2015 +0100 @@ -37,6 +37,8 @@ private final DebugInfoMode debugInfoMode; private final boolean doLivenessAnalysis; private final boolean inlineTrivial; + private GraphBuilderPlugins.LoadFieldPlugin loadFieldPlugin; + private GraphBuilderPlugins.ParameterPlugin parameterPlugin; public static enum DebugInfoMode { SafePointsOnly, @@ -72,6 +74,12 @@ this.inlineTrivial = inlineTrivial; } + public GraphBuilderConfiguration copy() { + GraphBuilderConfiguration result = new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, skippedExceptionTypes, doLivenessAnalysis, inlineTrivial); + result.loadFieldPlugin = loadFieldPlugin; + return result; + } + public GraphBuilderConfiguration withSkippedExceptionTypes(ResolvedJavaType[] newSkippedExceptionTypes) { return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, newSkippedExceptionTypes, doLivenessAnalysis, inlineTrivial); } @@ -93,6 +101,14 @@ return new GraphBuilderConfiguration(eagerResolving, omitAllExceptionEdges, debugInfoMode, skippedExceptionTypes, doLivenessAnalysis, newInlineTrivial); } + public GraphBuilderPlugins.LoadFieldPlugin getLoadFieldPlugin() { + return loadFieldPlugin; + } + + public void setLoadFieldPlugin(GraphBuilderPlugins.LoadFieldPlugin loadFieldPlugin) { + this.loadFieldPlugin = loadFieldPlugin; + } + public ResolvedJavaType[] getSkippedExceptionTypes() { return skippedExceptionTypes; } @@ -145,4 +161,12 @@ public boolean shouldInlineTrivial() { return inlineTrivial; } + + public GraphBuilderPlugins.ParameterPlugin getParameterPlugin() { + return parameterPlugin; + } + + public void setParameterPlugin(GraphBuilderPlugins.ParameterPlugin parameterPlugin) { + this.parameterPlugin = parameterPlugin; + } }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Wed Feb 04 01:31:23 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Wed Feb 04 03:22:41 2015 +0100 @@ -69,7 +69,8 @@ @Override protected void run(StructuredGraph graph, HighTierContext context) { - new Instance(context.getMetaAccess(), context.getStampProvider(), context.getAssumptions(), graphBuilderConfig, graphBuilderPlugins, context.getOptimisticOptimizations()).run(graph); + new Instance(context.getMetaAccess(), context.getStampProvider(), context.getAssumptions(), context.getConstantReflection(), graphBuilderConfig, graphBuilderPlugins, + context.getOptimisticOptimizations()).run(graph); } public GraphBuilderConfiguration getGraphBuilderConfig() { @@ -93,6 +94,7 @@ private final OptimisticOptimizations optimisticOpts; private final StampProvider stampProvider; private final Assumptions assumptions; + private final ConstantReflectionProvider constantReflectionProvider; /** * Gets the graph being processed by this builder. @@ -101,19 +103,21 @@ return currentGraph; } - public Instance(MetaAccessProvider metaAccess, StampProvider stampProvider, Assumptions assumptions, GraphBuilderConfiguration graphBuilderConfig, GraphBuilderPlugins graphBuilderPlugins, - OptimisticOptimizations optimisticOpts) { + public Instance(MetaAccessProvider metaAccess, StampProvider stampProvider, Assumptions assumptions, ConstantReflectionProvider constantReflectionProvider, + GraphBuilderConfiguration graphBuilderConfig, GraphBuilderPlugins graphBuilderPlugins, OptimisticOptimizations optimisticOpts) { this.graphBuilderConfig = graphBuilderConfig; this.optimisticOpts = optimisticOpts; this.metaAccess = metaAccess; this.stampProvider = stampProvider; this.assumptions = assumptions; this.graphBuilderPlugins = graphBuilderPlugins; + this.constantReflectionProvider = constantReflectionProvider; assert metaAccess != null; } - public Instance(MetaAccessProvider metaAccess, StampProvider stampProvider, Assumptions assumptions, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) { - this(metaAccess, stampProvider, assumptions, graphBuilderConfig, null, optimisticOpts); + public Instance(MetaAccessProvider metaAccess, StampProvider stampProvider, Assumptions assumptions, ConstantReflectionProvider constantReflectionProvider, + GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) { + this(metaAccess, stampProvider, assumptions, constantReflectionProvider, graphBuilderConfig, null, optimisticOpts); } @Override @@ -124,7 +128,7 @@ assert method.getCode() != null : "method must contain bytecodes: " + method; this.currentGraph = graph; HIRFrameStateBuilder frameState = new HIRFrameStateBuilder(method, graph, null); - frameState.initializeForMethodStart(graphBuilderConfig.eagerResolving()); + frameState.initializeForMethodStart(graphBuilderConfig.eagerResolving(), this.graphBuilderConfig.getParameterPlugin()); TTY.Filter filter = new TTY.Filter(PrintFilter.getValue(), method); try { BytecodeParser parser = new BytecodeParser(metaAccess, method, graphBuilderConfig, optimisticOpts, entryBCI); @@ -558,7 +562,7 @@ @Override protected ValueNode genObjectEquals(ValueNode x, ValueNode y) { - return new ObjectEqualsNode(x, y); + return ObjectEqualsNode.create(x, y, constantReflectionProvider); } @Override @@ -998,7 +1002,6 @@ } public <T extends FloatingNode> T append(T v) { - assert !(v instanceof ConstantNode); T added = currentGraph.unique(v); return added; } @@ -1482,11 +1485,24 @@ } condition = genUnique(condition); - ValueNode trueSuccessor = createBlockTarget(probability, trueBlock, frameState); - ValueNode falseSuccessor = createBlockTarget(1 - probability, falseBlock, frameState); + if (condition instanceof LogicConstantNode) { + LogicConstantNode constantLogicNode = (LogicConstantNode) condition; + boolean value = constantLogicNode.getValue(); + if (negate) { + value = !value; + } + BciBlock nextBlock = falseBlock; + if (value) { + nextBlock = trueBlock; + } + appendGoto(createTarget(nextBlock, frameState)); + } else { + ValueNode trueSuccessor = createBlockTarget(probability, trueBlock, frameState); + ValueNode falseSuccessor = createBlockTarget(1 - probability, falseBlock, frameState); - ValueNode ifNode = negate ? genIfNode(condition, falseSuccessor, trueSuccessor, 1 - probability) : genIfNode(condition, trueSuccessor, falseSuccessor, probability); - append(ifNode); + ValueNode ifNode = negate ? genIfNode(condition, falseSuccessor, trueSuccessor, 1 - probability) : genIfNode(condition, trueSuccessor, falseSuccessor, probability); + append(ifNode); + } } public StampProvider getStampProvider() {
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugins.java Wed Feb 04 01:31:23 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPlugins.java Wed Feb 04 03:22:41 2015 +0100 @@ -30,12 +30,21 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; /** * Interface for managing a set of graph builder {@link GraphBuilderPlugin}s. */ public interface GraphBuilderPlugins { + public interface LoadFieldPlugin extends GraphBuilderPlugin { + boolean apply(GraphBuilderContext builder, ValueNode receiver, ResolvedJavaField field); + } + + public interface ParameterPlugin extends GraphBuilderPlugin { + FloatingNode interceptParameter(int index); + } + /** * Plugin for handling a method invocation. */
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java Wed Feb 04 01:31:23 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java Wed Feb 04 03:22:41 2015 +0100 @@ -31,6 +31,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.debug.*; +import com.oracle.graal.java.GraphBuilderPlugins.ParameterPlugin; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; @@ -81,14 +82,20 @@ } } - public final void initializeForMethodStart(boolean eagerResolve) { + public final void initializeForMethodStart(boolean eagerResolve, ParameterPlugin parameterPlugin) { int javaIndex = 0; int index = 0; if (!method.isStatic()) { // add the receiver - ParameterNode receiver = graph.unique(new ParameterNode(javaIndex, StampFactory.declaredNonNull(method.getDeclaringClass()))); - storeLocal(javaIndex, receiver); + FloatingNode receiver = null; + if (parameterPlugin != null) { + receiver = parameterPlugin.interceptParameter(index); + } + if (receiver == null) { + receiver = new ParameterNode(javaIndex, StampFactory.declaredNonNull(method.getDeclaringClass())); + } + storeLocal(javaIndex, graph.unique(receiver)); javaIndex = 1; index = 1; } @@ -107,8 +114,14 @@ } else { stamp = StampFactory.forKind(kind); } - ParameterNode param = graph.unique(new ParameterNode(index, stamp)); - storeLocal(javaIndex, param); + FloatingNode param = null; + if (parameterPlugin != null) { + param = parameterPlugin.interceptParameter(index); + } + if (param == null) { + param = new ParameterNode(index, stamp); + } + storeLocal(javaIndex, graph.unique(param)); javaIndex += kind.getSlotCount(); index++; }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Wed Feb 04 01:31:23 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Wed Feb 04 03:22:41 2015 +0100 @@ -39,14 +39,19 @@ @NodeInfo public abstract class CompareNode extends BinaryOpLogicNode { + protected final Condition condition; + protected final boolean unorderedIsTrue; + /** * Constructs a new Compare instruction. * * @param x the instruction producing the first input to the instruction * @param y the instruction that produces the second input to this instruction */ - public CompareNode(ValueNode x, ValueNode y) { + public CompareNode(Condition condition, boolean unorderedIsTrue, ValueNode x, ValueNode y) { super(x, y); + this.condition = condition; + this.unorderedIsTrue = unorderedIsTrue; } /** @@ -54,14 +59,18 @@ * * @return the condition */ - public abstract Condition condition(); + public final Condition condition() { + return condition; + } /** * Checks whether unordered inputs mean true or false (only applies to float operations). * * @return {@code true} if unordered inputs produce true */ - public abstract boolean unorderedIsTrue(); + public final boolean unorderedIsTrue() { + return this.unorderedIsTrue; + } private ValueNode optimizeConditional(Constant constant, ConditionalNode conditionalNode, ConstantReflectionProvider constantReflection, Condition cond) { Constant trueConstant = conditionalNode.trueValue().asConstant(); @@ -93,8 +102,10 @@ @Override public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { - if (forX.isConstant() && forY.isConstant()) { - return LogicConstantNode.forBoolean(condition().foldCondition(forX.asConstant(), forY.asConstant(), tool.getConstantReflection(), unorderedIsTrue())); + ConstantReflectionProvider constantReflection = tool.getConstantReflection(); + LogicNode constantCondition = tryConstantFold(condition(), forX, forY, constantReflection, unorderedIsTrue()); + if (constantCondition != null) { + return constantCondition; } ValueNode result; if (forX.isConstant()) { @@ -115,7 +126,14 @@ return this; } - protected abstract CompareNode duplicateModified(ValueNode newX, ValueNode newY); + public static LogicNode tryConstantFold(Condition condition, ValueNode forX, ValueNode forY, ConstantReflectionProvider constantReflection, boolean unorderedIsTrue) { + if (forX.isConstant() && forY.isConstant() && constantReflection != null) { + return LogicConstantNode.forBoolean(condition.foldCondition(forX.asConstant(), forY.asConstant(), constantReflection, unorderedIsTrue)); + } + return null; + } + + protected abstract LogicNode duplicateModified(ValueNode newX, ValueNode newY); protected ValueNode canonicalizeSymmetricConstant(CanonicalizerTool tool, Constant constant, ValueNode nonConstant, boolean mirrored) { if (nonConstant instanceof ConditionalNode) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java Wed Feb 04 01:31:23 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java Wed Feb 04 03:22:41 2015 +0100 @@ -22,6 +22,7 @@ */ package com.oracle.graal.nodes.calc; +import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.type.*; @@ -31,22 +32,21 @@ import com.oracle.graal.nodes.util.*; @NodeInfo(shortName = "==") -public class FloatEqualsNode extends CompareNode { +public final class FloatEqualsNode extends CompareNode { public FloatEqualsNode(ValueNode x, ValueNode y) { - super(x, y); + super(Condition.EQ, false, x, y); assert x.stamp() instanceof FloatStamp && y.stamp() instanceof FloatStamp : x.stamp() + " " + y.stamp(); assert x.stamp().isCompatible(y.stamp()); } - @Override - public Condition condition() { - return Condition.EQ; - } - - @Override - public boolean unorderedIsTrue() { - return false; + public static LogicNode create(ValueNode x, ValueNode y, ConstantReflectionProvider constantReflection) { + LogicNode result = CompareNode.tryConstantFold(Condition.EQ, x, y, constantReflection, false); + if (result != null) { + return result; + } else { + return new FloatEqualsNode(x, y); + } } @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java Wed Feb 04 01:31:23 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java Wed Feb 04 03:22:41 2015 +0100 @@ -33,23 +33,10 @@ @NodeInfo(shortName = "<") public class FloatLessThanNode extends CompareNode { - protected final boolean unorderedIsTrue; - public FloatLessThanNode(ValueNode x, ValueNode y, boolean unorderedIsTrue) { - super(x, y); + super(Condition.LT, unorderedIsTrue, x, y); assert x.stamp() instanceof FloatStamp && y.stamp() instanceof FloatStamp; assert x.stamp().isCompatible(y.stamp()); - this.unorderedIsTrue = unorderedIsTrue; - } - - @Override - public Condition condition() { - return Condition.LT; - } - - @Override - public boolean unorderedIsTrue() { - return unorderedIsTrue; } @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowNode.java Wed Feb 04 01:31:23 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowNode.java Wed Feb 04 03:22:41 2015 +0100 @@ -33,22 +33,12 @@ public class IntegerBelowNode extends CompareNode { public IntegerBelowNode(ValueNode x, ValueNode y) { - super(x, y); + super(Condition.BT, false, x, y); assert x.stamp() instanceof IntegerStamp; assert y.stamp() instanceof IntegerStamp; } @Override - public Condition condition() { - return Condition.BT; - } - - @Override - public boolean unorderedIsTrue() { - return false; - } - - @Override public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { ValueNode result = super.canonical(tool, forX, forY); if (result != this) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java Wed Feb 04 01:31:23 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java Wed Feb 04 03:22:41 2015 +0100 @@ -35,22 +35,12 @@ public class IntegerEqualsNode extends CompareNode { public IntegerEqualsNode(ValueNode x, ValueNode y) { - super(x, y); + super(Condition.EQ, false, x, y); assert !x.getKind().isNumericFloat() && x.getKind() != Kind.Object; assert !y.getKind().isNumericFloat() && y.getKind() != Kind.Object; } @Override - public Condition condition() { - return Condition.EQ; - } - - @Override - public boolean unorderedIsTrue() { - return false; - } - - @Override protected ValueNode optimizeNormalizeCmp(Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored) { PrimitiveConstant primitive = (PrimitiveConstant) constant; if (primitive.getKind() == Kind.Int && primitive.asInt() == 0) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java Wed Feb 04 01:31:23 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java Wed Feb 04 03:22:41 2015 +0100 @@ -35,22 +35,12 @@ public class IntegerLessThanNode extends CompareNode { public IntegerLessThanNode(ValueNode x, ValueNode y) { - super(x, y); + super(Condition.LT, false, x, y); assert !x.getKind().isNumericFloat() && x.getKind() != Kind.Object; assert !y.getKind().isNumericFloat() && y.getKind() != Kind.Object; } @Override - public Condition condition() { - return Condition.LT; - } - - @Override - public boolean unorderedIsTrue() { - return false; - } - - @Override protected ValueNode optimizeNormalizeCmp(Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored) { PrimitiveConstant primitive = (PrimitiveConstant) constant; assert condition() == Condition.LT;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java Wed Feb 04 01:31:23 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java Wed Feb 04 03:22:41 2015 +0100 @@ -55,7 +55,7 @@ LogicNode equalComp; LogicNode lessComp; if (getX().stamp() instanceof FloatStamp) { - equalComp = graph().unique(new FloatEqualsNode(getX(), getY())); + equalComp = graph().unique(FloatEqualsNode.create(getX(), getY(), tool.getConstantReflection())); lessComp = graph().unique(new FloatLessThanNode(getX(), getY(), isUnorderedLess)); } else { equalComp = graph().unique(new IntegerEqualsNode(getX(), getY()));
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java Wed Feb 04 01:31:23 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java Wed Feb 04 03:22:41 2015 +0100 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; +import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; @@ -38,6 +39,15 @@ assert y.stamp() instanceof AbstractObjectStamp; } + public static LogicNode create(ValueNode x, ValueNode y, ConstantReflectionProvider constantReflection) { + LogicNode result = CompareNode.tryConstantFold(Condition.EQ, x, y, constantReflection, false); + if (result != null) { + return result; + } else { + return new ObjectEqualsNode(x, y); + } + } + private void virtualizeNonVirtualComparison(State state, ValueNode other, VirtualizerTool tool) { if (!state.getVirtualObject().hasIdentity() && state.getVirtualObject().entryKind(0) == Kind.Boolean) { if (other.isConstant()) { @@ -75,7 +85,7 @@ /* * One of the two objects has identity, the other doesn't. In code, this looks like * "Integer.valueOf(a) == new Integer(b)", which is always false. - * + * * In other words: an object created via valueOf can never be equal to one created * by new in the same compilation unit. */
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/PointerEqualsNode.java Wed Feb 04 01:31:23 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/PointerEqualsNode.java Wed Feb 04 03:22:41 2015 +0100 @@ -33,22 +33,12 @@ public class PointerEqualsNode extends CompareNode { public PointerEqualsNode(ValueNode x, ValueNode y) { - super(x, y); + super(Condition.EQ, false, x, y); assert x.stamp() instanceof AbstractPointerStamp; assert y.stamp() instanceof AbstractPointerStamp; } @Override - public Condition condition() { - return Condition.EQ; - } - - @Override - public boolean unorderedIsTrue() { - return false; - } - - @Override public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) { return LogicConstantNode.tautology();
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Wed Feb 04 01:31:23 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Wed Feb 04 03:22:41 2015 +0100 @@ -619,8 +619,8 @@ if (MethodsElidedInSnippets != null && methodToParse.getSignature().getReturnKind() == Kind.Void && MethodFilter.matches(MethodsElidedInSnippets, methodToParse)) { graph.addAfterFixed(graph.start(), graph.add(new ReturnNode(null))); } else { - createGraphBuilder(metaAccess, replacements.providers.getStampProvider(), replacements.assumptions, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply( - graph); + createGraphBuilder(metaAccess, replacements.providers.getStampProvider(), replacements.assumptions, replacements.providers.getConstantReflection(), + GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(graph); } afterParsing(graph); @@ -633,9 +633,9 @@ return graph; } - protected Instance createGraphBuilder(MetaAccessProvider metaAccess, StampProvider stampProvider, Assumptions assumptions, GraphBuilderConfiguration graphBuilderConfig, - OptimisticOptimizations optimisticOpts) { - return new GraphBuilderPhase.Instance(metaAccess, stampProvider, assumptions, graphBuilderConfig, optimisticOpts); + protected Instance createGraphBuilder(MetaAccessProvider metaAccess, StampProvider stampProvider, Assumptions assumptions, ConstantReflectionProvider constantReflectionProvider, + GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) { + return new GraphBuilderPhase.Instance(metaAccess, stampProvider, assumptions, constantReflectionProvider, graphBuilderConfig, optimisticOpts); } protected void afterParsing(StructuredGraph graph) {
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Wed Feb 04 01:31:23 2015 +0100 +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Wed Feb 04 03:22:41 2015 +0100 @@ -177,7 +177,8 @@ Suites suites = suitesProvider.createSuites(); removeInliningPhase(suites); StructuredGraph graph = new StructuredGraph(javaMethod); - new GraphBuilderPhase.Instance(metaAccess, providers.getStampProvider(), new Assumptions(false), GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph); + new GraphBuilderPhase.Instance(metaAccess, providers.getStampProvider(), new Assumptions(false), providers.getConstantReflection(), GraphBuilderConfiguration.getEagerDefault(), + OptimisticOptimizations.ALL).apply(graph); PhaseSuite<HighTierContext> graphBuilderSuite = getGraphBuilderSuite(suitesProvider); CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false); Backend backend = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend();
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Wed Feb 04 01:31:23 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Wed Feb 04 03:22:41 2015 +0100 @@ -36,9 +36,11 @@ import com.oracle.graal.graph.Graph.Mark; import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node; +import com.oracle.graal.java.*; import com.oracle.graal.loop.*; import com.oracle.graal.nodes.CallTargetNode.InvokeKind; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.util.*; @@ -70,15 +72,26 @@ private final TruffleCache truffleCache; private final SnippetReflectionProvider snippetReflection; private final ResolvedJavaMethod callDirectMethod; + private final ResolvedJavaMethod callInlinedMethod; private final ResolvedJavaMethod callSiteProxyMethod; + protected final ResolvedJavaMethod callRootMethod; + private final GraphBuilderConfiguration configForRoot; - public PartialEvaluator(Providers providers, TruffleCache truffleCache, SnippetReflectionProvider snippetReflection) { + public PartialEvaluator(Providers providers, GraphBuilderConfiguration configForRoot, TruffleCache truffleCache, SnippetReflectionProvider snippetReflection) { this.providers = providers; this.canonicalizer = new CanonicalizerPhase(!ImmutableCode.getValue()); this.snippetReflection = snippetReflection; this.truffleCache = truffleCache; this.callDirectMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallTarget.getCallDirectMethod()); + this.callInlinedMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallTarget.getCallInlinedMethod()); this.callSiteProxyMethod = providers.getMetaAccess().lookupJavaMethod(GraalFrameInstance.CallNodeFrame.METHOD); + this.configForRoot = configForRoot; + + try { + callRootMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallTarget.class.getDeclaredMethod("callRoot", Object[].class)); + } catch (NoSuchMethodException ex) { + throw new RuntimeException(ex); + } } public StructuredGraph createGraph(final OptimizedCallTarget callTarget, final Assumptions assumptions) { @@ -91,65 +104,34 @@ } catch (Throwable e) { throw Debug.handle(e); } - final StructuredGraph graph = truffleCache.createRootGraph(callTarget.toString()); + + final StructuredGraph graph = new StructuredGraph(callTarget.toString(), callRootMethod); assert graph != null : "no graph for root method"; try (Scope s = Debug.scope("CreateGraph", graph); Indent indent = Debug.logAndIndent("createGraph %s", graph)) { - // Canonicalize / constant propagate. - PhaseContext baseContext = new PhaseContext(providers, assumptions); - - injectConstantCallTarget(graph, callTarget, baseContext); - - Debug.dump(graph, "Before expansion"); - - TruffleExpansionLogger expansionLogger = null; - if (TraceTruffleExpansion.getValue()) { - expansionLogger = new TruffleExpansionLogger(providers, graph); - } - expandTree(graph, assumptions, expansionLogger); + Map<ResolvedJavaMethod, StructuredGraph> graphCache = null; + if (CacheGraphs.getValue()) { + graphCache = new HashMap<>(); + } + PhaseContext baseContext = new PhaseContext(providers, assumptions); + HighTierContext tierContext = new HighTierContext(providers, assumptions, graphCache, new PhaseSuite<HighTierContext>(), OptimisticOptimizations.NONE); - TruffleInliningCache inliningCache = null; - if (TruffleFunctionInlining.getValue()) { - callTarget.setInlining(new TruffleInlining(callTarget, new DefaultInliningPolicy())); - if (TruffleFunctionInliningCache.getValue()) { - inliningCache = new TruffleInliningCache(); - } + if (TruffleCompilerOptions.FastPE.getValue()) { + fastPartialEvaluation(callTarget, assumptions, graph, baseContext, tierContext); + } else { + createRootGraph(graph); + partialEvaluation(callTarget, assumptions, graph, baseContext, tierContext); } - expandDirectCalls(graph, assumptions, expansionLogger, callTarget.getInlining(), inliningCache); - if (Thread.currentThread().isInterrupted()) { return null; } new VerifyFrameDoesNotEscapePhase().apply(graph, false); - if (TraceTruffleCompilationHistogram.getValue() && constantReceivers != null) { createHistogram(); } - - canonicalizer.apply(graph, baseContext); - Map<ResolvedJavaMethod, StructuredGraph> graphCache = null; - if (CacheGraphs.getValue()) { - graphCache = new HashMap<>(); - } - HighTierContext tierContext = new HighTierContext(providers, assumptions, graphCache, new PhaseSuite<HighTierContext>(), OptimisticOptimizations.NONE); - - // EA frame and clean up. - do { - try (Scope pe = Debug.scope("TrufflePartialEscape", graph)) { - new PartialEscapePhase(true, canonicalizer).apply(graph, tierContext); - new IncrementalCanonicalizerPhase<>(canonicalizer, new ConditionalEliminationPhase()).apply(graph, tierContext); - } catch (Throwable t) { - Debug.handle(t); - } - } while (expandTree(graph, assumptions, expansionLogger)); - - if (expansionLogger != null) { - expansionLogger.print(callTarget); - } - postPartialEvaluation(graph); } catch (Throwable e) { @@ -159,6 +141,104 @@ return graph; } + private class InterceptLoadFieldPlugin implements GraphBuilderPlugins.LoadFieldPlugin { + + public boolean apply(GraphBuilderContext builder, ValueNode receiver, ResolvedJavaField field) { + System.out.println("Load field plugin called for receiver: " + receiver + " and field " + field); + + if (receiver.isConstant()) { + JavaConstant asJavaConstant = receiver.asJavaConstant(); + JavaConstant result = providers.getConstantReflection().readConstantFieldValue(field, asJavaConstant); + if (result != null) { + ConstantNode constantNode = builder.append(ConstantNode.forConstant(result, providers.getMetaAccess())); + builder.push(constantNode.getKind(), constantNode); + return true; + } + } + return false; + } + } + + private class InterceptReceiverPlugin implements GraphBuilderPlugins.ParameterPlugin { + + private final Object receiver; + + public InterceptReceiverPlugin(Object receiver) { + this.receiver = receiver; + } + + public FloatingNode interceptParameter(int index) { + if (index == 0) { + return ConstantNode.forConstant(snippetReflection.forObject(receiver), providers.getMetaAccess()); + } + return null; + } + } + + @SuppressWarnings("unused") + private void fastPartialEvaluation(OptimizedCallTarget callTarget, Assumptions assumptions, StructuredGraph graph, PhaseContext baseContext, HighTierContext tierContext) { + GraphBuilderConfiguration newConfig = configForRoot.copy(); + newConfig.setLoadFieldPlugin(new InterceptLoadFieldPlugin()); + newConfig.setParameterPlugin(new InterceptReceiverPlugin(callTarget)); + new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), new Assumptions(false), providers.getConstantReflection(), newConfig, TruffleCompilerImpl.Optimizations).apply(graph); + Debug.dump(graph, "After FastPE"); + } + + private void partialEvaluation(final OptimizedCallTarget callTarget, final Assumptions assumptions, final StructuredGraph graph, PhaseContext baseContext, HighTierContext tierContext) { + injectConstantCallTarget(graph, callTarget, baseContext); + + Debug.dump(graph, "Before expansion"); + + TruffleExpansionLogger expansionLogger = null; + if (TraceTruffleExpansion.getValue()) { + expansionLogger = new TruffleExpansionLogger(providers, graph); + } + + expandTree(graph, assumptions, expansionLogger); + + TruffleInliningCache inliningCache = null; + if (TruffleFunctionInlining.getValue()) { + callTarget.setInlining(new TruffleInlining(callTarget, new DefaultInliningPolicy())); + if (TruffleFunctionInliningCache.getValue()) { + inliningCache = new TruffleInliningCache(); + } + } + + expandDirectCalls(graph, assumptions, expansionLogger, callTarget.getInlining(), inliningCache); + + if (Thread.currentThread().isInterrupted()) { + return; + } + + canonicalizer.apply(graph, baseContext); + // EA frame and clean up. + do { + try (Scope pe = Debug.scope("TrufflePartialEscape", graph)) { + new PartialEscapePhase(true, canonicalizer).apply(graph, tierContext); + new IncrementalCanonicalizerPhase<>(canonicalizer, new ConditionalEliminationPhase()).apply(graph, tierContext); + } catch (Throwable t) { + Debug.handle(t); + } + } while (expandTree(graph, assumptions, expansionLogger)); + + if (expansionLogger != null) { + expansionLogger.print(callTarget); + } + } + + public StructuredGraph createRootGraph(StructuredGraph graph) { + new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), new Assumptions(false), providers.getConstantReflection(), configForRoot, + TruffleCompilerImpl.Optimizations).apply(graph); + return graph; + } + + public StructuredGraph createInlineGraph(String name) { + StructuredGraph graph = new StructuredGraph(name, callInlinedMethod); + new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), new Assumptions(false), providers.getConstantReflection(), configForRoot, + TruffleCompilerImpl.Optimizations).apply(graph); + return graph; + } + private static void postPartialEvaluation(final StructuredGraph graph) { NeverPartOfCompilationNode.verifyNotFoundIn(graph); for (MaterializeFrameNode materializeNode : graph.getNodes(MaterializeFrameNode.class).snapshot()) { @@ -464,7 +544,7 @@ private StructuredGraph createInlineGraph(PhaseContext phaseContext, Assumptions assumptions, TruffleInliningCache cache, TruffleInliningDecision decision) { try (Scope s = Debug.scope("GuestLanguageInlinedGraph", new DebugDumpScope(decision.getTarget().toString()))) { OptimizedCallTarget target = decision.getTarget(); - StructuredGraph inlineGraph = truffleCache.createInlineGraph(target.toString()); + StructuredGraph inlineGraph = createInlineGraph(target.toString()); injectConstantCallTarget(inlineGraph, decision.getTarget(), phaseContext); TruffleExpansionLogger expansionLogger = null; if (TraceTruffleExpansion.getValue()) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java Wed Feb 04 01:31:23 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java Wed Feb 04 03:22:41 2015 +0100 @@ -30,13 +30,6 @@ public interface TruffleCache { /** - * Creates the graph for the root method, i.e. {@link OptimizedCallTarget#callBoundary}. - */ - StructuredGraph createRootGraph(String name); - - StructuredGraph createInlineGraph(String name); - - /** * Returns a cached graph for a method with given arguments. */ StructuredGraph lookup(final ResolvedJavaMethod method, final NodeInputList<ValueNode> arguments, final CanonicalizerPhase finalCanonicalizer);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java Wed Feb 04 01:31:23 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java Wed Feb 04 03:22:41 2015 +0100 @@ -56,7 +56,6 @@ private final Providers providers; private final GraphBuilderConfiguration config; - private final GraphBuilderConfiguration configForRoot; private final OptimisticOptimizations optimisticOptimizations; private final HashMap<List<Object>, StructuredGraph> cache = new HashMap<>(); @@ -68,40 +67,17 @@ private final ResolvedJavaType errorClass; private final ResolvedJavaType controlFlowExceptionClass; - protected final ResolvedJavaMethod callRootMethod; - protected final ResolvedJavaMethod callInlinedMethod; - private long counter; - public TruffleCacheImpl(Providers providers, GraphBuilderConfiguration config, GraphBuilderConfiguration configForRoot, OptimisticOptimizations optimisticOptimizations) { + public TruffleCacheImpl(Providers providers, GraphBuilderConfiguration config, OptimisticOptimizations optimisticOptimizations) { this.providers = providers; this.config = config; - this.configForRoot = configForRoot; this.optimisticOptimizations = optimisticOptimizations; this.stringBuilderClass = providers.getMetaAccess().lookupJavaType(StringBuilder.class); this.runtimeExceptionClass = providers.getMetaAccess().lookupJavaType(RuntimeException.class); this.errorClass = providers.getMetaAccess().lookupJavaType(Error.class); this.controlFlowExceptionClass = providers.getMetaAccess().lookupJavaType(ControlFlowException.class); - - try { - callRootMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallTarget.class.getDeclaredMethod("callRoot", Object[].class)); - } catch (NoSuchMethodException ex) { - throw new RuntimeException(ex); - } - this.callInlinedMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallTarget.getCallInlinedMethod()); - } - - public StructuredGraph createInlineGraph(String name) { - StructuredGraph graph = new StructuredGraph(name, callInlinedMethod); - new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), new Assumptions(false), config, TruffleCompilerImpl.Optimizations).apply(graph); - return graph; - } - - public StructuredGraph createRootGraph(String name) { - StructuredGraph graph = new StructuredGraph(name, callRootMethod); - new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), new Assumptions(false), configForRoot, TruffleCompilerImpl.Optimizations).apply(graph); - return graph; } private static List<Object> computeCacheKey(ResolvedJavaMethod method, NodeInputList<ValueNode> arguments) { @@ -294,7 +270,7 @@ protected StructuredGraph parseGraph(final ResolvedJavaMethod method, final PhaseContext phaseContext) { final StructuredGraph graph = new StructuredGraph(method); - new GraphBuilderPhase.Instance(phaseContext.getMetaAccess(), phaseContext.getStampProvider(), phaseContext.getAssumptions(), config, optimisticOptimizations).apply(graph); + new GraphBuilderPhase.Instance(phaseContext.getMetaAccess(), phaseContext.getStampProvider(), phaseContext.getAssumptions(), null, config, optimisticOptimizations).apply(graph); return graph; }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Wed Feb 04 01:31:23 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Wed Feb 04 03:22:41 2015 +0100 @@ -84,9 +84,9 @@ ResolvedJavaType[] skippedExceptionTypes = getSkippedExceptionTypes(providers.getMetaAccess()); GraphBuilderConfiguration eagerConfig = GraphBuilderConfiguration.getEagerDefault().withSkippedExceptionTypes(skippedExceptionTypes); this.config = GraphBuilderConfiguration.getDefault().withSkippedExceptionTypes(skippedExceptionTypes); - this.truffleCache = new TruffleCacheImpl(providers, eagerConfig, config, TruffleCompilerImpl.Optimizations); + this.truffleCache = new TruffleCacheImpl(providers, eagerConfig, TruffleCompilerImpl.Optimizations); - this.partialEvaluator = new PartialEvaluator(providers, truffleCache, Graal.getRequiredCapability(SnippetReflectionProvider.class)); + this.partialEvaluator = new PartialEvaluator(providers, config, truffleCache, Graal.getRequiredCapability(SnippetReflectionProvider.class)); if (Debug.isEnabled()) { DebugEnvironment.initialize(System.out);