From fcc1c8a43728ac9c9d3cd144d034e4925ec5bbcc Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Mon, 25 Apr 2016 12:23:38 -0700 Subject: [PATCH] nir/algebraic: Add a mechanism for specifying the bit size of a value Reviewed-by: Iago Toral Quiroga --- src/compiler/nir/nir_algebraic.py | 29 +++++++++++++++++++++++++---- src/compiler/nir/nir_opt_algebraic.py | 4 ++++ src/compiler/nir/nir_search.h | 2 ++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/compiler/nir/nir_algebraic.py b/src/compiler/nir/nir_algebraic.py index 565bee581be..35f659774a8 100644 --- a/src/compiler/nir/nir_algebraic.py +++ b/src/compiler/nir/nir_algebraic.py @@ -25,6 +25,7 @@ # Jason Ekstrand (jason@jlekstrand.net) from __future__ import print_function +import ast import itertools import struct import sys @@ -63,7 +64,7 @@ class Value(object): __template = mako.template.Template(""" static const ${val.c_type} ${val.name} = { - { ${val.type_enum} }, + { ${val.type_enum}, ${val.bit_size} }, % if isinstance(val, Constant): ${val.type()}, { ${hex(val)} /* ${val.value} */ }, % elif isinstance(val, Variable): @@ -99,10 +100,23 @@ static const ${val.c_type} ${val.name} = { Variable=Variable, Expression=Expression) +_constant_re = re.compile(r"(?P[^@]+)(?:@(?P\d+))?") + class Constant(Value): def __init__(self, val, name): Value.__init__(self, name, "constant") - self.value = val + + if isinstance(val, (str)): + m = _constant_re.match(val) + self.value = ast.literal_eval(m.group('value')) + self.bit_size = int(m.group('bits')) if m.group('bits') else 0 + else: + self.value = val + self.bit_size = 0 + + if isinstance(self.value, bool): + assert self.bit_size == 0 or self.bit_size == 32 + self.bit_size = 32 def __hex__(self): if isinstance(self.value, (bool)): @@ -122,7 +136,8 @@ class Constant(Value): elif isinstance(self.value, float): return "nir_type_float" -_var_name_re = re.compile(r"(?P#)?(?P\w+)(?:@(?P\w+))?") +_var_name_re = re.compile(r"(?P#)?(?P\w+)" + r"(?:@(?Pint|uint|bool|float)?(?P\d+)?)?") class Variable(Value): def __init__(self, val, name, varset): @@ -134,6 +149,11 @@ class Variable(Value): self.var_name = m.group('name') self.is_constant = m.group('const') is not None self.required_type = m.group('type') + self.bit_size = int(m.group('bits')) if m.group('bits') else 0 + + if self.required_type == 'bool': + assert self.bit_size == 0 or self.bit_size == 32 + self.bit_size = 32 if self.required_type is not None: assert self.required_type in ('float', 'bool', 'int', 'uint') @@ -148,7 +168,7 @@ class Variable(Value): elif self.required_type == 'float': return "nir_type_float" -_opcode_re = re.compile(r"(?P~)?(?P\w+)") +_opcode_re = re.compile(r"(?P~)?(?P\w+)(?:@(?P\d+))?") class Expression(Value): def __init__(self, expr, name_base, varset): @@ -159,6 +179,7 @@ class Expression(Value): assert m and m.group('opcode') is not None self.opcode = m.group('opcode') + self.bit_size = int(m.group('bits')) if m.group('bits') else 0 self.inexact = m.group('inexact') is not None self.sources = [ Value.create(src, "{0}_{1}".format(name_base, i), varset) for (i, src) in enumerate(expr[1:]) ] diff --git a/src/compiler/nir/nir_opt_algebraic.py b/src/compiler/nir/nir_opt_algebraic.py index 8f08e6b1341..fa7d7c7e96f 100644 --- a/src/compiler/nir/nir_opt_algebraic.py +++ b/src/compiler/nir/nir_opt_algebraic.py @@ -53,6 +53,10 @@ d = 'd' # For constants, you have to be careful to make sure that it is the right # type because python is unaware of the source and destination types of the # opcodes. +# +# All expression types can have a bit-size specified. For opcodes, this +# looks like "op@32", for variables it is "a@32" or "a@uint32" to specify a +# type and size, and for literals, you can write "2.0@32". optimizations = [ (('fneg', ('fneg', a)), a), diff --git a/src/compiler/nir/nir_search.h b/src/compiler/nir/nir_search.h index 61742f129b1..c49eba76dec 100644 --- a/src/compiler/nir/nir_search.h +++ b/src/compiler/nir/nir_search.h @@ -40,6 +40,8 @@ typedef enum { typedef struct { nir_search_value_type type; + + unsigned bit_size; } nir_search_value; typedef struct { -- 2.11.0