forked from M-Labs/artiq
Fixup 4359a437
(tuples of lists), add regression tests
This commit is contained in:
parent
edc314524c
commit
768b970deb
|
@ -311,11 +311,9 @@ def is_collection(typ):
|
||||||
types.is_mono(typ, "list")
|
types.is_mono(typ, "list")
|
||||||
|
|
||||||
def is_allocated(typ):
|
def is_allocated(typ):
|
||||||
if types.is_tuple(typ):
|
|
||||||
return any(is_allocated(e.find()) for e in typ.elts)
|
|
||||||
return not (is_none(typ) or is_bool(typ) or is_int(typ) or
|
return not (is_none(typ) or is_bool(typ) or is_int(typ) or
|
||||||
is_float(typ) or is_range(typ) or
|
is_float(typ) or is_range(typ) or
|
||||||
types._is_pointer(typ) or types.is_function(typ) or
|
types._is_pointer(typ) or types.is_function(typ) or
|
||||||
types.is_c_function(typ) or types.is_rpc(typ) or
|
types.is_c_function(typ) or types.is_rpc(typ) or
|
||||||
types.is_method(typ) or
|
types.is_method(typ) or types.is_tuple(typ) or
|
||||||
types.is_value(typ))
|
types.is_value(typ))
|
||||||
|
|
|
@ -1384,7 +1384,7 @@ class LLVMIRGenerator:
|
||||||
|
|
||||||
self.llbuilder.position_at_end(lltail)
|
self.llbuilder.position_at_end(lltail)
|
||||||
llret = self.llbuilder.load(llslot, name="rpc.ret")
|
llret = self.llbuilder.load(llslot, name="rpc.ret")
|
||||||
if not builtins.is_allocated(fun_type.ret):
|
if not fun_type.ret.fold(False, lambda r, t: r or builtins.is_allocated(t)):
|
||||||
# We didn't allocate anything except the slot for the value itself.
|
# We didn't allocate anything except the slot for the value itself.
|
||||||
# Don't waste stack space.
|
# Don't waste stack space.
|
||||||
self.llbuilder.call(self.llbuiltin("llvm.stackrestore"), [llstackptr])
|
self.llbuilder.call(self.llbuiltin("llvm.stackrestore"), [llstackptr])
|
||||||
|
|
|
@ -58,6 +58,9 @@ class RoundtripTest(ExperimentCase):
|
||||||
def test_object_list(self):
|
def test_object_list(self):
|
||||||
self.assertRoundtrip([object(), object()])
|
self.assertRoundtrip([object(), object()])
|
||||||
|
|
||||||
|
def test_list_tuple(self):
|
||||||
|
self.assertRoundtrip(([1, 2], [3, 4]))
|
||||||
|
|
||||||
|
|
||||||
class _DefaultArg(EnvExperiment):
|
class _DefaultArg(EnvExperiment):
|
||||||
def build(self):
|
def build(self):
|
||||||
|
@ -296,3 +299,40 @@ class LargePayloadTest(ExperimentCase):
|
||||||
def test_1MB(self):
|
def test_1MB(self):
|
||||||
exp = self.create(_Payload1MB)
|
exp = self.create(_Payload1MB)
|
||||||
exp.run()
|
exp.run()
|
||||||
|
|
||||||
|
|
||||||
|
class _ListTuple(EnvExperiment):
|
||||||
|
def build(self):
|
||||||
|
self.setattr_device("core")
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def run(self):
|
||||||
|
# Make sure lifetime for the array data in tuples of lists is managed
|
||||||
|
# correctly. This is written in a somewhat convoluted fashion to provoke
|
||||||
|
# memory corruption even in the face of compiler optimizations.
|
||||||
|
for _ in range(self.get_num_iters()):
|
||||||
|
a, b = self.get_values(0, 1, 32)
|
||||||
|
c, d = self.get_values(2, 3, 64)
|
||||||
|
self.verify(a)
|
||||||
|
self.verify(c)
|
||||||
|
self.verify(b)
|
||||||
|
self.verify(d)
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def verify(self, data):
|
||||||
|
for i in range(len(data)):
|
||||||
|
if data[i] != data[0] + i:
|
||||||
|
raise ValueError
|
||||||
|
|
||||||
|
def get_num_iters(self) -> TInt32:
|
||||||
|
return 2
|
||||||
|
|
||||||
|
def get_values(self, base_a, base_b, n) -> TTuple([TList(TInt32), TList(TInt32)]):
|
||||||
|
return [numpy.int32(base_a + i) for i in range(n)], \
|
||||||
|
[numpy.int32(base_b + i) for i in range(n)]
|
||||||
|
|
||||||
|
|
||||||
|
class ListTupleTest(ExperimentCase):
|
||||||
|
def test_list_tuple(self):
|
||||||
|
exp = self.create(_ListTuple)
|
||||||
|
exp.run()
|
||||||
|
|
Loading…
Reference in New Issue