Вызов универсальной функции с LLVM MCJIT

Итак … Я недавно (~ 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";

1

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]