def leia(self, node, builder): try: # Ler inteiro args_int = [ir.PointerType(ir.IntType(32), 0)] leia_int_t = ir.FunctionType(ir.IntType(32), args_int) leia_int = ir.Function(self.module, leia_int_t, 'leia_int') self.funcs.append(leia_int) # Ler flutuante args_float = [ir.PointerType(ir.FloatType(), 0)] leia_float_t = ir.FunctionType(ir.FloatType(), args_float) leia_float = ir.Function(self.module, leia_float_t, 'leia_float') self.funcs.append(leia_float) # Caso as funções leia já foram declaradas, faz a chamada das mesmas except Exception as e: pass var = self.searchVarTable(node.value) args = [] args.append(var) if str(var.type) == 'i32*': # Se o parâmetro passado é inteiro chama a função leia_int builder.call(self.searchFunc('leia_int'), args) elif var.type == 'float': builder.call(self.searchFunc('leia_float'), args) else: print 'erro'
def generate_main(self): int32 = ir.IntType(32) # Generate function signature fn_type = ir.FunctionType( int32, # return: int [ int32, # argc: int ir.PointerType(ir.PointerType( ir.IntType(8))), # argv: ptr[ptr[i8]] ]) # Generate function. fn = ir.Function(self.module, fn_type, "main") fn.args[0].name = "argc" fn.args[1].name = "argv" # Add new basic blocks entry_bb = fn.append_basic_block("entry") exit_success_bb = fn.append_basic_block("exit.success") # Set basic block. builder = ir.IRBuilder(exit_success_bb) # Add return builder.ret(ir.Constant(int32, 0)) # Move instruction pointer to entry bb. builder.position_at_start(entry_bb) return fn, builder, [exit_success_bb]
def main_method_ll_ast(entry_func_id): argc = ll.IntType(32) argv = ll.PointerType(ll.PointerType(ll.IntType(8))) return { 'name': 'main', 'ret': { 'type': ll.IntType(32) }, 'args': [{ 'type': argc }, { 'type': argv }], 'instrs': [{ 'op': 'call', 'func': { "id": entry_func_id }, 'args': [] }, { 'op': 'ret', 'value': { 'op': 'const_val', 'value': ll.Constant(ll.IntType(32), 0) } }] }
def eval(self): symbol_name = '{}__ARRAY__{}'.format(self.builder.function.name, self.name) # Use this: Immutable int32 = ir.IntType(32) null = 0 # A = ir.Constant.literal_array((ir.Constant(int32, 1), ir.Constant(int32, 2), ir.Constant(int32, 3))) # then # value = self.builder.extract_value(A,3) # type, i32 * head, i32 * tail t_node = ir.LiteralStructType( (ir.IntType(8), int32, ir.PointerType(32))) #t_node type is: { float*, i32 }*. # That is, %t_node is a pointer to a structure containing a pointer to a byte, int32 and an i32*. # create a pointer to the head p_type = ir.PointerType(t_node) p = self.builder.alloca(p_type) # fty = ir.FunctionType(ir.IntType(32), [ir.IntType(32), ir.IntType(32)]) # args = (self.elements[0].eval(), self.elements[1].eval()) # add = self.builder.asm(fty, "mov $2, $0\nadd $1, $0", "=r,r,r",args, '',name="asm_add") # Allocate n elements allocation = self.builder.alloca(t_node, size=len(self.elements)) #print(symbol_name, self.module) for i in range(len(self.elements)): idx = ir.Constant(int32, i) print('2', symbol_name, self.module) p_element_type = self.builder.alloca(ir.PointerType(8)) p_value = self.builder.gep(allocation, [idx, idx]) print('>>>>>>>', p_value, symbol_name, self.module) p_ptr_next = self.builder.gep(allocation, [ir.Constant(int32, 1)]) print(symbol_name, self.module) self.builder.store( ir.Constant(ir.IntType(8), self.elements[i].eval()), p_value) print('.......', symbol_name, self.module) if i + 1 == len(self.elements): self.builder.store(p_ptr_next, ir.Constant(p_type, null)) else: idx_next = ir.Constant(p_type, i + 1) p_next = self.builder.gep(allocation, idx_next) self.builder.store(p_ptr_next, ir.Constant(p_type, p_next)) #print(e) #p = self.builder.alloca(p_type, name=symbol_name, ) #a = ir.ArrayType(ir.IntType(32), self.size) return allocation
def unbox_type(typ, obj, c): ctx = cgutils.create_struct_proxy(typ)(c.context, c.builder) ctx.ptr = call_raw_function_pointer( addr_func_c, ir.FunctionType(ir.PointerType(ir.IntType(8)), (ir.PointerType(ir.IntType(8)),)), (obj,), c.builder, ) return NativeValue(ctx._getvalue())
def set_objc(self): ObjectiveCUtil.set_objc_class(self.module) self.object_class = self.module.context.get_identified_type( 'object_class') self.Class = ir.PointerType(self.object_class) func_type = ir.FunctionType(ir.PointerType(self.object_class), [self.Class, char_pointer, i64]) self.objc_allocateClassPair = ir.Function( self.module, func_type, name='objc_allocateClassPair')
def _wrapper_function_type(self): byte_t = ir.IntType(8) byte_ptr_t = ir.PointerType(byte_t) byte_ptr_ptr_t = ir.PointerType(byte_ptr_t) intp_t = self.context.get_value_type(types.intp) intp_ptr_t = ir.PointerType(intp_t) fnty = ir.FunctionType( ir.VoidType(), [byte_ptr_ptr_t, intp_ptr_t, intp_ptr_t, byte_ptr_t]) return fnty
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 test_gep(self): block = self.block(name='my_block') builder = ir.IRBuilder(block) a, b = builder.function.args[:2] c = builder.alloca(ir.PointerType(int32), name='c') d = builder.gep(c, [ir.Constant(int32, 5), a], name='d') self.assertEqual(d.type, ir.PointerType(int32)) self.check_block(block, """\ my_block: %"c" = alloca i32* %"d" = getelementptr i32** %"c", i32 5, i32 %".1" """)
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 init_internal_functions(self): printf_ty = ir.FunctionType(int32, [ir.PointerType(int8)], var_arg=True) printf = ir.Function(self.module, printf_ty, name="printf") self.functions['printf'] = printf gets_ty = ir.FunctionType(int32, [ir.PointerType(int8)]) gets = ir.Function(self.module, gets_ty, name="gets") self.functions['gets'] = gets strlen_ty = ir.FunctionType(int32, [ir.PointerType(int8)]) strlen = ir.Function(self.module, strlen_ty, name="strlen") self.functions['strlen'] = strlen
def visit_FuncCall(self, node): if node.name == "create_int_array": return llvm.PointerType(self.int_type) elif node.name == "create_float_array": return llvm.PointerType(self.float_type) elif node.name == "create_bool_array": return llvm.PointerType(self.bool_type) elif node.name not in self.symbol_table: raise NotImplementedError('function not found') # TODO typecheck arguments for arg in node.args: self.visit(arg) return self.symbol_table[node.name].return_type
def insert_addrspace_conv(lmod, elemtype, addrspace): addrspacename = { nvvm.ADDRSPACE_SHARED: 'shared', nvvm.ADDRSPACE_LOCAL: 'local', nvvm.ADDRSPACE_CONSTANT: 'constant', }[addrspace] tyname = str(elemtype) tyname = {'float': 'f32', 'double': 'f64'}.get(tyname, tyname) s2g_name_fmt = 'llvm.nvvm.ptr.' + addrspacename + '.to.gen.p0%s.p%d%s' s2g_name = s2g_name_fmt % (tyname, addrspace, tyname) elem_ptr_ty = ir.PointerType(elemtype) elem_ptr_ty_addrspace = ir.PointerType(elemtype, addrspace) s2g_fnty = ir.FunctionType(elem_ptr_ty, [elem_ptr_ty_addrspace]) return cgutils.get_or_insert_function(lmod, s2g_fnty, s2g_name)
def irarray(dtype, builder): base = dtype.base dims = dtype.dims pdepth = dtype.pdepth if len(dims) > 1: # Get the outer array arrlen, *rest = dims arrtyp = irtype(base, pdepth + len(rest), [arrlen]) arraddr = builder.alloca(arrtyp) arraddr = builder.bitcast(arraddr, irtype(base, pdepth + len(dims), [])) # Build the inner arrays for i in range(arrlen): arrtype = DanaType(base, pdepth=pdepth, dims=dims[1:]) addr = irarray(arrtype, builder) staddr = builder.gep(arraddr, [ir.Constant(ir.IntType(32), i)]) builder.store(addr, staddr) return arraddr # Simple array elif dims: # Just allocate a variable base = irtype(base) size = dims[0] arrtyp = ir.ArrayType(base, size) arraddr = builder.alloca(arrtyp) addr = builder.bitcast(arraddr, ir.PointerType(base)) return addr else: arrtyp = irtype(base) return builder.alloca(arrtyp)
def test_cast_ops(self): block = self.block(name='my_block') builder = ir.IRBuilder(block) a, b, fa, ptr = builder.function.args[:4] c = builder.trunc(a, int8, name='c') d = builder.zext(c, int32, name='d') e = builder.sext(c, int32, name='e') fb = builder.fptrunc(fa, flt, 'fb') fc = builder.fpext(fb, dbl, 'fc') g = builder.fptoui(fa, int32, 'g') h = builder.fptosi(fa, int8, 'h') fd = builder.uitofp(g, flt, 'fd') fe = builder.sitofp(h, dbl, 'fe') i = builder.ptrtoint(ptr, int32, 'i') j = builder.inttoptr(i, ir.PointerType(int8), 'j') k = builder.bitcast(a, flt, "k") self.assertFalse(block.is_terminated) self.check_block(block, """\ my_block: %"c" = trunc i32 %".1" to i8 %"d" = zext i8 %"c" to i32 %"e" = sext i8 %"c" to i32 %"fb" = fptrunc double %".3" to float %"fc" = fpext float %"fb" to double %"g" = fptoui double %".3" to i32 %"h" = fptosi double %".3" to i8 %"fd" = uitofp i32 %"g" to float %"fe" = sitofp i8 %"h" to double %"i" = ptrtoint i32* %".4" to i32 %"j" = inttoptr i32 %"i" to i8* %"k" = bitcast i32 %".1" to float """)
def codeGenerate(self): if self.is_array == False: if self.param_type == 'int': return ll.IntType(32), self.name else: if self.param_type == 'int': return ll.PointerType(ll.IntType(32)), self.name
def codegen_ArrayRef(self, node): node.show() name = node.name subscript = node.subscript name_ir, name_ptr = self.codegen(name) value_ir_type = name.ir_type.element subscript_ir, subscript_ptr = self.codegen(subscript) if len(name.ir_type.dim_array) > 1: level_lenth = name.ir_type.dim_array[-1] * 8 else: level_lenth = 1 * 8 dim_lenth = ir.Constant(ir.IntType(64), level_lenth) subscript_ir = self.builder.fptoui(subscript_ir, ir.IntType(64)) subscript_value_in_array = self.builder.mul(dim_lenth, subscript_ir, "array_add") name_ptr_int = self.builder.ptrtoint(name_ptr, ir.IntType(64)) value_ptr = self.builder.add(subscript_value_in_array, name_ptr_int, 'addtmp') # import pdb;pdb.set_trace() value_ptr = self.builder.inttoptr(value_ptr, ir.PointerType(value_ir_type)) value_result = self.builder.load(value_ptr) # the node.ir_type should be used in somewhere node.ir_type = name.ir_type.gep(ir.Constant(ir.IntType(64), 0)) node.ir_type.dim_array = name.ir_type.dim_array[:-1] return value_result, value_ptr
def call_function(self, builder, callee, resty, argtys, args, env=None): """ Call the Numba-compiled *callee*. """ if env is None: # This only works with functions that don't use the environment # (nopython functions). env = cgutils.get_null_value(PYOBJECT) retty = self._get_return_argument(callee).type.pointee retvaltmp = cgutils.alloca_once(builder, retty) # initialize return value to zeros builder.store(cgutils.get_null_value(retty), retvaltmp) excinfoptr = cgutils.alloca_once(builder, ir.PointerType(excinfo_t), name="excinfo") args = [self.context.get_value_as_argument(builder, ty, arg) for ty, arg in zip(argtys, args)] realargs = [retvaltmp, excinfoptr, env] + args code = builder.call(callee, realargs) status = self._get_return_status(builder, code, builder.load(excinfoptr)) retval = builder.load(retvaltmp) out = self.context.get_returned_value(builder, resty, retval) return status, out
def test_mem_ops(self): block = self.block(name='my_block') builder = ir.IRBuilder(block) a, b = builder.function.args[:2] c = builder.alloca(int32, name='c') d = builder.alloca(int32, size=42, name='d') e = builder.alloca(int32, size=a, name='e') self.assertEqual(e.type, ir.PointerType(int32)) f = builder.store(b, c) self.assertEqual(f.type, ir.VoidType()) g = builder.load(c, 'g') self.assertEqual(g.type, int32) with self.assertRaises(TypeError): builder.store(b, a) with self.assertRaises(TypeError): builder.load(b) self.check_block( block, """\ my_block: %"c" = alloca i32 %"d" = alloca i32, i32 42 %"e" = alloca i32, i32 %".1" store i32 %".2", i32* %"c" %"g" = load i32* %"c" """)
def numba_buffer_adaptor(self, buf, ptr): fnty = Type.function(Type.void(), [ir.PointerType(self.py_buffer_t), self.voidptr]) fn = self._get_function(fnty, name="numba_adapt_buffer") fn.args[0].add_attribute(lc.ATTR_NO_CAPTURE) fn.args[1].add_attribute(lc.ATTR_NO_CAPTURE) return self.builder.call(fn, (buf, ptr))
def call_function(self, builder, callee, resty, argtys, args, env=None): """ Call the Numba-compiled *callee*. """ if env is None: # This only works with functions that don't use the environment # (nopython functions). env = cgutils.get_null_value(PYOBJECT) is_generator_function = isinstance(resty, types.Generator) # XXX better fix for callees that are not function values # (pointers to function; thus have no `.args` attribute) retty = self._get_return_argument(callee.function_type).pointee retvaltmp = cgutils.alloca_once(builder, retty) # initialize return value to zeros builder.store(cgutils.get_null_value(retty), retvaltmp) excinfoptr = cgutils.alloca_once(builder, ir.PointerType(excinfo_t), name="excinfo") arginfo = self._get_arg_packer(argtys) args = list(arginfo.as_arguments(builder, args)) realargs = [retvaltmp, excinfoptr, env] + args code = builder.call(callee, realargs) status = self._get_return_status(builder, code, builder.load(excinfoptr)) retval = builder.load(retvaltmp) out = self.context.get_returned_value(builder, resty, retval) return status, out
def constant(context, builder, ty, pyval): # pylint: disable=unused-argument ptr = ir.Constant(ir.IntType(64), self.get_value_address(pyval)).inttoptr( ir.PointerType(ir.IntType(8))) ret = ir.Constant.literal_struct((ptr, )) return ret
def call_raw_function_pointer(func_ptr, function_type, args, builder: ir.IRBuilder): val = ir.Constant(ir.IntType(64), func_ptr) ptr = builder.inttoptr(val, ir.PointerType(function_type)) # Due to limitations in llvmlite ptr cannot be a constant, so do the cast as an instruction to make the call # argument an instruction. return builder.call(ptr, args)
def visitStrlenFunc(self, ctx: simpleCParser.StrlenFuncContext): ''' 语法规则:strlenFunc : 'strlen' '(' mID ')'; 描述:strlen函数 返回:函数返回值 ''' if 'strlen' in self.Functions: strlen = self.Functions['strlen'] else: strlenType = ir.FunctionType(int32, [ir.PointerType(int8)], var_arg=False) strlen = ir.Function(self.Module, strlenType, name="strlen") self.Functions['strlen'] = strlen TheBuilder = self.Builders[-1] zero = ir.Constant(int32, 0) #加载变量 PreviousNeedLoad = self.WhetherNeedLoad self.WhetherNeedLoad = False res = self.visit(ctx.getChild(2)) self.WhetherNeedLoad = PreviousNeedLoad Arguments = TheBuilder.gep(res['name'], [zero, zero], inbounds=True) ReturnVariableName = TheBuilder.call(strlen, [Arguments]) Result = {'type': int32, 'name': ReturnVariableName} return Result
def declare_vprint(lmod): voidptrty = ir.PointerType(ir.IntType(8)) # NOTE: the second argument to vprintf() points to the variable-length # array of arguments (after the format) vprintfty = ir.FunctionType(ir.IntType(32), [voidptrty, voidptrty]) vprintf = cgutils.get_or_insert_function(lmod, vprintfty, "vprintf") return vprintf
def call_function(self, builder, callee, resty, argtys, args): """ Call the Numba-compiled *callee*. """ # XXX better fix for callees that are not function values # (pointers to function; thus have no `.args` attribute) retty = self._get_return_argument(callee.function_type).pointee retvaltmp = cgutils.alloca_once(builder, retty) # initialize return value to zeros builder.store(cgutils.get_null_value(retty), retvaltmp) excinfoptr = cgutils.alloca_once(builder, ir.PointerType(excinfo_t), name="excinfo") arginfo = self._get_arg_packer(argtys) args = list(arginfo.as_arguments(builder, args)) realargs = [retvaltmp, excinfoptr] + args code = builder.call(callee, realargs) status = self._get_return_status(builder, code, builder.load(excinfoptr)) retval = builder.load(retvaltmp) out = self.context.get_returned_value(builder, resty, retval) return status, out
def test_comparisons(self): # A bunch of mutually unequal types types = [ ir.LabelType(), ir.VoidType(), ir.FunctionType(int1, (int8, int8)), ir.FunctionType(int1, (int8,)), ir.FunctionType(int1, (int8,), var_arg=True), ir.FunctionType(int8, (int8,)), int1, int8, int32, flt, dbl, ir.ArrayType(flt, 5), ir.ArrayType(dbl, 5), ir.ArrayType(dbl, 4), ir.LiteralStructType((int1, int8)), ir.LiteralStructType((int8, int1)), ] types.extend([ir.PointerType(tp) for tp in types if not isinstance(tp, ir.VoidType)]) for a, b in itertools.product(types, types): if a is not b: self.assertFalse(a == b, (a, b)) self.assertTrue(a != b, (a, b)) # We assume copy.copy() works fine here... for tp in types: other = copy.copy(tp) self.assertIsNot(other, tp) if isinstance(tp, ir.LabelType): self.assertFalse(tp == other, (tp, other)) self.assertTrue(tp != other, (tp, other)) else: self.assertTrue(tp == other, (tp, other)) self.assertFalse(tp != other, (tp, other))
def escreva(self, no, builder): try: args = [ir.PointerType(ir.IntType(8), 0)] func_t = ir.FunctionType(ir.IntType(32), args, True) func = ir.Function(self.module, func_t, 'printf') except Exception: pass
def test_gep(self): def check_constant(tp, i, expected): actual = tp.gep(ir.Constant(int32, i)) self.assertEqual(actual, expected) def check_index_type(tp): index = ir.Constant(dbl, 1.0) with self.assertRaises(TypeError): tp.gep(index) tp = ir.PointerType(dbl) for i in range(5): check_constant(tp, i, dbl) check_index_type(tp) tp = ir.ArrayType(int1, 3) for i in range(3): check_constant(tp, i, int1) check_index_type(tp) tp = ir.LiteralStructType((dbl, ir.LiteralStructType((int1, int8)))) check_constant(tp, 0, dbl) check_constant(tp, 1, ir.LiteralStructType((int1, int8))) with self.assertRaises(IndexError): tp.gep(ir.Constant(int32, 2)) check_index_type(tp)
def storage_check(self, result, location): """Ensure result type matches location type""" if isinstance(result.type, ir.PointerType): if isinstance(location.type.pointee, ir.PointerType): return result, self.current_builder.bitcast(location, ir.PointerType(result.type)) if result.type != location.type.pointee: return result, self.current_builder.bitcast(location, ir.PointerType(result.type)) return result, location assert isinstance(result.type, ir.IntType) if result.type != location.type.pointee: location = self.current_builder.bitcast(location, ir.PointerType(result.type)) if result.type.width < location.type.pointee.width: result = self.current_builder.zext(result, location.type.pointee) else: result = self.current_builder.trunc(result, location.type.pointee) return result, location