def o_roundx(self, target_bits, builder): if builder is None: return VInt(target_bits) else: r = VInt(64) a, b = self._nd(builder) h_b = builder.ashr(b, ll.Constant(ll.IntType(64), 1)) function = builder.basic_block.function add_block = function.append_basic_block("fr_add") sub_block = function.append_basic_block("fr_sub") merge_block = function.append_basic_block("fr_merge") condition = builder.icmp_signed( "<", a, ll.Constant(ll.IntType(64), 0)) builder.cbranch(condition, sub_block, add_block) builder.position_at_end(add_block) a_add = builder.add(a, h_b) builder.branch(merge_block) builder.position_at_end(sub_block) a_sub = builder.sub(a, h_b) builder.branch(merge_block) builder.position_at_end(merge_block) a = builder.phi(ll.IntType(64)) a.add_incoming(a_add, add_block) a.add_incoming(a_sub, sub_block) r.auto_store(builder, builder.sdiv(a, b)) return r.o_intx(target_bits, builder)
def o_len(self, builder): r = VInt() if builder is not None: count_ptr = builder.gep(self.llvm_value, [ ll.Constant(ll.IntType(32), 0), ll.Constant(ll.IntType(32), 0)]) r.auto_store(builder, builder.load(count_ptr)) return r
def o_intx(self, target_bits, builder): if builder is None: return VInt(target_bits) else: r = VInt(64) a, b = self._nd(builder) r.auto_store(builder, builder.sdiv(a, b)) return r.o_intx(target_bits, builder)
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, lc.Constant.int(lc.Type.int(), 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), lc.Constant.int(lc.Type.int(), 1))) cont = builder.icmp( lc.ICMP_SLT, i.auto_load(builder), lc.Constant.int(lc.Type.int(), self.count)) builder.cbranch(cont, copy_block, end_block) builder.position_at_end(end_block)
def o_getattr(self, attr, builder): if attr == "numerator": idx = 0 elif attr == "denominator": idx = 1 else: raise AttributeError r = VInt(64) if builder is not None: elt = builder.extract_value(self.auto_load(builder), idx) r.auto_store(builder, elt) return r
def o_getattr(self, attr, builder): if attr == "numerator": idx = 0 elif attr == "denominator": idx = 1 else: raise AttributeError r = VInt(64) if builder is not None: elt = builder.extract_element( self.auto_load(builder), lc.Constant.int(lc.Type.int(), idx)) r.auto_store(builder, elt) return r
def __init__(self, builder, args): minimum, step = None, None if len(args) == 1: maximum = args[0] elif len(args) == 2: minimum, maximum = args else: minimum, maximum, step = args if minimum is None: minimum = VInt() if builder is not None: minimum.set_const_value(builder, 0) if step is None: step = VInt() if builder is not None: step.set_const_value(builder, 1) self._counter = minimum.new() self._counter.merge(maximum) self._counter.merge(step) self._minimum = self._counter.new() self._maximum = self._counter.new() self._step = self._counter.new() if builder is not None: self._minimum.alloca(builder, "irange_min") self._maximum.alloca(builder, "irange_max") self._step.alloca(builder, "irange_step") self._counter.alloca(builder, "irange_count") self._minimum.set_value(builder, minimum) self._maximum.set_value(builder, maximum) self._step.set_value(builder, step) counter_init = operators.sub(self._minimum, self._step, builder) self._counter.set_value(builder, counter_init)
def init_module(module): func_def = ast.parse(inspect.getsource(_gcd)).body[0] function, _ = module.compile_function(func_def, {"a": VInt(64), "b": VInt(64)}) function.linkage = "internal"