如何在libgccjit中正确导入并调用memcpy函数?
在libgccjit中正确导入并调用memcpy的方法
问题背景
我正在用libgccjit构建测试用JIT函数,需要导入memcpy但操作失败。尝试用gcc_jit_context_get_builtin_function导入__builtin_memcpy没成功,两次尝试的代码和报错如下:
第一次尝试代码
void generate_memcpy_code(void){ gcc_jit_context *ctxt; gcc_jit_type *void_ptr_type, *void_type, *int_type; gcc_jit_type *param_types[3]; gcc_jit_param *params[3]; gcc_jit_function *func; gcc_jit_block *block; gcc_jit_lvalue *dst_lval, *src_lval; gcc_jit_rvalue *size_val; ctxt = gcc_jit_context_acquire(); void_type = gcc_jit_context_get_type( ctxt, GCC_JIT_TYPE_VOID ); void_ptr_type = gcc_jit_context_get_type( ctxt, GCC_JIT_TYPE_VOID_PTR ); int_type = gcc_jit_context_get_type( ctxt, GCC_JIT_TYPE_INT ); param_types[0] = void_ptr_type; param_types[1] = void_ptr_type; param_types[2] = int_type; params[0] = gcc_jit_context_new_param(ctxt, NULL, void_ptr_type, "dst"); params[1] = gcc_jit_context_new_param(ctxt, NULL, void_ptr_type, "src"); params[2] = gcc_jit_context_new_param(ctxt, NULL, int_type, "size"); func = gcc_jit_context_new_function(ctxt, NULL, GCC_JIT_FUNCTION_EXPORTED, void_type, "my_memcpy", 3, params, 0 ); block = gcc_jit_function_new_block(func, "body"); dst_lval = gcc_jit_param_as_lvalue( gcc_jit_function_get_param(func, 0) ); src_lval = gcc_jit_param_as_lvalue( gcc_jit_function_get_param(func, 1) ); size_val = gcc_jit_param_as_rvalue( gcc_jit_function_get_param(func, 2) ); gcc_jit_rvalue *args[3] = { gcc_jit_lvalue_as_rvalue(dst_lval), gcc_jit_lvalue_as_rvalue(src_lval), size_val }; gcc_jit_rvalue *memcpy_call = gcc_jit_context_new_call( ctxt, NULL, gcc_jit_context_get_builtin_function(ctxt, "__builtin_memcpy"), 3, args); gcc_jit_block_add_eval(block, NULL, memcpy_call); gcc_jit_context_compile(ctxt); gcc_jit_context_release(ctxt); }
报错信息
libgccjit.so: error: unimplemented primitive type for builtin: 34 libgccjit.so: error: gcc_jit_context_new_call: NULL function libgccjit.so: error: gcc_jit_block_add_eval: NULL rvalue libgccjit.so: error: unterminated block in my_memcpy: body
第二次尝试代码(封装导入)
gcc_jit_location *memcpy_loc = gcc_jit_context_new_location( ctxt, "/home/yli137/openmpi/reorder_concept/libgcc.h", 4, 6 ); gcc_jit_function *memcpy_function = gcc_jit_context_new_function( ctxt, memcpy_loc, GCC_JIT_FUNCTION_IMPORTED, void_type, "generate_memcpy", 3, inputs, 0 ); gcc_jit_rvalue *memcpy_call = gcc_jit_context_new_call( ctxt, NULL, memcpy_function, 3, args); gcc_jit_block_add_eval(block, memcpy_loc, memcpy_call);
报错信息
libgccjit.so: error: /tmp/libgccjit-1xJjYm/fake.so: undefined symbol: generate_memcpy gcc_jit_result_get_code: NULL result Segmentation fault
正确实现方式
修正后的完整代码
#include <libgccjit.h> #include <stddef.h> // 用于size_t类型定义 void generate_memcpy_code(void){ gcc_jit_context *ctxt; gcc_jit_type *void_ptr_type, *void_type, *size_t_type; gcc_jit_param *params[3]; gcc_jit_function *func, *memcpy_func; gcc_jit_block *block; gcc_jit_rvalue *args[3]; ctxt = gcc_jit_context_acquire(); // 获取基础类型 void_type = gcc_jit_context_get_type(ctxt, GCC_JIT_TYPE_VOID); void_ptr_type = gcc_jit_context_get_type(ctxt, GCC_JIT_TYPE_VOID_PTR); size_t_type = gcc_jit_context_get_type(ctxt, GCC_JIT_TYPE_SIZE_T); // 使用标准size类型 // 创建my_memcpy函数的参数 params[0] = gcc_jit_context_new_param(ctxt, NULL, void_ptr_type, "dst"); params[1] = gcc_jit_context_new_param(ctxt, NULL, gcc_jit_type_get_const(void_ptr_type), "src"); // src应为const void* params[2] = gcc_jit_context_new_param(ctxt, NULL, size_t_type, "size"); // 创建导出的my_memcpy函数 func = gcc_jit_context_new_function(ctxt, NULL, GCC_JIT_FUNCTION_EXPORTED, void_type, "my_memcpy", 3, params, 0); // 导入标准库的memcpy函数 gcc_jit_type *memcpy_param_types[3] = { void_ptr_type, gcc_jit_type_get_const(void_ptr_type), size_t_type }; memcpy_func = gcc_jit_context_new_function(ctxt, NULL, GCC_JIT_FUNCTION_IMPORTED, void_ptr_type, // memcpy返回值为void* "memcpy", 3, memcpy_param_types, 0); block = gcc_jit_function_new_block(func, "body"); // 准备调用memcpy的参数 args[0] = gcc_jit_param_as_rvalue(params[0]); args[1] = gcc_jit_param_as_rvalue(params[1]); args[2] = gcc_jit_param_as_rvalue(params[2]); // 调用memcpy gcc_jit_rvalue *memcpy_call = gcc_jit_context_new_call(ctxt, NULL, memcpy_func, 3, args); gcc_jit_block_add_eval(block, NULL, memcpy_call); // 终止代码块:添加void返回语句 gcc_jit_block_end_with_void_return(block, NULL); // 编译并释放上下文 gcc_jit_context_compile(ctxt); gcc_jit_context_release(ctxt); }
关键修正点说明
- 匹配标准memcpy签名:
memcpy的标准签名是void* memcpy(void* dest, const void* src, size_t n),需将第二个参数改为const void*,第三个参数使用size_t而非int,这是之前类型错误的核心原因。 - 导入正确的函数:直接导入系统标准库的
memcpy,而非自定义的generate_memcpy,避免未定义符号错误。 - 终止代码块:所有函数块必须以返回或跳转语句结束,添加
gcc_jit_block_end_with_void_return解决"unterminated block"报错。 - 避免使用__builtin_memcpy:libgccjit对部分内置函数的支持有限,直接调用会触发类型不兼容问题,优先导入标准库函数。
内容的提问来源于stack exchange,提问作者WhoAmIWhereAmIWhatIAmDoing
相关产品推荐
相关产品推荐

