Add a TypeDocumenter for Cretonne types.

Use the autodoc Sphinx module to add a .. autoctontype:: directive which
generates documentation for one of the types in the cretonne.types module.
This commit is contained in:
Jakob Olesen
2016-02-08 18:21:58 -08:00
parent c459c11a5a
commit 19b4facbe0
4 changed files with 87 additions and 50 deletions

View File

@@ -13,6 +13,7 @@
import re import re
from docutils import nodes from docutils import nodes
from docutils.parsers.rst import directives
from sphinx import addnodes from sphinx import addnodes
from sphinx.directives import ObjectDescription from sphinx.directives import ObjectDescription
@@ -22,6 +23,8 @@ from sphinx.roles import XRefRole
from sphinx.util.docfields import Field, GroupedField, TypedField from sphinx.util.docfields import Field, GroupedField, TypedField
from sphinx.util.nodes import make_refnode from sphinx.util.nodes import make_refnode
import sphinx.ext.autodoc
class CtonObject(ObjectDescription): class CtonObject(ObjectDescription):
""" """
Any kind of Cretonne IL object. Any kind of Cretonne IL object.
@@ -29,6 +32,11 @@ class CtonObject(ObjectDescription):
This is a shared base class for the different kinds of indexable objects This is a shared base class for the different kinds of indexable objects
in the Cretonne IL reference. in the Cretonne IL reference.
""" """
option_spec = {
'noindex': directives.flag,
'module': directives.unchanged,
'annotation': directives.unchanged,
}
def add_target_and_index(self, name, sig, signode): def add_target_and_index(self, name, sig, signode):
""" """
@@ -209,7 +217,33 @@ class CretonneDomain(Domain):
make_refnode(builder, fromdocname, obj[0], make_refnode(builder, fromdocname, obj[0],
obj[1] + '-' + target, contnode, target))] obj[1] + '-' + target, contnode, target))]
class TypeDocumenter(sphinx.ext.autodoc.Documenter):
# Invoke with .. autoctontype::
objtype = 'ctontype'
# Convert into cton:type directives
domain = 'cton'
directivetype = 'type'
@classmethod
def can_document_member(cls, member, membername, isattr, parent):
return False
def resolve_name(self, modname, parents, path, base):
return 'cretonne.types', [ base ]
def add_content(self, more_content, no_docstring=False):
super(TypeDocumenter, self).add_content(more_content, no_docstring)
sourcename = self.get_sourcename()
membytes = self.object.membytes
if membytes:
self.add_line(u':bytes: {}'.format(membytes), sourcename)
else:
self.add_line(u':bytes: Can\'t be stored in memory', sourcename)
def setup(app): def setup(app):
app.add_domain(CretonneDomain) app.add_domain(CretonneDomain)
app.add_autodocumenter(TypeDocumenter)
return { 'version' : '0.1' } return { 'version' : '0.1' }

View File

