2010-12-13 17 views
15

Estoy escribiendo un motor de scripts de LLVM que JIT compila el 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).Vinculación del código JIT de LLVM a funciones externas de C++

Por ejemplo si extern la función erf "C",

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

y crear 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); 

obtener el siguiente mensaje de error al ejecutar mi script con Erft (0.0):

LLVM ERROR: Program used external function 'erft' which could not be resolved!

Hacer el mapeo manualmente,

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

me va a conseguir el error siguiente:

declaration of `void llvm::ExecutionEngine::addGlobalMapping(const llvm::GlobalValue*, void*)' outside of class is not definition

Obviamente estoy haciendo algo muy mal. Cualquier ayuda se agradece mucho

+1

Una advertencia para futuros visitantes: las respuestas se refieren a métodos en desuso ... – antipattern

+0

La respuesta a [esto] (https://stackoverflow.com/questions/48105342/llvm-jit-add-library-to-module) La pregunta muestra cómo hacer esto con métodos no desaprobados. –

Respuesta

0

No sé llvm, pero esto no tiene sentido:

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

que 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.

2

Esto podría estar ocurriendo porque se le olvidó añadir el depedency "libm", trate de usar:

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

Ver here para obtener más información sobre el Module::addLibrary().

13

Suponiendo que no lo ha deshabilitado (llamando al EE->DisableSymbolSearching()) entonces LLVM utilizará dlsym() para encontrar 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, siempre puede registrar las funciones individuales usted mismo usando EE->addGlobalMapping(GV, &function) donde GV = la declaración de función llvm :: Function * que coincide con la función nativa que está llamando. En su caso con ERTF() que es:

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

Tenga en cuenta que usted nombró la función global erft() y la variable local erft, de ahí el "::". ¡Elija diferentes nombres la próxima vez!

Cuestiones relacionadas