1 /* 2 * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 25 package org.graalvm.compiler.nodes; 26 27 import static org.graalvm.compiler.nodeinfo.InputType.Condition; 28 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; 29 30 import jdk.vm.ci.meta.TriState; 31 import org.graalvm.compiler.core.common.type.StampFactory; 32 import org.graalvm.compiler.graph.Node.IndirectCanonicalization; 33 import org.graalvm.compiler.graph.NodeClass; 34 import org.graalvm.compiler.nodeinfo.NodeInfo; 35 import org.graalvm.compiler.nodes.calc.FloatingNode; 36 37 @NodeInfo(allowedUsageTypes = {Condition}, size = SIZE_1) 38 public abstract class LogicNode extends FloatingNode implements IndirectCanonicalization { 39 40 public static final NodeClass<LogicNode> TYPE = NodeClass.create(LogicNode.class); 41 42 public LogicNode(NodeClass<? extends LogicNode> c) { 43 super(c, StampFactory.forVoid()); 44 } 45 46 public static LogicNode and(LogicNode a, LogicNode b, double shortCircuitProbability) { 47 return and(a, false, b, false, shortCircuitProbability); 48 } 49 50 public static LogicNode and(LogicNode a, boolean negateA, LogicNode b, boolean negateB, double shortCircuitProbability) { 51 StructuredGraph graph = a.graph(); 52 ShortCircuitOrNode notAorNotB = graph.unique(new ShortCircuitOrNode(a, !negateA, b, !negateB, shortCircuitProbability)); 53 return graph.unique(new LogicNegationNode(notAorNotB)); 54 } 55 56 public static LogicNode or(LogicNode a, LogicNode b, double shortCircuitProbability) { 57 return or(a, false, b, false, shortCircuitProbability); 58 } 59 60 public static LogicNode or(LogicNode a, boolean negateA, LogicNode b, boolean negateB, double shortCircuitProbability) { 61 return a.graph().unique(new ShortCircuitOrNode(a, negateA, b, negateB, shortCircuitProbability)); 62 } 63 64 public final boolean isTautology() { 65 if (this instanceof LogicConstantNode) { 66 LogicConstantNode logicConstantNode = (LogicConstantNode) this; 67 return logicConstantNode.getValue(); 68 } 69 70 return false; 71 } 72 73 public final boolean isContradiction() { 74 if (this instanceof LogicConstantNode) { 75 LogicConstantNode logicConstantNode = (LogicConstantNode) this; 76 return !logicConstantNode.getValue(); 77 } 78 79 return false; 80 } 81 82 /** 83 * Determines what this condition implies about the other. 84 * 85 * <ul> 86 * <li>If negate(this, thisNegated) => other, returns {@link TriState#TRUE}</li> 87 * <li>If negate(this, thisNegated) => !other, returns {@link TriState#FALSE}</li> 88 * </ul> 89 * 90 * @param thisNegated whether this condition should be considered as false. 91 * @param other the other condition. 92 */ 93 public TriState implies(boolean thisNegated, LogicNode other) { 94 if (this == other) { 95 return TriState.get(!thisNegated); 96 } 97 if (other instanceof LogicNegationNode) { 98 return flip(this.implies(thisNegated, ((LogicNegationNode) other).getValue())); 99 } 100 return TriState.UNKNOWN; 101 } 102 103 private static TriState flip(TriState triState) { 104 return triState.isUnknown() 105 ? triState 106 : TriState.get(!triState.toBoolean()); 107 } 108 }