@@ -87,10 +87,7 @@ All SSA values have a type which determines the size and shape (for SIMD
vectors) of the value. Many instructions are polymorphic -- they can operate on vectors) of the value. Many instructions are polymorphic -- they can operate on
different types. different types.
.. type:: bool .. autoctontype:: bool
A boolean value that is either true or false. Booleans can't be stored in
memory.
Integer types Integer types
------------- -------------
@@ -99,21 +96,10 @@ Integer values have a fixed size and can be interpreted as either signed or
unsigned. Some instructions will interpret an operand as a signed or unsigned unsigned. Some instructions will interpret an operand as a signed or unsigned
number, others don't care. number, others don't care.
.. type:: i8 .. autoctontype:: i8
.. autoctontype:: i16
A 8-bit integer value taking up 1 byte in memory. .. autoctontype:: i32
.. autoctontype:: i64
.. type:: i16
A 16-bit integer value taking up 2 bytes in memory.
.. type:: i32
A 32-bit integer value taking up 4 bytes in memory.
.. type:: i64
A 64-bit integer value taking up 8 bytes in memory.
Floating point types Floating point types
-------------------- --------------------
@@ -122,17 +108,8 @@ The floating point types have the IEEE semantics that are supported by most
hardware. There is no support for higher-precision types like quads or hardware. There is no support for higher-precision types like quads or
double-double formats. double-double formats.
.. type:: f32 .. autoctontype:: f32
.. autoctontype:: f64
A 32-bit floating point type represented in the IEEE 754 *single precision*
format. This corresponds to the :c:type:`float` type in most C
implementations.
.. type:: f64
A 64-bit floating point type represented in the IEEE 754 *double precision*
format. This corresponds to the :c:type:`double` type in most C
implementations.
SIMD vector types SIMD vector types
----------------- -----------------
@@ -201,7 +178,7 @@ in this reference.
.. type:: fB .. type:: fB
Either of the floating point scalar types: :type:`f32` or :type:`f64. Either of the floating point scalar types: :type:`f32` or :type:`f64`.
.. type:: Float .. type:: Float

View File

@@ -12,6 +12,11 @@ instructions.
class Type(object): class Type(object):
"""A concrete value type.""" """A concrete value type."""
def __init__(self, name, membytes, doc):
self.name = name
self.membytes = membytes
self.__doc__ = doc
def __str__(self): def __str__(self):
return self.name return self.name
@@ -19,12 +24,12 @@ class ScalarType(Type):
""" """
A concrete scalar (not vector) type. A concrete scalar (not vector) type.
Also tracks a unique set of :class:`VectorType` instances with this type as Also tracks a unique set of :py:class:`VectorType` instances with this type
the lane type. as the lane type.
""" """
def __init__(self, name): def __init__(self, name, membytes, doc):
self.name = name super(ScalarType, self).__init__(name, membytes, doc)
self._vectors = dict() self._vectors = dict()
def __repr__(self): def __repr__(self):
@@ -53,9 +58,14 @@ class VectorType(Type):
def __init__(self, base, lanes): def __init__(self, base, lanes):
assert isinstance(base, ScalarType), 'SIMD lanes must be scalar types' assert isinstance(base, ScalarType), 'SIMD lanes must be scalar types'
super(VectorType, self).__init__(
name='{}x{}'.format(base.name, lanes),
membytes=lanes*base.membytes,
doc="""
A SIMD vector with {} lanes containing a {} each.
""".format(lanes, base.name))
self.base = base self.base = base
self.lanes = lanes self.lanes = lanes
self.name = '{}x{}'.format(base.name, lanes)
def __repr__(self): def __repr__(self):
return 'VectorType(base={}, lanes={})'.format(self.base.name, self.lanes) return 'VectorType(base={}, lanes={})'.format(self.base.name, self.lanes)
@@ -65,7 +75,10 @@ class IntType(ScalarType):
def __init__(self, bits): def __init__(self, bits):
assert bits > 0, 'IntType must have positive number of bits' assert bits > 0, 'IntType must have positive number of bits'
super(IntType, self).__init__('i{:d}'.format(bits)) super(IntType, self).__init__(
name='i{:d}'.format(bits),
membytes=bits/8,
doc="An integer type with {} bits.".format(bits))
self.bits = bits self.bits = bits
def __repr__(self): def __repr__(self):
@@ -74,9 +87,9 @@ class IntType(ScalarType):
class FloatType(ScalarType): class FloatType(ScalarType):
"""A concrete scalar floating point type.""" """A concrete scalar floating point type."""
def __init__(self, bits): def __init__(self, bits, doc):
assert bits > 0, 'FloatType must have positive number of bits' assert bits > 0, 'FloatType must have positive number of bits'
super(FloatType, self).__init__('f{:d}'.format(bits)) super(FloatType, self).__init__( name='f{:d}'.format(bits), membytes=bits/8, doc=doc)
self.bits = bits self.bits = bits
def __repr__(self): def __repr__(self):

View File

@@ -2,19 +2,32 @@
from . import ScalarType, IntType, FloatType from . import ScalarType, IntType, FloatType
#: A boolean value. bool = ScalarType('bool', 0,
bool = ScalarType('bool') """
A boolean value that is either true or false.
""")
i8 = IntType(8) #: 8-bit int. i8 = IntType(8)
i16 = IntType(16) #: 16-bit int. i16 = IntType(16)
i32 = IntType(32) #: 32-bit int. i32 = IntType(32)
i64 = IntType(64) #: 64-bit int. i64 = IntType(64)
f32 = FloatType(32) #: IEEE 32-bit float. f32 = FloatType(32,
f64 = FloatType(64) #: IEEE 64-bit float """
A 32-bit floating point type represented in the IEEE 754-2008 *binary32*
interchange format. This corresponds to the :c:type:`float` type in most
C implementations.
""")
i8x16 = i8.by(16) #: Vector of 16 i8 lanes. f64 = FloatType(64,
"""
A 64-bit floating point type represented in the IEEE 754-2008 *binary64*
interchange format. This corresponds to the :c:type:`double` type in
most C implementations.
""")
f32x4 = f32.by(4) #: Vector of 4 f32 lanes. i8x16 = i8.by(16)
f64x2 = f64.by(2) #: Vector of 2 f64 lanes.
f32x4 = f32.by(4)
f64x2 = f64.by(2)