diff options
author | Paul Phillips <paulp@improving.org> | 2009-11-07 07:32:22 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2009-11-07 07:32:22 +0000 |
commit | 6fbb22661739840cf163f6dfbce18bf2c79b051e (patch) | |
tree | 3890f532c8a8bac80496042191a09c5fe451bc5a | |
parent | 5084c4d8a12d2645fb4402aa01cc553e89c7c931 (diff) | |
download | scala-6fbb22661739840cf163f6dfbce18bf2c79b051e.tar.gz scala-6fbb22661739840cf163f6dfbce18bf2c79b051e.tar.bz2 scala-6fbb22661739840cf163f6dfbce18bf2c79b051e.zip |
Broke up foldBinOp logic a little bit looking t...
Broke up foldBinOp logic a little bit looking to reduce the likelihood
of inliner pathology. This also knocked about two minutes off my time to
build optimised locker.
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala | 198 |
1 files changed, 99 insertions, 99 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala b/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala index c3447d9efe..e8bb4581f1 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala @@ -46,7 +46,7 @@ abstract class ConstantFolder { else tree } catch { case _: ArithmeticException => tree // the code will crash at runtime, - // but that is better than the + // but that is better than the // compiler itself crashing } @@ -69,111 +69,111 @@ abstract class ConstantFolder { case _ => null } - private def foldBinop(op: Name, x: Constant, y: Constant): Constant = try { + /** These are local helpers to keep foldBinop from overly taxing the + * optimizer. + */ + private def foldBooleanOp(op: Name, x: Constant, y: Constant): Constant = op match { + case nme.ZOR => Constant(x.booleanValue | y.booleanValue) + case nme.OR => Constant(x.booleanValue | y.booleanValue) + case nme.XOR => Constant(x.booleanValue ^ y.booleanValue) + case nme.ZAND => Constant(x.booleanValue & y.booleanValue) + case nme.AND => Constant(x.booleanValue & y.booleanValue) + case nme.EQ => Constant(x.booleanValue == y.booleanValue) + case nme.NE => Constant(x.booleanValue != y.booleanValue) + case _ => null + } + private def foldSubrangeOp(op: Name, x: Constant, y: Constant): Constant = op match { + case nme.OR => Constant(x.intValue | y.intValue) + case nme.XOR => Constant(x.intValue ^ y.intValue) + case nme.AND => Constant(x.intValue & y.intValue) + case nme.LSL => Constant(x.intValue << y.intValue) + case nme.LSR => Constant(x.intValue >>> y.intValue) + case nme.ASR => Constant(x.intValue >> y.intValue) + case nme.EQ => Constant(x.intValue == y.intValue) + case nme.NE => Constant(x.intValue != y.intValue) + case nme.LT => Constant(x.intValue < y.intValue) + case nme.GT => Constant(x.intValue > y.intValue) + case nme.LE => Constant(x.intValue <= y.intValue) + case nme.GE => Constant(x.intValue >= y.intValue) + case nme.ADD => Constant(x.intValue + y.intValue) + case nme.SUB => Constant(x.intValue - y.intValue) + case nme.MUL => Constant(x.intValue * y.intValue) + case nme.DIV => Constant(x.intValue / y.intValue) + case nme.MOD => Constant(x.intValue % y.intValue) + case _ => null + } + private def foldLongOp(op: Name, x: Constant, y: Constant): Constant = op match { + case nme.OR => Constant(x.longValue | y.longValue) + case nme.XOR => Constant(x.longValue ^ y.longValue) + case nme.AND => Constant(x.longValue & y.longValue) + case nme.LSL => Constant(x.longValue << y.longValue) + case nme.LSR => Constant(x.longValue >>> y.longValue) + case nme.ASR => Constant(x.longValue >> y.longValue) + case nme.EQ => Constant(x.longValue == y.longValue) + case nme.NE => Constant(x.longValue != y.longValue) + case nme.LT => Constant(x.longValue < y.longValue) + case nme.GT => Constant(x.longValue > y.longValue) + case nme.LE => Constant(x.longValue <= y.longValue) + case nme.GE => Constant(x.longValue >= y.longValue) + case nme.ADD => Constant(x.longValue + y.longValue) + case nme.SUB => Constant(x.longValue - y.longValue) + case nme.MUL => Constant(x.longValue * y.longValue) + case nme.DIV => Constant(x.longValue / y.longValue) + case nme.MOD => Constant(x.longValue % y.longValue) + case _ => null + } + private def foldFloatOp(op: Name, x: Constant, y: Constant): Constant = op match { + case nme.EQ => Constant(x.floatValue == y.floatValue) + case nme.NE => Constant(x.floatValue != y.floatValue) + case nme.LT => Constant(x.floatValue < y.floatValue) + case nme.GT => Constant(x.floatValue > y.floatValue) + case nme.LE => Constant(x.floatValue <= y.floatValue) + case nme.GE => Constant(x.floatValue >= y.floatValue) + case nme.ADD => Constant(x.floatValue + y.floatValue) + case nme.SUB => Constant(x.floatValue - y.floatValue) + case nme.MUL => Constant(x.floatValue * y.floatValue) + case nme.DIV => Constant(x.floatValue / y.floatValue) + case nme.MOD => Constant(x.floatValue % y.floatValue) + case _ => null + } + private def foldDoubleOp(op: Name, x: Constant, y: Constant): Constant = op match { + case nme.EQ => Constant(x.doubleValue == y.doubleValue) + case nme.NE => Constant(x.doubleValue != y.doubleValue) + case nme.LT => Constant(x.doubleValue < y.doubleValue) + case nme.GT => Constant(x.doubleValue > y.doubleValue) + case nme.LE => Constant(x.doubleValue <= y.doubleValue) + case nme.GE => Constant(x.doubleValue >= y.doubleValue) + case nme.ADD => Constant(x.doubleValue + y.doubleValue) + case nme.SUB => Constant(x.doubleValue - y.doubleValue) + case nme.MUL => Constant(x.doubleValue * y.doubleValue) + case nme.DIV => Constant(x.doubleValue / y.doubleValue) + case nme.MOD => Constant(x.doubleValue % y.doubleValue) + case _ => null + } + + private def foldBinop(op: Name, x: Constant, y: Constant): Constant = { // temporarily logging folded ==/!= so the log doesn't have unexplained absences // Careful, these four lines added 3 minutes to the time to compile this file under -optimise // if ((op == nme.EQ || op == nme.NE) && x.tag != y.tag && settings.logEqEq.value) { // val opstr = if (op == nme.EQ) "==" else "!=" // scala.runtime.Equality.log("Folding constant expression (%s %s %s)".format(x.value, opstr, y.value)) // } + val optag = + if (x.tag == y.tag) x.tag + else if (isNumeric(x.tag) && isNumeric(y.tag)) Math.max(x.tag, y.tag) + else NoTag - val optag = if (x.tag == y.tag) x.tag - else if (isNumeric(x.tag) && isNumeric(y.tag)) - if (x.tag > y.tag) x.tag else y.tag - else NoTag - optag match { - case BooleanTag => - op match { - case nme.ZOR => Constant(x.booleanValue | y.booleanValue) - case nme.OR => Constant(x.booleanValue | y.booleanValue) - case nme.XOR => Constant(x.booleanValue ^ y.booleanValue) - case nme.ZAND => Constant(x.booleanValue & y.booleanValue) - case nme.AND => Constant(x.booleanValue & y.booleanValue) - case nme.EQ => Constant(x.booleanValue == y.booleanValue) - case nme.NE => Constant(x.booleanValue != y.booleanValue) - case _ => null - } - case ByteTag | ShortTag | CharTag | IntTag => - op match { - case nme.OR => Constant(x.intValue | y.intValue) - case nme.XOR => Constant(x.intValue ^ y.intValue) - case nme.AND => Constant(x.intValue & y.intValue) - case nme.LSL => Constant(x.intValue << y.intValue) - case nme.LSR => Constant(x.intValue >>> y.intValue) - case nme.ASR => Constant(x.intValue >> y.intValue) - case nme.EQ => Constant(x.intValue == y.intValue) - case nme.NE => Constant(x.intValue != y.intValue) - case nme.LT => Constant(x.intValue < y.intValue) - case nme.GT => Constant(x.intValue > y.intValue) - case nme.LE => Constant(x.intValue <= y.intValue) - case nme.GE => Constant(x.intValue >= y.intValue) - case nme.ADD => Constant(x.intValue + y.intValue) - case nme.SUB => Constant(x.intValue - y.intValue) - case nme.MUL => Constant(x.intValue * y.intValue) - case nme.DIV => Constant(x.intValue / y.intValue) - case nme.MOD => Constant(x.intValue % y.intValue) - case _ => null - } - case LongTag => - op match { - case nme.OR => Constant(x.longValue | y.longValue) - case nme.XOR => Constant(x.longValue ^ y.longValue) - case nme.AND => Constant(x.longValue & y.longValue) - case nme.LSL => Constant(x.longValue << y.longValue) - case nme.LSR => Constant(x.longValue >>> y.longValue) - case nme.ASR => Constant(x.longValue >> y.longValue) - case nme.EQ => Constant(x.longValue == y.longValue) - case nme.NE => Constant(x.longValue != y.longValue) - case nme.LT => Constant(x.longValue < y.longValue) - case nme.GT => Constant(x.longValue > y.longValue) - case nme.LE => Constant(x.longValue <= y.longValue) - case nme.GE => Constant(x.longValue >= y.longValue) - case nme.ADD => Constant(x.longValue + y.longValue) - case nme.SUB => Constant(x.longValue - y.longValue) - case nme.MUL => Constant(x.longValue * y.longValue) - case nme.DIV => Constant(x.longValue / y.longValue) - case nme.MOD => Constant(x.longValue % y.longValue) - case _ => null - } - case FloatTag => - op match { - case nme.EQ => Constant(x.floatValue == y.floatValue) - case nme.NE => Constant(x.floatValue != y.floatValue) - case nme.LT => Constant(x.floatValue < y.floatValue) - case nme.GT => Constant(x.floatValue > y.floatValue) - case nme.LE => Constant(x.floatValue <= y.floatValue) - case nme.GE => Constant(x.floatValue >= y.floatValue) - case nme.ADD => Constant(x.floatValue + y.floatValue) - case nme.SUB => Constant(x.floatValue - y.floatValue) - case nme.MUL => Constant(x.floatValue * y.floatValue) - case nme.DIV => Constant(x.floatValue / y.floatValue) - case nme.MOD => Constant(x.floatValue % y.floatValue) - case _ => null - } - case DoubleTag => - op match { - case nme.EQ => Constant(x.doubleValue == y.doubleValue) - case nme.NE => Constant(x.doubleValue != y.doubleValue) - case nme.LT => Constant(x.doubleValue < y.doubleValue) - case nme.GT => Constant(x.doubleValue > y.doubleValue) - case nme.LE => Constant(x.doubleValue <= y.doubleValue) - case nme.GE => Constant(x.doubleValue >= y.doubleValue) - case nme.ADD => Constant(x.doubleValue + y.doubleValue) - case nme.SUB => Constant(x.doubleValue - y.doubleValue) - case nme.MUL => Constant(x.doubleValue * y.doubleValue) - case nme.DIV => Constant(x.doubleValue / y.doubleValue) - case nme.MOD => Constant(x.doubleValue % y.doubleValue) - case _ => null - } - case StringTag => - op match { - case nme.ADD => Constant(x.stringValue + y.stringValue) - case _ => null - } - case _ => - null + try optag match { + case BooleanTag => foldBooleanOp(op, x, y) + case ByteTag | ShortTag | CharTag | IntTag => foldSubrangeOp(op, x, y) + case LongTag => foldLongOp(op, x, y) + case FloatTag => foldFloatOp(op, x, y) + case DoubleTag => foldDoubleOp(op, x, y) + case StringTag if op == nme.ADD => Constant(x.stringValue + y.stringValue) + case _ => null + } + catch { + case ex: ArithmeticException => null } - } catch { - case ex: ArithmeticException => null } } |