< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AddNode.java

Print this page
rev 52509 : [mq]: graal
   1 /*
   2  * Copyright (c) 2011, 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 
  24 
  25 package org.graalvm.compiler.nodes.calc;
  26 
  27 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
  28 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp;
  29 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.Add;

  30 import org.graalvm.compiler.core.common.type.Stamp;
  31 import org.graalvm.compiler.graph.NodeClass;
  32 import org.graalvm.compiler.graph.spi.Canonicalizable.BinaryCommutative;
  33 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
  34 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
  35 import org.graalvm.compiler.nodeinfo.NodeInfo;
  36 import org.graalvm.compiler.nodes.ConstantNode;
  37 import org.graalvm.compiler.nodes.NodeView;
  38 import org.graalvm.compiler.nodes.ValueNode;
  39 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
  40 

  41 import jdk.vm.ci.meta.Constant;

  42 import jdk.vm.ci.meta.Value;
  43 
  44 @NodeInfo(shortName = "+")
  45 public class AddNode extends BinaryArithmeticNode<Add> implements NarrowableArithmeticNode, BinaryCommutative<ValueNode> {
  46 
  47     public static final NodeClass<AddNode> TYPE = NodeClass.create(AddNode.class);
  48 
  49     public AddNode(ValueNode x, ValueNode y) {
  50         this(TYPE, x, y);
  51     }
  52 
  53     protected AddNode(NodeClass<? extends AddNode> c, ValueNode x, ValueNode y) {
  54         super(c, ArithmeticOpTable::getAdd, x, y);
  55     }
  56 
  57     public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
  58         BinaryOp<Add> op = ArithmeticOpTable.forStamp(x.stamp(view)).getAdd();
  59         Stamp stamp = op.foldStamp(x.stamp(view), y.stamp(view));
  60         ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp, view);
  61         if (tryConstantFold != null) {


  80                 }
  81             }
  82             if (forY instanceof SubNode) {
  83                 SubNode sub = (SubNode) forY;
  84                 if (sub.getY() == forX) {
  85                     // b + (a - b)
  86                     return sub.getX();
  87                 }
  88             }
  89         }
  90         if (forY.isConstant()) {
  91             Constant c = forY.asConstant();
  92             if (op.isNeutral(c)) {
  93                 return forX;
  94             }
  95             if (associative && self != null) {
  96                 // canonicalize expressions like "(a + 1) + 2"
  97                 ValueNode reassociated = reassociate(self, ValueNode.isConstantPredicate(), forX, forY, view);
  98                 if (reassociated != self) {
  99                     return reassociated;
















































 100                 }
 101             }
 102         }
 103         if (forX instanceof NegateNode) {
 104             return BinaryArithmeticNode.sub(forY, ((NegateNode) forX).getValue(), view);
 105         } else if (forY instanceof NegateNode) {
 106             return BinaryArithmeticNode.sub(forX, ((NegateNode) forY).getValue(), view);
 107         }
 108         if (self == null) {
 109             self = (AddNode) new AddNode(forX, forY).maybeCommuteInputs();
 110         }
 111         return self;
 112     }
 113 
 114     @Override
 115     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
 116         ValueNode ret = super.canonical(tool, forX, forY);
 117         if (ret != this) {
 118             return ret;
 119         }


   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.calc;
  26 
  27 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
  28 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp;
  29 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.Add;
  30 import org.graalvm.compiler.core.common.type.IntegerStamp;
  31 import org.graalvm.compiler.core.common.type.Stamp;
  32 import org.graalvm.compiler.graph.NodeClass;
  33 import org.graalvm.compiler.graph.spi.Canonicalizable.BinaryCommutative;
  34 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
  35 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
  36 import org.graalvm.compiler.nodeinfo.NodeInfo;
  37 import org.graalvm.compiler.nodes.ConstantNode;
  38 import org.graalvm.compiler.nodes.NodeView;
  39 import org.graalvm.compiler.nodes.ValueNode;
  40 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
  41 
  42 import jdk.vm.ci.code.CodeUtil;
  43 import jdk.vm.ci.meta.Constant;
  44 import jdk.vm.ci.meta.JavaConstant;
  45 import jdk.vm.ci.meta.Value;
  46 
  47 @NodeInfo(shortName = "+")
  48 public class AddNode extends BinaryArithmeticNode<Add> implements NarrowableArithmeticNode, BinaryCommutative<ValueNode> {
  49 
  50     public static final NodeClass<AddNode> TYPE = NodeClass.create(AddNode.class);
  51 
  52     public AddNode(ValueNode x, ValueNode y) {
  53         this(TYPE, x, y);
  54     }
  55 
  56     protected AddNode(NodeClass<? extends AddNode> c, ValueNode x, ValueNode y) {
  57         super(c, ArithmeticOpTable::getAdd, x, y);
  58     }
  59 
  60     public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
  61         BinaryOp<Add> op = ArithmeticOpTable.forStamp(x.stamp(view)).getAdd();
  62         Stamp stamp = op.foldStamp(x.stamp(view), y.stamp(view));
  63         ConstantNode tryConstantFold = tryConstantFold(op, x, y, stamp, view);
  64         if (tryConstantFold != null) {


  83                 }
  84             }
  85             if (forY instanceof SubNode) {
  86                 SubNode sub = (SubNode) forY;
  87                 if (sub.getY() == forX) {
  88                     // b + (a - b)
  89                     return sub.getX();
  90                 }
  91             }
  92         }
  93         if (forY.isConstant()) {
  94             Constant c = forY.asConstant();
  95             if (op.isNeutral(c)) {
  96                 return forX;
  97             }
  98             if (associative && self != null) {
  99                 // canonicalize expressions like "(a + 1) + 2"
 100                 ValueNode reassociated = reassociate(self, ValueNode.isConstantPredicate(), forX, forY, view);
 101                 if (reassociated != self) {
 102                     return reassociated;
 103                 }
 104             }
 105 
 106             // Attempt to optimize the pattern of an extend node between two add nodes.
 107             if (c instanceof JavaConstant && (forX instanceof SignExtendNode || forX instanceof ZeroExtendNode)) {
 108                 IntegerConvertNode<?, ?> integerConvertNode = (IntegerConvertNode<?, ?>) forX;
 109                 ValueNode valueNode = integerConvertNode.getValue();
 110                 long constant = ((JavaConstant) c).asLong();
 111                 if (valueNode instanceof AddNode) {
 112                     AddNode addBeforeExtend = (AddNode) valueNode;
 113                     if (addBeforeExtend.getY().isConstant()) {
 114                         // There is a second add before the extend node that also has a constant as
 115                         // second operand. Therefore there will be canonicalizations triggered if we
 116                         // can move the add above the extension. For this we need to check whether
 117                         // the result of the addition is the same before the extension (which can be
 118                         // either zero extend or sign extend).
 119                         IntegerStamp beforeExtendStamp = (IntegerStamp) addBeforeExtend.stamp(view);
 120                         int bits = beforeExtendStamp.getBits();
 121                         if (constant >= CodeUtil.minValue(bits) && constant <= CodeUtil.maxValue(bits)) {
 122                             IntegerStamp narrowConstantStamp = IntegerStamp.create(bits, constant, constant);
 123 
 124                             if (!IntegerStamp.addCanOverflow(narrowConstantStamp, beforeExtendStamp)) {
 125                                 ConstantNode constantNode = ConstantNode.forIntegerStamp(narrowConstantStamp, constant);
 126                                 if (forX instanceof SignExtendNode) {
 127                                     return SignExtendNode.create(AddNode.create(addBeforeExtend, constantNode, view), integerConvertNode.getResultBits(), view);
 128                                 } else {
 129                                     assert forX instanceof ZeroExtendNode;
 130 
 131                                     // Must check to not cross zero with the new add.
 132                                     boolean crossesZeroPoint = true;
 133                                     if (constant > 0) {
 134                                         if (beforeExtendStamp.lowerBound() >= 0 || beforeExtendStamp.upperBound() < -constant) {
 135                                             // We are good here.
 136                                             crossesZeroPoint = false;
 137                                         }
 138                                     } else {
 139                                         if (beforeExtendStamp.lowerBound() >= -constant || beforeExtendStamp.upperBound() < 0) {
 140                                             // We are good here as well.
 141                                             crossesZeroPoint = false;
 142                                         }
 143                                     }
 144                                     if (!crossesZeroPoint) {
 145                                         return ZeroExtendNode.create(AddNode.create(addBeforeExtend, constantNode, view), integerConvertNode.getResultBits(), view);
 146                                     }
 147                                 }
 148                             }
 149                         }
 150                     }
 151                 }
 152             }
 153         }
 154         if (forX instanceof NegateNode) {
 155             return BinaryArithmeticNode.sub(forY, ((NegateNode) forX).getValue(), view);
 156         } else if (forY instanceof NegateNode) {
 157             return BinaryArithmeticNode.sub(forX, ((NegateNode) forY).getValue(), view);
 158         }
 159         if (self == null) {
 160             self = (AddNode) new AddNode(forX, forY).maybeCommuteInputs();
 161         }
 162         return self;
 163     }
 164 
 165     @Override
 166     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
 167         ValueNode ret = super.canonical(tool, forX, forY);
 168         if (ret != this) {
 169             return ret;
 170         }


< prev index next >