forked from M-Labs/artiq
1
0
Fork 0
artiq/artiq/py2llvm/arrays.py

71 lines
2.3 KiB
Python

import llvmlite.ir as ll
from artiq.py2llvm.values import VGeneric
from artiq.py2llvm.base_types import VInt
class VArray(VGeneric):
def __init__(self, el_init, count):
VGeneric.__init__(self)
self.el_init = el_init
self.count = count
if not count:
raise TypeError("Arrays must have at least one element")
def get_llvm_type(self):
return ll.ArrayType(self.el_init.get_llvm_type(), self.count)
def __repr__(self):
return "<VArray:{} x{}>".format(repr(self.el_init), self.count)
def same_type(self, other):
return (
isinstance(other, VArray)
and self.el_init.same_type(other.el_init)
and self.count == other.count)
def merge(self, other):
if isinstance(other, VArray):
self.el_init.merge(other.el_init)
else:
raise TypeError("Incompatible types: {} and {}"
.format(repr(self), repr(other)))
def merge_subscript(self, other):
self.el_init.merge(other)
def set_value(self, builder, v):
if not isinstance(v, VArray):
raise TypeError
if v.llvm_value is not None:
raise NotImplementedError("Array aliasing is not supported")
i = VInt()
i.alloca(builder, "ai_i")
i.auto_store(builder, ll.Constant(ll.IntType(32), 0))
function = builder.basic_block.function
copy_block = function.append_basic_block("ai_copy")
end_block = function.append_basic_block("ai_end")
builder.branch(copy_block)
builder.position_at_end(copy_block)
self.o_subscript(i, builder).set_value(builder, v.el_init)
i.auto_store(builder, builder.add(
i.auto_load(builder), ll.Constant(ll.IntType(32), 1)))
cont = builder.icmp_signed(
"<", i.auto_load(builder),
ll.Constant(ll.IntType(32), self.count))
builder.cbranch(cont, copy_block, end_block)
builder.position_at_end(end_block)
def o_subscript(self, index, builder):
r = self.el_init.new()
if builder is not None:
index = index.o_int(builder).auto_load(builder)
ssa_r = builder.gep(self.llvm_value, [
ll.Constant(ll.IntType(32), 0), index])
r.auto_store(builder, ssa_r)
return r