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:
Jakob Stoklund Olesen
2016-11-01 11:55:07 -07:00
parent c2dc400572
commit b7634ae5c3
3 changed files with 52 additions and 18 deletions

View File

@@ -18,5 +18,14 @@ 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

View File

@@ -392,9 +392,9 @@ srem = Instruction(
.. todo:: Integer remainder vs modulus.
Clarify whether the result has the sign of the divisor or the dividend.
Should we add a ``smod`` instruction for the case where the result has
the same sign as the divisor?
Clarify whether the result has the sign of the divisor or the
dividend. Should we add a ``smod`` instruction for the case where
the result has the same sign as the divisor?
""",
ins=(x, y), outs=a)

View File

@@ -8,19 +8,45 @@ from __future__ import absolute_import
import math
from . import value
try:
from typing import Tuple # noqa
Interval = Tuple[int, int]
except ImportError:
pass
MAX_LANES = 256
MAX_BITS = 64
def is_power_of_two(x):
# type: (int) -> bool
return x > 0 and x & (x-1) == 0
def int_log2(x):
# type: (int) -> int
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):
"""
A set of types.
@@ -69,6 +95,7 @@ class TypeSet(object):
"""
def __init__(self, lanes=None, ints=None, floats=None, bools=None):
# type: (Interval, Interval, Interval, Interval) -> None
if lanes:
if lanes is True:
lanes = (1, MAX_LANES)
@@ -119,6 +146,7 @@ class TypeSet(object):
self.max_bool = None
def typeset_key(self):
# type: () -> Tuple[int, int, int, int, int, int, int, int]
"""Key tuple used for hashing and equality."""
return (self.min_lanes, self.max_lanes,
self.min_int, self.max_int,
@@ -126,6 +154,7 @@ class TypeSet(object):
self.min_bool, self.max_bool)
def __hash__(self):
# type: () -> int
h = hash(self.typeset_key())
assert h == getattr(self, 'prev_hash', h), "TypeSet changed!"
self.prev_hash = h
@@ -135,6 +164,7 @@ class TypeSet(object):
return self.typeset_key() == other.typeset_key()
def __repr__(self):
# type: () -> str
s = 'TypeSet(lanes=({}, {})'.format(self.min_lanes, self.max_lanes)
if self.min_int is not None:
s += ', ints=({}, {})'.format(self.min_int, self.max_int)
@@ -161,6 +191,7 @@ class TypeSet(object):
field, int_log2(max_val) + 1))
def __iand__(self, other):
# type: (TypeSet) -> TypeSet
"""
Intersect self with other type set.
@@ -181,23 +212,17 @@ class TypeSet(object):
self.min_lanes = max(self.min_lanes, other.min_lanes)
self.max_lanes = min(self.max_lanes, other.max_lanes)
self.min_int = max(self.min_int, other.min_int)
self.max_int = min(self.max_int, other.max_int)
if self.min_int > self.max_int:
self.min_int = None
self.max_int = None
self.min_int, self.max_int = intersect(
(self.min_int, self.max_int),
(other.min_int, other.max_int))
self.min_float = max(self.min_float, other.min_float)
self.max_float = min(self.max_float, other.max_float)
if self.min_float > self.max_float:
self.min_float = None
self.max_float = None
self.min_float, self.max_float = intersect(
(self.min_float, self.max_float),
(other.min_float, other.max_float))
self.min_bool = max(self.min_bool, other.min_bool)
self.max_bool = min(self.max_bool, other.max_bool)
if self.min_bool > self.max_bool:
self.min_bool = None
self.max_bool = None
self.min_bool, self.max_bool = intersect(
(self.min_bool, self.max_bool),
(other.min_bool, other.max_bool))
return self