ПРОБЛЕМА: В настоящее время у меня есть традиционный инструментарий модуля, который вставляет новые вызовы функций в заданный IR в соответствии с некоторой логикой (вставленные функции являются внешними по отношению к небольшой библиотеке, которая позднее связана с данной программой). При проведении экспериментов мои накладные расходы связаны с затратами на выполнение вызова функции библиотечной функции.
Что я пытаюсь сделать: Я хотел бы встроить эти тела функций в IRданная программа избавит от этого узкого места. Я предполагаю, что встроенная функция была бы чистым способом сделать это, поскольку встроенная функция была бы расширена до ее тела функции при понижении до ASM (пожалуйста, исправьте меня, если мое понимание здесь неверно, я впервые работаю с встроенными / LTO).
Текущий статус:
Мое исходное определение библиотечного вызова:
void register_my_mem(void *user_vaddr){
... C code ...
}
Пока:
Я создал определение в: llvm-project / llvm / include / llvm / IR / IntrinsicsX86.td
let TargetPrefix = "x86" в {def int_x86_register_mem: GCCBuiltin <"__buildin_register_my_mein",><[], [llvm_anyint_ty], []>;}
Добавлен еще один def в: otwm / llvm-project / clang / include / clang / Basic / BuiltinsX86.def
TARGET_BUILTIN (__buildin_register_my_mem, «vv *»,"", "")
Добавлен мой источник библиотеки (* .c, * .h) в compiler-rt / lib / test_lib и добавлен в CMakeLists.txt
- Заменена функция вставки вместо попытки вставить встроенную функцию в: llvm / lib / Transforms / Instrumentation / myModulePass.cpp
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);
Вопросы:
- Если моя логика для вставки встроенных функций не должна быть проходом модуля, куда мне его поместить?
- Не путаю ли я LTO со встроенными функциями?
- Я помещаю определения моей библиотечной функции в следующие файлы, как указано в http://lists.llvm.org/pipermail/llvm-dev/2017-June/114322.html, как, например, EmitRegisterMyMem ()?
- clang / lib / CodeGen / CodeGenFunction.cpp - определить llvm :: Instrinsic :: ID
- clang / lib / CodeGen / CodeGenFunction.h - объявить llvm :: Intrinsic :: ID
Мой LLVM компилируется, поэтому он семантически корректен, но в настоящее время при попытке вставить этот вызов функции LLVM segfaults говорит «Недопустимый тип для аргумента функции!»