【问题标题】:LLVMLITE Hello World Example Produces Wrong OutputLLVMLITE Hello World 示例产生错误的输出
【发布时间】:2020-02-28 15:19:14
【问题描述】:

我面临的关于 llvmlite 的问题是生成一个简单的 hello world 示例。

我无法在我创建的函数中显示字符串全局变量值。

它似乎总是打印出第一个。

我已经尝试返回产生错误的字符串类型。

from llvmlite import ir

i64 = ir.IntType(64)
i8 = ir.IntType(16)
hellostr = 'hello, world!'
stringtype = ir.ArrayType(i64, len(hellostr))


module = ir.Module( name="m_hello_example" )
hello = ir.GlobalVariable(module, stringtype, '.str4')
fn_int_to_int_type = ir.FunctionType(i64, [stringtype.as_pointer()] )
fn_hel = ir.Function( module, fn_int_to_int_type, name="fn_hel" )


fn_hel_block = fn_hel.append_basic_block( name="fn_hel_entry" )

builder = ir.IRBuilder(fn_hel_block )
# zero = builder.constant(i64, 0)
# const_1 = ir.Constant(stringtype,1);
# builder.ret(const_1)
const_1 = ir.Constant(i64,1);
# print(const_1)
builder.ret(const_1)
print( module )

我期待输出打印出字符串 'hello, world!'。

任何帮助将不胜感激。

谢谢。

【问题讨论】:

    标签: llvmlite


    【解决方案1】:

    最终我能够使用以下代码解决我的问题:

    import llvmlite.ir as ir
    import llvmlite.binding as llvm
    from ctypes import CFUNCTYPE
    
    
    def main():
        m = ir.Module()
        func_ty = ir.FunctionType(ir.VoidType(), []) #defining printer function as type void
        func = ir.Function(m, func_ty, name="printer") #define function as printer
        builder = ir.IRBuilder(func.append_basic_block('entry')) #defining the entry point of the function printer
    
        fmt = "%s\n\0" #in function printf allows for inserting arg in, next global_fmt statements allow for creating @"fstr" assignment
        c_fmt = ir.Constant(ir.ArrayType(ir.IntType(8), len(fmt)),
                            bytearray(fmt.encode("utf8")))
        global_fmt = ir.GlobalVariable(m, c_fmt.type, name="fstr")
        global_fmt.linkage = 'internal'
        global_fmt.global_constant = True
        global_fmt.initializer = c_fmt
    
        arg = "Hello, World!\0" #args will be passed into printf function.
        c_str_val = ir.Constant(ir.ArrayType(ir.IntType(8), len(arg)),
                                bytearray(arg.encode("utf8"))) #creates the c_str_value as a constant
    
        printf_ty = ir.FunctionType(ir.IntType(32), [], var_arg=True) #creation of the printf function begins here and specifies the passing of a argument
        printf = ir.Function(m, printf_ty, name="printf")    
    
        c_str = builder.alloca(c_str_val.type) #creation of the allocation of the %".2" variable
        builder.store(c_str_val, c_str) #store as defined on the next line below %".2"
    
        voidptr_ty = ir.IntType(8).as_pointer() 
        fmt_arg = builder.bitcast(global_fmt, voidptr_ty) #creates the %".4" variable with the point pointing to the fstr
        builder.call(printf, [fmt_arg, c_str]) #We are calling the prinf function with the fmt and arg and returning the value as defiend on the next line
        builder.ret_void()
    
        #Next lines are for calling llvm and returning the assembly.
        llvm.initialize()
        llvm.initialize_native_target()
        llvm.initialize_native_asmprinter()
    
        print(str(m)) #PRINTING OUT THE ASSEMBLY
        llvm_module = llvm.parse_assembly(str(m)) #Parsing teh assembly
        tm = llvm.Target.from_default_triple().create_target_machine() #creating the target machine
    
        with llvm.create_mcjit_compiler(llvm_module, tm) as ee:
            ee.finalize_object() #Making sure all modules owned by the execution engine are fully processed and usable for execution
            fptr = ee.get_function_address("printer") #fptr will reference the printer function
            py_func = CFUNCTYPE(None)(fptr)
            py_func() #run the function printer
    
    if __name__ == "__main__":
        main()
    

    看来我没有正确分配变量,因此我没有返回任何东西。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-10
      • 2017-11-06
      • 2012-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多