Mercurial > hg > truffle
changeset 21448:545cd6b3b377
Make ShiftNode narrowable under certain conditions.
author | Roland Schatz <roland.schatz@oracle.com> |
---|---|
date | Thu, 21 May 2015 13:25:44 +0200 |
parents | f172a195a8a9 |
children | 006d8ddb7ef9 |
files | graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowableArithmeticNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ShiftNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java |
diffstat | 4 files changed, 57 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowableArithmeticNode.java Thu May 07 14:47:27 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowableArithmeticNode.java Thu May 21 13:25:44 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -28,4 +28,14 @@ * result. */ public interface NarrowableArithmeticNode { + + /** + * Check whether this operation can be narrowed to {@code resultBits} bit without loss of + * precision. + * + * @param resultBits + */ + default boolean isNarrowable(int resultBits) { + return true; + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java Thu May 07 14:47:27 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java Thu May 21 13:25:44 2015 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.graal.nodes.calc; +import com.oracle.graal.api.code.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.compiler.common.type.ArithmeticOpTable.ShiftOp.Shr; import com.oracle.graal.graph.*; @@ -98,4 +99,19 @@ public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) { builder.setResult(this, gen.emitShr(builder.operand(getX()), builder.operand(getY()))); } + + @Override + public boolean isNarrowable(int resultBits) { + if (super.isNarrowable(resultBits)) { + /* + * For signed right shifts, the narrow can be done before the shift if the cut off bits + * are all equal to the sign bit of the input. That's equivalent to the condition that + * the input is in the signed range of the narrow type. + */ + IntegerStamp inputStamp = (IntegerStamp) getX().stamp(); + return CodeUtil.minValue(resultBits) <= inputStamp.lowerBound() && inputStamp.upperBound() <= CodeUtil.maxValue(resultBits); + } else { + return false; + } + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ShiftNode.java Thu May 07 14:47:27 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ShiftNode.java Thu May 21 13:25:44 2015 +0200 @@ -25,6 +25,7 @@ import java.io.*; import java.util.function.*; +import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.compiler.common.type.ArithmeticOpTable.ShiftOp; @@ -38,7 +39,7 @@ * The {@code ShiftOp} class represents shift operations. */ @NodeInfo -public abstract class ShiftNode<OP> extends BinaryNode implements ArithmeticLIRLowerable { +public abstract class ShiftNode<OP> extends BinaryNode implements ArithmeticLIRLowerable, NarrowableArithmeticNode { @SuppressWarnings("rawtypes") public static final NodeClass<ShiftNode> TYPE = NodeClass.create(ShiftNode.class); @@ -82,4 +83,18 @@ return getOp(getX()).getShiftAmountMask(stamp()); } + public boolean isNarrowable(int resultBits) { + assert CodeUtil.isPowerOf2(resultBits); + int narrowMask = resultBits - 1; + int wideMask = getShiftAmountMask(); + assert (wideMask & narrowMask) == narrowMask : String.format("wideMask %x should be wider than narrowMask %x", wideMask, narrowMask); + + /* + * Shifts are special because narrowing them also changes the implicit mask of the shift + * amount. We can narrow only if (y & wideMask) == (y & narrowMask) for all possible values + * of y. + */ + IntegerStamp yStamp = (IntegerStamp) getY().stamp(); + return (yStamp.upMask() & (wideMask & ~narrowMask)) == 0; + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java Thu May 07 14:47:27 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java Thu May 21 13:25:44 2015 +0200 @@ -87,4 +87,18 @@ public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) { builder.setResult(this, gen.emitUShr(builder.operand(getX()), builder.operand(getY()))); } + + @Override + public boolean isNarrowable(int resultBits) { + if (super.isNarrowable(resultBits)) { + /* + * For unsigned right shifts, the narrow can be done before the shift if the cut off + * bits are all zero. + */ + IntegerStamp inputStamp = (IntegerStamp) getX().stamp(); + return (inputStamp.upMask() & ~(resultBits - 1)) == 0; + } else { + return false; + } + } }