0

I'm using libgccjit to build an just in time function for my test. In particular, I want to import "memcpy" function, but I'm unsure how to do it. My current guess from looking at the documentation from https://gcc.gnu.org/onlinedocs/jit/topics/functions.html is that using gcc_jit_context_get_builtin_function to import __builtin_memcpy. But it seems I'm not correct. My current code is as follows

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);
}

It compiles but gives me errors

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

I'm not exactly sure how to import __builtin_memcpy and how to pass params into it.

Given the second try, I wrapped memcpy into a function generate_memcpy and tried to imported it

    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);

However, the error is as follows

libgccjit.so: error: /tmp/libgccjit-1xJjYm/fake.so: undefined symbol: generate_memcpy
gcc_jit_result_get_code: NULL result
Segmentation fault
  • You are correct that `__builtin_memcpy` is not a function that can be imported using `gcc_jit_context_get_builtin_function`. Instead, you can define a C function called `memcpy_wrapper` that simply calls `memcpy` and use `gcc_jit_context_new_function_from_c_location` to import this function into your JIT context. – VAIBHAV NIRMAL Mar 09 '23 at 17:40
  • That's what I described in the second part of the question. And there isn't a function `gcc_jit_context_new_function_from_c_location` – WhoAmIWhereAmIWhatIAmDoing Mar 09 '23 at 23:29

1 Answers1

0

Use gcc-12 which has __builtin_memcpy implemented and follow the page https://gcc.gnu.org/onlinedocs/jit/internals/index.html#working-on-the-jit-library which has the instructions on how to build gcc-12.

And for arguments for __builtin_memcpy, the third argument size need to use function gcc_jit_context_new_rvalue_from_long to create integer or size_t in order for libgccjit to recognize, otherwise will seg fault