%PDF- %PDF-
Direktori : /lib/python3/dist-packages/pythran/optimizations/ |
Current File : //lib/python3/dist-packages/pythran/optimizations/range_based_simplify.py |
''' Simplify expressions based on range information when possible''' from pythran.analyses import RangeValues from pythran.passmanager import Transformation import gast as ast from math import isinf from copy import deepcopy class RangeBasedSimplify(Transformation): ''' Simplify expressions based on range analysis >>> import gast as ast >>> from pythran import passmanager, backend >>> node = ast.parse("def any():\\n for x in builtins.range(10): y=x%8") >>> pm = passmanager.PassManager("test") >>> _, node = pm.apply(RangeBasedSimplify, node) >>> print(pm.dump(backend.Python, node)) def any(): for x in builtins.range(10): y = (x if (x < 8) else (x - 8)) >>> node = ast.parse("def any(): x = 1 or 2; return 3 == x") >>> pm = passmanager.PassManager("test") >>> _, node = pm.apply(RangeBasedSimplify, node) >>> print(pm.dump(backend.Python, node)) def any(): x = (1 or 2) return 0 >>> node = ast.parse("def a(i): x = 1,1,2; return x[2], x[0 if i else 1]") >>> pm = passmanager.PassManager("test") >>> _, node = pm.apply(RangeBasedSimplify, node) >>> print(pm.dump(backend.Python, node)) def a(i): x = (1, 1, 2) return (2, 1) ''' def __init__(self): Transformation.__init__(self, RangeValues) def visit_OMPDirective(self, node): return node def visit_BinOp(self, node): node = self.generic_visit(node) if not isinstance(node.op, ast.Mod): return node right_range = self.range_values[node.right] left_range = self.range_values[node.left] if right_range.low < 0 or isinf(right_range.high): return node if left_range.low < -right_range.low: return node if left_range.high > right_range.high * 2: return node cleft0, cleft1 = deepcopy(node.left), deepcopy(node.left) cright = deepcopy(node.right) self.update = True return ast.IfExp(ast.Compare(node.left, [ast.Lt()], [node.right]), cleft0, ast.BinOp(cleft1, ast.Sub(), cright)) def visit_range(self, node): range_value = self.range_values[node] if isinf(range_value.high): return self.generic_visit(node) elif range_value.low == range_value.high: self.update = True return ast.Constant(range_value.low, None) else: return self.generic_visit(node) visit_Compare = visit_range def visit_Name(self, node): if isinstance(node.ctx, ast.Load): return self.visit_range(node) return self.generic_visit(node) visit_Subscript = visit_Name