Classify Vars in patterns.
There's 4 classes of variables, depending on whether they have defs in the source and destination patterns. Add more XForm verification: In a legalize XForm, all source defs must be outputs. Fix a legalize pattern bug caught by this.
This commit is contained in:
@@ -2,9 +2,6 @@
|
||||
set -e
|
||||
cd $(dirname "$0")
|
||||
|
||||
echo "=== Python unit tests ==="
|
||||
python -m unittest discover
|
||||
|
||||
runif() {
|
||||
if command -v "$1" > /dev/null; then
|
||||
echo "=== $1 ==="
|
||||
@@ -19,13 +16,17 @@ runif() {
|
||||
# Install pylint with 'pip install pylint'.
|
||||
runif pylint --py3k --reports=no -- *.py cretonne isa
|
||||
|
||||
# Then run the unit tests again with Python 3.
|
||||
# We get deprecation warnings about assertRaisesRegexp which was renamed in
|
||||
# Python 3, but there doesn't seem to be an easy workaround.
|
||||
runif python3 -Wignore:Deprecation -m unittest discover
|
||||
|
||||
# Style linting.
|
||||
runif flake8 .
|
||||
|
||||
# Type checking.
|
||||
runif mypy --py2 build.py
|
||||
|
||||
echo "=== Python unit tests ==="
|
||||
python -m unittest discover
|
||||
|
||||
# Then run the unit tests again with Python 3.
|
||||
# We get deprecation warnings about assertRaisesRegexp which was renamed in
|
||||
# Python 3, but there doesn't seem to be an easy workaround.
|
||||
runif python3 -Wignore:Deprecation -m unittest discover
|
||||
|
||||
|
||||
@@ -73,6 +73,24 @@ class Expr(object):
|
||||
class Var(Expr):
|
||||
"""
|
||||
A free variable.
|
||||
|
||||
When variables are used in `XForms` with source ans destination patterns,
|
||||
they are classified as follows:
|
||||
|
||||
Input values
|
||||
Uses in the source pattern with no preceding def. These may appear as
|
||||
inputs in the destination pattern too, but no new inputs can be
|
||||
introduced.
|
||||
Output values
|
||||
Variables that are defined in both the source and destination pattern.
|
||||
These values may have uses outside the source pattern, and the
|
||||
destination pattern must compute the same value.
|
||||
Intermediate values
|
||||
Values that are defined in the source pattern, but not in the
|
||||
destination pattern. These may have uses outside the source pattern, so
|
||||
the defining instruction can't be deleted immediately.
|
||||
Temporary values
|
||||
Values that are defined only in the destination pattern.
|
||||
"""
|
||||
|
||||
def __init__(self, name):
|
||||
@@ -82,15 +100,42 @@ class Var(Expr):
|
||||
# See XForm._rewrite_defs().
|
||||
self.defctx = 0
|
||||
|
||||
# Context bits for `defctx` indicating which pattern has defines of this
|
||||
# var.
|
||||
SRCCTX = 1
|
||||
DSTCTX = 2
|
||||
|
||||
def __str__(self):
|
||||
# type: () -> str
|
||||
return self.name
|
||||
|
||||
def __repr__(self):
|
||||
# type: () -> str
|
||||
s = self.name
|
||||
if self.defctx:
|
||||
s += ", d={:02b}".format(self.defctx)
|
||||
return "Var({})".format(s)
|
||||
|
||||
def is_input(self):
|
||||
# type: () -> bool
|
||||
"""Is this an input value to the source pattern?"""
|
||||
return self.defctx == 0
|
||||
|
||||
def is_output(self):
|
||||
"""Is this an output value, defined in both src and dest patterns?"""
|
||||
# type: () -> bool
|
||||
return self.defctx == self.SRCCTX | self.DSTCTX
|
||||
|
||||
def is_intermediate(self):
|
||||
"""Is this an intermediate value, defined only in the src pattern?"""
|
||||
# type: () -> bool
|
||||
return self.defctx == self.SRCCTX
|
||||
|
||||
def is_temp(self):
|
||||
"""Is this a temp value, defined only in the dest pattern?"""
|
||||
# type: () -> bool
|
||||
return self.defctx == self.DSTCTX
|
||||
|
||||
|
||||
class Apply(Expr):
|
||||
"""
|
||||
|
||||
@@ -114,5 +114,5 @@ expand.legalize(
|
||||
Rtl(
|
||||
(a1, b1) << isub_bout(x, y),
|
||||
(a, b2) << isub_bout(a1, b_in),
|
||||
c << bor(b1, b2)
|
||||
b << bor(b1, b2)
|
||||
))
|
||||
|
||||
@@ -11,10 +11,6 @@ except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
SRCCTX = 1
|
||||
DSTCTX = 2
|
||||
|
||||
|
||||
def canonicalize_defapply(node):
|
||||
# type: (DefApply) -> Def
|
||||
"""
|
||||
@@ -87,13 +83,13 @@ class XForm(object):
|
||||
# Rewrite variables in src and dst RTL lists to our own copies.
|
||||
# Map name -> private Var.
|
||||
symtab = dict() # type: Dict[str, Var]
|
||||
self._rewrite_rtl(src, symtab, SRCCTX)
|
||||
self._rewrite_rtl(src, symtab, Var.SRCCTX)
|
||||
num_src_inputs = len(self.inputs)
|
||||
self._rewrite_rtl(dst, symtab, DSTCTX)
|
||||
self._rewrite_rtl(dst, symtab, Var.DSTCTX)
|
||||
|
||||
# Check for inconsistently used inputs.
|
||||
for i in self.inputs:
|
||||
if i.defctx:
|
||||
if not i.is_input():
|
||||
raise AssertionError(
|
||||
"'{}' used as both input and def".format(i))
|
||||
|
||||
@@ -189,6 +185,22 @@ class XForm(object):
|
||||
self.inputs.append(var)
|
||||
yield var
|
||||
|
||||
def verify_legalize(self):
|
||||
# type: () -> None
|
||||
"""
|
||||
Verify that this is a valid legalization XForm.
|
||||
|
||||
- The source pattern must describe a single instruction.
|
||||
- All values defined in the output pattern must be defined in the
|
||||
destination pattern.
|
||||
"""
|
||||
assert len(self.src.rtl) == 1, "Legalize needs single instruction."
|
||||
defs, expr = self.src.rtl[0].defs_expr()
|
||||
for d in defs:
|
||||
if not d.is_output():
|
||||
raise AssertionError(
|
||||
'{} not defined in dest pattern'.format(d))
|
||||
|
||||
|
||||
class XFormGroup(object):
|
||||
"""
|
||||
@@ -209,4 +221,6 @@ class XFormGroup(object):
|
||||
:param src: Single `Def` or `Apply` to be legalized.
|
||||
:param dst: `Rtl` list of replacement instructions.
|
||||
"""
|
||||
self.xforms.append(XForm(Rtl(src), dst))
|
||||
xform = XForm(Rtl(src), dst)
|
||||
xform.verify_legalize()
|
||||
self.xforms.append(xform)
|
||||
|
||||
@@ -14,7 +14,7 @@ from cretonne.ast import Def, Apply # noqa
|
||||
from cretonne.xform import XForm, XFormGroup # noqa
|
||||
|
||||
try:
|
||||
from typing import Union # noqa
|
||||
from typing import Union
|
||||
DefApply = Union[Def, Apply]
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user