# HG changeset patch # User Miguel Garcia # Date 1398780987 -7200 # Node ID 62f455eba8c516ee7859e6d7332b6370adc15be6 # Parent 746c0bda7ba6fef3cf922820a3048b35da114856# Parent 81eee524bbec22300eb9b2a4345a09d287fb6097 Merge diff -r 81eee524bbec -r 62f455eba8c5 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/CastCheckExtractor.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/CastCheckExtractor.java Tue Apr 29 14:50:51 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/CastCheckExtractor.java Tue Apr 29 16:16:27 2014 +0200 @@ -42,7 +42,7 @@ this.subject = subject; } - static CastCheckExtractor extractCastCheckInfo(LogicNode x, LogicNode y) { + private static CastCheckExtractor extractCastCheckInfo(LogicNode x, LogicNode y) { if (x instanceof IsNullNode) { IsNullNode isNull = (IsNullNode) x; ValueNode subject = isNull.object(); @@ -77,7 +77,7 @@ /** * Porcelain method. */ - public static boolean isInstanceOfCheckOn(LogicNode cond, ValueNode subject) { + static boolean isInstanceOfCheckOn(LogicNode cond, ValueNode subject) { if (!(cond instanceof InstanceOfNode)) { return false; } diff -r 81eee524bbec -r 62f455eba8c5 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/CheckCastReduction.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/CheckCastReduction.java Tue Apr 29 14:50:51 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/CheckCastReduction.java Tue Apr 29 16:16:27 2014 +0200 @@ -60,7 +60,7 @@ * This method turns non-redundant {@link com.oracle.graal.nodes.java.CheckCastNode}s into * {@link com.oracle.graal.nodes.GuardingPiNode}s. Once such lowering has been performed (during * run N of this phase) follow-up runs attempt to further simplify the resulting node, see - * {@link EquationalReasoner#downcastedGuardingPiNode(com.oracle.graal.nodes.GuardingPiNode, Witness)} + * {@link EquationalReasoner#downcastGuardingPiNode(com.oracle.graal.nodes.GuardingPiNode, Witness)} * and {@link #visitGuardingPiNode(com.oracle.graal.nodes.GuardingPiNode)} *

