linker - for - Vinculación del código JIT de LLVM con las funciones externas de C++
llvm 3.7 1 (3)
Suponiendo que no lo ha deshabilitado (al llamar a EE->DisableSymbolSearching()
), LLVM usará dlsym()
para buscar los símbolos en el programa JIT. Dependiendo de su plataforma, eso podría significar que necesita construir su JIT con -fPIC
, o que podría no estar disponible en absoluto (como en Windows).
Además de la búsqueda automática de símbolos, usted mismo puede registrar las funciones individuales usando EE->addGlobalMapping(GV, &function)
donde GV = la declaración de la función llvm :: Function * que coincide con la función nativa a la que llama. En tu caso con ertf () eso es:
EE->addGlobalMapping(erft, &::erft);
Tenga en cuenta que ha nombrado la función global erft()
y la variable local erft
, de ahí el "::". ¡Elija diferentes nombres la próxima vez!
Estoy escribiendo un motor de scripts LLVM que JIT compila código de scripting en un lenguaje personalizado. Mi problema es que no puedo llamar a funciones externas (incluso la función C99 erf () está fallando).
Por ejemplo, si extiendo "C" la función erf,
extern "C" double erft(double x){
return erf(x);
}
y crea una función con enlace externo
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);
Obtenga el siguiente mensaje de error cuando ejecute mi script con erft (0.0):
ERROR DE LLVM: ¡El programa utilizó la función externa ''erft'' que no se pudo resolver!
Hacer el mapeo manualmente
void ExecutionEngine::addGlobalMapping( const GlobalValue * erfF, void * erft);
me dará el siguiente error:
declaración de `void llvm :: ExecutionEngine :: addGlobalMapping (const llvm :: GlobalValue *, void *) ''fuera de clase no es definición
Obviamente estoy haciendo algo muy malo. Cualquier ayuda sería muy apreciada
No lo sé, pero esto no tiene sentido:
void ExecutionEngine::addGlobalMapping( const GlobalValue * erfF, void * erft);
Eso define una nueva función en C ++. Lo que debe hacer es registrar de alguna manera su función con LLVM. Definir esa función es como intentar agregar nuevos métodos a las clases de LLVM, no lo que quieres hacer.
Esto podría estar sucediendo porque olvidó agregar la dependencia de "libm", intente usar:
[your module]->addLibrary("m");
Consulte aquí para obtener más información sobre el Module::addLibrary()
.