< 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]: graal2

*** 1,7 **** /* ! * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. --- 1,7 ---- /* ! * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.
*** 25,34 **** --- 25,35 ---- package org.graalvm.compiler.nodes.calc; import org.graalvm.compiler.core.common.type.ArithmeticOpTable; import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp; import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.Add; + import org.graalvm.compiler.core.common.type.IntegerStamp; import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.graph.spi.Canonicalizable.BinaryCommutative; import org.graalvm.compiler.graph.spi.CanonicalizerTool; import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
*** 36,46 **** --- 37,49 ---- import org.graalvm.compiler.nodes.ConstantNode; import org.graalvm.compiler.nodes.NodeView; import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; + import jdk.vm.ci.code.CodeUtil; import jdk.vm.ci.meta.Constant; + import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.Value; @NodeInfo(shortName = "+") public class AddNode extends BinaryArithmeticNode<Add> implements NarrowableArithmeticNode, BinaryCommutative<ValueNode> {
*** 97,106 **** --- 100,157 ---- ValueNode reassociated = reassociate(self, ValueNode.isConstantPredicate(), forX, forY, view); if (reassociated != self) { return reassociated; } } + + // Attempt to optimize the pattern of an extend node between two add nodes. + if (c instanceof JavaConstant && (forX instanceof SignExtendNode || forX instanceof ZeroExtendNode)) { + IntegerConvertNode<?, ?> integerConvertNode = (IntegerConvertNode<?, ?>) forX; + ValueNode valueNode = integerConvertNode.getValue(); + long constant = ((JavaConstant) c).asLong(); + if (valueNode instanceof AddNode) { + AddNode addBeforeExtend = (AddNode) valueNode; + if (addBeforeExtend.getY().isConstant()) { + // There is a second add before the extend node that also has a constant as + // second operand. Therefore there will be canonicalizations triggered if we + // can move the add above the extension. For this we need to check whether + // the result of the addition is the same before the extension (which can be + // either zero extend or sign extend). + IntegerStamp beforeExtendStamp = (IntegerStamp) addBeforeExtend.stamp(view); + int bits = beforeExtendStamp.getBits(); + if (constant >= CodeUtil.minValue(bits) && constant <= CodeUtil.maxValue(bits)) { + IntegerStamp narrowConstantStamp = IntegerStamp.create(bits, constant, constant); + + if (!IntegerStamp.addCanOverflow(narrowConstantStamp, beforeExtendStamp)) { + ConstantNode constantNode = ConstantNode.forIntegerStamp(narrowConstantStamp, constant); + if (forX instanceof SignExtendNode) { + return SignExtendNode.create(AddNode.create(addBeforeExtend, constantNode, view), integerConvertNode.getResultBits(), view); + } else { + assert forX instanceof ZeroExtendNode; + + // Must check to not cross zero with the new add. + boolean crossesZeroPoint = true; + if (constant > 0) { + if (beforeExtendStamp.lowerBound() >= 0 || beforeExtendStamp.upperBound() < -constant) { + // We are good here. + crossesZeroPoint = false; + } + } else { + if (beforeExtendStamp.lowerBound() >= -constant || beforeExtendStamp.upperBound() < 0) { + // We are good here as well. + crossesZeroPoint = false; + } + } + if (!crossesZeroPoint) { + return ZeroExtendNode.create(AddNode.create(addBeforeExtend, constantNode, view), integerConvertNode.getResultBits(), view); + } + } + } + } + } + } + } } if (forX instanceof NegateNode) { return BinaryArithmeticNode.sub(forY, ((NegateNode) forX).getValue(), view); } else if (forY instanceof NegateNode) { return BinaryArithmeticNode.sub(forX, ((NegateNode) forY).getValue(), view);
< prev index next >