Run unittests with Python 3 if it is available.
The check.sh script always runs the Python unittests with 'python', but if 'python3' is in the path, run it with that too. Fix a Python 3 compat issue and avoid passing None to max() and min(). Use an explicit intersect() function instead to intersect intervals.
This commit is contained in:
@@ -18,5 +18,14 @@ runif() {
|
|||||||
#
|
#
|
||||||
# Install pylint with 'pip install pylint'.
|
# Install pylint with 'pip install pylint'.
|
||||||
runif pylint --py3k --reports=no -- *.py cretonne isa
|
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 .
|
runif flake8 .
|
||||||
|
|
||||||
|
# Type checking.
|
||||||
runif mypy --py2 build.py
|
runif mypy --py2 build.py
|
||||||
|
|||||||
@@ -392,9 +392,9 @@ srem = Instruction(
|
|||||||
|
|
||||||
.. todo:: Integer remainder vs modulus.
|
.. todo:: Integer remainder vs modulus.
|
||||||
|
|
||||||
Clarify whether the result has the sign of the divisor or the dividend.
|
Clarify whether the result has the sign of the divisor or the
|
||||||
Should we add a ``smod`` instruction for the case where the result has
|
dividend. Should we add a ``smod`` instruction for the case where
|
||||||
the same sign as the divisor?
|
the result has the same sign as the divisor?
|
||||||
""",
|
""",
|
||||||
ins=(x, y), outs=a)
|
ins=(x, y), outs=a)
|
||||||
|
|
||||||
|
|||||||
@@ -8,19 +8,45 @@ from __future__ import absolute_import
|
|||||||
import math
|
import math
|
||||||
from . import value
|
from . import value
|
||||||
|
|
||||||
|
try:
|
||||||
|
from typing import Tuple # noqa
|
||||||
|
Interval = Tuple[int, int]
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
|
||||||
MAX_LANES = 256
|
MAX_LANES = 256
|
||||||
MAX_BITS = 64
|
MAX_BITS = 64
|
||||||
|
|
||||||
|
|
||||||
def is_power_of_two(x):
|
def is_power_of_two(x):
|
||||||
|
# type: (int) -> bool
|
||||||
return x > 0 and x & (x-1) == 0
|
return x > 0 and x & (x-1) == 0
|
||||||
|
|
||||||
|
|
||||||
def int_log2(x):
|
def int_log2(x):
|
||||||
|
# type: (int) -> int
|
||||||
return int(math.log(x, 2))
|
return int(math.log(x, 2))
|
||||||
|
|
||||||
|
|
||||||
|
def intersect(a, b):
|
||||||
|
# type: (Interval, Interval) -> Interval
|
||||||
|
"""
|
||||||
|
Given two `(min, max)` inclusive intervals, compute their intersection.
|
||||||
|
|
||||||
|
Use `(None, None)` to represent the empty interval on input and output.
|
||||||
|
"""
|
||||||
|
if a[0] is None or b[0] is None:
|
||||||
|
return (None, None)
|
||||||
|
lo = max(a[0], b[0])
|
||||||
|
assert lo is not None
|
||||||
|
hi = min(a[1], b[1])
|
||||||
|
assert hi is not None
|
||||||
|
if lo <= hi:
|
||||||
|
return (lo, hi)
|
||||||
|
else:
|
||||||
|
return (None, None)
|
||||||
|
|
||||||
|
|
||||||
class TypeSet(object):
|
class TypeSet(object):
|
||||||
"""
|
"""
|
||||||
A set of types.
|
A set of types.
|
||||||
@@ -69,6 +95,7 @@ class TypeSet(object):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, lanes=None, ints=None, floats=None, bools=None):
|
def __init__(self, lanes=None, ints=None, floats=None, bools=None):
|
||||||
|
# type: (Interval, Interval, Interval, Interval) -> None
|
||||||
if lanes:
|
if lanes:
|
||||||
if lanes is True:
|
if lanes is True:
|
||||||
lanes = (1, MAX_LANES)
|
lanes = (1, MAX_LANES)
|
||||||
@@ -119,6 +146,7 @@ class TypeSet(object):
|
|||||||
self.max_bool = None
|
self.max_bool = None
|
||||||
|
|
||||||
def typeset_key(self):
|
def typeset_key(self):
|
||||||
|
# type: () -> Tuple[int, int, int, int, int, int, int, int]
|
||||||
"""Key tuple used for hashing and equality."""
|
"""Key tuple used for hashing and equality."""
|
||||||
return (self.min_lanes, self.max_lanes,
|
return (self.min_lanes, self.max_lanes,
|
||||||
self.min_int, self.max_int,
|
self.min_int, self.max_int,
|
||||||
@@ -126,6 +154,7 @@ class TypeSet(object):
|
|||||||
self.min_bool, self.max_bool)
|
self.min_bool, self.max_bool)
|
||||||
|
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
|
# type: () -> int
|
||||||
h = hash(self.typeset_key())
|
h = hash(self.typeset_key())
|
||||||
assert h == getattr(self, 'prev_hash', h), "TypeSet changed!"
|
assert h == getattr(self, 'prev_hash', h), "TypeSet changed!"
|
||||||
self.prev_hash = h
|
self.prev_hash = h
|
||||||
@@ -135,6 +164,7 @@ class TypeSet(object):
|
|||||||
return self.typeset_key() == other.typeset_key()
|
return self.typeset_key() == other.typeset_key()
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
# type: () -> str
|
||||||
s = 'TypeSet(lanes=({}, {})'.format(self.min_lanes, self.max_lanes)
|
s = 'TypeSet(lanes=({}, {})'.format(self.min_lanes, self.max_lanes)
|
||||||
if self.min_int is not None:
|
if self.min_int is not None:
|
||||||
s += ', ints=({}, {})'.format(self.min_int, self.max_int)
|
s += ', ints=({}, {})'.format(self.min_int, self.max_int)
|
||||||
@@ -161,6 +191,7 @@ class TypeSet(object):
|
|||||||
field, int_log2(max_val) + 1))
|
field, int_log2(max_val) + 1))
|
||||||
|
|
||||||
def __iand__(self, other):
|
def __iand__(self, other):
|
||||||
|
# type: (TypeSet) -> TypeSet
|
||||||
"""
|
"""
|
||||||
Intersect self with other type set.
|
Intersect self with other type set.
|
||||||
|
|
||||||
@@ -181,23 +212,17 @@ class TypeSet(object):
|
|||||||
self.min_lanes = max(self.min_lanes, other.min_lanes)
|
self.min_lanes = max(self.min_lanes, other.min_lanes)
|
||||||
self.max_lanes = min(self.max_lanes, other.max_lanes)
|
self.max_lanes = min(self.max_lanes, other.max_lanes)
|
||||||
|
|
||||||
self.min_int = max(self.min_int, other.min_int)
|
self.min_int, self.max_int = intersect(
|
||||||
self.max_int = min(self.max_int, other.max_int)
|
(self.min_int, self.max_int),
|
||||||
if self.min_int > self.max_int:
|
(other.min_int, other.max_int))
|
||||||
self.min_int = None
|
|
||||||
self.max_int = None
|
|
||||||
|
|
||||||
self.min_float = max(self.min_float, other.min_float)
|
self.min_float, self.max_float = intersect(
|
||||||
self.max_float = min(self.max_float, other.max_float)
|
(self.min_float, self.max_float),
|
||||||
if self.min_float > self.max_float:
|
(other.min_float, other.max_float))
|
||||||
self.min_float = None
|
|
||||||
self.max_float = None
|
|
||||||
|
|
||||||
self.min_bool = max(self.min_bool, other.min_bool)
|
self.min_bool, self.max_bool = intersect(
|
||||||
self.max_bool = min(self.max_bool, other.max_bool)
|
(self.min_bool, self.max_bool),
|
||||||
if self.min_bool > self.max_bool:
|
(other.min_bool, other.max_bool))
|
||||||
self.min_bool = None
|
|
||||||
self.max_bool = None
|
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user