Предоставление внутренней функции C ++ для llvm jit’d Stack Overflow

Я пытаюсь поэкспериментировать с llvm прямо сейчас. Я хотел бы использовать языки, которые могут быть скомпилированы в LLVM битовый код для сценариев. До сих пор мне удавалось загрузить модуль битового кода llvm и вызвать функцию, определенную в нем, из моего «внутреннего» кода C ++. Затем я попытался представить функцию c ++ из своего внутреннего кода jit’d-коду — до сих пор в этих усилиях мне не удалось получить ничего, кроме SEGFAULT.

Мой код выглядит следующим образом. Я попытался создать функцию и глобальное отображение в моем механизме выполнения, которое указывает на функцию, которую я хотел бы вызвать.

extern "C" void externGuy()
{
cout << "I'm the extern guy" << endl;
}
void ExposeFunction()
{
std::vector<Type*> NoArgs(0);
FunctionType* FT = FunctionType::get(Type::getVoidTy(getGlobalContext()), NoArgs, false);
Function* fnc = Function::Create(FT, Function::ExternalLinkage, "externGuy", StartModule);
JIT->addGlobalMapping(fnc, (void*)externGuy);
}
// ... Create module, create execution engine
ExposeFunction();

Проблема в том, что я не могу добавить функцию в модуль после ее загрузки из файла битового кода?

Обновить:
Я реорганизовал свой код так, чтобы он читался так:

// ... Create module, create execution engine
std::vector<Type*> NoArgs(0);
FunctionType* FT = FunctionType::get(Type::getVoidTy(getGlobalContext()), NoArgs, false);
Function* fnc = Function::Create(FT, Function::ExternalLinkage, "externGuy", m);
fnc->dump();
JIT->addGlobalMapping(fnc, (void*)externGuy);

Так что вместо segfault я получаю:

Program used external function 'externGuy' which could not be resolved

Кроме того, результат dump () печатает:

declare void @externGuy1()

Если я изменю свой битовый код сценария c ++, чтобы вызвать externGuy1() вместо externGuy() это предложит мне, что я хотел использовать externGuy, addGlobalMapping просто, похоже, не работает для меня. Я не уверен, что мне здесь не хватает. Я также добавил -fPIC к моей команде компиляции, как я видел, предложено в другом вопросе — я честно не уверен, помогло ли это что-нибудь, но без вреда при попытке.

1

Решение

Я наконец получил это, чтобы работать. Я подозреваю, что, возможно, создание функции, а также ее определение в скрипте вызывает, возможно, более 1 объявления имени функции, и сопоставление просто не сработало. Что я сделал, так это определил функцию в скрипте и затем использовал getFunction использовать для сопоставления вместо. С использованием dump() метод на выходе функции:

declare void @externGuy() #1

Вот почему я думаю, что это как-то связано с тем, что отображение не работает изначально. Я также помню учебник Калейдоскопа, говорящий, что getPointerToFunction будет делать JIT-компиляцию, когда он вызывается, если это еще не сделано, поэтому я подумал, что мне придется сделать отображение перед этим вызовом.

В общем, чтобы все это работало, это было следующим:

// Get the function and map it
Function* extrn = m->getFunction("externGuy");
extrn->dump();
JIT->addGlobalMapping(extrn, (void*)&::externGuy);
// Get a pointer to the jit compiled function
Function* mane = m->getFunction("hello");
void* fptr = JIT->getPointerToFunction(mane);
// Make a call to the jit compiled function which contains a call to externGuy
void (*FP)() = (void(*)())(intptr_t)fptr;
FP();
1

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


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