# HG changeset patch
# User Miguel Garcia
- * If the argument is known null due to its stamp, there's no need to have an anchor for that
- * fact and this method returns null.
- *
- * Otherwise, if an anchor is found it is returned, null otherwise.
- *
@@ -718,7 +700,7 @@
*/
public PiNode nonTrivialNull(ValueNode object) {
assert FlowUtil.hasLegalObjectStamp(object);
- GuardingNode anchor = nonTrivialNullAnchor(object);
+ GuardingNode anchor = state.nonTrivialNullAnchor(object);
if (anchor == null) {
return null;
}
diff -r 45a54859fd7d -r 49a917f9fa07 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/Evidence.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/Evidence.java Sun May 04 16:12:44 2014 +0200
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.phases.common.cfs;
+
+import com.oracle.graal.nodes.extended.GuardingNode;
+
+public class Evidence {
+
+ public final GuardingNode success;
+ public final boolean failure;
+
+ public Evidence(GuardingNode success, boolean failure) {
+ this.success = success;
+ this.failure = failure;
+ assert repOK();
+ }
+
+ public Evidence(GuardingNode success) {
+ this(success, false);
+ }
+
+ private Evidence(boolean failure) {
+ this(null, failure);
+ }
+
+ public boolean isPositive() {
+ return success != null;
+ }
+
+ public boolean isNegative() {
+ return failure;
+ }
+
+ private boolean repOK() {
+ // either success or failure, ie boolean-XOR
+ return (success != null) != failure;
+ }
+
+ public static Evidence COUNTEREXAMPLE = new Evidence(true);
+
+}
diff -r 45a54859fd7d -r 49a917f9fa07 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 Sat May 03 16:19:43 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/FixedGuardReduction.java Sun May 04 16:12:44 2014 +0200
@@ -23,9 +23,7 @@
package com.oracle.graal.phases.common.cfs;
import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.IsNullNode;
import com.oracle.graal.nodes.extended.GuardingNode;
-import com.oracle.graal.nodes.java.*;
import com.oracle.graal.phases.tiers.PhaseContext;
/**
@@ -99,118 +97,33 @@
return;
}
- /*
- * Attempt to eliminate the current FixedGuardNode by using another GuardingNode already in
- * scope and with equivalent condition.
- */
+ final boolean isTrue = !f.isNegated();
+ final Evidence evidence = state.outcome(isTrue, f.condition());
- GuardingNode existingGuard = f.isNegated() ? state.falseFacts.get(f.condition()) : state.trueFacts.get(f.condition());
- if (existingGuard != null) {
- // assert existingGuard instanceof FixedGuardNode;
- metricFixedGuardNodeRemoved.increment();
- f.replaceAtUsages(existingGuard.asNode());
- graph.removeFixed(f);
+ // can't produce evidence, must be information gain
+ if (evidence == null) {
+ state.addFact(isTrue, f.condition(), f);
return;
}
- final LogicNode cond = f.condition();
- final boolean isTrue = !f.isNegated();
-
- /*
- * A FixedGuardNode can only be removed provided a replacement anchor is found (so called
- * "evidence"), ie an anchor that amounts to the same combination of (negated, condition) as
- * for the FixedGuardNode at hand. Just deverbosifying the condition in place isn't
- * semantics-preserving.
- */
-
- // TODO what about isDependencyTainted
-
- if (cond instanceof IsNullNode) {
- final IsNullNode isNullNode = (IsNullNode) cond;
- if (isTrue) {
- // grab an anchor attesting nullness
- final GuardingNode replacement = reasoner.nonTrivialNullAnchor(isNullNode.object());
- if (replacement != null) {
- removeFixedGuardNode(f, replacement);
- return;
- }
- if (state.isNonNull(isNullNode.object())) {
- markFixedGuardNodeAlwaysFails(f);
- return;
- }
- // can't produce evidence, fall-through to addFact
- } else {
- // grab an anchor attesting non-nullness
- final Witness w = state.typeInfo(isNullNode.object());
- if (w != null && w.isNonNull()) {
- removeFixedGuardNode(f, w.guard());
- return;
- }
- if (state.isNull(isNullNode.object())) {
- markFixedGuardNodeAlwaysFails(f);
- return;
- }
- // can't produce evidence, fall-through to addFact
- }
- } else if (cond instanceof InstanceOfNode) {
- final InstanceOfNode iOf = (InstanceOfNode) cond;
- final Witness w = state.typeInfo(iOf.object());
- if (isTrue) {
- // grab an anchor attesting instanceof
- if (w != null) {
- if (w.isNonNull() && w.type() != null) {
- if (iOf.type().isAssignableFrom(w.type())) {
- removeFixedGuardNode(f, w.guard());
- return;
- }
- if (State.knownNotToConform(w.type(), iOf.type())) {
- markFixedGuardNodeAlwaysFails(f);
- return;
- }
- }
- }
- if (state.isNull(iOf.object())) {
- markFixedGuardNodeAlwaysFails(f);
- return;
- }
- // can't produce evidence, fall-through to addFact
- } else {
- // grab an anchor attesting not-instanceof
- // (1 of 2) attempt determining nullness
- final GuardingNode nullGuard = reasoner.nonTrivialNullAnchor(iOf.object());
- if (nullGuard != null) {
- removeFixedGuardNode(f, nullGuard);
- return;
- }
- // (2 of 2) attempt determining known-not-to-conform
- if (w != null && !w.cluelessAboutType()) {
- if (State.knownNotToConform(w.type(), iOf.type())) {
- removeFixedGuardNode(f, w.guard());
- return;
- }
- }
- // can't produce evidence, fall-through to addFact
- }
- } else if (isTrue && cond instanceof ShortCircuitOrNode) {
- CastCheckExtractor cce = CastCheckExtractor.extract(cond);
- if (cce != null && !State.isDependencyTainted(cce.subject, f)) {
- // grab an anchor attesting check-cast
- Witness w = state.typeInfo(cce.subject);
- if (w != null && w.type() != null) {
- if (cce.type.isAssignableFrom(w.type())) {
- removeFixedGuardNode(f, w.guard());
- return;
- }
- if (State.knownNotToConform(w.type(), cce.type)) {
- markFixedGuardNodeAlwaysFails(f);
- return;
- }
- }
- }
- // can't produce evidence, fall-through to addFact
+ if (evidence.isPositive()) {
+ /*
+ * A FixedGuardNode can only be removed provided a replacement anchor is found (so
+ * called "evidence"), ie an anchor that amounts to the same combination of (negated,
+ * condition) as for the FixedGuardNode at hand. Just deverbosifying the condition in
+ * place isn't semantics-preserving.
+ *
+ * Eliminate the current FixedGuardNode by using another GuardingNode already in scope,
+ * a GuardingNode that guards a condition that is at least as strong as that of the
+ * FixedGuardNode.
+ */
+ removeFixedGuardNode(f, evidence.success);
+ return;
}
- state.addFact(isTrue, cond, f);
+ assert evidence.isNegative();
+ markFixedGuardNodeAlwaysFails(f);
+
}
/**
@@ -232,9 +145,7 @@
*
+ * If the argument is known null due to its stamp, there's no need to have an anchor for that + * fact and this method returns null. + *
+ * + *+ * Otherwise, if an anchor is found it is returned, null otherwise. + *
+ */ + public GuardingNode nonTrivialNullAnchor(ValueNode object) { + assert FlowUtil.hasLegalObjectStamp(object); + if (StampTool.isObjectAlwaysNull(object)) { + return null; + } + return knownNull.get(GraphUtil.unproxify(object)); + } + + /** + * This method: + *