PROBLEM: I currently have a traditional module instrumentation pass that inserts new function calls into a given IR according to some logic (inserted functions are external from a small lib that is later linked to given program). Running experiments, my overhead is from the cost of executing a function call to the library function.
What I am trying to do: I would like to inline these function bodies into the IR of the given program to get rid of this bottleneck. I assume an intrinsic would be a clean way of doing this, since an intrinsic function would be expanded to its function body when being lowered to ASM (please correct me if my understanding is incorrect here, this is my first time working with intrinsics/LTO).
Current Status:
My original library call definition:
void register_my_mem(void *user_vaddr){
... C code ...
}
So far:
I have created a def in: llvm-project/llvm/include/llvm/IR/IntrinsicsX86.td
let TargetPrefix = "x86" in { def int_x86_register_mem : GCCBuiltin<"__builtin_register_my_mem">, Intrinsic<[], [llvm_anyint_ty], []>; }
Added another def in: otwm/llvm-project/clang/include/clang/Basic/BuiltinsX86.def
TARGET_BUILTIN(__builtin_register_my_mem, "vv*", "", "")
Added my library source (*.c, *.h) to the compiler-rt/lib/test_lib and added to CMakeLists.txt
WAS:
FunctionCallee sm_func =
curr_inst->getModule()->getOrInsertFunction("register_my_mem",
func_type);
ArrayRef<Value*> args = {
builder.CreatePointerCast(sm_arg_val, currType->getPointerTo())
};
builder.CreateCall(sm_func, args);
NEW:
Intrinsic::ID aREGISTER(Intrinsic::x86_register_my_mem);
Function *sm_func = Intrinsic::getDeclaration(currFunc->getParent(),
aREGISTER, func_type);
ArrayRef<Value*> args = {
builder.CreatePointerCast(sm_arg_val, currType->getPointerTo())
};
builder.CreateCall(sm_func, args);
Questions:
My LLVM compiles, so it is semantically correct, but currently when trying to insert this function call, LLVM segfaults saying "Not a valid type for function argument!"
I'm seeing multiple issues here.
Indeed, you're confusing LTO with intrinsics. Intrinsics are special "functions" that are either expanded into special instructions by a backend or lowered to library function calls. This is certainly not something you're going to achieve. You don't need an intrinsic at all, you'd just need to inline the function call in question: either by hands (from your module pass) or via LTO, indeed.
The particular error comes because you're declaring your intrinsic as receiving an integer argument (and this is how the declaration would look like), but:
func_type
is a non-integer type)Hope this makes an issue clear.