From 5c9a12f101e9d6288bcc2576172cebaefd7a0f9f Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Thu, 10 Nov 2016 14:46:42 -0800 Subject: [PATCH] Add TypeVar.rust_expr(). Generate a Rust expression that computes the value of a derived type variable. --- lib/cretonne/meta/cdsl/ast.py | 10 +++++ lib/cretonne/meta/cdsl/test_typevar.py | 8 +++- lib/cretonne/meta/cdsl/typevar.py | 56 +++++++++++++++++--------- lib/cretonne/meta/gen_instr.py | 3 +- 4 files changed, 55 insertions(+), 22 deletions(-) diff --git a/lib/cretonne/meta/cdsl/ast.py b/lib/cretonne/meta/cdsl/ast.py index d8b3b7b875..8db7352333 100644 --- a/lib/cretonne/meta/cdsl/ast.py +++ b/lib/cretonne/meta/cdsl/ast.py @@ -197,6 +197,16 @@ class Var(Expr): return False return self.typevar is self.original_typevar + def rust_type(self): + # type: () -> str + """ + Get a Rust expression that computes the type of this variable. + + It is assumed that local variables exist corresponding to the free type + variables. + """ + return self.typevar.rust_expr() + def constrain_typevar(self, sym_typevar, sym_ctrl, ctrl_var): # type: (TypeVar, TypeVar, Var) -> None """ diff --git a/lib/cretonne/meta/cdsl/test_typevar.py b/lib/cretonne/meta/cdsl/test_typevar.py index 7dae18221a..29db26f583 100644 --- a/lib/cretonne/meta/cdsl/test_typevar.py +++ b/lib/cretonne/meta/cdsl/test_typevar.py @@ -57,10 +57,14 @@ class TestTypeVar(TestCase): x2 = TypeVar('x2', 'i16 and up', ints=(16, 64)) with self.assertRaises(AssertionError): x2.double_width() - self.assertEqual(str(x2.half_width()), '`HalfWidth(x2)`') + self.assertEqual(str(x2.half_width()), '`half_width(x2)`') + self.assertEqual(x2.half_width().rust_expr(), 'x2.half_width()') + self.assertEqual( + x2.half_width().double_width().rust_expr(), + 'x2.half_width().double_width()') x3 = TypeVar('x3', 'up to i32', ints=(8, 32)) - self.assertEqual(str(x3.double_width()), '`DoubleWidth(x3)`') + self.assertEqual(str(x3.double_width()), '`double_width(x3)`') with self.assertRaises(AssertionError): x3.half_width() diff --git a/lib/cretonne/meta/cdsl/typevar.py b/lib/cretonne/meta/cdsl/typevar.py index 30986c5db8..d14866cf77 100644 --- a/lib/cretonne/meta/cdsl/typevar.py +++ b/lib/cretonne/meta/cdsl/typevar.py @@ -312,11 +312,14 @@ class TypeVar(object): return self is other # Supported functions for derived type variables. - SAMEAS = 'SameAs' - LANEOF = 'LaneOf' - ASBOOL = 'AsBool' - HALFWIDTH = 'HalfWidth' - DOUBLEWIDTH = 'DoubleWidth' + # The names here must match the method names on `ir::types::Type`. + # The camel_case of the names must match `enum OperandConstraint` in + # `instructions.rs`. + SAMEAS = 'same_as' + LANEOF = 'lane_of' + ASBOOL = 'as_bool' + HALFWIDTH = 'half_width' + DOUBLEWIDTH = 'double_width' @staticmethod def derived(base, derived_func): @@ -370,13 +373,14 @@ class TypeVar(object): Return a derived type variable that has the same number of vector lanes as this one, but the lanes are half the width. """ - ts = self.type_set - if ts.min_int: - assert ts.min_int > 8, "Can't halve all integer types" - if ts.min_float: - assert ts.min_float > 32, "Can't halve all float types" - if ts.min_bool: - assert ts.min_bool > 8, "Can't halve all boolean types" + if not self.is_derived: + ts = self.type_set + if ts.min_int: + assert ts.min_int > 8, "Can't halve all integer types" + if ts.min_float: + assert ts.min_float > 32, "Can't halve all float types" + if ts.min_bool: + assert ts.min_bool > 8, "Can't halve all boolean types" return TypeVar.derived(self, self.HALFWIDTH) @@ -386,13 +390,14 @@ class TypeVar(object): Return a derived type variable that has the same number of vector lanes as this one, but the lanes are double the width. """ - ts = self.type_set - if ts.max_int: - assert ts.max_int < MAX_BITS, "Can't double all integer types." - if ts.max_float: - assert ts.max_float < MAX_BITS, "Can't double all float types." - if ts.max_bool: - assert ts.max_bool < MAX_BITS, "Can't double all boolean types." + if not self.is_derived: + ts = self.type_set + if ts.max_int: + assert ts.max_int < MAX_BITS, "Can't double all integer types." + if ts.max_float: + assert ts.max_float < MAX_BITS, "Can't double all float types." + if ts.max_bool: + assert ts.max_bool < MAX_BITS, "Can't double all bool types." return TypeVar.derived(self, self.DOUBLEWIDTH) @@ -409,6 +414,19 @@ class TypeVar(object): else: return self + def rust_expr(self): + # type: () -> str + """ + Get a Rust expression that computes the type of this type variable. + """ + if self.is_derived: + return '{}.{}()'.format( + self.base.rust_expr(), self.derived_func) + elif self.singleton_type: + return self.singleton_type.rust_name() + else: + return self.name + def constrain_types(self, other): # type: (TypeVar) -> None """ diff --git a/lib/cretonne/meta/gen_instr.py b/lib/cretonne/meta/gen_instr.py index 4f240ab6b1..11aaa4fa0d 100644 --- a/lib/cretonne/meta/gen_instr.py +++ b/lib/cretonne/meta/gen_instr.py @@ -5,6 +5,7 @@ from __future__ import absolute_import import srcgen import constant_hash from unique_table import UniqueTable, UniqueSeqTable +from cdsl import camel_case from cdsl.operands import ImmediateKind import cdsl.types from cdsl.formats import InstructionFormat @@ -330,7 +331,7 @@ def get_constraint(op, ctrl_typevar, type_sets): if tv.is_derived: assert tv.base is ctrl_typevar, "Not derived from ctrl_typevar" - return tv.derived_func + return camel_case(tv.derived_func) assert tv is ctrl_typevar return 'Same'