Связывание JL-кода LLVM с внешними функциями C ++ - PullRequest
18 голосов
/ 13 декабря 2010

Я пишу механизм сценариев LLVM, который JIT компилирует код сценариев на пользовательском языке. Моя проблема в том, что я не могу вызвать внешние функции (даже функция C99 erf () не работает).

Например, если я наберу "С" функцию erf,

extern "C" double erft(double x){
return erf(x);
}

и создать функцию с внешней связью

std::vector<const Type*> Double1(1,Type::getDoubleTy(getGlobalContext()));
FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),Double1,false);
Function *erft = Function::Create(FT,Function::ExternalLinkage,"erft",TheModule);

получить следующее сообщение об ошибке при запуске моего скрипта с erft (0.0):

ОШИБКА LLVM: Программа использовала внешнюю функцию 'erft', которая не может быть разрешена!

Выполнение сопоставления вручную,

void ExecutionEngine::addGlobalMapping( const GlobalValue *  erfF, void *  erft); 

выдаст мне следующую ошибку:

объявление `void llvm :: ExecutionEngine :: addGlobalMapping (const llvm :: GlobalValue *, void *) 'вне класса не является определением

Очевидно, я делаю что-то очень неправильное. Любая помощь будет высоко ценится

Ответы [ 3 ]

15 голосов
/ 22 мая 2011

Если вы не отключили его (вызвав EE->DisableSymbolSearching()), тогда LLVM будет использовать dlsym() для поиска символов в самой программе JIT.В зависимости от вашей платформы это может означать, что вам нужно собрать JIT с -fPIC или что он может быть недоступен вообще (например, в Windows).

Помимо автоматического поиска символов, вы можетевсегда регистрируйте отдельные функции самостоятельно, используя EE->addGlobalMapping(GV, &function), где GV = объявление функции llvm :: Function *, соответствующее исходной функции, которую вы вызываете.В вашем случае с ertf () это:

EE->addGlobalMapping(erft, &::erft);

Обратите внимание, что вы назвали глобальную функцию erft() и локальную переменную erft, следовательно, "::".Пожалуйста, выберите другие имена в следующий раз!

2 голосов
/ 09 марта 2011

Это может произойти, потому что вы забыли добавить зависимость "libm", попробуйте использовать:

[your module]->addLibrary("m");

См. здесь для получения дополнительной информации о Module::addLibrary().

0 голосов
/ 13 декабря 2010

Я не знаю llvm, но это не имеет смысла:

void ExecutionEngine::addGlobalMapping( const GlobalValue *  erfF, void *  erft); 

Это определяет новую функцию в C ++. Вам нужно как-то зарегистрировать свою функцию в LLVM. Определение этой функции похоже на попытку добавить новые методы в классы LLVM, а не то, что вы хотите сделать.

...