* @@ -109,7 +109,7 @@ * others. */ - PiNode untrivialNull = reasoner.untrivialNull(subject); + PiNode untrivialNull = reasoner.nonTrivialNull(subject); if (untrivialNull != null) { metricCheckCastRemoved.increment(); checkCast.replaceAtUsages(untrivialNull); @@ -121,7 +121,7 @@ if (w == null) { /* - * If there's no witness, attempting `downcasted(subject)` is futile. + * If there's no witness, attempting `downcast(subject)` is futile. */ visitCheckCastNodeLackingWitness(checkCast); return; @@ -146,7 +146,7 @@ if (toType.isInterface()) { return; } - assert reasoner.downcasted(subject) == subject; + assert reasoner.downcast(subject) == subject; lowerCheckCastAnchorFriendlyWay(checkCast, subject); } @@ -288,18 +288,18 @@ ValueNode subject; if (checkCast.object() instanceof CheckCastNode) { - subject = reasoner.downcasted(checkCast); + subject = reasoner.downcast(checkCast); if (subject == checkCast) { - subject = reasoner.downcasted(checkCast.object()); + subject = reasoner.downcast(checkCast.object()); } } else { - subject = reasoner.downcasted(checkCast.object()); + subject = reasoner.downcast(checkCast.object()); } ObjectStamp subjectStamp = (ObjectStamp) subject.stamp(); ResolvedJavaType subjectType = subjectStamp.type(); - // TODO move this check to downcasted() + // TODO move this check to downcast() assert !precisionLoss(checkCast.object(), subject); /* @@ -316,7 +316,7 @@ } /* - * At this point, `downcasted()` might or might not have delivered a more precise value. If + * At this point, `downcast()` might or might not have delivered a more precise value. If * more precise, it wasn't precise enough to conform to `toType`. Even so, for the * `toType.isInterface()` case (dealt with below) we'll replace the checkCast's input with * that value (its class-stamp being more precise than the original). diff -r 81eee524bbec -r 62f455eba8c5 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/EquationalReasoner.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/EquationalReasoner.java Tue Apr 29 14:50:51 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/EquationalReasoner.java Tue Apr 29 16:16:27 2014 +0200 @@ -51,10 +51,10 @@ * This class implements a simple partial evaluator that recursively reduces a given * {@link com.oracle.graal.nodes.calc.FloatingNode} into a simpler one based on the current state. * Such evaluator comes handy when visiting a {@link com.oracle.graal.nodes.FixedNode} N, just - * before updating the state for N. At the pre-state, an {@link EquationalReasoner - * EquationalReasoner} can be used to reduce N's inputs (actually only those inputs of Value and - * Condition {@link com.oracle.graal.graph.InputType InputType}). For an explanation of where it's - * warranted to replace "old input" with "reduced input", see the inline comments in method + * before updating the state for N. At the pre-state, an {@link EquationalReasoner} can be used to + * reduce N's inputs (actually only those inputs of Value and Condition + * {@link com.oracle.graal.graph.InputType InputType}). For an explanation of where it's warranted + * to replace "old input" with "reduced input", see the inline comments in method * {@link EquationalReasoner#deverbosify(com.oracle.graal.graph.Node n) deverbosify(Node n)} *

* @@ -253,13 +253,13 @@ * the cases above. One sure way to achieve that is with `rememberSubstitution(old, new)` */ if (v instanceof ValueProxy) { - return downcasted(v); + return downcast(v); } if (n instanceof FloatingNode) { /* * `deverbosifyFloatingNode()` will drill down over floating inputs, when that not - * possible anymore it resorts to calling `downcasted()`. Thus it's ok to take the + * possible anymore it resorts to calling `downcast()`. Thus it's ok to take the * `deverbosifyFloatingNode()` route first, as no downcasting opportunity will be * missed. */ @@ -267,7 +267,7 @@ } if (FlowUtil.hasLegalObjectStamp(v)) { - return downcasted(v); + return downcast(v); } return n; @@ -339,7 +339,7 @@ * No input has changed doesn't imply there's no witness to refine the * floating-object value. */ - ValueNode d = downcasted(f); + ValueNode d = downcast(f); return d; } else { return f; @@ -356,7 +356,7 @@ /** * In case of doubt (on whether a reduction actually triggered) it's always ok to invoke " - * rememberSubstitution(f, downcasted(f))": this method records a map entry only if + * rememberSubstitution(f, downcast(f))": this method records a map entry only if * pre-image and image differ. * * @return the image of the substitution (ie, the second argument) unmodified. @@ -483,7 +483,7 @@ return isNull; } ValueNode scrutinee = GraphUtil.unproxify(isNull.object()); - GuardingNode evidence = untrivialNullAnchor(scrutinee); + GuardingNode evidence = nonTrivialNullAnchor(scrutinee); if (evidence != null) { metricNullCheckRemoved.increment(); return trueConstant; @@ -515,7 +515,7 @@ } /** - * It's always ok to use "downcasted(object)" instead of " object" + * It's always ok to use "downcast(object)" instead of " object" * because this method re-wraps the argument in a {@link com.oracle.graal.nodes.PiNode} only if * the new stamp is strictly more refined than the original. * @@ -534,7 +534,7 @@ *
  • the unmodified argument otherwise.
  • * */ - ValueNode downcasted(final ValueNode object) { + ValueNode downcast(final ValueNode object) { // ------------------------------------------------- // actions based only on the stamp of the input node @@ -547,7 +547,7 @@ return object; } if (StampTool.isObjectAlwaysNull(object.stamp())) { - return untrivialNull(object); + return nonTrivialNull(object); } // ------------------------------------------ @@ -556,7 +556,7 @@ ValueNode scrutinee = GraphUtil.unproxify(object); - PiNode untrivialNull = untrivialNull(scrutinee); + PiNode untrivialNull = nonTrivialNull(scrutinee); if (untrivialNull != null) { return untrivialNull; } @@ -581,7 +581,7 @@ ValueNode result; if (object instanceof ValueProxy) { - result = downcastedValueProxy((ValueProxy) object, w); + result = downcastValueProxy((ValueProxy) object, w); } else { result = downcastedUtil(object, w); } @@ -653,7 +653,7 @@ * Otherwise, if an anchor is found it is returned, null otherwise. *

    */ - public GuardingNode untrivialNullAnchor(ValueNode object) { + public GuardingNode nonTrivialNullAnchor(ValueNode object) { assert FlowUtil.hasLegalObjectStamp(object); if (StampTool.isObjectAlwaysNull(object)) { return null; @@ -676,9 +676,9 @@ * . *

    */ - public PiNode untrivialNull(ValueNode object) { + public PiNode nonTrivialNull(ValueNode object) { assert FlowUtil.hasLegalObjectStamp(object); - GuardingNode anchor = untrivialNullAnchor(object); + GuardingNode anchor = nonTrivialNullAnchor(object); if (anchor == null) { return null; } @@ -711,7 +711,7 @@ * the reason being that the state abstraction can be updated only at fixed nodes). * As a result, the witness for a (PiNode, PiArrayNode, UnsafeCastNode, or GuardedValueNode) * may be less precise than the proxy's stamp. We don't want to lose such precision, - * thus downcasted(proxy) == proxy in such cases. + * thus downcast(proxy) == proxy in such cases. *

    * *

    @@ -733,7 +733,7 @@ *

    */ // @formatter:on - private ValueNode downcastedValueProxy(ValueProxy proxy, Witness w) { + private ValueNode downcastValueProxy(ValueProxy proxy, Witness w) { assert FlowUtil.hasLegalObjectStamp((ValueNode) proxy); assert FlowUtil.hasLegalObjectStamp((proxy).getOriginalNode()); assert GraphUtil.unproxify((ValueNode) proxy) == GraphUtil.unproxify(proxy.getOriginalNode()); @@ -741,13 +741,13 @@ assert GraphUtil.unproxify((ValueNode) proxy) == GraphUtil.unproxify((proxy).getOriginalNode()); if (proxy instanceof PiNode) { - return downcastedPiNodeOrPiArrayNode((PiNode) proxy, w); + return downcastPiNodeOrPiArrayNode((PiNode) proxy, w); } else if (proxy instanceof GuardingPiNode) { - return downcastedGuardingPiNode((GuardingPiNode) proxy, w); + return downcastGuardingPiNode((GuardingPiNode) proxy, w); } else if (proxy instanceof TypeProfileProxyNode) { - return downcastedTypeProfileProxyNode((TypeProfileProxyNode) proxy); + return downcastTypeProfileProxyNode((TypeProfileProxyNode) proxy); } else if (proxy instanceof CheckCastNode) { - return downcastedCheckCastNode((CheckCastNode) proxy, w); + return downcastCheckCastNode((CheckCastNode) proxy, w); } else if (proxy instanceof ProxyNode || proxy instanceof GuardedValueNode) { // TODO scaladacapo return downcastedUtil((ValueNode) proxy, w); return (ValueNode) proxy; @@ -781,9 +781,9 @@ * GuardingPiNode is clear: devirtualizing the `intValue()` callsite. *

    * - * @see #downcastedValueProxy + * @see #downcastValueProxy */ - public ValueNode downcastedGuardingPiNode(GuardingPiNode envelope, Witness w) { + public ValueNode downcastGuardingPiNode(GuardingPiNode envelope, Witness w) { assert envelope != w.guard().asNode() : "The stamp of " + envelope + " would lead to downcasting with that very same GuardingPiNode as guard."; return downcastedUtil(envelope, w); } @@ -813,9 +813,9 @@ * PiNode.canonical()} does). Not clear the benefits of duplicating that logic here. *

    * - * @see #downcastedValueProxy + * @see #downcastValueProxy */ - private ValueNode downcastedPiNodeOrPiArrayNode(PiNode envelope, Witness w) { + private ValueNode downcastPiNodeOrPiArrayNode(PiNode envelope, Witness w) { return downcastedUtil(envelope, w); } @@ -829,11 +829,11 @@ * Otherwise returns the unmodified argument. *

    * - * @see #downcastedValueProxy + * @see #downcastValueProxy */ - private ValueNode downcastedTypeProfileProxyNode(TypeProfileProxyNode envelope) { + private ValueNode downcastTypeProfileProxyNode(TypeProfileProxyNode envelope) { ValueNode payload = envelope.getOriginalNode(); - ValueNode d = downcasted(payload); + ValueNode d = downcast(payload); if (payload != d) { TypeProfileProxyNode changed = (TypeProfileProxyNode) envelope.copyWithInputs(); added.add(changed); @@ -860,7 +860,7 @@ * the downcasted scrutinee does not conform to the checkCast's target-type. *

    */ - private ValueNode downcastedCheckCastNode(CheckCastNode checkCast, Witness w) { + private ValueNode downcastCheckCastNode(CheckCastNode checkCast, Witness w) { final ResolvedJavaType toType = checkCast.type(); @@ -869,7 +869,7 @@ while (innerMost instanceof CheckCastNode) { innerMost = ((CheckCastNode) innerMost).object(); } - ValueNode deepest = downcasted(innerMost); + ValueNode deepest = downcast(innerMost); ResolvedJavaType deepestType = ((ObjectStamp) deepest.stamp()).type(); if ((deepestType != null && deepestType.equals(toType)) || FlowUtil.isMorePrecise(deepestType, toType)) { assert !w.knowsBetterThan(deepest); @@ -877,7 +877,7 @@ } } - ValueNode subject = downcasted(checkCast.object()); + ValueNode subject = downcast(checkCast.object()); ObjectStamp subjectStamp = (ObjectStamp) subject.stamp(); ResolvedJavaType subjectType = subjectStamp.type(); diff -r 81eee524bbec -r 62f455eba8c5 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/FixedGuardReduction.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/FixedGuardReduction.java Tue Apr 29 14:50:51 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/FixedGuardReduction.java Tue Apr 29 16:16:27 2014 +0200 @@ -104,7 +104,7 @@ final IsNullNode isNullNode = (IsNullNode) cond; if (isTrue) { // grab an anchor attesting nullness - final GuardingNode replacement = reasoner.untrivialNullAnchor(isNullNode.object()); + final GuardingNode replacement = reasoner.nonTrivialNullAnchor(isNullNode.object()); if (replacement != null) { removeFixedGuardNode(f, replacement); return; @@ -152,7 +152,7 @@ } else { // grab an anchor attesting not-instanceof // (1 of 2) attempt determining nullness - final GuardingNode nullGuard = reasoner.untrivialNullAnchor(iOf.object()); + final GuardingNode nullGuard = reasoner.nonTrivialNullAnchor(iOf.object()); if (nullGuard != null) { removeFixedGuardNode(f, nullGuard); return; diff -r 81eee524bbec -r 62f455eba8c5 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/FlowSensitiveReductionPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/FlowSensitiveReductionPhase.java Tue Apr 29 14:50:51 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/FlowSensitiveReductionPhase.java Tue Apr 29 16:16:27 2014 +0200 @@ -43,7 +43,9 @@ @Override protected final void run(StructuredGraph graph, PhaseContext context) { try (Debug.Scope s = Debug.scope("FlowSensitiveReduction")) { + Debug.dump(graph, "FlowSensitiveReduction initial"); new FlowSensitiveReduction(graph.start(), new State(), context).apply(); + Debug.dump(graph, "FlowSensitiveReduction done"); } catch (Throwable e) { throw Debug.handle(e); } diff -r 81eee524bbec -r 62f455eba8c5 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/GuardingPiReduction.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/GuardingPiReduction.java Tue Apr 29 14:50:51 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/GuardingPiReduction.java Tue Apr 29 16:16:27 2014 +0200 @@ -203,7 +203,7 @@ /* * GuardingPiNode succeeds if payload null */ - ValueNode replacement = StampTool.isObjectAlwaysNull(payload) ? payload : reasoner.untrivialNull(payload); + ValueNode replacement = StampTool.isObjectAlwaysNull(payload) ? payload : reasoner.nonTrivialNull(payload); if (replacement != null) { // replacement == null means !isKnownNull(payload) removeGuardingPiNode(envelope, replacement); @@ -222,7 +222,7 @@ assert io.type() != null; Witness w = state.typeInfo(payload); if (w != null && w.isNonNull() && isEqualOrMorePrecise(w.type(), io.type())) { - ValueNode d = reasoner.downcasted(payload); + ValueNode d = reasoner.downcast(payload); removeGuardingPiNode(envelope, d); return true; } @@ -318,7 +318,7 @@ warnAboutOutOfTheBlueGuardingPiNode(envelope); } - ValueNode d = reasoner.downcasted(payload); + ValueNode d = reasoner.downcast(payload); if (d == null) { return false; } diff -r 81eee524bbec -r 62f455eba8c5 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/State.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/State.java Tue Apr 29 14:50:51 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/State.java Tue Apr 29 16:16:27 2014 +0200 @@ -112,7 +112,7 @@ * standardize on one of them, and drop the other? Because the {@link #typeRefinements} eagerly * aggregates information for easier querying afterwards, e.g. when producing a "downcasted" * value (which involves building a {@link com.oracle.graal.nodes.PiNode}, see - * {@link EquationalReasoner#downcasted(com.oracle.graal.nodes.ValueNode) downcasted()} + * {@link EquationalReasoner#downcast(com.oracle.graal.nodes.ValueNode) downcast()} *

    * */ @@ -283,6 +283,8 @@ if (isUnreachable) { typeRefinements.clear(); knownNull.clear(); + trueFacts.clear(); + falseFacts.clear(); return true; } @@ -514,6 +516,7 @@ if (isDependencyTainted(object, anchor)) { return false; } + assert anchor instanceof FixedNode; ResolvedJavaType stampType = StampTool.typeOrNull(object); if (stampType != null && !stampType.isInterface()) { return trackIO(object, stampType, anchor); @@ -548,6 +551,7 @@ if (isDependencyTainted(object, anchor)) { return false; } + assert anchor instanceof FixedNode; Witness w = getOrElseAddTypeInfo(object); if (w.trackCC(observed, anchor)) { versionNr++; @@ -573,6 +577,7 @@ if (isDependencyTainted(object, anchor)) { return false; } + assert anchor instanceof FixedNode; Witness w = getOrElseAddTypeInfo(object); if (w.trackIO(observed, anchor)) { versionNr++; @@ -611,6 +616,7 @@ */ public void addFact(boolean isTrue, LogicNode condition, GuardingNode anchor) { assert anchor != null; + assert anchor instanceof FixedNode; assert !isUnreachable; if (condition instanceof LogicConstantNode) { @@ -699,6 +705,7 @@ if (isDependencyTainted(equals.y(), anchor)) { return; } + assert anchor instanceof FixedNode; ValueNode x = GraphUtil.unproxify(equals.x()); ValueNode y = GraphUtil.unproxify(equals.y()); if (isTrue) { @@ -757,6 +764,7 @@ if (isDependencyTainted(value, anchor)) { return; } + assert anchor instanceof FixedNode; ValueNode original = GraphUtil.unproxify(value); boolean wasNull = isNull(original); boolean wasNonNull = isNonNull(original); @@ -783,6 +791,7 @@ * @return true iff `value` may lose dependency not covered by `anchor`. */ public static boolean isDependencyTainted(ValueNode value, GuardingNode anchor) { + assert anchor instanceof FixedNode; if (value instanceof ValueProxy) { if (value instanceof GuardedNode) { GuardedNode gn = (GuardedNode) value; @@ -808,6 +817,8 @@ isUnreachable = false; typeRefinements.clear(); knownNull.clear(); + trueFacts.clear(); + falseFacts.clear(); } } diff -r 81eee524bbec -r 62f455eba8c5 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java Tue Apr 29 14:50:51 2014 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java Tue Apr 29 16:16:27 2014 +0200 @@ -31,6 +31,7 @@ import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.nodes.*; import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.common.cfs.IterativeFlowSensitiveReductionPhase; import com.oracle.graal.phases.tiers.*; public class IterativeInliningPhase extends AbstractInliningPhase { @@ -70,9 +71,14 @@ new DeadCodeEliminationPhase().apply(graph); - if (ConditionalElimination.getValue() && OptCanonicalizer.getValue()) { + boolean reduceOrEliminate = FlowSensitiveReduction.getValue() || ConditionalElimination.getValue(); + if (reduceOrEliminate && OptCanonicalizer.getValue()) { canonicalizer.apply(graph, context); - new IterativeConditionalEliminationPhase(canonicalizer).apply(graph, context); + if (FlowSensitiveReduction.getValue()) { + new IterativeFlowSensitiveReductionPhase(canonicalizer).apply(graph, context); + } else { + new IterativeConditionalEliminationPhase(canonicalizer).apply(graph, context); + } } if (!progress) { break;