def scanf(mod, bu, s): v = mod.get_global_variable_named(s) sf = mod.get_function_named("scanf") t1 = bu.alloca(Type.int()) t2 = bu.gep(v, [Constant.int(Type.int(), 0), Constant.int(Type.int(), 0)]) bu.call(sf, [t2, t1]) return bu.load(t1)
def for_range(builder, count, intp): start = Constant.int(intp, 0) stop = count bbcond = append_basic_block(builder, "for.cond") bbbody = append_basic_block(builder, "for.body") bbend = append_basic_block(builder, "for.end") bbstart = builder.basic_block builder.branch(bbcond) ONE = Constant.int(intp, 1) with goto_block(builder, bbcond): index = builder.phi(intp, name="loop.index") pred = builder.icmp(lc.ICMP_SLT, index, stop) builder.cbranch(pred, bbbody, bbend) with goto_block(builder, bbbody): yield index bbbody = builder.basic_block incr = builder.add(index, ONE) terminate(builder, bbcond) index.add_incoming(start, bbstart) index.add_incoming(incr, bbbody) builder.position_at_end(bbend)
def divmod_by_constant(builder, val, divisor): """ Compute the (quotient, remainder) of *val* divided by the constant positive *divisor*. The semantics reflects those of Python integer floor division, rather than C's / LLVM's signed division and modulo. The difference lies with a negative *val*. """ assert divisor > 0 divisor = Constant.int(val.type, divisor) one = Constant.int(val.type, 1) quot = alloca_once(builder, val.type) with ifelse(builder, is_neg_int(builder, val)) as (if_neg, if_pos): with if_pos: # quot = val / divisor quot_val = builder.sdiv(val, divisor) builder.store(quot_val, quot) with if_neg: # quot = -1 + (val + 1) / divisor val_plus_one = builder.add(val, one) quot_val = builder.sdiv(val_plus_one, divisor) builder.store(builder.sub(quot_val, one), quot) # rem = val - quot * divisor # (should be slightly faster than a separate modulo operation) quot_val = builder.load(quot) rem_val = builder.sub(val, builder.mul(quot_val, divisor)) return quot_val, rem_val
def int_power_func_body(context, builder, x, y): pcounter = cgutils.alloca_once(builder, y.type) presult = cgutils.alloca_once(builder, x.type) result = Constant.int(x.type, 1) counter = y builder.store(counter, pcounter) builder.store(result, presult) bbcond = cgutils.append_basic_block(builder, ".cond") bbbody = cgutils.append_basic_block(builder, ".body") bbexit = cgutils.append_basic_block(builder, ".exit") del counter del result builder.branch(bbcond) with cgutils.goto_block(builder, bbcond): counter = builder.load(pcounter) ONE = Constant.int(counter.type, 1) ZERO = Constant.null(counter.type) builder.store(builder.sub(counter, ONE), pcounter) pred = builder.icmp(lc.ICMP_SGT, counter, ZERO) builder.cbranch(pred, bbbody, bbexit) with cgutils.goto_block(builder, bbbody): result = builder.load(presult) builder.store(builder.mul(result, x), presult) builder.branch(bbcond) builder.position_at_end(bbexit) return builder.load(presult)
def code_gen(self): if self.context.parent_context is None: if self.var_name_token.word in self.context.type_table: raise cmexception.RedefineException(self.var_name_token, 'Global Variable') else: t = Helper.get_type(self.typo.word) expr = self.expr_node.code_gen() if expr in g_llvm_module.global_variables: expr.name = self.var_name_token.word self.context.value_table[self.var_name_token.word] = expr else: gv = GlobalVariable.new(g_llvm_module, t, self.var_name_token.word) gv.initializer = expr self.context.value_table[self.var_name_token.word] = gv self.context.type_table[self.var_name_token.word] = t else: if not self.var_name_token.word in self.context.type_table: t = Helper.get_type(self.typo.word) var_address = g_llvm_builder.alloca(t, name=self.var_name_token.word) self.context.type_table[self.var_name_token.word] = t self.context.value_table[self.var_name_token.word] = var_address expr = self.expr_node.code_gen() if expr in g_llvm_module.global_variables: expr = g_llvm_builder.gep(expr, [Constant.int(Type.int(32), 0), Constant.int(Type.int(32), 0)]) casted_expr = Helper.auto_cast(g_llvm_builder, expr, t) if casted_expr: g_llvm_builder.store(casted_expr, var_address) else: raise cmexception.CastException(self.var_name_token, t, expr.type) else: raise cmexception.RedefineException(self.var_name_token)
def get_constant(self, ty, val): assert not self.is_struct_type(ty) lty = self.get_value_type(ty) if ty == types.none: assert val is None return self.get_dummy_value() elif ty == types.boolean: return Constant.int(Type.int(1), int(val)) elif ty in types.signed_domain: return Constant.int_signextend(lty, val) elif ty in types.unsigned_domain: return Constant.int(lty, val) elif ty in types.real_domain: return Constant.real(lty, val) elif isinstance(ty, types.UniTuple): consts = [self.get_constant(ty.dtype, v) for v in val] return Constant.array(consts[0].type, consts) raise NotImplementedError(ty)
def code_gen(self): index = self.index_expr_node.code_gen() expr = self.value_expr_node.code_gen() if self.array_name_token.word in self.context.type_table: t = self.context.type_table[self.array_name_token.word] if t.count <= index.z_ext_value: raise cmexception.ArrayIndexOutOfBoundException( self.index_expr_node.constant_token, t.count) value_address = self.context.value_table[ self.array_name_token.word] address = g_llvm_builder.gep( value_address, [Constant.int(Type.int(32), 0), index]) g_llvm_builder.store(expr, address) else: if self.array_name_token.word in self.context.parent_context.type_table: t = self.context.parent_context.type_table[ self.array_name_token.word] if t.count <= index.z_ext_value: raise cmexception.ArrayIndexOutOfBoundException( self.index_expr_node.constant_token, t.count) global_array = g_llvm_module.get_global_variable_named( self.array_name_token.word) address = g_llvm_builder.gep( global_array, [Constant.int(Type.int(32), 0), index]) g_llvm_builder.store(expr, address) else: raise cmexception.NotDefinedException(self.array_name_token, 'Array')
def emit(self): if self.text.lower() == "true": return Constant.int(tp_bool, 1) elif self.text.lower() == "false": return Constant.int(tp_bool, 0) else: raise RuntimeError("Invalid boolean value.")
def code_gen(self): if self.context.parent_context is None: if self.var_name_token.word in self.context.type_table: raise cmexception.RedefineException(self.var_name_token, 'Global Variable') else: t = Helper.get_type(self.typo.word) gv = GlobalVariable.new(g_llvm_module, t, self.var_name_token.word) self.context.type_table[self.var_name_token.word] = t self.context.value_table[self.var_name_token.word] = gv if self.typo.word == 'int': gv.initializer = Constant.int(Type.int(32), 0) elif self.typo.word == 'double': gv.initializer = Constant.real(Type.double(), 0) elif self.typo.word == 'char': gv.initializer = Constant.int(Type.int(8), 0) else: gv.initializer = Constant.stringz("") else: if not self.var_name_token.word in self.context.type_table: t = Helper.get_type(self.typo.word) var_address = g_llvm_builder.alloca(t, name=self.var_name_token.word) self.context.type_table[self.var_name_token.word] = t self.context.value_table[self.var_name_token.word] = var_address else: raise cmexception.RedefineException(self.var_name_token)
def int_power_func_body(context, builder, x, y): pcounter = builder.alloca(y.type) presult = builder.alloca(x.type) result = Constant.int(x.type, 1) counter = y builder.store(counter, pcounter) builder.store(result, presult) bbcond = cgutils.append_basic_block(builder, ".cond") bbbody = cgutils.append_basic_block(builder, ".body") bbexit = cgutils.append_basic_block(builder, ".exit") del counter del result builder.branch(bbcond) with cgutils.goto_block(builder, bbcond): counter = builder.load(pcounter) ONE = Constant.int(counter.type, 1) ZERO = Constant.null(counter.type) builder.store(builder.sub(counter, ONE), pcounter) pred = builder.icmp(lc.ICMP_SGT, counter, ZERO) builder.cbranch(pred, bbbody, bbexit) with cgutils.goto_block(builder, bbbody): result = builder.load(presult) builder.store(builder.mul(result, x), presult) builder.branch(bbcond) builder.position_at_end(bbexit) return builder.load(presult)
def make_exception_switch(self, api, builder, code): """Handle user defined exceptions. Build a switch to check which exception class was raised. """ nexc = len(self.exceptions) elseblk = cgutils.append_basic_block(builder, ".invalid.user.exception") swt = builder.switch(code, elseblk, n=nexc) for num, exc in self.exceptions.items(): bb = cgutils.append_basic_block(builder, ".user.exception.%d" % num) swt.add_case(Constant.int(code.type, num), bb) builder.position_at_end(bb) api.raise_exception(exc, exc) builder.ret(api.get_null_object()) builder.position_at_end(elseblk) # Handle native error elseblk = cgutils.append_basic_block(builder, ".invalid.native.error") swt = builder.switch(code, elseblk, n=len(errcode.error_names)) msgfmt = "{error} in native function: {fname}" for errnum, errname in errcode.error_names.items(): bb = cgutils.append_basic_block(builder, ".native.error.%d" % errnum) swt.add_case(Constant.int(code.type, errnum), bb) builder.position_at_end(bb) api.raise_native_error(msgfmt.format(error=errname, fname=self.fndesc.mangled_name)) builder.ret(api.get_null_object()) builder.position_at_end(elseblk) msg = "unknown error in native function: %s" % self.fndesc.mangled_name api.raise_native_error(msg)
def _long_from_native_int(self, ival, func_name, native_int_type, signed): fnty = Type.function(self.pyobj, [native_int_type]) fn = self._get_function(fnty, name=func_name) resptr = cgutils.alloca_once(self.builder, self.pyobj) if PYVERSION < (3, 0): # Under Python 2, we try to return a PyInt object whenever # the given number fits in a C long. pyint_fnty = Type.function(self.pyobj, [self.long]) pyint_fn = self._get_function(pyint_fnty, name="PyInt_FromLong") long_max = Constant.int(native_int_type, _helperlib.long_max) if signed: long_min = Constant.int(native_int_type, _helperlib.long_min) use_pyint = self.builder.and_( self.builder.icmp(lc.ICMP_SGE, ival, long_min), self.builder.icmp(lc.ICMP_SLE, ival, long_max), ) else: use_pyint = self.builder.icmp(lc.ICMP_ULE, ival, long_max) with cgutils.ifelse(self.builder, use_pyint) as (then, otherwise): with then: downcast_ival = self.builder.trunc(ival, self.long) res = self.builder.call(pyint_fn, [downcast_ival]) self.builder.store(res, resptr) with otherwise: res = self.builder.call(fn, [ival]) self.builder.store(res, resptr) else: fn = self._get_function(fnty, name=func_name) self.builder.store(self.builder.call(fn, [ival]), resptr) return self.builder.load(resptr)
def code_gen(self): condition = self.expr.code_gen() if str(condition.type) == 'double': condition_value = g_llvm_builder.fcmp( RPRED_UNE, condition, Constant.real(condition.type, 0)) else: condition_value = g_llvm_builder.icmp( IPRED_NE, condition, Constant.int(condition.type, 0)) function = g_llvm_builder.basic_block.function #pre_header_block = g_llvm_builder.basic_block loop_block = function.append_basic_block('while') afterloop_block = function.append_basic_block('afterwhile') g_llvm_builder.cbranch(condition_value, loop_block, afterloop_block) g_llvm_builder.position_at_end(loop_block) for stmt in self.stmts: stmt.code_gen() condition = self.expr.code_gen() if str(condition.type) == 'double': condition_value = g_llvm_builder.fcmp( RPRED_UNE, condition, Constant.real(condition.type, 0)) else: condition_value = g_llvm_builder.icmp( IPRED_NE, condition, Constant.int(condition.type, 0)) g_llvm_builder.cbranch(condition_value, loop_block, afterloop_block) g_llvm_builder.position_at_end(afterloop_block)
def code_gen(self): if self.context.parent_context is None: if self.var_name_token.word in self.context.type_table: raise cmexception.RedefineException(self.var_name_token, 'Global Variable') else: t = Helper.get_type(self.typo.word) gv = GlobalVariable.new(g_llvm_module, t, self.var_name_token.word) self.context.type_table[self.var_name_token.word] = t self.context.value_table[self.var_name_token.word] = gv if self.typo.word == 'int': gv.initializer = Constant.int(Type.int(32), 0) elif self.typo.word == 'double': gv.initializer = Constant.real(Type.double(), 0) elif self.typo.word == 'char': gv.initializer = Constant.int(Type.int(8), 0) else: gv.initializer = Constant.stringz("") else: if not self.var_name_token.word in self.context.type_table: t = Helper.get_type(self.typo.word) var_address = g_llvm_builder.alloca( t, name=self.var_name_token.word) self.context.type_table[self.var_name_token.word] = t self.context.value_table[ self.var_name_token.word] = var_address else: raise cmexception.RedefineException(self.var_name_token)
def from_S_ints(arr, key): raise NotImplementedError builder = arr.builder num = len(key) newnd = arr.nd - num if newnd < 0: raise ValueError("Too many keys") new = arr.getview(nd=newnd) oldshape = get_shape_ptr(builder, arr.array_ptr) newshape = get_shape_ptr(builder, new.array_ptr) # Load the shape array for i in range(newnd): val = load_at(builder, oldshape, i + num) store_at(builder, newshape, i, val) # Load the data-pointer old_data_ptr = get_data_ptr(builder, arr.array_ptr) new_data_ptr = get_data_ptr(builder, new.array_ptr) loc = Constant.int(intp_type, 0) factor = Constant.int(intp_type, 1) for index in range(arr.nd - 1, -1, -1): val = load_at(builder, oldshape, index) factor = builder.mul(factor, val) if index < num: # keyval = auto_const_intp(key[index]) # Multiply by strides tmp = builder.mul(keyval, factor) # Add to location loc = builder.add(loc, tmp) ptr = builder.gep(old_data_ptr, [loc]) builder.store(ptr, new_data_ptr) return new
def op_LOAD_CONST(self, value, target): if isinstance(value, bool): self.stack[target] = Constant.int(bool_type, value) elif isinstance(value, int): self.stack[target] = Constant.int(int_type, value) elif isinstance(value, (float, long)): self.stack[target] = Constant.real(float_type, value) elif isinstance(value, str): # create null terminated string n = 0 content = Constant.stringz(value) # create a unique global constant name, keep hashing # until we find one while True: try: name = CONSTANT_NAMING % (abs(hash(value)) ^ n) break except LLVMException: n += 1 pass globalstr = self.module.add_global_variable(content.type, name) globalstr.initializer = content globalstr.linkage = lc.LINKAGE_LINKONCE_ODR self.stack[target] = globalstr.bitcast( pointer(content.type.element)) else: raise NotImplementedError
def code_gen(self): if self.var_name_token.word in self.context.type_table: var_type = self.context.type_table[self.var_name_token.word] value_addr = self.context.value_table[self.var_name_token.word] expr = self.expr_node.code_gen() if expr in g_llvm_module.global_variables: expr = g_llvm_builder.gep(expr, [ Constant.int(Type.int(32), 0), Constant.int(Type.int(32), 0) ]) casted_expr = Helper.auto_cast(g_llvm_builder, expr, var_type) if casted_expr: g_llvm_builder.store(casted_expr, value_addr) else: raise cmexception.CastException(self.var_name_token, var_type, expr.type) else: if self.var_name_token.word in self.context.parent_context.type_table: gv = g_llvm_module.get_global_variable_named( self.var_name_token.word) expr = self.expr_node.code_gen() g_llvm_builder.store(expr, gv) else: raise cmexception.NotDefinedException(self.var_name_token, 'Variable')
def __init__(self, context, builder, value=None, ref=None, cast_ref=False): self._type = context.get_struct_type(self) self._context = context self._builder = builder if ref is None: self._value = alloca_once(builder, self._type) if value is not None: assert not is_pointer(value.type) assert value.type == self._type, (value.type, self._type) builder.store(value, self._value) else: assert value is None assert is_pointer(ref.type) if self._type != ref.type.pointee: if cast_ref: ref = builder.bitcast(ref, Type.pointer(self._type)) else: raise TypeError( "mismatching pointer type: got %s, expected %s" % (ref.type.pointee, self._type)) self._value = ref self._namemap = {} self._fdmap = [] self._typemap = [] base = Constant.int(Type.int(), 0) for i, (k, tp) in enumerate(self._fields): self._namemap[k] = i self._fdmap.append((base, Constant.int(Type.int(), i))) self._typemap.append(tp)
def op_LOAD_CONST(self, value, target): if isinstance(value, bool): self.stack[target] = Constant.int(bool_type, value) elif isinstance(value, int): self.stack[target] = Constant.int(int_type, value) elif isinstance(value, (float, long)): self.stack[target] = Constant.real(float_type, value) elif isinstance(value, str): # create null terminated string n = 0 content = Constant.stringz(value) # create a unique global constant name, keep hashing # until we find one while True: try: name = CONSTANT_NAMING % (abs(hash(value)) ^ n) break except LLVMException: n += 1 pass globalstr = self.module.add_global_variable(content.type, name) globalstr.initializer = content globalstr.linkage = lc.LINKAGE_LINKONCE_ODR self.stack[target] = globalstr.bitcast(pointer(content.type.element)) else: raise NotImplementedError
def getiter_range_generic(context, builder, iterobj, start, stop, step): diff = builder.sub(stop, start) intty = start.type zero = Constant.int(intty, 0) one = Constant.int(intty, 1) pos_diff = builder.icmp(lc.ICMP_SGT, diff, zero) pos_step = builder.icmp(lc.ICMP_SGT, step, zero) sign_differs = builder.xor(pos_diff, pos_step) zero_step = builder.icmp(lc.ICMP_EQ, step, zero) with cgutils.if_unlikely(builder, zero_step): # step shouldn't be zero context.return_errcode(builder, 1) with cgutils.ifelse(builder, sign_differs) as (then, orelse): with then: builder.store(zero, iterobj.count) with orelse: rem = builder.srem(diff, step) uneven = builder.icmp(lc.ICMP_SGT, rem, zero) newcount = builder.add(builder.sdiv(diff, step), builder.select(uneven, one, zero)) builder.store(newcount, iterobj.count) return iterobj._getvalue()
def visit_LitInt(self, node): ty = self.specialize(node) if ty is double_type: return Constant.real(double_type, node.n) elif ty == int_type: return Constant.int(int_type, node.n) elif ty == int64_type: return Constant.int(int64_type, node.n)
def get_item_pointer2(builder, data, shape, strides, layout, inds, wraparound=False): if wraparound: # Wraparound indices = [] for ind, dimlen in zip(inds, shape): ZERO = Constant.null(ind.type) negative = builder.icmp(lc.ICMP_SLT, ind, ZERO) wrapped = builder.add(dimlen, ind) selected = builder.select(negative, wrapped, ind) indices.append(selected) else: indices = inds del inds intp = indices[0].type # Indexing code if layout in 'CF': steps = [] # Compute steps for each dimension if layout == 'C': # C contiguous for i in range(len(shape)): last = Constant.int(intp, 1) for j in shape[i + 1:]: last = builder.mul(last, j) steps.append(last) elif layout == 'F': # F contiguous for i in range(len(shape)): last = Constant.int(intp, 1) for j in shape[:i]: last = builder.mul(last, j) steps.append(last) else: raise Exception("unreachable") # Compute index loc = Constant.int(intp, 0) for i, s in zip(indices, steps): tmp = builder.mul(i, s) loc = builder.add(loc, tmp) ptr = builder.gep(data, [loc]) return ptr else: # Any layout dimoffs = [builder.mul(s, i) for s, i in zip(strides, indices)] offset = functools.reduce(builder.add, dimoffs) base = builder.ptrtoint(data, offset.type) where = builder.add(base, offset) ptr = builder.inttoptr(where, data.type) return ptr
def const(self, val): if isinstance(val, (int, long)): return Constant.int(int_type, val) elif isinstance(val, float): return Constant.real(float_type, val) elif isinstance(val, bool): return Constant.int(bool_type, int(val)) elif isinstance(val, str): return Constant.stringz(val) else: raise NotImplementedError
def const(self, val): if isinstance(val, (int, long)): return Constant.int(int_type, val) elif isinstance(val, float): return Constant.real(double_type, val) elif isinstance(val, bool): return Constant.int(bool_type, int(val)) elif isinstance(val, str): return Constant.stringz(val) else: raise NotImplementedError
def body(self, index): mod = self.function.module c_int32 = lambda val: Constant.int(Type.int(32), val) # global place holder for current mutant id id_var = mod.add_global_variable(Type.int(32), "P86.mutant_id") id_var.initializer = Constant.int(Type.int(32), 0) id_var.linkage = core.LINKAGE_EXTERNAL # global place holder module name containing the currently # selected mutant str_var = mod.add_global_variable(Type.pointer(Type.int(8)), "P86.mutant_mod") str_var.initializer = Constant.null(Type.pointer(Type.int(8))) str_var.linkage = core.LINKAGE_EXTERNAL # pointer to the tail of the mutant list (reverse order) lst_var = mod.add_global_variable(Type.pointer(mutant_t), "P86.mutant_list") lst_var.initializer = Constant.null(Type.pointer(mutant_t)) lst_var.linkage = core.LINKAGE_EXTERNAL ptr = self.var(Type.pointer(mutant_t), self.builder.load(lst_var)) zero = self.constant(Type.int(32), 0) one = self.constant(Type.int(32), 1) # index zero disables all mutants with self.ifelse(index == zero) as ifelse: with ifelse.then(): self.builder.store(id_var.initializer, id_var) self.builder.store(str_var.initializer, str_var) self.ret() # iterate the list until we get to the Nth element with self.loop() as loop: with loop.condition() as setcond: setcond(index > one) with loop.body(): nxt = self.builder.gep(ptr.value, [c_int32(0), c_int32(2)]) ptr.assign(CVar(self, nxt)) index -= one # assign mutant id handle = self.builder.gep(ptr.value, [c_int32(0), c_int32(0)]) handle = self.builder.load(handle) self.builder.store(handle, id_var) # assign module name containing the mutant handle = self.builder.gep(ptr.value, [c_int32(0), c_int32(1)]) handle = self.builder.load(handle) self.builder.store(handle, str_var) self.ret()
def code_gen(self): value = self.right.code_gen() if self.operator.word == '-': if value.type == Type.int(32) or value.type == Type.int(8): return Constant.int(value.type, '0').sub(value) elif value.type == Type.double(): return Constant.real(value.type, '0').fsub(value) else: if value.type == Type.int(32) or value.type == Type.int(8) or Type.int(1): return Constant.int(value.type, '0').icmp(IPRED_EQ, value) elif value.type == Type.double(): return Constant.real(value.type, '0').fcmp(RPRED_UEQ, value)
def atom(self, expr): if expr.assym in self.locl: return self.locl[expr.assym] if expr.assym in self.env.names: return self.env.names[expr.assym] if expr.isnum: return Constant.int(Type.int(), expr.value) if expr.isstring: s = Constant.stringz(expr.value.encode('utf-8')) mem = self.env.constant(s) return self.bb.gep(mem, [Constant.int(Type.int(), 0)]*2) sys.stderr.write("atom undefined {}\n".format(expr)) sys.exit(1)
def code_gen(self): value = self.right.code_gen() if self.operator.word == '-': if value.type == Type.int(32) or value.type == Type.int(8): return Constant.int(value.type, '0').sub(value) elif value.type == Type.double(): return Constant.real(value.type, '0').fsub(value) else: if value.type == Type.int(32) or value.type == Type.int( 8) or Type.int(1): return Constant.int(value.type, '0').icmp(IPRED_EQ, value) elif value.type == Type.double(): return Constant.real(value.type, '0').fcmp(RPRED_UEQ, value)
def EmitGlobalString(module, builder, g_string): """ Emits a global string and returns a pointer to it. :param llvm.core.Module module: The current LLVM module. :param llvm.core.Builder builder: The current LLVM IR builder. :param str g_string: The string to emit. :rtype: llvm.core.PointerType """ s = Constant.stringz(g_string) gs = module.add_global_variable(s.type, 'g_string') gs.initializer = s return builder.gep(gs, [Constant.int(tp_int, 0), Constant.int(tp_int, 0)], inbounds=True)
def is_leap_year(builder, year_val): """ Return a predicate indicating whether *year_val* (offset by 1970) is a leap year. """ actual_year = builder.add(year_val, Constant.int(DATETIME64, 1970)) multiple_of_4 = cgutils.is_null( builder, builder.and_(actual_year, Constant.int(DATETIME64, 3))) not_multiple_of_100 = cgutils.is_not_null( builder, builder.srem(actual_year, Constant.int(DATETIME64, 100))) multiple_of_400 = cgutils.is_null( builder, builder.srem(actual_year, Constant.int(DATETIME64, 400))) return builder.and_(multiple_of_4, builder.or_(not_multiple_of_100, multiple_of_400))
def body(self): mod = self.function.module c_int32 = lambda val: Constant.int(Type.int(32), val) for id_val in self.mutants: # allocate memory for mutant info handle = self.builder.malloc(mutant_t) # set mutant id id_val = Constant.int(mutant_t.elements[0], id_val) id_var = self.builder.gep(handle, [c_int32(0), c_int32(0)]) self.builder.store(id_val, id_var) # set the module id str_val = self.constant_string(mod.id).value str_var = self.builder.gep(handle, [c_int32(0), c_int32(1)]) self.builder.store(str_val, str_var) # set the pointer to the next mutant info ptr_var = self.builder.gep(handle, [c_int32(0), c_int32(2)]) try: lst_var = mod.get_global_variable_named("P86.mutant_list") except: lst_var = mod.add_global_variable(Type.pointer(mutant_t), "P86.mutant_list") lst_var.linkage = core.LINKAGE_EXTERNAL lst_val = self.builder.load(lst_var) self.builder.store(lst_val, ptr_var) self.builder.store(handle, lst_var) # increment the total number of mutants try: cnt_var = mod.get_global_variable_named("P86.mutant_count") except: cnt_var = mod.add_global_variable(Type.int(32), "P86.mutant_count") cnt_var.linkage = core.LINKAGE_EXTERNAL one = Constant.int(Type.int(32), 1) cnt_val = self.builder.load(cnt_var) handle = self.builder.add(cnt_val, one) self.builder.store(handle, cnt_var) self.ret()
def code_gen(self): function_prototype_and_context = self.prototype.code_gen(True) function_prototype = function_prototype_and_context[0] context = function_prototype_and_context[1] block = function_prototype.append_basic_block('entry') global g_llvm_builder g_llvm_builder = Builder.new(block) for i in range(len(self.prototype.args)): context.value_table[self.prototype.args[i] [0]] = function_prototype.args[i] if self.body: for stmt in self.body: stmt.code_gen() key = self.prototype.func_name_token.word + '()' expected_return_type = self.context.type_table[key].return_type void_type = Type.void() if expected_return_type == void_type: g_llvm_builder.ret_void() else: if str(expected_return_type) == 'double': g_llvm_builder.ret(Constant.real(expected_return_type, 0)) else: g_llvm_builder.ret(Constant.int(expected_return_type, 0)) # Validate the generated code, checking for consistency. try: function_prototype.verify() g_llvm_pass_manager.run(function_prototype) except: print function_prototype.delete()
def test_uses(self): m = Module.new("a") t = Type.int() ft = Type.function(t, [t, t, t]) f = m.add_function(ft, "func") b = f.append_basic_block("entry") bld = Builder.new(b) tmp1 = bld.add(Constant.int(t, 100), f.args[0], "tmp1") tmp2 = bld.add(tmp1, f.args[1], "tmp2") tmp3 = bld.add(tmp1, f.args[2], "tmp3") bld.ret(tmp3) # Testing use count self.assertEqual(f.args[0].use_count, 1) self.assertEqual(f.args[1].use_count, 1) self.assertEqual(f.args[2].use_count, 1) self.assertEqual(tmp1.use_count, 2) self.assertEqual(tmp2.use_count, 0) self.assertEqual(tmp3.use_count, 1) # Testing uses self.assert_(f.args[0].uses[0] is tmp1) self.assertEqual(len(f.args[0].uses), 1) self.assert_(f.args[1].uses[0] is tmp2) self.assertEqual(len(f.args[1].uses), 1) self.assert_(f.args[2].uses[0] is tmp3) self.assertEqual(len(f.args[2].uses), 1) self.assertEqual(len(tmp1.uses), 2) self.assertEqual(len(tmp2.uses), 0) self.assertEqual(len(tmp3.uses), 1)
def code_gen(self): condition = self.condition.code_gen() if str(condition.type) == 'double': condition_value = g_llvm_builder.fcmp( RPRED_UNE, condition, Constant.real(condition.type, 0)) else: condition_value = g_llvm_builder.icmp( IPRED_NE, condition, Constant.int(condition.type, 0)) function = g_llvm_builder.basic_block.function if_block = function.append_basic_block('if') else_block = function.append_basic_block('else') merge_block = function.append_basic_block('merge') g_llvm_builder.cbranch(condition_value, if_block, else_block) g_llvm_builder.position_at_end(if_block) self.if_node.code_gen() g_llvm_builder.branch(merge_block) g_llvm_builder.position_at_end(else_block) if self.else_node is not None: self.else_node.code_gen() g_llvm_builder.branch(merge_block) g_llvm_builder.position_at_end(merge_block)
def code_gen(self): if self.array_name_token.word in self.context.type_table: t = self.context.type_table[self.array_name_token.word] array_address = self.context.value_table[ self.array_name_token.word] if g_llvm_builder is not None: element_address = g_llvm_builder.gep(array_address, [ Constant.int(Type.int(32), 0), self.index_expr_node.code_gen() ]) return g_llvm_builder.load(element_address) else: raise cmexception.GlobalStatementAssignException( self.array_name_token) else: if self.context.parent_context is not None: if self.array_name_token.word in self.context.parent_context.type_table: # t = self.context.parent_context.type_table[self.array_name_token.word] # if str(t) == 'i8*': # return self.context.parent_context.value_table[self.array_name_token.word] # else: return g_llvm_builder.load( self.context.parent_context.value_table[ self.array_name_token.word]) else: raise cmexception.NotDefinedException( self.array_name_token) else: raise cmexception.NotDefinedException(self.array_name_token)
def test_atomic_ldst(self): mod = Module.new('mod') functype = Type.function(Type.void(), []) func = mod.add_function(functype, name='foo') bb = func.append_basic_block('entry') bldr = Builder.new(bb) ptr = bldr.alloca(Type.int()) val = Constant.int(Type.int(), 1234) for ordering in self.orderings: loaded = bldr.atomic_load(ptr, ordering) self.assert_('load atomic' in str(loaded)) self.assertEqual(ordering, str(loaded).strip().split(' ')[-3].rstrip(',')) self.assert_('align 1' in str(loaded)) stored = bldr.atomic_store(loaded, ptr, ordering) self.assert_('store atomic' in str(stored)) self.assertEqual(ordering, str(stored).strip().split(' ')[-3].rstrip(',')) self.assert_('align 1' in str(stored)) fenced = bldr.fence(ordering) self.assertEqual(['fence', ordering], str(fenced).strip().split(' '))
def test_atomic_rmw(self): mod = Module.new("mod") functype = Type.function(Type.void(), []) func = mod.add_function(functype, name="foo") bb = func.append_basic_block("entry") bldr = Builder.new(bb) ptr = bldr.alloca(Type.int()) old = bldr.load(ptr) val = Constant.int(Type.int(), 1234) for ordering in self.orderings: inst = bldr.atomic_rmw("xchg", ptr, val, ordering) self.assertEqual(ordering, str(inst).split(" ")[-1]) for op in self.atomic_op: inst = bldr.atomic_rmw(op, ptr, val, ordering) self.assertEqual(op, str(inst).strip().split(" ")[3]) inst = bldr.atomic_rmw("xchg", ptr, val, ordering, crossthread=False) self.assertEqual("singlethread", str(inst).strip().split(" ")[-2]) for op in self.atomic_op: atomic_op = getattr(bldr, "atomic_%s" % op) inst = atomic_op(ptr, val, ordering) self.assertEqual(op, str(inst).strip().split(" ")[3])
def test_bswap(self): # setup a function and a builder mod = Module.new('test') functy = Type.function(Type.int(), []) func = mod.add_function(functy, "showme") block = func.append_basic_block("entry") b = Builder.new(block) # let's do bswap on a 32-bit integer using llvm.bswap val = Constant.int(Type.int(), 0x42) bswap = Function.intrinsic(mod, lc.INTR_BSWAP, [Type.int()]) bswap_res = b.call(bswap, [val]) b.ret(bswap_res) # logging.debug(mod) # the output is: # # ; ModuleID = 'test' # # define void @showme() { # entry: # %0 = call i32 @llvm.bswap.i32(i32 42) # ret i32 %0 # } # let's run the function ee = le.ExecutionEngine.new(mod) retval = ee.run_function(func, []) self.assertEqual(retval.as_int(), 0x42000000)
def test_uses(self): m = Module.new('a') t = Type.int() ft = Type.function(t, [t, t, t]) f = m.add_function(ft, "func") b = f.append_basic_block('entry') bld = Builder.new(b) tmp1 = bld.add(Constant.int(t, 100), f.args[0], "tmp1") tmp2 = bld.add(tmp1, f.args[1], "tmp2") tmp3 = bld.add(tmp1, f.args[2], "tmp3") bld.ret(tmp3) # Testing use count self.assertEqual(f.args[0].use_count, 1) self.assertEqual(f.args[1].use_count, 1) self.assertEqual(f.args[2].use_count, 1) self.assertEqual(tmp1.use_count, 2) self.assertEqual(tmp2.use_count, 0) self.assertEqual(tmp3.use_count, 1) # Testing uses self.assert_(f.args[0].uses[0] is tmp1) self.assertEqual(len(f.args[0].uses), 1) self.assert_(f.args[1].uses[0] is tmp2) self.assertEqual(len(f.args[1].uses), 1) self.assert_(f.args[2].uses[0] is tmp3) self.assertEqual(len(f.args[2].uses), 1) self.assertEqual(len(tmp1.uses), 2) self.assertEqual(len(tmp2.uses), 0) self.assertEqual(len(tmp3.uses), 1)
def test_atomic_rmw(self): mod = Module.new('mod') functype = Type.function(Type.void(), []) func = mod.add_function(functype, name='foo') bb = func.append_basic_block('entry') bldr = Builder.new(bb) ptr = bldr.alloca(Type.int()) old = bldr.load(ptr) val = Constant.int(Type.int(), 1234) for ordering in self.orderings: inst = bldr.atomic_rmw('xchg', ptr, val, ordering) self.assertEqual(ordering, str(inst).split(' ')[-1]) for op in self.atomic_op: inst = bldr.atomic_rmw(op, ptr, val, ordering) self.assertEqual(op, str(inst).strip().split(' ')[3]) inst = bldr.atomic_rmw('xchg', ptr, val, ordering, crossthread=False) self.assertEqual('singlethread', str(inst).strip().split(' ')[-2]) for op in self.atomic_op: atomic_op = getattr(bldr, 'atomic_%s' % op) inst = atomic_op(ptr, val, ordering) self.assertEqual(op, str(inst).strip().split(' ')[3])
def timedelta_sign_impl(context, builder, sig, args): val, = args ret = alloc_timedelta_result(builder) zero = Constant.int(TIMEDELTA64, 0) with cgutils.ifelse(builder, builder.icmp(lc.ICMP_SGT, val, zero) ) as (gt_zero, le_zero): with gt_zero: builder.store(Constant.int(TIMEDELTA64, 1), ret) with le_zero: with cgutils.ifelse(builder, builder.icmp(lc.ICMP_EQ, val, zero) ) as (eq_zero, lt_zero): with eq_zero: builder.store(Constant.int(TIMEDELTA64, 0), ret) with lt_zero: builder.store(Constant.int(TIMEDELTA64, -1), ret) return builder.load(ret)
def test_bswap(self): # setup a function and a builder mod = Module.new("test") functy = Type.function(Type.int(), []) func = mod.add_function(functy, "showme") block = func.append_basic_block("entry") b = Builder.new(block) # let's do bswap on a 32-bit integer using llvm.bswap val = Constant.int(Type.int(), 0x42) bswap = Function.intrinsic(mod, lc.INTR_BSWAP, [Type.int()]) bswap_res = b.call(bswap, [val]) b.ret(bswap_res) # logging.debug(mod) # the output is: # # ; ModuleID = 'test' # # define void @showme() { # entry: # %0 = call i32 @llvm.bswap.i32(i32 42) # ret i32 %0 # } # let's run the function ee = le.ExecutionEngine.new(mod) retval = ee.run_function(func, []) self.assertEqual(retval.as_int(), 0x42000000)
def test_issue100(self): m = Module.new('a') pm = FunctionPassManager.new(m) ee = ExecutionEngine.new(m) pm.add(ee.target_data) ti = Type.int() tf = Type.function(ti, []) f = m.add_function(tf, "func1") bb = f.append_basic_block('entry') b = Builder.new(bb) b.ret(Constant.int(ti, 0)) f.verify() pm.run(f) assert ee.run_function(f, []).as_int() == 0
def code_gen(self): function_prototype_and_context = self.prototype.code_gen(True) function_prototype = function_prototype_and_context[0] context = function_prototype_and_context[1] block = function_prototype.append_basic_block('entry') global g_llvm_builder g_llvm_builder = Builder.new(block) for i in range(len(self.prototype.args)): context.value_table[self.prototype.args[i][0]] = function_prototype.args[i] if self.body: for stmt in self.body: stmt.code_gen() key = self.prototype.func_name_token.word + '()' expected_return_type = self.context.type_table[key].return_type void_type = Type.void() if expected_return_type == void_type: g_llvm_builder.ret_void() else: if str(expected_return_type) == 'double': g_llvm_builder.ret(Constant.real(expected_return_type, 0)) else: g_llvm_builder.ret(Constant.int(expected_return_type, 0)) # Validate the generated code, checking for consistency. try: function_prototype.verify() g_llvm_pass_manager.run(function_prototype) except: print function_prototype.delete()
def code_gen(self): if self.constant_token.lexme_type == LexmeType.Integer: return Constant.int(Helper.get_type(self.constant_token.lexme_type), self.constant_token.word) elif self.constant_token.lexme_type == LexmeType.Double: return Constant.real(Helper.get_type(self.constant_token.lexme_type), self.constant_token.word) elif self.constant_token.lexme_type == LexmeType.String: s = self.constant_token.word.strip('"') global constant_string_num global_string = GlobalVariable.new(g_llvm_module, Type.array(Type.int(8), len(s) + 1), ".str%d" % constant_string_num) constant_string_num += 1 global_string.initializer = Constant.stringz(s) return global_string elif self.constant_token.lexme_type == LexmeType.Char: ascii = ord(self.constant_token.word.strip("'")) return Constant.int(Helper.get_type(self.constant_token.lexme_type), ascii)
def op_UNARY_NEGATIVE(self, ty, source, target): if ty == btypes.int_type: self.stack[target] = self.builder.sub(Constant.int(int_type, 0), self.stack[source], target) elif ty == btypes.float_type: self.stack[target] = self.builder.fsub( Constant.real(float_type, 0.0), self.stack[source], target)
def offsetof(struct_type, fieldnum, builder): nullval = Constant.null(Type.pointer(struct_type)) if hasattr(fieldnum, '__index__'): fieldnum = fieldnum.__index__() fieldnum = Constant.int(int_type, fieldnum) offset = builder.gep(nullval, [zero_p, fieldnum]) offsetI = builder.bitcast(offset, int_type) return offsetI
def test_named_md(self): m = Module.new('test_named_md') nmd = m.get_or_insert_named_metadata('something') md = MetaData.get(m, [Constant.int(Type.int(), 0xbeef)]) nmd.add(md) self.assertTrue(str(nmd).startswith('!something')) ir = str(m) self.assertTrue('!something' in ir)
def __init__(self, context, builder, value=None, ref=None): self._type = context.get_struct_type(self) self._builder = builder if ref is None: self._value = alloca_once(builder, self._type) if value is not None: assert not is_pointer(value.type) assert value.type == self._type, (value.type, self._type) builder.store(value, self._value) else: assert value is None assert self._type == ref.type.pointee self._value = ref self._fdmap = {} base = Constant.int(Type.int(), 0) for i, (k, _) in enumerate(self._fields): self._fdmap[k] = (base, Constant.int(Type.int(), i))