From e2bf4f898160203a071aaed30d890e927cd89b67 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Fri, 28 Jul 2017 14:52:24 -0700 Subject: [PATCH] Include bound typevars in the instruction predicate. We already do this for the encoding tables, but the instruction predicates computed by Apply.inst_predicate() did not include them. Make sure we don't duplicate the type check in the Encoding constructor when passed an Apply AST node. --- lib/cretonne/meta/cdsl/ast.py | 9 ++++++++- lib/cretonne/meta/cdsl/isa.py | 19 ++++++++++--------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/lib/cretonne/meta/cdsl/ast.py b/lib/cretonne/meta/cdsl/ast.py index 0a9b5eece4..aa53e7b9b5 100644 --- a/lib/cretonne/meta/cdsl/ast.py +++ b/lib/cretonne/meta/cdsl/ast.py @@ -7,7 +7,7 @@ for patern matching an rewriting of cretonne instructions. from __future__ import absolute_import from . import instructions from .typevar import TypeVar -from .predicates import IsEqual, And +from .predicates import IsEqual, And, TypePredicate try: from typing import Union, Tuple, Sequence, TYPE_CHECKING, Dict, List # noqa @@ -367,6 +367,13 @@ class Apply(Expr): pred = And.combine(pred, IsEqual(ffield, arg)) + # Add checks for any bound type variables. + for bound_ty, tv in zip(self.typevars, self.inst.all_typevars()): + if bound_ty is None: + continue + type_chk = TypePredicate.typevar_check(self.inst, tv, bound_ty) + pred = And.combine(pred, type_chk) + return pred def copy(self, m): diff --git a/lib/cretonne/meta/cdsl/isa.py b/lib/cretonne/meta/cdsl/isa.py index 3e903408ef..3e971e7a5a 100644 --- a/lib/cretonne/meta/cdsl/isa.py +++ b/lib/cretonne/meta/cdsl/isa.py @@ -420,6 +420,16 @@ class Encoding(object): else: self.inst, self.typevars = inst.fully_bound() + # Add secondary type variables to the instruction predicate. + # This is already included by Apply.inst_predicate() above. + if len(self.typevars) > 1: + for tv, vt in zip(self.inst.other_typevars, self.typevars[1:]): + # A None tv is an 'any' wild card: `ishl.i32.any`. + if vt is None: + continue + typred = TypePredicate.typevar_check(self.inst, tv, vt) + instp = And.combine(instp, typred) + self.cpumode = cpumode assert self.inst.format == recipe.format, ( "Format {} must match recipe: {}".format( @@ -433,15 +443,6 @@ class Encoding(object): self.recipe = recipe self.encbits = encbits - # Add secondary type variables to the instruction predicate. - if len(self.typevars) > 1: - for tv, vt in zip(self.inst.other_typevars, self.typevars[1:]): - # A None tv is an 'any' wild card: `ishl.i32.any`. - if vt is None: - continue - typred = TypePredicate.typevar_check(self.inst, tv, vt) - instp = And.combine(instp, typred) - # Record specific predicates. Note that the recipe also has predicates. self.instp = self.cpumode.isa.unique_pred(instp) self.isap = self.cpumode.isa.unique_pred(isap)