From d6eb2b023a432ed6d7097c70f8416133b054ef86 Mon Sep 17 00:00:00 2001 From: whitequark Date: Thu, 7 Feb 2019 06:07:55 +0000 Subject: [PATCH] compiler: monomorphize casts first, but more carefully. This reverts 425cd7851, which broke the use of casts to define integer width. Instead of it, two steps are taken: * First, literals are monomorphized, leading to predictable result. * Second, casts are monomorphized, in a top-bottom way. I.e. consider the expression `int64(round(x))`. If round() was visited first, the intermediate precision would be 32-bit, which is clearly undesirable. Therefore, contextual rules should take priority over non-contextual ones. Fixes #1252. --- .../compiler/transforms/cast_monomorphizer.py | 19 +++++++++++++++++-- .../compiler/transforms/int_monomorphizer.py | 19 ------------------- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/artiq/compiler/transforms/cast_monomorphizer.py b/artiq/compiler/transforms/cast_monomorphizer.py index 8e373ab1e..c0935ff1f 100644 --- a/artiq/compiler/transforms/cast_monomorphizer.py +++ b/artiq/compiler/transforms/cast_monomorphizer.py @@ -11,8 +11,6 @@ class CastMonomorphizer(algorithm.Visitor): self.engine = engine def visit_CallT(self, node): - self.generic_visit(node) - if (types.is_builtin(node.func.type, "int") or types.is_builtin(node.func.type, "int32") or types.is_builtin(node.func.type, "int64")): @@ -30,3 +28,20 @@ class CastMonomorphizer(algorithm.Visitor): node.args[0].type.unify(typ) + if types.is_builtin(node.func.type, "int") or \ + types.is_builtin(node.func.type, "round"): + typ = node.type.find() + if types.is_var(typ["width"]): + typ["width"].unify(types.TValue(32)) + + self.generic_visit(node) + + def visit_CoerceT(self, node): + if isinstance(node.value, asttyped.NumT) and \ + builtins.is_int(node.type) and \ + builtins.is_int(node.value.type) and \ + not types.is_var(node.type["width"]) and \ + types.is_var(node.value.type["width"]): + node.value.type.unify(node.type) + + self.generic_visit(node) diff --git a/artiq/compiler/transforms/int_monomorphizer.py b/artiq/compiler/transforms/int_monomorphizer.py index 5002bb086..adab3b165 100644 --- a/artiq/compiler/transforms/int_monomorphizer.py +++ b/artiq/compiler/transforms/int_monomorphizer.py @@ -26,22 +26,3 @@ class IntMonomorphizer(algorithm.Visitor): return node.type["width"].unify(types.TValue(width)) - - def visit_CallT(self, node): - self.generic_visit(node) - - if types.is_builtin(node.func.type, "int") or \ - types.is_builtin(node.func.type, "round"): - typ = node.type.find() - if types.is_var(typ["width"]): - typ["width"].unify(types.TValue(32)) - - def visit_CoerceT(self, node): - if isinstance(node.value, asttyped.NumT) and \ - builtins.is_int(node.type) and \ - builtins.is_int(node.value.type) and \ - not types.is_var(node.type["width"]) and \ - types.is_var(node.value.type["width"]): - node.value.type.unify(node.type) - - self.generic_visit(node)