Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r74394:6b4912d3adb7 Date: 2014-11-07 23:12 +0100 http://bitbucket.org/pypy/pypy/changeset/6b4912d3adb7/
Log: Merge float-opt by Toni Mattis: turn float divisions by a constant power of two into float multiplication diff --git a/rpython/jit/metainterp/optimizeopt/rewrite.py b/rpython/jit/metainterp/optimizeopt/rewrite.py --- a/rpython/jit/metainterp/optimizeopt/rewrite.py +++ b/rpython/jit/metainterp/optimizeopt/rewrite.py @@ -1,7 +1,7 @@ from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.metainterp import compile from rpython.jit.metainterp.history import (Const, ConstInt, BoxInt, BoxFloat, - BoxPtr, make_hashable_int) + BoxPtr, make_hashable_int, ConstFloat) from rpython.jit.metainterp.optimize import InvalidLoop from rpython.jit.metainterp.optimizeopt.intutils import IntBound from rpython.jit.metainterp.optimizeopt.optimizer import (Optimization, REMOVED, @@ -10,7 +10,7 @@ from rpython.jit.metainterp.resoperation import (opboolinvers, opboolreflex, rop, ResOperation) from rpython.rlib.rarithmetic import highest_bit - +import math class OptRewrite(Optimization): """Rewrite operations into equivalent, cheaper operations. @@ -231,6 +231,25 @@ self.emit_operation(op) self.pure(rop.FLOAT_MUL, [arg2, arg1], op.result) + def optimize_FLOAT_TRUEDIV(self, op): + arg1 = op.getarg(0) + arg2 = op.getarg(1) + v2 = self.getvalue(arg2) + + # replace "x / const" by "x * (1/const)" if possible + if v2.is_constant(): + divisor = v2.box.getfloat() + fraction = math.frexp(divisor)[0] + # This optimization is valid for powers of two + # but not for zeroes, some denormals and NaN: + if fraction == 0.5 or fraction == -0.5: + reciprocal = 1.0 / divisor + rfraction = math.frexp(reciprocal)[0] + if rfraction == 0.5 or rfraction == -0.5: + op = op.copy_and_change(rop.FLOAT_MUL, + args=[arg1, ConstFloat(reciprocal)]) + self.emit_operation(op) + def optimize_FLOAT_NEG(self, op): v1 = op.getarg(0) self.emit_operation(op) diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py --- a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -2364,6 +2364,28 @@ """ self.optimize_loop(ops, expected) + def test_float_division_by_multiplication(self): + ops = """ + [f0] + f1 = float_truediv(f0, 2.0) + f2 = float_truediv(f1, 3.0) + f3 = float_truediv(f2, -0.25) + f4 = float_truediv(f3, 0.0) + f5 = escape(f4) + jump(f5) + """ + + expected = """ + [f0] + f1 = float_mul(f0, 0.5) + f2 = float_truediv(f1, 3.0) + f3 = float_mul(f2, -4.0) + f4 = float_truediv(f3, 0.0) + f5 = escape(f4) + jump(f5) + """ + self.optimize_loop(ops, expected) + # ---------- def _verify_fail_args(self, boxes, oparse, text): _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit