Generate type numbers at meta-time.

We need to generate hash tables keyed by types, so the Python scripts need to
know the index used to represent types in Rust code.

To enforce this, add a new gen_types.py script which generates constant
definitions for the ir/types module.

Also generate constants for common SIMD vector sizes.
This commit is contained in:
Jakob Stoklund Olesen
2016-08-26 12:43:38 -07:00
parent 4b72d0e64d
commit 747dd508df
4 changed files with 80 additions and 36 deletions

View File

@@ -5,6 +5,7 @@
from __future__ import absolute_import
import argparse
import isa
import gen_types
import gen_instr
import gen_settings
import gen_build_deps
@@ -18,6 +19,7 @@ out_dir = args.out_dir
isas = isa.all_isas()
gen_types.generate(out_dir)
gen_instr.generate(isas, out_dir)
gen_settings.generate(isas, out_dir)
gen_encoding.generate(isas, out_dir)

View File

@@ -6,6 +6,7 @@ instructions.
"""
from __future__ import absolute_import
import re
import math
import importlib
from collections import namedtuple
from .predicates import And
@@ -279,9 +280,12 @@ class ValueType(object):
or one of its subclasses.
"""
# map name -> ValueType.
# Map name -> ValueType.
_registry = dict()
# List of all the scalar types.
all_scalars = list()
def __init__(self, name, membytes, doc):
self.name = name
self.membytes = membytes
@@ -321,6 +325,10 @@ class ScalarType(ValueType):
def __init__(self, name, membytes, doc):
super(ScalarType, self).__init__(name, membytes, doc)
self._vectors = dict()
# Assign numbers starting from 1. (0 is VOID).
ValueType.all_scalars.append(self)
self.number = len(ValueType.all_scalars)
assert self.number < 16, 'Too many scalar types'
def __repr__(self):
return 'ScalarType({})'.format(self.name)
@@ -356,10 +364,11 @@ class VectorType(ValueType):
name='{}x{}'.format(base.name, lanes),
membytes=lanes*base.membytes,
doc="""
A SIMD vector with {} lanes containing a {} each.
A SIMD vector with {} lanes containing a `{}` each.
""".format(lanes, base.name))
self.base = base
self.lanes = lanes
self.number = 16*int(math.log(lanes, 2)) + base.number
def __repr__(self):
return ('VectorType(base={}, lanes={})'
@@ -386,8 +395,10 @@ class FloatType(ScalarType):
def __init__(self, bits, doc):
assert bits > 0, 'FloatType must have positive number of bits'
super(FloatType, self).__init__(name='f{:d}'.format(bits),
membytes=bits // 8, doc=doc)
super(FloatType, self).__init__(
name='f{:d}'.format(bits),
membytes=bits // 8,
doc=doc)
self.bits = bits
def __repr__(self):

51
meta/gen_types.py Normal file
View File

@@ -0,0 +1,51 @@
"""
Generate sources with type info.
This generates a `types.rs` file which is included in
`libcretonne/ir/types/rs`. The file provides constant definitions for the most
commonly used types, including all of the scalar types.
This ensures that Python and Rust use the same type numbering.
"""
from __future__ import absolute_import
import srcgen
from cretonne import ValueType
def emit_type(ty, fmt):
"""
Emit a constant definition of a single value type.
"""
name = ty.name.upper()
fmt.doc_comment(ty.__doc__)
fmt.line(
'pub const {}: Type = Type({:#x});'
.format(name, ty.number))
def emit_vectors(bits, fmt):
"""
Emit definition for all vector types with `bits` total size.
"""
size = bits // 8
for ty in ValueType.all_scalars:
mb = ty.membytes
if mb == 0 or mb >= size:
continue
emit_type(ty.by(size // mb), fmt)
def emit_types(fmt):
for ty in ValueType.all_scalars:
emit_type(ty, fmt)
# Emit vector definitions for common SIMD sizes.
emit_vectors(64, fmt)
emit_vectors(128, fmt)
emit_vectors(256, fmt)
emit_vectors(512, fmt)
def generate(out_dir):
fmt = srcgen.Formatter()
emit_types(fmt)
fmt.update_file('types.rs', out_dir)