1 /*
   2  * Copyright (c) 2009, 2015, 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 package org.graalvm.compiler.core.gen;
  24 
  25 import jdk.vm.ci.meta.Value;
  26 
  27 import org.graalvm.compiler.core.match.MatchableNode;
  28 import org.graalvm.compiler.graph.Node;
  29 import org.graalvm.compiler.lir.LIRFrameState;
  30 import org.graalvm.compiler.lir.LIRInstruction;
  31 import org.graalvm.compiler.lir.LabelRef;
  32 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
  33 import org.graalvm.compiler.nodes.ConstantNode;
  34 import org.graalvm.compiler.nodes.DeoptimizingNode;
  35 import org.graalvm.compiler.nodes.FixedNode;
  36 import org.graalvm.compiler.nodes.IfNode;
  37 import org.graalvm.compiler.nodes.PiNode;
  38 import org.graalvm.compiler.nodes.calc.AddNode;
  39 import org.graalvm.compiler.nodes.calc.AndNode;
  40 import org.graalvm.compiler.nodes.calc.FloatConvertNode;
  41 import org.graalvm.compiler.nodes.calc.FloatEqualsNode;
  42 import org.graalvm.compiler.nodes.calc.FloatLessThanNode;
  43 import org.graalvm.compiler.nodes.calc.IntegerBelowNode;
  44 import org.graalvm.compiler.nodes.calc.IntegerEqualsNode;
  45 import org.graalvm.compiler.nodes.calc.IntegerLessThanNode;
  46 import org.graalvm.compiler.nodes.calc.IntegerTestNode;
  47 import org.graalvm.compiler.nodes.calc.LeftShiftNode;
  48 import org.graalvm.compiler.nodes.calc.MulNode;
  49 import org.graalvm.compiler.nodes.calc.NarrowNode;
  50 import org.graalvm.compiler.nodes.calc.ObjectEqualsNode;
  51 import org.graalvm.compiler.nodes.calc.OrNode;
  52 import org.graalvm.compiler.nodes.calc.PointerEqualsNode;
  53 import org.graalvm.compiler.nodes.calc.ReinterpretNode;
  54 import org.graalvm.compiler.nodes.calc.SignExtendNode;
  55 import org.graalvm.compiler.nodes.calc.SubNode;
  56 import org.graalvm.compiler.nodes.calc.UnsignedRightShiftNode;
  57 import org.graalvm.compiler.nodes.calc.XorNode;
  58 import org.graalvm.compiler.nodes.calc.ZeroExtendNode;
  59 import org.graalvm.compiler.nodes.java.LogicCompareAndSwapNode;
  60 import org.graalvm.compiler.nodes.java.ValueCompareAndSwapNode;
  61 import org.graalvm.compiler.nodes.memory.FloatingReadNode;
  62 import org.graalvm.compiler.nodes.memory.ReadNode;
  63 import org.graalvm.compiler.nodes.memory.WriteNode;
  64 
  65 @MatchableNode(nodeClass = ConstantNode.class, shareable = true)
  66 @MatchableNode(nodeClass = FloatConvertNode.class, inputs = {"value"})
  67 @MatchableNode(nodeClass = FloatingReadNode.class, inputs = {"address"})
  68 @MatchableNode(nodeClass = IfNode.class, inputs = {"condition"})
  69 @MatchableNode(nodeClass = SubNode.class, inputs = {"x", "y"})
  70 @MatchableNode(nodeClass = LeftShiftNode.class, inputs = {"x", "y"})
  71 @MatchableNode(nodeClass = NarrowNode.class, inputs = {"value"})
  72 @MatchableNode(nodeClass = ReadNode.class, inputs = {"address"})
  73 @MatchableNode(nodeClass = ReinterpretNode.class, inputs = {"value"})
  74 @MatchableNode(nodeClass = SignExtendNode.class, inputs = {"value"})
  75 @MatchableNode(nodeClass = UnsignedRightShiftNode.class, inputs = {"x", "y"})
  76 @MatchableNode(nodeClass = WriteNode.class, inputs = {"address", "value"})
  77 @MatchableNode(nodeClass = ZeroExtendNode.class, inputs = {"value"})
  78 @MatchableNode(nodeClass = AndNode.class, inputs = {"x", "y"}, commutative = true)
  79 @MatchableNode(nodeClass = FloatEqualsNode.class, inputs = {"x", "y"}, commutative = true)
  80 @MatchableNode(nodeClass = FloatLessThanNode.class, inputs = {"x", "y"}, commutative = true)
  81 @MatchableNode(nodeClass = PointerEqualsNode.class, inputs = {"x", "y"}, commutative = true)
  82 @MatchableNode(nodeClass = AddNode.class, inputs = {"x", "y"}, commutative = true)
  83 @MatchableNode(nodeClass = IntegerBelowNode.class, inputs = {"x", "y"}, commutative = true)
  84 @MatchableNode(nodeClass = IntegerEqualsNode.class, inputs = {"x", "y"}, commutative = true)
  85 @MatchableNode(nodeClass = IntegerLessThanNode.class, inputs = {"x", "y"}, commutative = true)
  86 @MatchableNode(nodeClass = MulNode.class, inputs = {"x", "y"}, commutative = true)
  87 @MatchableNode(nodeClass = IntegerTestNode.class, inputs = {"x", "y"}, commutative = true)
  88 @MatchableNode(nodeClass = ObjectEqualsNode.class, inputs = {"x", "y"}, commutative = true)
  89 @MatchableNode(nodeClass = OrNode.class, inputs = {"x", "y"}, commutative = true)
  90 @MatchableNode(nodeClass = XorNode.class, inputs = {"x", "y"}, commutative = true)
  91 @MatchableNode(nodeClass = PiNode.class, inputs = {"object"})
  92 @MatchableNode(nodeClass = LogicCompareAndSwapNode.class, inputs = {"address", "expectedValue", "newValue"})
  93 @MatchableNode(nodeClass = ValueCompareAndSwapNode.class, inputs = {"address", "expectedValue", "newValue"})
  94 public abstract class NodeMatchRules {
  95 
  96     NodeLIRBuilder lirBuilder;
  97     protected final LIRGeneratorTool gen;
  98 
  99     protected NodeMatchRules(LIRGeneratorTool gen) {
 100         this.gen = gen;
 101     }
 102 
 103     protected LIRGeneratorTool getLIRGeneratorTool() {
 104         return gen;
 105     }
 106 
 107     /*
 108      * For now we do not want to expose the full lirBuilder to subclasses, so we delegate the few
 109      * methods that are actually needed. If the list grows too long, exposing lirBuilder might be
 110      * the better approach.
 111      */
 112 
 113     protected final Value operand(Node node) {
 114         return lirBuilder.operand(node);
 115     }
 116 
 117     protected final LIRFrameState state(DeoptimizingNode deopt) {
 118         return lirBuilder.state(deopt);
 119     }
 120 
 121     protected final LabelRef getLIRBlock(FixedNode b) {
 122         return lirBuilder.getLIRBlock(b);
 123     }
 124 
 125     protected final void append(LIRInstruction op) {
 126         lirBuilder.append(op);
 127     }
 128 }