# HG changeset patch # User Tom Rodriguez # Date 1423526100 28800 # Node ID ef52cebd40306d413ac8dc876d9783d057ccdc4a # Parent 18c2fd3d7fc7e346b406d842aeebc520f616f518 Fold away obvious identities when building induction variable expressions diff -r 18c2fd3d7fc7 -r ef52cebd4030 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/BasicInductionVariable.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/BasicInductionVariable.java Mon Feb 09 15:52:17 2015 -0800 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/BasicInductionVariable.java Mon Feb 09 15:55:00 2015 -0800 @@ -22,6 +22,8 @@ */ package com.oracle.graal.loop; +import static com.oracle.graal.loop.MathUtil.*; + import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.nodes.*; @@ -135,7 +137,7 @@ if (!maxTripCount.stamp().isCompatible(stamp)) { maxTripCount = IntegerConvertNode.convert(maxTripCount, stamp, graph()); } - return BinaryArithmeticNode.add(graph, BinaryArithmeticNode.mul(graph, stride, BinaryArithmeticNode.sub(graph, maxTripCount, ConstantNode.forIntegerStamp(stamp, 1, graph))), initNode); + return add(graph, mul(graph, stride, sub(graph, maxTripCount, ConstantNode.forIntegerStamp(stamp, 1, graph))), initNode); } @Override @@ -145,7 +147,7 @@ if (!maxTripCount.stamp().isCompatible(stamp)) { maxTripCount = IntegerConvertNode.convert(maxTripCount, stamp, graph()); } - return BinaryArithmeticNode.add(graph(), BinaryArithmeticNode.mul(graph(), strideNode(), maxTripCount), initNode()); + return add(graph(), mul(graph(), strideNode(), maxTripCount), initNode()); } @Override diff -r 18c2fd3d7fc7 -r ef52cebd4030 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java Mon Feb 09 15:52:17 2015 -0800 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java Mon Feb 09 15:55:00 2015 -0800 @@ -22,7 +22,7 @@ */ package com.oracle.graal.loop; -import static com.oracle.graal.nodes.calc.BinaryArithmeticNode.*; +import static com.oracle.graal.loop.MathUtil.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; @@ -55,20 +55,19 @@ public ValueNode maxTripCountNode(boolean assumePositive) { StructuredGraph graph = iv.valueNode().graph(); Stamp stamp = iv.valueNode().stamp(); - BinaryArithmeticNode range = BinaryArithmeticNode.sub(graph, end, iv.initNode()); + ValueNode range = sub(graph, end, iv.initNode()); if (oneOff) { if (iv.direction() == Direction.Up) { - range = BinaryArithmeticNode.add(graph, range, ConstantNode.forIntegerStamp(stamp, 1, graph)); + range = add(graph, range, ConstantNode.forIntegerStamp(stamp, 1, graph)); } else { - range = BinaryArithmeticNode.sub(graph, range, ConstantNode.forIntegerStamp(stamp, 1, graph)); + range = sub(graph, range, ConstantNode.forIntegerStamp(stamp, 1, graph)); } } - IntegerDivNode div = graph.add(new IntegerDivNode(range, iv.strideNode())); - graph.addBeforeFixed(loop.entryPoint(), div); - ConstantNode zero = ConstantNode.forIntegerStamp(stamp, 0, graph); + ValueNode div = divBefore(graph, loop.entryPoint(), range, iv.strideNode()); if (assumePositive) { return div; } + ConstantNode zero = ConstantNode.forIntegerStamp(stamp, 0, graph); return graph.unique(new ConditionalNode(graph.unique(new IntegerLessThanNode(zero, div)), div, zero)); } @@ -144,14 +143,14 @@ CompareNode cond; // we use a negated guard with a < condition to achieve a >= ConstantNode one = ConstantNode.forIntegerStamp(stamp, 1, graph); if (iv.direction() == Direction.Up) { - BinaryArithmeticNode v1 = sub(graph, ConstantNode.forIntegerStamp(stamp, CodeUtil.maxValue(stamp.getBits()), graph), sub(graph, iv.strideNode(), one)); + ValueNode v1 = sub(graph, ConstantNode.forIntegerStamp(stamp, CodeUtil.maxValue(stamp.getBits()), graph), sub(graph, iv.strideNode(), one)); if (oneOff) { v1 = sub(graph, v1, one); } cond = graph.unique(new IntegerLessThanNode(v1, end)); } else { assert iv.direction() == Direction.Down; - BinaryArithmeticNode v1 = add(graph, ConstantNode.forIntegerStamp(stamp, CodeUtil.minValue(stamp.getBits()), graph), sub(graph, one, iv.strideNode())); + ValueNode v1 = add(graph, ConstantNode.forIntegerStamp(stamp, CodeUtil.minValue(stamp.getBits()), graph), sub(graph, one, iv.strideNode())); if (oneOff) { v1 = add(graph, v1, one); } diff -r 18c2fd3d7fc7 -r ef52cebd4030 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedOffsetInductionVariable.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedOffsetInductionVariable.java Mon Feb 09 15:52:17 2015 -0800 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedOffsetInductionVariable.java Mon Feb 09 15:55:00 2015 -0800 @@ -22,6 +22,8 @@ */ package com.oracle.graal.loop; +import static com.oracle.graal.loop.MathUtil.*; + import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.nodes.*; @@ -125,14 +127,14 @@ private ValueNode op(ValueNode b, ValueNode o) { if (value instanceof AddNode) { - return BinaryArithmeticNode.add(graph(), b, o); + return add(graph(), b, o); } if (value instanceof SubNode) { if (base.valueNode() == value.getX()) { - return BinaryArithmeticNode.sub(graph(), b, o); + return sub(graph(), b, o); } else { assert base.valueNode() == value.getY(); - return BinaryArithmeticNode.sub(graph(), o, b); + return sub(graph(), o, b); } } throw GraalInternalError.shouldNotReachHere(); diff -r 18c2fd3d7fc7 -r ef52cebd4030 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedScaledInductionVariable.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedScaledInductionVariable.java Mon Feb 09 15:52:17 2015 -0800 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedScaledInductionVariable.java Mon Feb 09 15:55:00 2015 -0800 @@ -22,6 +22,8 @@ */ package com.oracle.graal.loop; +import static com.oracle.graal.loop.MathUtil.*; + import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; @@ -69,12 +71,12 @@ @Override public ValueNode initNode() { - return BinaryArithmeticNode.mul(graph(), base.initNode(), scale); + return mul(graph(), base.initNode(), scale); } @Override public ValueNode strideNode() { - return BinaryArithmeticNode.mul(graph(), base.strideNode(), scale); + return mul(graph(), base.strideNode(), scale); } @Override @@ -99,12 +101,12 @@ @Override public ValueNode extremumNode(boolean assumePositiveTripCount, Stamp stamp) { - return BinaryArithmeticNode.mul(graph(), base.extremumNode(assumePositiveTripCount, stamp), IntegerConvertNode.convert(scale, stamp, graph())); + return mul(graph(), base.extremumNode(assumePositiveTripCount, stamp), IntegerConvertNode.convert(scale, stamp, graph())); } @Override public ValueNode exitValueNode() { - return BinaryArithmeticNode.mul(graph(), base.exitValueNode(), scale); + return mul(graph(), base.exitValueNode(), scale); } @Override diff -r 18c2fd3d7fc7 -r ef52cebd4030 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/MathUtil.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/MathUtil.java Mon Feb 09 15:55:00 2015 -0800 @@ -0,0 +1,76 @@ +/* + * Copyright (c) 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.loop; + +import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; + +/** + * Utility methods to perform integer math with some obvious constant folding first. + */ +public class MathUtil { + private static boolean isConstantOne(ValueNode v1) { + return v1.isConstant() && v1.stamp() instanceof IntegerStamp && v1.asJavaConstant().asLong() == 1; + } + + private static boolean isConstantZero(ValueNode v1) { + return v1.isConstant() && v1.stamp() instanceof IntegerStamp && v1.asJavaConstant().asLong() == 0; + } + + public static ValueNode add(StructuredGraph graph, ValueNode v1, ValueNode v2) { + if (isConstantZero(v1)) { + return v2; + } + if (isConstantZero(v2)) { + return v1; + } + return BinaryArithmeticNode.add(graph, v1, v2); + } + + public static ValueNode mul(StructuredGraph graph, ValueNode v1, ValueNode v2) { + if (isConstantOne(v1)) { + return v2; + } + if (isConstantOne(v2)) { + return v1; + } + return BinaryArithmeticNode.mul(graph, v1, v2); + } + + public static ValueNode sub(StructuredGraph graph, ValueNode v1, ValueNode v2) { + if (isConstantZero(v2)) { + return v1; + } + return BinaryArithmeticNode.sub(graph, v1, v2); + } + + public static ValueNode divBefore(StructuredGraph graph, FixedNode before, ValueNode dividend, ValueNode divisor) { + if (isConstantOne(divisor)) { + return dividend; + } + IntegerDivNode div = graph.add(new IntegerDivNode(dividend, divisor)); + graph.addBeforeFixed(before, div); + return div; + } +}