From 85a4643cb0c031d91fed3868ca8e7734ea9577cd Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Fri, 12 Nov 2010 20:08:01 +0100 Subject: [PATCH] enable constant folding for UnaryMinusNode --- Cython/Compiler/Optimize.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/Cython/Compiler/Optimize.py b/Cython/Compiler/Optimize.py index 1039053a..80f05b49 100644 --- a/Cython/Compiler/Optimize.py +++ b/Cython/Compiler/Optimize.py @@ -2865,6 +2865,17 @@ class ConstantFolding(Visitor.VisitorTransform, SkipDeclarations): """Calculate the result of constant expressions to store it in ``expr_node.constant_result``, and replace trivial cases by their constant result. + + General rules: + + - We calculate float constants to make them available to the + compiler, but we do not aggregate them into a single literal + node to prevent any loss of precision. + + - We recursively calculate constants from non-literal nodes to + make them available to the compiler, but we only aggregate + literal nodes at each step. Non-literal nodes are never merged + into a single node. """ def _calculate_const(self, node): if node.constant_result is not ExprNodes.constant_value_not_set: @@ -2911,6 +2922,27 @@ class ConstantFolding(Visitor.VisitorTransform, SkipDeclarations): self._calculate_const(node) return node + def visit_UnaryMinusNode(self, node): + self._calculate_const(node) + if node.constant_result is ExprNodes.not_a_constant: + return node + if not node.operand.is_literal: + return node + if isinstance(node.operand, ExprNodes.LongNode): + return ExprNodes.LongNode(node.pos, value = '-' + node.operand.value, + constant_result = node.constant_result) + if isinstance(node.operand, ExprNodes.FloatNode): + # this is a safe operation + return ExprNodes.FloatNode(node.pos, value = '-' + node.operand.value, + constant_result = node.constant_result) + node_type = node.operand.type + if node_type.is_int and node_type.signed or \ + isinstance(node.operand, ExprNodes.IntNode) and node_type.is_pyobject: + return ExprNodes.IntNode(node.pos, value = '-' + node.operand.value, + type = node_type, + constant_result = node.constant_result) + return node + def visit_BoolBinopNode(self, node): self._calculate_const(node) if node.constant_result is ExprNodes.not_a_constant: -- 2.26.2