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 }
--- EOF ---