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