Итак … Я недавно (~ 2 недели) нырял в LLVM. Я прочитал документы, прошел учебники и т. Д.
Я решил попробовать кое-что еще, а именно включить типы в учебник по калейдоскопу. Я сразу же ударился о стену, когда обнаружил, что MCJIT будет запускать только функцию Function () для функций с сигнатурами основного стиля. Теперь я понимаю, почему учебник оборачивает функции в функцию anon …
Я потратил много времени, пытаясь найти что-то на этом, и не повезло. Я не могу найти никаких примеров этого в Интернете, что кажется странным. Я смог изменить ExecutionEngine, чтобы использовать Interpreter, и получил отличные результаты, однако это кажется бессмысленным, я могу просто написать «базовую библиотеку» на c ++ и вызвать функции условно.
Я знаю, что могу завершитьObject () и получить указатель на функцию, но он просто перемещает вещи назад на единицу, так как мне нужно привести функцию, и хотя я знаю сигнатуру функции, я не знаю способа динамического преобразования указателя функции.
Мой вопрос предполагает, что у меня есть готовая функция LLVM, добавленная в модуль и т. Д. Как я могу вызвать эту функцию через MCJIT?
Спасибо за любую помощь.
Ниже мой текущий блокнот кода.
InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
LLVMContext context;
IRBuilder<> Builder(context);
std::unique_ptr<Module> Owner(new Module("test", context));
Module *module = Owner.get();
Function* func = cast<Function>(module->getOrInsertFunction("add-test", Type::getInt32Ty(context), Type::getInt32Ty(context), Type::getInt32Ty(context), NULL));
BasicBlock* block = BasicBlock::Create(context, "entry", func);
Builder.SetInsertPoint(block);
Function::arg_iterator args = func->arg_begin();
Argument *arg_l = &*func->arg_begin();
arg_l->setName("arg_l");
Argument *arg_r = &(*++func->arg_begin());
arg_r->setName("arg_r");
Value* add = BinaryOperator::CreateAdd(arg_l, arg_r, "real-add", block);
ReturnInst::Create(context, add, block);
std::string errStr;
ExecutionEngine *EE = EngineBuilder(std::move(Owner)).setErrorStr(&errStr).create();
if (!EE) {
errs() << "Failed to start Execution Engine";
return;
}
EE->finalizeObject();
А теперь, если я получу указатель на функцию, Успех! оно работает.
int (*function)(int, int) = (int (*)(int, int))EE->getPointerToFunction(func);
int resi = function(11, 13);
outs() << "Result: " <<resi << "\n";
Но если я попытаюсь запустить функцию в EE, то получу «Полнофункциональная передача аргументов еще не поддерживается!»
std::vector<GenericValue> Args(2);
Args[0].IntVal = APInt(32, 1);
Args[1].IntVal = APInt(32, 2);
GenericValue GV = EE->runFunction(func, Args);
outs() << "Result: " << GV.IntVal << "\n";
Задача ещё не решена.
Других решений пока нет …