# HG changeset patch # User Roland Schatz # Date 1412081103 -7200 # Node ID fa3637e235b129f3b1ec9e18cf96d12fa4ac0a1f # Parent 5b7b1cb838e97e6e7c373df81b0661b4846ff8fd Make ArithmeticOpTable fields final. diff -r 5b7b1cb838e9 -r fa3637e235b1 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ArithmeticOpTable.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ArithmeticOpTable.java Tue Sep 30 12:15:13 2014 +0200 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ArithmeticOpTable.java Tue Sep 30 14:45:03 2014 +0200 @@ -23,24 +23,25 @@ package com.oracle.graal.compiler.common.type; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; /** * Information about arithmetic operations. */ public final class ArithmeticOpTable { - protected UnaryOp neg; - protected BinaryOp add; - protected BinaryOp sub; + private final UnaryOp neg; + private final BinaryOp add; + private final BinaryOp sub; - protected BinaryOp mul; - protected BinaryOp div; - protected BinaryOp rem; + private final BinaryOp mul; + private final BinaryOp div; + private final BinaryOp rem; - protected UnaryOp not; - protected BinaryOp and; - protected BinaryOp or; - protected BinaryOp xor; + private final UnaryOp not; + private final BinaryOp and; + private final BinaryOp or; + private final BinaryOp xor; public static ArithmeticOpTable forStamp(Stamp s) { if (s instanceof ArithmeticStamp) { @@ -50,7 +51,97 @@ } } - public static final ArithmeticOpTable EMPTY = new ArithmeticOpTable(); + public static final ArithmeticOpTable EMPTY = create(); + + public static ArithmeticOpTable create(Op... ops) { + UnaryOp neg = null; + BinaryOp add = null; + BinaryOp sub = null; + + BinaryOp mul = null; + BinaryOp div = null; + BinaryOp rem = null; + + UnaryOp not = null; + BinaryOp and = null; + BinaryOp or = null; + BinaryOp xor = null; + + for (Op op : ops) { + if (op == null) { + continue; + } + + if (op instanceof UnaryOp) { + UnaryOp unary = (UnaryOp) op; + switch (unary.getOperator()) { + case '-': + assert neg == null; + neg = unary; + break; + case '~': + assert not == null; + not = unary; + break; + default: + throw GraalInternalError.shouldNotReachHere("unknown unary operator " + unary.getOperator()); + } + } else { + BinaryOp binary = (BinaryOp) op; + switch (binary.getOperator()) { + case '+': + assert add == null; + add = binary; + break; + case '-': + assert sub == null; + sub = binary; + break; + case '*': + assert mul == null; + mul = binary; + break; + case '/': + assert div == null; + div = binary; + break; + case '%': + assert rem == null; + rem = binary; + break; + case '&': + assert and == null; + and = binary; + break; + case '|': + assert or == null; + or = binary; + break; + case '^': + assert xor == null; + xor = binary; + break; + default: + throw GraalInternalError.shouldNotReachHere("unknown binary operator " + binary.getOperator()); + } + } + } + + return new ArithmeticOpTable(neg, add, sub, mul, div, rem, not, and, or, xor); + } + + private ArithmeticOpTable(UnaryOp neg, BinaryOp add, BinaryOp sub, BinaryOp mul, BinaryOp div, BinaryOp rem, UnaryOp not, BinaryOp and, BinaryOp or, BinaryOp xor) { + this.neg = neg; + this.add = add; + this.sub = sub; + this.mul = mul; + this.div = div; + this.rem = rem; + this.not = not; + this.and = and; + this.or = or; + this.xor = xor; + } /** * Describes the unary negation operation. @@ -122,10 +213,32 @@ return xor; } + public abstract static class Op { + + private final char operator; + + protected Op(char operator) { + this.operator = operator; + } + + public char getOperator() { + return operator; + } + + @Override + public String toString() { + return Character.toString(operator); + } + } + /** * Describes a unary arithmetic operation. */ - public abstract static class UnaryOp { + public abstract static class UnaryOp extends Op { + + protected UnaryOp(char operation) { + super(operation); + } /** * Apply the operation to a {@link Constant}. @@ -141,12 +254,13 @@ /** * Describes a binary arithmetic operation. */ - public abstract static class BinaryOp { + public abstract static class BinaryOp extends Op { private final boolean associative; private final boolean commutative; - protected BinaryOp(boolean associative, boolean commutative) { + protected BinaryOp(char operation, boolean associative, boolean commutative) { + super(operation); this.associative = associative; this.commutative = commutative; } diff -r 5b7b1cb838e9 -r fa3637e235b1 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/FloatStamp.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/FloatStamp.java Tue Sep 30 12:15:13 2014 +0200 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/FloatStamp.java Tue Sep 30 14:45:03 2014 +0200 @@ -252,188 +252,184 @@ return null; } - private static final ArithmeticOpTable OPS = new ArithmeticOpTable(); + private static final ArithmeticOpTable OPS = ArithmeticOpTable.create( - static { - OPS.neg = new UnaryOp() { + new UnaryOp('-') { - @Override - public Constant foldConstant(Constant value) { - switch (value.getKind()) { - case Float: - return Constant.forFloat(-value.asFloat()); - case Double: - return Constant.forDouble(-value.asDouble()); - default: - throw GraalInternalError.shouldNotReachHere(); - } - } - - @Override - public Stamp foldStamp(Stamp s) { - FloatStamp stamp = (FloatStamp) s; - return new FloatStamp(stamp.getBits(), -stamp.upperBound(), -stamp.lowerBound(), stamp.isNonNaN()); + @Override + public Constant foldConstant(Constant value) { + switch (value.getKind()) { + case Float: + return Constant.forFloat(-value.asFloat()); + case Double: + return Constant.forDouble(-value.asDouble()); + default: + throw GraalInternalError.shouldNotReachHere(); } - }; + } - OPS.add = new BinaryOp(false, true) { + @Override + public Stamp foldStamp(Stamp s) { + FloatStamp stamp = (FloatStamp) s; + return new FloatStamp(stamp.getBits(), -stamp.upperBound(), -stamp.lowerBound(), stamp.isNonNaN()); + } + }, + + new BinaryOp('+', false, true) { - @Override - public Constant foldConstant(Constant a, Constant b) { - assert a.getKind() == b.getKind(); - switch (a.getKind()) { - case Float: - return Constant.forFloat(a.asFloat() + b.asFloat()); - case Double: - return Constant.forDouble(a.asDouble() + b.asDouble()); - default: - throw GraalInternalError.shouldNotReachHere(); - } + @Override + public Constant foldConstant(Constant a, Constant b) { + assert a.getKind() == b.getKind(); + switch (a.getKind()) { + case Float: + return Constant.forFloat(a.asFloat() + b.asFloat()); + case Double: + return Constant.forDouble(a.asDouble() + b.asDouble()); + default: + throw GraalInternalError.shouldNotReachHere(); } + } - @Override - public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { - // TODO - return stamp1.unrestricted(); - } + @Override + public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { + // TODO + return stamp1.unrestricted(); + } - @Override - public boolean isNeutral(Constant n) { - switch (n.getKind()) { - case Float: - return Float.compare(n.asFloat(), -0.0f) == 0; - case Double: - return Double.compare(n.asDouble(), -0.0) == 0; - default: - throw GraalInternalError.shouldNotReachHere(); - } + @Override + public boolean isNeutral(Constant n) { + switch (n.getKind()) { + case Float: + return Float.compare(n.asFloat(), -0.0f) == 0; + case Double: + return Double.compare(n.asDouble(), -0.0) == 0; + default: + throw GraalInternalError.shouldNotReachHere(); } - }; + } + }, - OPS.sub = new BinaryOp(false, false) { + new BinaryOp('-', false, false) { - @Override - public Constant foldConstant(Constant a, Constant b) { - assert a.getKind() == b.getKind(); - switch (a.getKind()) { - case Float: - return Constant.forFloat(a.asFloat() - b.asFloat()); - case Double: - return Constant.forDouble(a.asDouble() - b.asDouble()); - default: - throw GraalInternalError.shouldNotReachHere(); - } + @Override + public Constant foldConstant(Constant a, Constant b) { + assert a.getKind() == b.getKind(); + switch (a.getKind()) { + case Float: + return Constant.forFloat(a.asFloat() - b.asFloat()); + case Double: + return Constant.forDouble(a.asDouble() - b.asDouble()); + default: + throw GraalInternalError.shouldNotReachHere(); } + } - @Override - public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { - // TODO - return stamp1.unrestricted(); - } + @Override + public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { + // TODO + return stamp1.unrestricted(); + } - @Override - public boolean isNeutral(Constant n) { - switch (n.getKind()) { - case Float: - return Float.compare(n.asFloat(), 0.0f) == 0; - case Double: - return Double.compare(n.asDouble(), 0.0) == 0; - default: - throw GraalInternalError.shouldNotReachHere(); - } + @Override + public boolean isNeutral(Constant n) { + switch (n.getKind()) { + case Float: + return Float.compare(n.asFloat(), 0.0f) == 0; + case Double: + return Double.compare(n.asDouble(), 0.0) == 0; + default: + throw GraalInternalError.shouldNotReachHere(); } - }; + } + }, - OPS.mul = new BinaryOp(false, true) { + new BinaryOp('*', false, true) { - @Override - public Constant foldConstant(Constant a, Constant b) { - assert a.getKind() == b.getKind(); - switch (a.getKind()) { - case Float: - return Constant.forFloat(a.asFloat() * b.asFloat()); - case Double: - return Constant.forDouble(a.asDouble() * b.asDouble()); - default: - throw GraalInternalError.shouldNotReachHere(); - } + @Override + public Constant foldConstant(Constant a, Constant b) { + assert a.getKind() == b.getKind(); + switch (a.getKind()) { + case Float: + return Constant.forFloat(a.asFloat() * b.asFloat()); + case Double: + return Constant.forDouble(a.asDouble() * b.asDouble()); + default: + throw GraalInternalError.shouldNotReachHere(); } + } - @Override - public Stamp foldStamp(Stamp a, Stamp b) { - // TODO - return a.unrestricted(); - } + @Override + public Stamp foldStamp(Stamp a, Stamp b) { + // TODO + return a.unrestricted(); + } - @Override - public boolean isNeutral(Constant n) { - switch (n.getKind()) { - case Float: - return Float.compare(n.asFloat(), 1.0f) == 0; - case Double: - return Double.compare(n.asDouble(), 1.0) == 0; - default: - throw GraalInternalError.shouldNotReachHere(); - } + @Override + public boolean isNeutral(Constant n) { + switch (n.getKind()) { + case Float: + return Float.compare(n.asFloat(), 1.0f) == 0; + case Double: + return Double.compare(n.asDouble(), 1.0) == 0; + default: + throw GraalInternalError.shouldNotReachHere(); } + } + }, - // there is no multiplicative zero, since both 0.0 and -0.0 can flip sign - }; - - OPS.div = new BinaryOp(false, false) { + new BinaryOp('/', false, false) { - @Override - public Constant foldConstant(Constant a, Constant b) { - assert a.getKind() == b.getKind(); - switch (a.getKind()) { - case Float: - return Constant.forFloat(a.asFloat() / b.asFloat()); - case Double: - return Constant.forDouble(a.asDouble() / b.asDouble()); - default: - throw GraalInternalError.shouldNotReachHere(); - } + @Override + public Constant foldConstant(Constant a, Constant b) { + assert a.getKind() == b.getKind(); + switch (a.getKind()) { + case Float: + return Constant.forFloat(a.asFloat() / b.asFloat()); + case Double: + return Constant.forDouble(a.asDouble() / b.asDouble()); + default: + throw GraalInternalError.shouldNotReachHere(); } + } - @Override - public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { - // TODO - return stamp1.unrestricted(); - } + @Override + public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { + // TODO + return stamp1.unrestricted(); + } - @Override - public boolean isNeutral(Constant n) { - switch (n.getKind()) { - case Float: - return Float.compare(n.asFloat(), 1.0f) == 0; - case Double: - return Double.compare(n.asDouble(), 1.0) == 0; - default: - throw GraalInternalError.shouldNotReachHere(); - } + @Override + public boolean isNeutral(Constant n) { + switch (n.getKind()) { + case Float: + return Float.compare(n.asFloat(), 1.0f) == 0; + case Double: + return Double.compare(n.asDouble(), 1.0) == 0; + default: + throw GraalInternalError.shouldNotReachHere(); } - }; + } + }, - OPS.rem = new BinaryOp(false, false) { + new BinaryOp('%', false, false) { - @Override - public Constant foldConstant(Constant a, Constant b) { - assert a.getKind() == b.getKind(); - switch (a.getKind()) { - case Float: - return Constant.forFloat(a.asFloat() % b.asFloat()); - case Double: - return Constant.forDouble(a.asDouble() % b.asDouble()); - default: - throw GraalInternalError.shouldNotReachHere(); - } + @Override + public Constant foldConstant(Constant a, Constant b) { + assert a.getKind() == b.getKind(); + switch (a.getKind()) { + case Float: + return Constant.forFloat(a.asFloat() % b.asFloat()); + case Double: + return Constant.forDouble(a.asDouble() % b.asDouble()); + default: + throw GraalInternalError.shouldNotReachHere(); } + } - @Override - public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { - // TODO - return stamp1.unrestricted(); - } - }; - } + @Override + public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { + // TODO + return stamp1.unrestricted(); + } + }); } diff -r 5b7b1cb838e9 -r fa3637e235b1 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java Tue Sep 30 12:15:13 2014 +0200 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java Tue Sep 30 14:45:03 2014 +0200 @@ -350,290 +350,288 @@ return (x + y) ^ x ^ y; } - public static final ArithmeticOpTable OPS = new ArithmeticOpTable(); + public static final ArithmeticOpTable OPS = ArithmeticOpTable.create( - static { - OPS.neg = new UnaryOp() { + new UnaryOp('-') { - @Override - public Constant foldConstant(Constant value) { - return Constant.forIntegerKind(value.getKind(), -value.asLong()); - } + @Override + public Constant foldConstant(Constant value) { + return Constant.forIntegerKind(value.getKind(), -value.asLong()); + } - @Override - public Stamp foldStamp(Stamp s) { - IntegerStamp stamp = (IntegerStamp) s; - int bits = stamp.getBits(); - if (stamp.lowerBound() != CodeUtil.minValue(bits)) { - // TODO(ls) check if the mask calculation is correct... - return StampFactory.forInteger(bits, -stamp.upperBound(), -stamp.lowerBound()); - } else { - return stamp.unrestricted(); - } + @Override + public Stamp foldStamp(Stamp s) { + IntegerStamp stamp = (IntegerStamp) s; + int bits = stamp.getBits(); + if (stamp.lowerBound() != CodeUtil.minValue(bits)) { + // TODO(ls) check if the mask calculation is correct... + return StampFactory.forInteger(bits, -stamp.upperBound(), -stamp.lowerBound()); + } else { + return stamp.unrestricted(); } - }; + } + }, - OPS.add = new BinaryOp(true, true) { + new BinaryOp('+', true, true) { - @Override - public Constant foldConstant(Constant a, Constant b) { - assert a.getKind() == b.getKind(); - return Constant.forIntegerKind(a.getKind(), a.asLong() + b.asLong()); - } + @Override + public Constant foldConstant(Constant a, Constant b) { + assert a.getKind() == b.getKind(); + return Constant.forIntegerKind(a.getKind(), a.asLong() + b.asLong()); + } - @Override - public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { - IntegerStamp a = (IntegerStamp) stamp1; - IntegerStamp b = (IntegerStamp) stamp2; + @Override + public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { + IntegerStamp a = (IntegerStamp) stamp1; + IntegerStamp b = (IntegerStamp) stamp2; - int bits = a.getBits(); - assert bits == b.getBits(); + int bits = a.getBits(); + assert bits == b.getBits(); - if (a.isUnrestricted()) { - return a; - } else if (b.isUnrestricted()) { - return b; - } - long defaultMask = CodeUtil.mask(bits); - long variableBits = (a.downMask() ^ a.upMask()) | (b.downMask() ^ b.upMask()); - long variableBitsWithCarry = variableBits | (carryBits(a.downMask(), b.downMask()) ^ carryBits(a.upMask(), b.upMask())); - long newDownMask = (a.downMask() + b.downMask()) & ~variableBitsWithCarry; - long newUpMask = (a.downMask() + b.downMask()) | variableBitsWithCarry; + if (a.isUnrestricted()) { + return a; + } else if (b.isUnrestricted()) { + return b; + } + long defaultMask = CodeUtil.mask(bits); + long variableBits = (a.downMask() ^ a.upMask()) | (b.downMask() ^ b.upMask()); + long variableBitsWithCarry = variableBits | (carryBits(a.downMask(), b.downMask()) ^ carryBits(a.upMask(), b.upMask())); + long newDownMask = (a.downMask() + b.downMask()) & ~variableBitsWithCarry; + long newUpMask = (a.downMask() + b.downMask()) | variableBitsWithCarry; - newDownMask &= defaultMask; - newUpMask &= defaultMask; + newDownMask &= defaultMask; + newUpMask &= defaultMask; - long newLowerBound; - long newUpperBound; - boolean lowerOverflowsPositively = addOverflowsPositively(a.lowerBound(), b.lowerBound(), bits); - boolean upperOverflowsPositively = addOverflowsPositively(a.upperBound(), b.upperBound(), bits); - boolean lowerOverflowsNegatively = addOverflowsNegatively(a.lowerBound(), b.lowerBound(), bits); - boolean upperOverflowsNegatively = addOverflowsNegatively(a.upperBound(), b.upperBound(), bits); - if ((lowerOverflowsNegatively && !upperOverflowsNegatively) || (!lowerOverflowsPositively && upperOverflowsPositively)) { - newLowerBound = CodeUtil.minValue(bits); - newUpperBound = CodeUtil.maxValue(bits); - } else { - newLowerBound = CodeUtil.signExtend((a.lowerBound() + b.lowerBound()) & defaultMask, bits); - newUpperBound = CodeUtil.signExtend((a.upperBound() + b.upperBound()) & defaultMask, bits); - } - IntegerStamp limit = StampFactory.forInteger(bits, newLowerBound, newUpperBound); - newUpMask &= limit.upMask(); - newUpperBound = CodeUtil.signExtend(newUpperBound & newUpMask, bits); - newDownMask |= limit.downMask(); - newLowerBound |= newDownMask; - return new IntegerStamp(bits, newLowerBound, newUpperBound, newDownMask, newUpMask); - } - - @Override - public boolean isNeutral(Constant n) { - return n.asLong() == 0; - } - }; - - OPS.sub = new BinaryOp(true, false) { - - @Override - public Constant foldConstant(Constant a, Constant b) { - assert a.getKind() == b.getKind(); - return Constant.forIntegerKind(a.getKind(), a.asLong() - b.asLong()); - } - - @Override - public Stamp foldStamp(Stamp a, Stamp b) { - return OPS.add.foldStamp(a, OPS.neg.foldStamp(b)); - } - - @Override - public boolean isNeutral(Constant n) { - return n.asLong() == 0; + long newLowerBound; + long newUpperBound; + boolean lowerOverflowsPositively = addOverflowsPositively(a.lowerBound(), b.lowerBound(), bits); + boolean upperOverflowsPositively = addOverflowsPositively(a.upperBound(), b.upperBound(), bits); + boolean lowerOverflowsNegatively = addOverflowsNegatively(a.lowerBound(), b.lowerBound(), bits); + boolean upperOverflowsNegatively = addOverflowsNegatively(a.upperBound(), b.upperBound(), bits); + if ((lowerOverflowsNegatively && !upperOverflowsNegatively) || (!lowerOverflowsPositively && upperOverflowsPositively)) { + newLowerBound = CodeUtil.minValue(bits); + newUpperBound = CodeUtil.maxValue(bits); + } else { + newLowerBound = CodeUtil.signExtend((a.lowerBound() + b.lowerBound()) & defaultMask, bits); + newUpperBound = CodeUtil.signExtend((a.upperBound() + b.upperBound()) & defaultMask, bits); } + IntegerStamp limit = StampFactory.forInteger(bits, newLowerBound, newUpperBound); + newUpMask &= limit.upMask(); + newUpperBound = CodeUtil.signExtend(newUpperBound & newUpMask, bits); + newDownMask |= limit.downMask(); + newLowerBound |= newDownMask; + return new IntegerStamp(bits, newLowerBound, newUpperBound, newDownMask, newUpMask); + } - @Override - public Constant getZero(Stamp s) { - IntegerStamp stamp = (IntegerStamp) s; - return Constant.forPrimitiveInt(stamp.getBits(), 0); - } - }; + @Override + public boolean isNeutral(Constant n) { + return n.asLong() == 0; + } + }, + + new BinaryOp('-', true, false) { - OPS.mul = new BinaryOp(true, true) { + @Override + public Constant foldConstant(Constant a, Constant b) { + assert a.getKind() == b.getKind(); + return Constant.forIntegerKind(a.getKind(), a.asLong() - b.asLong()); + } - @Override - public Constant foldConstant(Constant a, Constant b) { - assert a.getKind() == b.getKind(); - return Constant.forIntegerKind(a.getKind(), a.asLong() * b.asLong()); - } + @Override + public Stamp foldStamp(Stamp a, Stamp b) { + return OPS.getAdd().foldStamp(a, OPS.getNeg().foldStamp(b)); + } + + @Override + public boolean isNeutral(Constant n) { + return n.asLong() == 0; + } - @Override - public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { - IntegerStamp a = (IntegerStamp) stamp1; - IntegerStamp b = (IntegerStamp) stamp2; - if (a.upMask() == 0) { - return a; - } else if (b.upMask() == 0) { - return b; - } else { - // TODO - return a.unrestricted(); - } - } + @Override + public Constant getZero(Stamp s) { + IntegerStamp stamp = (IntegerStamp) s; + return Constant.forPrimitiveInt(stamp.getBits(), 0); + } + }, + + new BinaryOp('*', true, true) { + + @Override + public Constant foldConstant(Constant a, Constant b) { + assert a.getKind() == b.getKind(); + return Constant.forIntegerKind(a.getKind(), a.asLong() * b.asLong()); + } - @Override - public boolean isNeutral(Constant n) { - return n.asLong() == 1; + @Override + public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { + IntegerStamp a = (IntegerStamp) stamp1; + IntegerStamp b = (IntegerStamp) stamp2; + if (a.upMask() == 0) { + return a; + } else if (b.upMask() == 0) { + return b; + } else { + // TODO + return a.unrestricted(); } - }; + } - OPS.div = new BinaryOp(true, false) { + @Override + public boolean isNeutral(Constant n) { + return n.asLong() == 1; + } + }, - @Override - public Constant foldConstant(Constant a, Constant b) { - assert a.getKind() == b.getKind(); - return Constant.forIntegerKind(a.getKind(), a.asLong() / b.asLong()); - } + new BinaryOp('/', true, false) { + + @Override + public Constant foldConstant(Constant a, Constant b) { + assert a.getKind() == b.getKind(); + return Constant.forIntegerKind(a.getKind(), a.asLong() / b.asLong()); + } - @Override - public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { - IntegerStamp a = (IntegerStamp) stamp1; - IntegerStamp b = (IntegerStamp) stamp2; - assert a.getBits() == b.getBits(); - if (b.isStrictlyPositive()) { - long newLowerBound = a.lowerBound() / b.lowerBound(); - long newUpperBound = a.upperBound() / b.lowerBound(); - return StampFactory.forInteger(a.getBits(), newLowerBound, newUpperBound); - } else { - return a.unrestricted(); - } + @Override + public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { + IntegerStamp a = (IntegerStamp) stamp1; + IntegerStamp b = (IntegerStamp) stamp2; + assert a.getBits() == b.getBits(); + if (b.isStrictlyPositive()) { + long newLowerBound = a.lowerBound() / b.lowerBound(); + long newUpperBound = a.upperBound() / b.lowerBound(); + return StampFactory.forInteger(a.getBits(), newLowerBound, newUpperBound); + } else { + return a.unrestricted(); } + } - @Override - public boolean isNeutral(Constant n) { - return n.asLong() == 1; - } - }; + @Override + public boolean isNeutral(Constant n) { + return n.asLong() == 1; + } + }, - OPS.rem = new BinaryOp(false, false) { + new BinaryOp('%', false, false) { - @Override - public Constant foldConstant(Constant a, Constant b) { - assert a.getKind() == b.getKind(); - return Constant.forIntegerKind(a.getKind(), a.asLong() % b.asLong()); - } + @Override + public Constant foldConstant(Constant a, Constant b) { + assert a.getKind() == b.getKind(); + return Constant.forIntegerKind(a.getKind(), a.asLong() % b.asLong()); + } - @Override - public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { - IntegerStamp a = (IntegerStamp) stamp1; - IntegerStamp b = (IntegerStamp) stamp2; - assert a.getBits() == b.getBits(); - // zero is always possible - long newLowerBound = Math.min(a.lowerBound(), 0); - long newUpperBound = Math.max(a.upperBound(), 0); + @Override + public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { + IntegerStamp a = (IntegerStamp) stamp1; + IntegerStamp b = (IntegerStamp) stamp2; + assert a.getBits() == b.getBits(); + // zero is always possible + long newLowerBound = Math.min(a.lowerBound(), 0); + long newUpperBound = Math.max(a.upperBound(), 0); - long magnitude; // the maximum absolute value of the result, derived from b - if (b.lowerBound() == CodeUtil.minValue(b.getBits())) { - // Math.abs(...) - 1 does not work in a case - magnitude = CodeUtil.maxValue(b.getBits()); - } else { - magnitude = Math.max(Math.abs(b.lowerBound()), Math.abs(b.upperBound())) - 1; - } - newLowerBound = Math.max(newLowerBound, -magnitude); - newUpperBound = Math.min(newUpperBound, magnitude); + long magnitude; // the maximum absolute value of the result, derived from b + if (b.lowerBound() == CodeUtil.minValue(b.getBits())) { + // Math.abs(...) - 1 does not work in a case + magnitude = CodeUtil.maxValue(b.getBits()); + } else { + magnitude = Math.max(Math.abs(b.lowerBound()), Math.abs(b.upperBound())) - 1; + } + newLowerBound = Math.max(newLowerBound, -magnitude); + newUpperBound = Math.min(newUpperBound, magnitude); - return StampFactory.forInteger(a.getBits(), newLowerBound, newUpperBound); - } - }; + return StampFactory.forInteger(a.getBits(), newLowerBound, newUpperBound); + } + }, - OPS.not = new UnaryOp() { + new UnaryOp('~') { - @Override - public Constant foldConstant(Constant value) { - return Constant.forIntegerKind(value.getKind(), ~value.asLong()); - } + @Override + public Constant foldConstant(Constant value) { + return Constant.forIntegerKind(value.getKind(), ~value.asLong()); + } - @Override - public Stamp foldStamp(Stamp stamp) { - IntegerStamp integerStamp = (IntegerStamp) stamp; - int bits = integerStamp.getBits(); - long defaultMask = CodeUtil.mask(bits); - return new IntegerStamp(bits, ~integerStamp.upperBound(), ~integerStamp.lowerBound(), (~integerStamp.upMask()) & defaultMask, (~integerStamp.downMask()) & defaultMask); - } - }; + @Override + public Stamp foldStamp(Stamp stamp) { + IntegerStamp integerStamp = (IntegerStamp) stamp; + int bits = integerStamp.getBits(); + long defaultMask = CodeUtil.mask(bits); + return new IntegerStamp(bits, ~integerStamp.upperBound(), ~integerStamp.lowerBound(), (~integerStamp.upMask()) & defaultMask, (~integerStamp.downMask()) & defaultMask); + } + }, - OPS.and = new BinaryOp(true, true) { + new BinaryOp('&', true, true) { - @Override - public Constant foldConstant(Constant a, Constant b) { - assert a.getKind() == b.getKind(); - return Constant.forIntegerKind(a.getKind(), a.asLong() & b.asLong()); - } + @Override + public Constant foldConstant(Constant a, Constant b) { + assert a.getKind() == b.getKind(); + return Constant.forIntegerKind(a.getKind(), a.asLong() & b.asLong()); + } - @Override - public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { - IntegerStamp a = (IntegerStamp) stamp1; - IntegerStamp b = (IntegerStamp) stamp2; - assert a.getBits() == b.getBits(); - return stampForMask(a.getBits(), a.downMask() & b.downMask(), a.upMask() & b.upMask()); - } + @Override + public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { + IntegerStamp a = (IntegerStamp) stamp1; + IntegerStamp b = (IntegerStamp) stamp2; + assert a.getBits() == b.getBits(); + return stampForMask(a.getBits(), a.downMask() & b.downMask(), a.upMask() & b.upMask()); + } - @Override - public boolean isNeutral(Constant n) { - int bits = n.getKind().getBitCount(); - long mask = CodeUtil.mask(bits); - return (n.asLong() & mask) == mask; - } - }; + @Override + public boolean isNeutral(Constant n) { + int bits = n.getKind().getBitCount(); + long mask = CodeUtil.mask(bits); + return (n.asLong() & mask) == mask; + } + }, - OPS.or = new BinaryOp(true, true) { + new BinaryOp('|', true, true) { - @Override - public Constant foldConstant(Constant a, Constant b) { - assert a.getKind() == b.getKind(); - return Constant.forIntegerKind(a.getKind(), a.asLong() | b.asLong()); - } + @Override + public Constant foldConstant(Constant a, Constant b) { + assert a.getKind() == b.getKind(); + return Constant.forIntegerKind(a.getKind(), a.asLong() | b.asLong()); + } - @Override - public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { - IntegerStamp a = (IntegerStamp) stamp1; - IntegerStamp b = (IntegerStamp) stamp2; - assert a.getBits() == b.getBits(); - return stampForMask(a.getBits(), a.downMask() | b.downMask(), a.upMask() | b.upMask()); - } + @Override + public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { + IntegerStamp a = (IntegerStamp) stamp1; + IntegerStamp b = (IntegerStamp) stamp2; + assert a.getBits() == b.getBits(); + return stampForMask(a.getBits(), a.downMask() | b.downMask(), a.upMask() | b.upMask()); + } - @Override - public boolean isNeutral(Constant n) { - return n.asLong() == 0; - } - }; - - OPS.xor = new BinaryOp(true, true) { + @Override + public boolean isNeutral(Constant n) { + return n.asLong() == 0; + } + }, - @Override - public Constant foldConstant(Constant a, Constant b) { - assert a.getKind() == b.getKind(); - return Constant.forIntegerKind(a.getKind(), a.asLong() ^ b.asLong()); - } + new BinaryOp('^', true, true) { - @Override - public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { - IntegerStamp a = (IntegerStamp) stamp1; - IntegerStamp b = (IntegerStamp) stamp2; - assert a.getBits() == b.getBits(); + @Override + public Constant foldConstant(Constant a, Constant b) { + assert a.getKind() == b.getKind(); + return Constant.forIntegerKind(a.getKind(), a.asLong() ^ b.asLong()); + } - long variableBits = (a.downMask() ^ a.upMask()) | (b.downMask() ^ b.upMask()); - long newDownMask = (a.downMask() ^ b.downMask()) & ~variableBits; - long newUpMask = (a.downMask() ^ b.downMask()) | variableBits; - return stampForMask(a.getBits(), newDownMask, newUpMask); - } + @Override + public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { + IntegerStamp a = (IntegerStamp) stamp1; + IntegerStamp b = (IntegerStamp) stamp2; + assert a.getBits() == b.getBits(); + + long variableBits = (a.downMask() ^ a.upMask()) | (b.downMask() ^ b.upMask()); + long newDownMask = (a.downMask() ^ b.downMask()) & ~variableBits; + long newUpMask = (a.downMask() ^ b.downMask()) | variableBits; + return stampForMask(a.getBits(), newDownMask, newUpMask); + } - @Override - public boolean isNeutral(Constant n) { - return n.asLong() == 0; - } + @Override + public boolean isNeutral(Constant n) { + return n.asLong() == 0; + } - @Override - public Constant getZero(Stamp s) { - IntegerStamp stamp = (IntegerStamp) s; - return Constant.forPrimitiveInt(stamp.getBits(), 0); - } - }; - } + @Override + public Constant getZero(Stamp s) { + IntegerStamp stamp = (IntegerStamp) s; + return Constant.forPrimitiveInt(stamp.getBits(), 0); + } + }); }