# HG changeset patch # User Doug Simon # Date 1373992245 -7200 # Node ID e2786e2c491a348a18cd0e2ccc907ec779212c2c # Parent 6d176112d16252142373dde61a90520ff14a5418# Parent 0a306985c262e5a9aca5b0744f33cf84ce71ffdd Merge. diff -r 0a306985c262 -r e2786e2c491a graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java Tue Jul 16 16:46:55 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java Tue Jul 16 18:30:45 2013 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.graal.compiler.test; +import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*; import static org.junit.Assert.*; import org.junit.*; @@ -29,7 +30,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.java.MethodCallTargetNode.*; +import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; import com.oracle.graal.phases.common.*; /** @@ -163,7 +164,9 @@ new CanonicalizerPhase.Instance(runtime(), null, true).apply(graph); IfNode ifNode = (IfNode) graph.start().next(); InstanceOfNode instanceOf = (InstanceOfNode) ifNode.condition(); - LogicDisjunctionNode disjunction = graph.unique(new LogicDisjunctionNode(graph.unique(new IsNullNode(graph.getLocal(0))), instanceOf)); + IsNullNode x = graph.unique(new IsNullNode(graph.getLocal(0))); + InstanceOfNode y = instanceOf; + ShortCircuitOrNode disjunction = graph.unique(new ShortCircuitOrNode(x, false, y, false, NOT_FREQUENT_PROBABILITY)); ifNode.setCondition(disjunction); ifNode.negate(disjunction); new CanonicalizerPhase.Instance(runtime(), null, true).apply(graph); diff -r 0a306985c262 -r e2786e2c491a graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Tue Jul 16 16:46:55 2013 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Tue Jul 16 18:30:45 2013 +0200 @@ -537,6 +537,12 @@ if (aLong != bLong) { return false; } + } else if (type == Double.TYPE) { + double aDouble = unsafe.getDouble(a, dataOffsets[i]); + double bDouble = unsafe.getDouble(b, dataOffsets[i]); + if (aDouble != bDouble) { + return false; + } } else { assert false : "unhandled type: " + type; } diff -r 0a306985c262 -r e2786e2c491a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java Tue Jul 16 16:46:55 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java Tue Jul 16 18:30:45 2013 +0200 @@ -26,8 +26,8 @@ import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import static com.oracle.graal.nodes.GuardingPiNode.*; import static com.oracle.graal.nodes.calc.IsNullNode.*; +import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*; import static com.oracle.graal.phases.GraalOptions.*; -import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*; import java.lang.reflect.*; import java.util.*; diff -r 0a306985c262 -r e2786e2c491a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastSnippets.java Tue Jul 16 16:46:55 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastSnippets.java Tue Jul 16 18:30:45 2013 +0200 @@ -26,10 +26,10 @@ import static com.oracle.graal.api.meta.DeoptimizationReason.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import static com.oracle.graal.hotspot.replacements.TypeCheckSnippetUtils.*; +import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*; import static com.oracle.graal.nodes.extended.UnsafeCastNode.*; import static com.oracle.graal.phases.GraalOptions.*; import static com.oracle.graal.replacements.SnippetTemplate.*; -import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; diff -r 0a306985c262 -r e2786e2c491a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Tue Jul 16 16:46:55 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Tue Jul 16 18:30:45 2013 +0200 @@ -24,7 +24,7 @@ import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static com.oracle.graal.hotspot.meta.HotSpotRuntime.*; -import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*; +import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*; import sun.misc.*; import com.oracle.graal.api.code.*; diff -r 0a306985c262 -r e2786e2c491a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Tue Jul 16 16:46:55 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Tue Jul 16 18:30:45 2013 +0200 @@ -27,8 +27,8 @@ import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import static com.oracle.graal.hotspot.replacements.TypeCheckSnippetUtils.*; +import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*; import static com.oracle.graal.phases.GraalOptions.*; -import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; diff -r 0a306985c262 -r e2786e2c491a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Tue Jul 16 16:46:55 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Tue Jul 16 18:30:45 2013 +0200 @@ -27,8 +27,8 @@ import static com.oracle.graal.hotspot.nodes.EndLockScopeNode.*; import static com.oracle.graal.hotspot.nodes.VMErrorNode.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; +import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*; import static com.oracle.graal.replacements.SnippetTemplate.*; -import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*; import java.util.*; diff -r 0a306985c262 -r e2786e2c491a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Tue Jul 16 16:46:55 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Tue Jul 16 18:30:45 2013 +0200 @@ -25,11 +25,11 @@ import static com.oracle.graal.api.code.UnsignedMath.*; import static com.oracle.graal.api.meta.LocationIdentity.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; +import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*; import static com.oracle.graal.nodes.extended.UnsafeArrayCastNode.*; import static com.oracle.graal.nodes.extended.UnsafeCastNode.*; import static com.oracle.graal.phases.GraalOptions.*; import static com.oracle.graal.replacements.SnippetTemplate.*; -import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*; import static com.oracle.graal.replacements.nodes.ExplodeLoopNode.*; import com.oracle.graal.api.code.*; diff -r 0a306985c262 -r e2786e2c491a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneSnippets.java Tue Jul 16 16:46:55 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneSnippets.java Tue Jul 16 18:30:45 2013 +0200 @@ -24,8 +24,8 @@ import static com.oracle.graal.api.meta.LocationIdentity.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; +import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*; import static com.oracle.graal.phases.GraalOptions.*; -import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*; import java.lang.reflect.*; diff -r 0a306985c262 -r e2786e2c491a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/SystemSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/SystemSubstitutions.java Tue Jul 16 16:46:55 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/SystemSubstitutions.java Tue Jul 16 18:30:45 2013 +0200 @@ -23,7 +23,7 @@ package com.oracle.graal.hotspot.replacements; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; -import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*; +import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; diff -r 0a306985c262 -r e2786e2c491a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java Tue Jul 16 16:46:55 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java Tue Jul 16 18:30:45 2013 +0200 @@ -23,8 +23,8 @@ package com.oracle.graal.hotspot.replacements; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; +import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*; import static com.oracle.graal.phases.GraalOptions.*; -import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*; import java.util.*; diff -r 0a306985c262 -r e2786e2c491a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java Tue Jul 16 16:46:55 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java Tue Jul 16 18:30:45 2013 +0200 @@ -24,8 +24,8 @@ import static com.oracle.graal.api.meta.LocationIdentity.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; +import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*; import static com.oracle.graal.replacements.SnippetTemplate.*; -import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; diff -r 0a306985c262 -r e2786e2c491a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java Tue Jul 16 16:46:55 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java Tue Jul 16 18:30:45 2013 +0200 @@ -23,6 +23,7 @@ package com.oracle.graal.hotspot.replacements; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; +import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*; import static com.oracle.graal.phases.GraalOptions.*; import static com.oracle.graal.replacements.SnippetTemplate.*; @@ -42,7 +43,6 @@ import com.oracle.graal.replacements.SnippetTemplate.SnippetInfo; import com.oracle.graal.replacements.nodes.*; import com.oracle.graal.word.*; -import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*; public class WriteBarrierSnippets implements Snippets { diff -r 0a306985c262 -r e2786e2c491a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicBinaryNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicBinaryNode.java Tue Jul 16 16:46:55 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2013, 2013, 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.nodes; - -import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.spi.*; - -public abstract class LogicBinaryNode extends LogicNode implements Negatable, Node.IterableNodeType { - - @Input private LogicNode x; - @Input private LogicNode y; - private boolean xNegated; - private boolean yNegated; - - public LogicBinaryNode(LogicNode x, LogicNode y) { - this(x, false, y, false); - } - - public LogicBinaryNode(LogicNode x, boolean xNegated, LogicNode y, boolean yNegated) { - this.x = x; - this.xNegated = xNegated; - this.y = y; - this.yNegated = yNegated; - } - - public LogicNode getX() { - return x; - } - - public LogicNode getY() { - return y; - } - - public boolean isXNegated() { - return xNegated; - } - - public boolean isYNegated() { - return yNegated; - } - - @Override - public Negatable negate(LogicNode condition) { - if (condition == x) { - xNegated = !xNegated; - } - if (condition == y) { - yNegated = !yNegated; - } - return this; - } -} diff -r 0a306985c262 -r e2786e2c491a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicConjunctionNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicConjunctionNode.java Tue Jul 16 16:46:55 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2013, 2013, 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.nodes; - -import com.oracle.graal.nodes.spi.*; - -/** - * This node is true if {@link #getX() x} and {@link #getY() y} are true. - */ -public class LogicConjunctionNode extends LogicBinaryNode implements Canonicalizable { - - public LogicConjunctionNode(LogicNode x, LogicNode y) { - this(x, false, y, false); - } - - public LogicConjunctionNode(LogicNode x, boolean xNegated, LogicNode y, boolean yNegated) { - super(x, xNegated, y, yNegated); - } - - @Override - public LogicNode canonical(CanonicalizerTool tool) { - LogicNode x = getX(); - LogicNode y = getY(); - if (x == y) { - // @formatter:off - // a && a = a - // a && !a = false - // !a && a = false - // !a && !a = !a - // @formatter:on - if (isXNegated()) { - if (isYNegated()) { - // !a && !a = !a - negateUsages(); - return x; - } else { - // !a && a = false - return LogicConstantNode.contradiction(graph()); - } - } else { - if (isYNegated()) { - // a && !a = false - return LogicConstantNode.contradiction(graph()); - } else { - // a && a = a - return x; - } - } - } - if (x instanceof LogicConstantNode) { - if (((LogicConstantNode) x).getValue() ^ isXNegated()) { - if (isYNegated()) { - negateUsages(); - } - return y; - } else { - return LogicConstantNode.contradiction(graph()); - } - } - if (y instanceof LogicConstantNode) { - if (((LogicConstantNode) y).getValue() ^ isYNegated()) { - if (isXNegated()) { - negateUsages(); - } - return x; - } else { - return LogicConstantNode.contradiction(graph()); - } - } - return this; - } -} diff -r 0a306985c262 -r e2786e2c491a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicDisjunctionNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicDisjunctionNode.java Tue Jul 16 16:46:55 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2013, 2013, 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.nodes; - -import com.oracle.graal.nodes.spi.*; - -/** - * This node is true if {@link #getX() x} or {@link #getY() y} are true. - * - */ -public class LogicDisjunctionNode extends LogicBinaryNode implements Canonicalizable { - - public LogicDisjunctionNode(LogicNode x, LogicNode y) { - this(x, false, y, false); - } - - public LogicDisjunctionNode(LogicNode x, boolean xNegated, LogicNode y, boolean yNegated) { - super(x, xNegated, y, yNegated); - } - - @Override - public LogicNode canonical(CanonicalizerTool tool) { - LogicNode x = getX(); - LogicNode y = getY(); - if (x == y) { - // @formatter:off - // a || a = a - // a || !a = true - // !a || a = true - // !a || !a = !a - // @formatter:on - if (isXNegated()) { - if (isYNegated()) { - // !a || !a = !a - negateUsages(); - return x; - } else { - // !a || a = true - return LogicConstantNode.tautology(graph()); - } - } else { - if (isYNegated()) { - // a || !a = true - return LogicConstantNode.tautology(graph()); - } else { - // a || a = a - return x; - } - } - } - if (x instanceof LogicConstantNode) { - if (((LogicConstantNode) x).getValue() ^ isXNegated()) { - return LogicConstantNode.tautology(graph()); - } else { - if (isYNegated()) { - negateUsages(); - } - return y; - } - } - if (y instanceof LogicConstantNode) { - if (((LogicConstantNode) y).getValue() ^ isYNegated()) { - return LogicConstantNode.tautology(graph()); - } else { - if (isXNegated()) { - negateUsages(); - } - return x; - } - } - return this; - } - -} diff -r 0a306985c262 -r e2786e2c491a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ShortCircuitAndNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ShortCircuitAndNode.java Tue Jul 16 18:30:45 2013 +0200 @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013, 2013, 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.nodes; + +import com.oracle.graal.nodes.spi.*; + +/** + * The short-circuit AND (i.e. {@code &&} in Java) operator. + */ +public class ShortCircuitAndNode extends ShortCircuitBooleanNode implements Canonicalizable { + + public ShortCircuitAndNode(LogicNode x, boolean xNegated, LogicNode y, boolean yNegated, double shortCircuitProbability) { + super(x, xNegated, y, yNegated, shortCircuitProbability); + } + + @Override + public LogicNode canonical(CanonicalizerTool tool) { + LogicNode x = getX(); + LogicNode y = getY(); + if (x == y) { + // @formatter:off + // a && a = a + // a && !a = false + // !a && a = false + // !a && !a = !a + // @formatter:on + if (isXNegated()) { + if (isYNegated()) { + // !a && !a = !a + negateUsages(); + return x; + } else { + // !a && a = false + return LogicConstantNode.contradiction(graph()); + } + } else { + if (isYNegated()) { + // a && !a = false + return LogicConstantNode.contradiction(graph()); + } else { + // a && a = a + return x; + } + } + } + if (x instanceof LogicConstantNode) { + if (((LogicConstantNode) x).getValue() ^ isXNegated()) { + if (isYNegated()) { + negateUsages(); + } + return y; + } else { + return LogicConstantNode.contradiction(graph()); + } + } + if (y instanceof LogicConstantNode) { + if (((LogicConstantNode) y).getValue() ^ isYNegated()) { + if (isXNegated()) { + negateUsages(); + } + return x; + } else { + return LogicConstantNode.contradiction(graph()); + } + } + return this; + } +} diff -r 0a306985c262 -r e2786e2c491a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ShortCircuitBooleanNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ShortCircuitBooleanNode.java Tue Jul 16 18:30:45 2013 +0200 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013, 2013, 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.nodes; + +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.spi.*; + +/** + * Base class for the short-circuit boolean operators. + */ +public abstract class ShortCircuitBooleanNode extends LogicNode implements Negatable, Node.IterableNodeType { + + @Input private LogicNode x; + @Input private LogicNode y; + private boolean xNegated; + private boolean yNegated; + private double shortCircuitProbability; + + public ShortCircuitBooleanNode(LogicNode x, boolean xNegated, LogicNode y, boolean yNegated, double shortCircuitProbability) { + this.x = x; + this.xNegated = xNegated; + this.y = y; + this.yNegated = yNegated; + this.shortCircuitProbability = shortCircuitProbability; + } + + public LogicNode getX() { + return x; + } + + public LogicNode getY() { + return y; + } + + public boolean isXNegated() { + return xNegated; + } + + public boolean isYNegated() { + return yNegated; + } + + /** + * Gets the probability that the {@link #getY() y} part of this binary node is not + * evaluated. This is the probability that this operator will short-circuit its execution. + */ + public double getShortCircuitProbability() { + return shortCircuitProbability; + } + + @Override + public Negatable negate(LogicNode condition) { + if (condition == x) { + xNegated = !xNegated; + } + if (condition == y) { + yNegated = !yNegated; + } + return this; + } +} diff -r 0a306985c262 -r e2786e2c491a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ShortCircuitOrNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ShortCircuitOrNode.java Tue Jul 16 18:30:45 2013 +0200 @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013, 2013, 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.nodes; + +import com.oracle.graal.nodes.spi.*; + +/** + * The short-circuit OR (i.e. {@code ||} in Java) operator. + */ +public class ShortCircuitOrNode extends ShortCircuitBooleanNode implements Canonicalizable { + + public ShortCircuitOrNode(LogicNode x, boolean xNegated, LogicNode y, boolean yNegated, double shortCircuitProbability) { + super(x, xNegated, y, yNegated, shortCircuitProbability); + } + + @Override + public LogicNode canonical(CanonicalizerTool tool) { + LogicNode x = getX(); + LogicNode y = getY(); + if (x == y) { + // @formatter:off + // a || a = a + // a || !a = true + // !a || a = true + // !a || !a = !a + // @formatter:on + if (isXNegated()) { + if (isYNegated()) { + // !a || !a = !a + negateUsages(); + return x; + } else { + // !a || a = true + return LogicConstantNode.tautology(graph()); + } + } else { + if (isYNegated()) { + // a || !a = true + return LogicConstantNode.tautology(graph()); + } else { + // a || a = a + return x; + } + } + } + if (x instanceof LogicConstantNode) { + if (((LogicConstantNode) x).getValue() ^ isXNegated()) { + return LogicConstantNode.tautology(graph()); + } else { + if (isYNegated()) { + negateUsages(); + } + return y; + } + } + if (y instanceof LogicConstantNode) { + if (((LogicConstantNode) y).getValue() ^ isYNegated()) { + return LogicConstantNode.tautology(graph()); + } else { + if (isXNegated()) { + negateUsages(); + } + return x; + } + } + return this; + } + +} diff -r 0a306985c262 -r e2786e2c491a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BranchProbabilityNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BranchProbabilityNode.java Tue Jul 16 18:30:45 2013 +0200 @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2012, 2013, 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.nodes.extended; + +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.spi.*; + +/** + * Instances of this node class will look for a preceding if node and put the given probability into + * the if node's taken probability. Then the branch probability node will be removed. This node is + * intended primarily for snippets, so that they can define their fast and slow paths. + */ +public class BranchProbabilityNode extends FloatingNode implements Canonicalizable, Lowerable { + + public static final double LIKELY_PROBABILITY = 0.6; + public static final double NOT_LIKELY_PROBABILITY = 1 - LIKELY_PROBABILITY; + + public static final double FREQUENT_PROBABILITY = 0.9; + public static final double NOT_FREQUENT_PROBABILITY = 1 - FREQUENT_PROBABILITY; + + public static final double FAST_PATH_PROBABILITY = 0.99; + public static final double SLOW_PATH_PROBABILITY = 1 - FAST_PATH_PROBABILITY; + + public static final double VERY_FAST_PATH_PROBABILITY = 0.999; + public static final double VERY_SLOW_PATH_PROBABILITY = 1 - VERY_FAST_PATH_PROBABILITY; + + @Input private ValueNode probability; + @Input private ValueNode condition; + + public BranchProbabilityNode(ValueNode probability, ValueNode condition) { + super(condition.stamp()); + this.probability = probability; + this.condition = condition; + } + + public ValueNode getProbability() { + return probability; + } + + public ValueNode getCondition() { + return condition; + } + + @Override + public ValueNode canonical(CanonicalizerTool tool) { + if (probability.isConstant()) { + double probabilityValue = probability.asConstant().asDouble(); + if (probabilityValue < 0.0) { + throw new GraalInternalError("A negative probability of " + probabilityValue + " is not allowed!"); + } else if (probabilityValue > 1.0) { + throw new GraalInternalError("A probability of more than 1.0 (" + probabilityValue + ") is not allowed!"); + } + boolean couldSet = false; + for (IntegerEqualsNode node : this.usages().filter(IntegerEqualsNode.class)) { + if (node.condition() == Condition.EQ) { + ValueNode other = node.x(); + if (node.x() == this) { + other = node.y(); + } + if (other.isConstant()) { + double probabilityToSet = probabilityValue; + if (other.asConstant().asInt() == 0) { + probabilityToSet = 1.0 - probabilityToSet; + } + for (IfNode ifNodeUsages : node.usages().filter(IfNode.class)) { + couldSet = true; + ifNodeUsages.setTrueSuccessorProbability(probabilityToSet); + } + } + } + } + if (!couldSet) { + if (isSubstitutionGraph()) { + return this; + } + throw new GraalInternalError("Wrong usage of branch probability injection!"); + } + return condition; + } + return this; + } + + private boolean isSubstitutionGraph() { + return usages().count() == 1 && usages().first() instanceof ReturnNode; + } + + /** + * This intrinsic should only be used for the condition of an if statement. The parameter + * condition should also only denote a simple condition and not a combined condition involving + * && or || operators. It injects the probability of the condition into the if statement. + * + * @param probability the probability that the given condition is true as a double value between + * 0.0 and 1.0. + * @param condition the simple condition without any && or || operators + * @return the condition + */ + @NodeIntrinsic + public static boolean probability(double probability, boolean condition) { + assert probability >= 0.0 && probability <= 1.0; + return condition; + } + + @Override + public void lower(LoweringTool tool, LoweringType loweringType) { + throw new GraalInternalError("Branch probability could not be injected, because the probability value did not reduce to a constant value."); + } +} diff -r 0a306985c262 -r e2786e2c491a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Tue Jul 16 16:46:55 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Tue Jul 16 18:30:45 2013 +0200 @@ -24,10 +24,11 @@ import static com.oracle.graal.api.code.DeoptimizationAction.*; import static com.oracle.graal.api.meta.DeoptimizationReason.*; +import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ProfilingInfo.*; +import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; @@ -117,7 +118,17 @@ condition = typeTest; stamp = stamp.join(StampFactory.objectNonNull()); } else { - condition = graph().unique(new LogicDisjunctionNode(graph().unique(new IsNullNode(object)), typeTest)); + double shortCircuitProbability; + if (profile == null) { + shortCircuitProbability = NOT_FREQUENT_PROBABILITY; + } else { + // Tell the instanceof it does not need to do a null check + typeTest.setProfile(new JavaTypeProfile(TriState.FALSE, profile.getNotRecordedProbability(), profile.getTypes())); + + // TODO (ds) replace with probability of null-seen when available + shortCircuitProbability = NOT_FREQUENT_PROBABILITY; + } + condition = graph().unique(new ShortCircuitOrNode(graph().unique(new IsNullNode(object)), false, typeTest, false, shortCircuitProbability)); } } GuardingPiNode checkedObject = graph().add(new GuardingPiNode(object, condition, false, forStoreCheck ? ArrayStoreException : ClassCastException, InvalidateReprofile, stamp)); diff -r 0a306985c262 -r e2786e2c491a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java Tue Jul 16 16:46:55 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java Tue Jul 16 18:30:45 2013 +0200 @@ -120,7 +120,7 @@ @Override public boolean verify() { for (Node usage : usages()) { - assertTrue(usage instanceof IfNode || usage instanceof FixedGuardNode || usage instanceof GuardingPiNode || usage instanceof ConditionalNode || usage instanceof LogicBinaryNode, + assertTrue(usage instanceof IfNode || usage instanceof FixedGuardNode || usage instanceof GuardingPiNode || usage instanceof ConditionalNode || usage instanceof ShortCircuitBooleanNode, "unsupported usage: %s", usage); } return super.verify(); diff -r 0a306985c262 -r e2786e2c491a graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Tue Jul 16 16:46:55 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Tue Jul 16 18:30:45 2013 +0200 @@ -319,8 +319,8 @@ } private void registerCondition(boolean isTrue, LogicNode condition, ValueNode anchor) { - if (!isTrue && condition instanceof LogicDisjunctionNode) { - LogicDisjunctionNode disjunction = (LogicDisjunctionNode) condition; + if (!isTrue && condition instanceof ShortCircuitOrNode) { + ShortCircuitOrNode disjunction = (ShortCircuitOrNode) condition; registerCondition(disjunction.isXNegated(), disjunction.getX(), anchor); registerCondition(disjunction.isYNegated(), disjunction.getY(), anchor); } else { diff -r 0a306985c262 -r e2786e2c491a graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ExpandLogicPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ExpandLogicPhase.java Tue Jul 16 16:46:55 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ExpandLogicPhase.java Tue Jul 16 18:30:45 2013 +0200 @@ -31,29 +31,29 @@ @Override protected void run(StructuredGraph graph) { - for (LogicBinaryNode logic : graph.getNodes(LogicBinaryNode.class)) { + for (ShortCircuitBooleanNode logic : graph.getNodes(ShortCircuitBooleanNode.class)) { processBinary(logic); } - assert graph.getNodes(LogicBinaryNode.class).isEmpty(); + assert graph.getNodes(ShortCircuitBooleanNode.class).isEmpty(); } - private static void processBinary(LogicBinaryNode binary) { + private static void processBinary(ShortCircuitBooleanNode binary) { while (binary.usages().isNotEmpty()) { Node usage = binary.usages().first(); - if (usage instanceof LogicBinaryNode) { - processBinary((LogicBinaryNode) usage); + if (usage instanceof ShortCircuitBooleanNode) { + processBinary((ShortCircuitBooleanNode) usage); } else if (usage instanceof IfNode) { - if (binary instanceof LogicConjunctionNode) { - processIf(binary.getX(), binary.isXNegated(), binary.getY(), binary.isYNegated(), (IfNode) usage, false); - } else if (binary instanceof LogicDisjunctionNode) { - processIf(binary.getX(), !binary.isXNegated(), binary.getY(), !binary.isYNegated(), (IfNode) usage, true); + if (binary instanceof ShortCircuitAndNode) { + processIf(binary.getX(), binary.isXNegated(), binary.getY(), binary.isYNegated(), (IfNode) usage, false, binary.getShortCircuitProbability()); + } else if (binary instanceof ShortCircuitOrNode) { + processIf(binary.getX(), !binary.isXNegated(), binary.getY(), !binary.isYNegated(), (IfNode) usage, true, binary.getShortCircuitProbability()); } else { throw GraalInternalError.shouldNotReachHere(); } } else if (usage instanceof ConditionalNode) { - if (binary instanceof LogicConjunctionNode) { + if (binary instanceof ShortCircuitOrNode) { processConditional(binary.getX(), binary.isXNegated(), binary.getY(), binary.isYNegated(), (ConditionalNode) usage, false); - } else if (binary instanceof LogicDisjunctionNode) { + } else if (binary instanceof ShortCircuitOrNode) { processConditional(binary.getX(), !binary.isXNegated(), binary.getY(), !binary.isYNegated(), (ConditionalNode) usage, true); } else { throw GraalInternalError.shouldNotReachHere(); @@ -65,10 +65,11 @@ binary.safeDelete(); } - private static void processIf(LogicNode x, boolean xNegated, LogicNode y, boolean yNegated, IfNode ifNode, boolean negateTargets) { + private static void processIf(LogicNode x, boolean xNegated, LogicNode y, boolean yNegated, IfNode ifNode, boolean negateTargets, double shortCircuitProbability) { AbstractBeginNode trueTarget = negateTargets ? ifNode.falseSuccessor() : ifNode.trueSuccessor(); AbstractBeginNode falseTarget = negateTargets ? ifNode.trueSuccessor() : ifNode.falseSuccessor(); - double p = Math.sqrt(ifNode.probability(trueTarget)); + double firstIfProbability = shortCircuitProbability; + double secondIfProbability = 1 - ifNode.probability(trueTarget); ifNode.clearSuccessors(); Graph graph = ifNode.graph(); MergeNode falseTargetMerge = graph.add(new MergeNode()); @@ -79,8 +80,8 @@ falseTargetMerge.addForwardEnd(secondFalseEnd); AbstractBeginNode firstFalseTarget = AbstractBeginNode.begin(firstFalseEnd); AbstractBeginNode secondFalseTarget = AbstractBeginNode.begin(secondFalseEnd); - AbstractBeginNode secondIf = AbstractBeginNode.begin(graph.add(new IfNode(y, yNegated ? firstFalseTarget : trueTarget, yNegated ? trueTarget : firstFalseTarget, yNegated ? 1 - p : p))); - IfNode firstIf = graph.add(new IfNode(x, xNegated ? secondFalseTarget : secondIf, xNegated ? secondIf : secondFalseTarget, xNegated ? 1 - p : p)); + AbstractBeginNode secondIf = AbstractBeginNode.begin(graph.add(new IfNode(y, yNegated ? firstFalseTarget : trueTarget, yNegated ? trueTarget : firstFalseTarget, secondIfProbability))); + IfNode firstIf = graph.add(new IfNode(x, xNegated ? secondFalseTarget : secondIf, xNegated ? secondIf : secondFalseTarget, firstIfProbability)); ifNode.replaceAtPredecessor(firstIf); ifNode.safeDelete(); } diff -r 0a306985c262 -r e2786e2c491a graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java --- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java Tue Jul 16 16:46:55 2013 +0200 +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java Tue Jul 16 18:30:45 2013 +0200 @@ -22,8 +22,8 @@ */ package com.oracle.graal.replacements.amd64; +import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*; import static com.oracle.graal.replacements.SnippetTemplate.*; -import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*; import java.util.*; diff -r 0a306985c262 -r e2786e2c491a graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java Tue Jul 16 16:46:55 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java Tue Jul 16 18:30:45 2013 +0200 @@ -93,7 +93,7 @@ */ protected InstanceOfUsageReplacer createReplacer(FloatingNode instanceOf, Instantiation instantiation, Node usage, final StructuredGraph graph) { InstanceOfUsageReplacer replacer; - if (usage instanceof IfNode || usage instanceof FixedGuardNode || usage instanceof LogicBinaryNode || usage instanceof GuardingPiNode) { + if (usage instanceof IfNode || usage instanceof FixedGuardNode || usage instanceof ShortCircuitBooleanNode || usage instanceof GuardingPiNode) { replacer = new NonMaterializationUsageReplacer(instantiation, ConstantNode.forInt(1, graph), ConstantNode.forInt(0, graph), instanceOf, usage); } else { assert usage instanceof ConditionalNode : "unexpected usage of " + instanceOf + ": " + usage; diff -r 0a306985c262 -r e2786e2c491a graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BranchProbabilityNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BranchProbabilityNode.java Tue Jul 16 16:46:55 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2012, 2013, 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.replacements.nodes; - -import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; - -/** - * Instances of this node class will look for a preceding if node and put the given probability into - * the if node's taken probability. Then the branch probability node will be removed. This node is - * intended primarily for snippets, so that they can define their fast and slow paths. - */ -public class BranchProbabilityNode extends FloatingNode implements Canonicalizable, Lowerable { - - public static final double LIKELY_PROBABILITY = 0.6; - public static final double NOT_LIKELY_PROBABILITY = 1 - LIKELY_PROBABILITY; - - public static final double FREQUENT_PROBABILITY = 0.9; - public static final double NOT_FREQUENT_PROBABILITY = 1 - FREQUENT_PROBABILITY; - - public static final double FAST_PATH_PROBABILITY = 0.99; - public static final double SLOW_PATH_PROBABILITY = 1 - FAST_PATH_PROBABILITY; - - public static final double VERY_FAST_PATH_PROBABILITY = 0.999; - public static final double VERY_SLOW_PATH_PROBABILITY = 1 - VERY_FAST_PATH_PROBABILITY; - - @Input private ValueNode probability; - @Input private ValueNode condition; - - public BranchProbabilityNode(ValueNode probability, ValueNode condition) { - super(condition.stamp()); - this.probability = probability; - this.condition = condition; - } - - public ValueNode getProbability() { - return probability; - } - - public ValueNode getCondition() { - return condition; - } - - @Override - public ValueNode canonical(CanonicalizerTool tool) { - if (probability.isConstant()) { - double probabilityValue = probability.asConstant().asDouble(); - if (probabilityValue < 0.0) { - throw new GraalInternalError("A negative probability of " + probabilityValue + " is not allowed!"); - } else if (probabilityValue > 1.0) { - throw new GraalInternalError("A probability of more than 1.0 (" + probabilityValue + ") is not allowed!"); - } - boolean couldSet = false; - for (IntegerEqualsNode node : this.usages().filter(IntegerEqualsNode.class)) { - if (node.condition() == Condition.EQ) { - ValueNode other = node.x(); - if (node.x() == this) { - other = node.y(); - } - if (other.isConstant()) { - double probabilityToSet = probabilityValue; - if (other.asConstant().asInt() == 0) { - probabilityToSet = 1.0 - probabilityToSet; - } - for (IfNode ifNodeUsages : node.usages().filter(IfNode.class)) { - couldSet = true; - ifNodeUsages.setTrueSuccessorProbability(probabilityToSet); - } - } - } - } - if (!couldSet) { - if (isSubstitutionGraph()) { - return this; - } - throw new GraalInternalError("Wrong usage of branch probability injection!"); - } - return condition; - } - return this; - } - - private boolean isSubstitutionGraph() { - return usages().count() == 1 && usages().first() instanceof ReturnNode; - } - - /** - * This intrinsic should only be used for the condition of an if statement. The parameter - * condition should also only denote a simple condition and not a combined condition involving - * && or || operators. It injects the probability of the condition into the if statement. - * - * @param probability the probability that the given condition is true as a double value between - * 0.0 and 1.0. - * @param condition the simple condition without any && or || operators - * @return the condition - */ - @NodeIntrinsic - public static boolean probability(double probability, boolean condition) { - assert probability >= 0.0 && probability <= 1.0; - return condition; - } - - @Override - public void lower(LoweringTool tool, LoweringType loweringType) { - throw new GraalInternalError("Branch probability could not be injected, because the probability value did not reduce to a constant value."); - } -} diff -r 0a306985c262 -r e2786e2c491a graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java Tue Jul 16 16:46:55 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java Tue Jul 16 18:30:45 2013 +0200 @@ -28,8 +28,8 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.replacements.nodes.*; import com.oracle.graal.truffle.nodes.*; import com.oracle.truffle.api.*;