# HG changeset patch # User Miguel Garcia # Date 1399304720 -7200 # Node ID 4f603d776eccfd6528a70b3ebf913e3f4daffa4d # Parent 8653634b9d112512922460622794d5d3f42745fa [flow-sensitive] too many type-refinements didn't improve performance diff -r 8653634b9d11 -r 4f603d776ecc 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 Mon May 05 17:06:02 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/EquationalReasoner.java Mon May 05 17:45:20 2014 +0200 @@ -237,6 +237,17 @@ // picked cached substitution return result; } + if (FlowUtil.hasLegalObjectStamp(v) && state.isNull(v)) { + // it's ok to return nullConstant in deverbosify unlike in downcast + metricNullInserted.increment(); + return nullConstant; + } + if (v instanceof ValueProxy) { + return v; + } + if (!(n instanceof FloatingNode)) { + return n; + } if ((visited != null && visited.contains(n)) || added.contains(v)) { return v; } @@ -254,30 +265,13 @@ * Past this point, if we ever want `n` to be deverbosified, it must be looked-up by one of * the cases above. One sure way to achieve that is with `rememberSubstitution(old, new)` */ - if (v instanceof ValueProxy) { - return downcast(v); - } - if (n instanceof FloatingNode) { - /* - * `deverbosifyFloatingNode()` will drill down over floating inputs, when that not - * possible anymore it resorts to calling `downcast()`. Thus it's ok to take the - * `deverbosifyFloatingNode()` route first, as no downcasting opportunity will be - * missed. - */ - return deverbosifyFloatingNode((FloatingNode) n); - } - - if (FlowUtil.hasLegalObjectStamp(v)) { - if (state.isNull(v)) { - // it's ok to return nullConstant in deverbosify unlike in downcast - metricNullInserted.increment(); - return nullConstant; - } - return downcast(v); - } - - return n; + /* + * `deverbosifyFloatingNode()` will drill down over floating inputs, when that not possible + * anymore it resorts to calling `downcast()`. Thus it's ok to take the + * `deverbosifyFloatingNode()` route first, as no downcasting opportunity will be missed. + */ + return deverbosifyFloatingNode((FloatingNode) n); } /** @@ -341,16 +335,7 @@ } if (changed == null) { assert visited.contains(f) || added.contains(f); - if (FlowUtil.hasLegalObjectStamp(f)) { - /* - * No input has changed doesn't imply there's no witness to refine the - * floating-object value. - */ - ValueNode d = downcast(f); - return d; - } else { - return f; - } + return f; } FlowUtil.inferStampAndCheck(changed); added.add(changed); diff -r 8653634b9d11 -r 4f603d776ecc graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/FlowSensitiveReduction.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/FlowSensitiveReduction.java Mon May 05 17:06:02 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/FlowSensitiveReduction.java Mon May 05 17:45:20 2014 +0200 @@ -305,9 +305,16 @@ * */ private MethodCallTargetNode deverbosifyInputsCopyOnWrite(MethodCallTargetNode parent) { + final MethodCallTargetNode.InvokeKind ik = parent.invokeKind(); + final boolean shouldTryDevirt = (ik == MethodCallTargetNode.InvokeKind.Interface || ik == MethodCallTargetNode.InvokeKind.Virtual); + boolean shouldDowncastReceiver = shouldTryDevirt; MethodCallTargetNode changed = null; for (ValueNode i : FlowUtil.distinctValueAndConditionInputs(parent)) { - Node j = reasoner.deverbosify(i); + ValueNode j = (ValueNode) reasoner.deverbosify(i); + if (shouldDowncastReceiver) { + shouldDowncastReceiver = false; + j = reasoner.downcast(j); + } if (i != j) { assert j != parent; if (changed == null) {