def meminfo_varsize_free(self, builder, meminfo, ptr): """ Free a memory area allocated for a NRT varsize object. Note this does *not* free the NRT object itself! """ self._require_nrt() mod = builder.module fnty = ir.FunctionType(ir.VoidType(), [cgutils.voidptr_t, cgutils.voidptr_t]) fn = mod.get_or_insert_function(fnty, name="NRT_MemInfo_varsize_free") return builder.call(fn, (meminfo, ptr))
def mark_location(self, builder, loc): # Avoid duplication if self._last_lineno == loc.line: return self._last_lineno = loc.line # Add call to an inline asm to mark line location asmty = ir.FunctionType(ir.VoidType(), []) asm = ir.InlineAsm(asmty, "// dbg {}".format(loc.line), "", side_effect=True) call = builder.call(asm, []) md = self._di_location(loc.line) call.set_metadata('numba.dbg', md)
def load_builtins(self): """ create builtin get and put functions (empty for now)""" # name returnType Param builtins = [ ("putbool", ir.VoidType(), [ir.IntType(1)]), ("putstring", ir.VoidType(), [ir.PointerType(ir.IntType(8))]), ("putinteger", ir.VoidType(), [ir.IntType(32)]), ("putfloat", ir.VoidType(), [ir.FloatType()]), ("getbool", ir.IntType(1), []), ("getinteger", ir.IntType(32), []), ("getfloat", ir.FloatType(), []), ("main.StringEquals", ir.IntType(1), [ir.PointerType(ir.IntType(8)), ir.PointerType(ir.IntType(8))]), ("getstring", ir.PointerType(ir.IntType(8)), []) ] for entry in builtins: fType = ir.FunctionType(entry[1], entry[2]) func = ir.Function(self.module, fType, name=entry[0]) symbol = Symbol(entry[0], func, fType, id_type='function') self.symbolTable.add(symbol)
def ir_type(string): if "ref" in string: if "int" in string: return ir.PointerType(i32) return ir.PointerType(f32) if "int" in string: return i32 #if "sfloat" in string: # return f32 #if "float" in string: # return f32 return ir.VoidType()
def codegen(context, builder, sig, args): fnty = ir.FunctionType( ir.VoidType(), [ll_dict_type], ) [td] = sig.args [d] = args dp = _container_get_data(context, builder, td, d) fn = builder.module.get_or_insert_function(fnty, name='numba_dict_dump') builder.call(fn, [dp])
def register_writeln(self): write_func_type=ir.FunctionType(ir.VoidType(),(ir.IntType(32),)) write_func=ir.Function(self.module,write_func_type,'writeln') builder=ir.IRBuilder(write_func.append_basic_block('entry')) f=builder.inttoptr(ir.Constant(ir.IntType(64),do_write_addr), write_func_type.as_pointer(),name='f') x=write_func.args[0] x.name='x' call=builder.call(f,[x]) builder.ret_void() self.sym_table.add_fn('writeln',write_func,0)
def visitFuncDecl(self, ctx): # ID '(' params? ')' ('->' typ)? block name = ctx.ID().getText() try: ret_typ = self.visit(ctx.typ()) except AttributeError: ret_typ = ir.VoidType() try: params = ctx.params().param() param_types = [self.visit(x.typ()) for x in params] param_names = [x.ID().getText() for x in params] except AttributeError: # No parameters: param_types = [] param_names = [] func_typ = ir.FunctionType(ret_typ, param_types) self._create_func(func_typ, name) self._symbols.push_frame() self._create_block() # Bind parameters inside the function scope: for arg, typ, name in zip(self._func.args, param_types, param_names): arg.name = name self._create_var(typ, name, arg) self.visit(ctx.block()) self._symbols.pop_frame() # FIXME: handle the cases in which we are returning inside a void function # or not returning from a non-void function. if not self._builder.block.is_terminated: if func_typ == ir.VoidType(): self._builder.ret_void() else: self._builder.unreachable() self._func = None
def map_type_to_llvm(rial_type: str) -> Optional[Type]: rial_type = map_shortcut_to_type(rial_type) if rial_type == "Int32": # 32bit integer return ir.IntType(32) if rial_type == "UInt32": return LLVMUIntType(32) if rial_type == "Int64": return ir.IntType(64) if rial_type == "UInt64": return LLVMUIntType(64) if rial_type == "Boolean": # 1 bit return ir.IntType(1) if rial_type == "CString": # Char pointer return ir.IntType(8).as_pointer() if rial_type == "void": # Void return ir.VoidType() if rial_type == "Float32": return ir.FloatType() if rial_type == "Double64": return ir.DoubleType() if rial_type == "Byte": return LLVMUIntType(8) if rial_type == "Char": return ir.IntType(8) if rial_type == "Half": return ir.HalfType() # Variable integer match = re.match(r"^Int([0-9]+)$", rial_type) if match is not None: count = match.group(1) return ir.IntType(int(count)) return None
def exit(module, builder, n=0): """ Call exit(n). """ c_ptr = ir.IntType(8).as_pointer() n_ = ir.Constant(ir.IntType(64), n) fn_exit = get_global(module, "exit") if not fn_exit: fn_type = ir.FunctionType(ir.VoidType(), [ir.IntType(64)]) fn_exit = ir.Function(module, fn_type, name="exit") builder.call(fn_exit, [n_])
def makeArgumentType(typedesc): if typedesc == 'int': return ir.IntType(32) if typedesc == 'void': return ir.VoidType() if typedesc == 'float': return ir.FloatType() if typedesc in classDict: t = classDict[typedesc]['identifiedStruct'] return t.as_pointer() print classDict.keys() print "making unknown argument type:", typedesc raise ValueError
class Undefined(Intrinsic): name = "Undefined" type = ir.FunctionType(ir.VoidType(), ()) # note the instantiation! (ir.VoidType() and not ir.VoidType) args = [] Archs = defaultdict(lambda: None, [(archinfo.ArchX86, 'ud2')]) def __init__(self, arch, dsm): Intrinsic.__init__(self, arch, dsm) @classmethod def mnemonic(cls, arch): return cls.Archs[type(arch)]
def __init__(self, module, builder, fn=None, *args, **kwargs): self.func_arg_map = kwargs.pop("func_arg_map", {}) super(LLVMPrinter, self).__init__(*args, **kwargs) self.fp_type = ir.DoubleType() self.fp_pointer = self.fp_type.as_pointer() self.integer = ir.IntType(64) self.integer_pointer = self.integer.as_pointer() self.void = ir.VoidType() self.module = module self.builder = builder self.fn = fn self.ext_fn = {} # keep track of wrappers to external functions self.tmp_var = {}
def codegen(context, builder, sig, args): dict_val, = args cdict = cgutils.create_struct_proxy(dict_type)(context, builder, value=dict_val) fnty = lir.FunctionType(lir.VoidType(), [lir.IntType(8).as_pointer()]) func_name = f"hashmap_dump_{key_type_postfix}_to_{value_type_postfix}" fn_hashmap_dump = cgutils.get_or_insert_function(builder.module, fnty, name=func_name) builder.call(fn_hashmap_dump, [cdict.data_ptr]) return
def _codegen_ProgramNode(self,node,builder): self.register_writeln() self.register_readln() global_func_type=ir.FunctionType(ir.VoidType(),()) self.global_func=ir.Function(self.module,global_func_type,'main') self.global_block=self.global_func.append_basic_block('main') builder=ir.IRBuilder(self.global_block) if node.routine: self._codegen(node.routine,builder) builder.ret_void()
def printf(module, builder, fmt, *args): """ Call printf(fmt, *args). """ c_ptr = ir.IntType(8).as_pointer() fmt_ptr = create_global_string(module, builder, fmt) fn_printf = get_global(module, "_lfortran_printf") if not fn_printf: fn_type = ir.FunctionType(ir.VoidType(), [c_ptr], var_arg=True) fn_printf = ir.Function(module, fn_type, name="_lfortran_printf") builder.call(fn_printf, [fmt_ptr] + list(args))
class LLVMTypes: """ A helper class to get LLVM Values for integer C types. """ byte_t = lc.Type.int(8) byte_ptr_t = lc.Type.pointer(byte_t) byte_ptr_ptr_t = lc.Type.pointer(byte_ptr_t) int32_t = lc.Type.int(32) int32_ptr_t = lc.Type.pointer(int32_t) int64_t = lc.Type.int(64) int64_ptr_t = lc.Type.pointer(int64_t) void_t = lir.VoidType()
def ir_type(string): # convert kaleidoscope type to ir type if "ref" in string: if "int" in string: return ir.PointerType(i32) return ir.PointerType(f32) if "int" in string: return i32 if "float" in string: return f32 if "bool" in string: return i1 return ir.VoidType()
def ir_type(self): '''self.ir_type -> IR Type based on self.type''' return { 'void': ir.VoidType(), 'char': ir.IntType(8), 'char*': ir.IntType(8).as_pointer(), 'char**': ir.IntType(8).as_pointer().as_pointer(), 'int': ir.IntType(32), 'cint': ir.IntType(32), 'float': ir.FloatType(), 'double': ir.DoubleType(), 'bool': ir.IntType(1) }[self.type]
def declaracao_funcao(self, node): offset = 0 if len(node.child) == 1: retorno = None llvm_retorno = ir.VoidType() else: offset = 1 if node.child[0].value == "inteiro": retorno = "inteiro" llvm_retorno = ir.IntType(32) else: retorno = "flutuante" llvm_retorno = ir.FloatType() cabeca = self.cabecalho(retorno, node.child[offset]) lista_param = cabeca[0] llvm_params = [] corpo_node = cabeca[1] func_nome = cabeca[2] for param in lista_param: tipo = param[0] if tipo == "inteiro": llvm_params.append(ir.IntType(32)) else: llvm_params.append(ir.FloatType()) if func_nome == "principal": nome_func = "main" else: nome_func = func_nome llvm_func_type = ir.FunctionType(llvm_retorno, llvm_params) self.func = ir.Function(self.module, llvm_func_type, name=nome_func) escopo_nome = func_nome self.lista_escopos.append(escopo_nome) self.escopo = escopo_nome entry_block = self.func.append_basic_block('entry') self.builder = ir.IRBuilder(entry_block) self.bloco = entry_block self.tabelaSimbolos[func_nome] = [ "funcao", func_nome, lista_param, llvm_retorno, 0, escopo_nome, self.func ] self.corpo(corpo_node)
def codegen(context, builder, sig, args): nrt_table = context.nrt.get_nrt_api(builder) llptrtype = context.get_value_type(types.intp) cdict = cgutils.create_struct_proxy(sig.return_type)(context, builder) fnty = lir.FunctionType( lir.VoidType(), [ cdict.meminfo.type.as_pointer(), # meminfo to fill lir.IntType(8).as_pointer(), # NRT API func table lir.IntType(8), lir.IntType(8), # gen_key, gen_value flags llptrtype, llptrtype, # hash_func, equality func llptrtype, llptrtype, # key incref, decref llptrtype, llptrtype, # val incref, decref lir.IntType(64), lir.IntType(64) ]) # key size, val size func_name = f"hashmap_create_{key_type_postfix}_to_{value_type_postfix}" fn_hashmap_create = cgutils.get_or_insert_function(builder.module, fnty, name=func_name) gen_key = context.get_constant(types.int8, types.int8(not key_numeric)) gen_val = context.get_constant(types.int8, types.int8(not val_numeric)) lir_key_type = context.get_value_type(dict_key_type) hash_func_addr_const = context.get_constant(types.intp, hash_func_addr) eq_func_addr_const = context.get_constant(types.intp, eq_func_addr) key_incref = context.get_constant(types.intp, key_incref_func_addr) key_decref = context.get_constant(types.intp, key_decref_func_addr) key_type_size = context.get_constant( types.int64, context.get_abi_sizeof(lir_key_type)) lir_val_type = context.get_value_type(dict_val_type) val_incref = context.get_constant(types.intp, val_incref_func_addr) val_decref = context.get_constant(types.intp, val_decref_func_addr) val_type_size = context.get_constant( types.int64, context.get_abi_sizeof(lir_val_type)) builder.call(fn_hashmap_create, [ cdict._get_ptr_by_name('meminfo'), nrt_table, gen_key, gen_val, hash_func_addr_const, eq_func_addr_const, key_incref, key_decref, val_incref, val_decref, key_type_size, val_type_size ]) cdict.data_ptr = context.nrt.meminfo_data(builder, cdict.meminfo) return cdict._getvalue()
def test_helper_is_close(mode): with pnlvm.LLVMBuilderContext() as ctx: double_ptr_ty = ir.DoubleType().as_pointer() func_ty = ir.FunctionType( ir.VoidType(), [double_ptr_ty, double_ptr_ty, double_ptr_ty, ctx.int32_ty]) # Create clamp function custom_name = ctx.get_unique_name("all_close") function = ir.Function(ctx.module, func_ty, name=custom_name) in1, in2, out, count = function.args block = function.append_basic_block(name="entry") builder = ir.IRBuilder(block) index = None with pnlvm.helpers.for_loop_zero_inc(builder, count, "compare") as (b1, index): val1_ptr = b1.gep(in1, [index]) val2_ptr = b1.gep(in2, [index]) val1 = b1.load(val1_ptr) val2 = b1.load(val2_ptr) close = pnlvm.helpers.is_close(ctx, b1, val1, val2) out_ptr = b1.gep(out, [index]) out_val = b1.select(close, val1.type(1), val1.type(0)) res = b1.select(close, out_ptr.type.pointee(1), out_ptr.type.pointee(0)) b1.store(out_val, out_ptr) builder.ret_void() vec1 = copy.deepcopy(VECTOR) tmp = np.random.rand(DIM_X) tmp[0::2] = vec1[0::2] vec2 = np.asfarray(tmp) assert len(vec1) == len(vec2) res = np.empty_like(vec2) ref = np.isclose(vec1, vec2) bin_f = pnlvm.LLVMBinaryFunction.get(custom_name) if mode == 'CPU': ct_ty = ctypes.POINTER(bin_f.byref_arg_types[0]) ct_vec1 = vec1.ctypes.data_as(ct_ty) ct_vec2 = vec2.ctypes.data_as(ct_ty) ct_res = res.ctypes.data_as(ct_ty) bin_f(ct_vec1, ct_vec2, ct_res, DIM_X) else: bin_f.cuda_wrap_call(vec1, vec2, res, np.int32(DIM_X)) assert np.array_equal(res, ref)
def type_convert(self, type): if (isinstance(type, ir.Type)): return type if (type in ['integer', 'int']): return ir.IntType(32) if (type in ['real']): return ir.DoubleType() if (type in ['boolean']): return ir.IntType(1) if (type in ['void']): return ir.VoidType() if (type in ['char']): return ir.IntType(8) raise Exception('Error: invalid data type')
def compile(self): fptr = {} for func in self.module.functions: if not func.is_declaration: return_type = None if func.ftype.return_type != ir.VoidType(): return_type = to_ctypes( create_composite_type_from_string( str(func.ftype.return_type))) args = [ctypes_from_llvm(arg) for arg in func.ftype.args] function_address = self.ee.get_function_address(func.name) fptr[func.name] = ct.CFUNCTYPE(return_type, *args)(function_address) self.fptr = fptr
def codegen(context, builder, sig, args): new_data_val, new_data_size = args[1:] str_view_ctinfo = cgutils.create_struct_proxy(sig.args[0])( context, builder, value=args[0]) fnty = lir.FunctionType(lir.VoidType(), [ lir.IntType(8).as_pointer(), lir.IntType(8).as_pointer(), lir.IntType(64) ]) fn = cgutils.get_or_insert_function(builder.module, fnty, name="string_view_set_data") return builder.call( fn, [str_view_ctinfo.data_ptr, new_data_val, new_data_size])
def setitem_str_arr(context, builder, sig, args): arr, ind, val = args string_array = context.make_helper(builder, string_array_type, arr) fnty = lir.FunctionType(lir.VoidType(), [ lir.IntType(32).as_pointer(), lir.IntType(8).as_pointer(), lir.IntType(8).as_pointer(), lir.IntType(64) ]) fn_setitem = builder.module.get_or_insert_function( fnty, name="setitem_string_array") builder.call(fn_setitem, [string_array.offsets, string_array.data, val, ind]) return context.get_dummy_value()
def codegen(context, builder, sig, args): arr_info = context.make_array(column_tp)(context, builder, value=args[3]) ctinfo = context.make_array(schema_arr_tp)(context, builder, value=args[4]) fnty = lir.FunctionType(lir.VoidType(), [lir.IntType(8).as_pointer(), lir.IntType(8).as_pointer(), lir.IntType(64), lir.IntType(8).as_pointer(), lir.IntType(64).as_pointer()]) fn = builder.module.get_or_insert_function(fnty, name="c_read_xenon") res = builder.call(fn, [args[0], args[1], args[2], builder.bitcast(arr_info.data, lir.IntType(8).as_pointer()), ctinfo.data]) return context.get_dummy_value()
def function_declaration(self, node): self.scope_var_list = [] return_type = self.get_type(node) parameter_type_list, parameter_key_list = self.get_function_parameter_list(node) #parametros: nomes e tipos function_key = self.get_function_key(node) #nome da função return_value = None function_type = None if return_type == 'void': function_type = ir.FunctionType(ir.VoidType(), (parameter_type_list)) return_value = ir.VoidType() else: if return_type == 'inteiro': function_type = ir.FunctionType(ir.IntType(32), (parameter_type_list)) return_value = ir.IntType(32) elif return_type == 'flutuante': function_type = ir.FunctionType(ir.DoubleType(), (parameter_type_list)) return_value = ir.DoubleType() function = ir.Function(self.module, function_type, function_key) self.function_list.append(function) self.entry_block = function.append_basic_block(name='entry_' + function_key) self.exit_block = function.append_basic_block(name='exit_' + function_key) builder = ir.IRBuilder(self.entry_block) with builder.goto_entry_block(): self.parameter_list(function.args, parameter_type_list, parameter_key_list, builder) #resolve os parametros da função if return_type != 'void': return_value = builder.alloca(return_value, name='return_value') self.body(node.children[1].children[1], builder, return_value) #resolve actions builder.branch(self.exit_block) with builder.goto_block(self.exit_block): if return_type == 'void': builder.ret_void() else: load_return = builder.load(return_value) builder.ret(load_return)
def __init__(self, target, machine): # Record target and machine self.target = target self.machine = machine # We choose the word type to be an integer with the same size as a # pointer to i8. The word size is expressed in bytes word_size = ir.IntType(8).as_pointer().get_abi_size( self.machine.target_data) # Define the word type and bytes-per-word appropriately self.word_type = ir.IntType(word_size * 8) self.bytes_per_word = word_size # Define the type used for constructor function records priority_type = ir.IntType(32) ctor_func_type = ir.FunctionType(ir.VoidType(), []) data_ptr_type = ir.PointerType(ir.IntType(8)) self.ctor_record_type = ir.LiteralStructType( [priority_type, ctor_func_type.as_pointer(), data_ptr_type]) # Initialise context attributes self.module = None self.global_scope = {} self.externals = {} self.scope = collections.ChainMap(self.global_scope) self.builder = None self.string_constants = {} self.ctor_records = [] # Block at end of current switch/which statement self.break_block = None # LLVM Value of condition in current switch statement self.switch_val = None # Block which new switch tests should be appended to self.switch_block = None # Labels are mappings from names to.basic blocks A goto branches to the # block. The labels dict is only created within functions. self.labels = None # Callables which should be called after all code has been emitted self.post_emit_hooks = [] # Flag to indicate when one is within the emitting_code() context. self._is_emitting = False
def nrt_decref(self, builder, typ, value): if not self.enable_nrt: raise Exception("Require NRT") members = self.data_model_manager[typ].traverse(builder, value) for mt, mv in members: self.nrt_decref(builder, mt, mv) meminfo = self.get_nrt_meminfo(builder, typ, value) if meminfo: mod = cgutils.get_module(builder) fnty = llvmir.FunctionType(llvmir.VoidType(), [llvmir.IntType(8).as_pointer()]) fn = mod.get_or_insert_function(fnty, name="NRT_decref") builder.call(fn, [meminfo])
def codegen(context, builder, sig, args): in_set, in_str_arr = args string_array = context.make_helper(builder, string_array_type, in_str_arr) fnty = lir.FunctionType(lir.VoidType(), [lir.IntType(8).as_pointer(), lir.IntType(32).as_pointer(), lir.IntType(8).as_pointer(), ]) fn_getitem = builder.module.get_or_insert_function(fnty, name="populate_str_arr_from_set") builder.call(fn_getitem, [in_set, string_array.offsets, string_array.data]) return context.get_dummy_value()