2010-05-10 21 views
16

Estoy en el proceso de implementar una aplicación multiplataforma (Mac OS X, Windows y Linux) que hará un montón de análisis intensivos de CPU de datos financieros. La mayor parte del motor de análisis se escribirá en C++ por razones de velocidad, con un motor de scripting accesible para el usuario que interactúa con el motor de prueba de C++. Quiero escribir varios front-ends de scripting a lo largo del tiempo para emular otro software popular con bases de usuarios grandes ya existentes. El primer frente será un lenguaje de scripting similar a VisualBasic.Vinculación del código LLVM JIT a las bibliotecas LLVM estáticas?

Estoy pensando que LLVM sería perfecto para mis necesidades. El rendimiento es muy importante debido a la gran cantidad de datos; puede tomar horas o días ejecutar una única serie de pruebas para obtener una respuesta. Creo que el uso de LLVM también me permitirá usar una única solución de fondo mientras implemento diferentes front-ends para diferentes sabores del lenguaje de scripts a lo largo del tiempo.

El motor de prueba se separará de la interfaz y las pruebas incluso se llevarán a cabo en un proceso separado con el progreso y los resultados informados a la interfaz de administración de pruebas. Las pruebas consistirán en código de scripting integrado con el código del motor de prueba.

En una implementación anterior de un sistema de prueba comercial similar que escribí, construí un intérprete rápido que se conectaba fácilmente con la biblioteca de pruebas porque estaba escrito en C++ y vinculado directamente a la biblioteca del motor de prueba. Las retrollamadas desde el código de script hasta la prueba de los objetos de la biblioteca implican la traducción entre los formatos con una sobrecarga significativa.

Estoy imaginando que con LLVM, podría implementar las devoluciones de llamada en C++ directamente para poder hacer que el código de script funcione casi como si hubiera sido escrito en C++. Del mismo modo, si todo el código se compiló en formato de código de bytes LLVM, parece que los optimizadores de LLVM podrían optimizar a través de los límites entre el lenguaje de scripting y el código del motor de prueba que se escribió en C++.

No quiero tener que compilar el motor de prueba todo el tiempo. Idealmente, me gustaría compilar JIT solo el código de scripting. Para pruebas pequeñas, omitiría algunos pases de optimización, mientras que para pruebas grandes, realizaría optimizaciones completas durante el enlace.

¿Es esto posible? ¿Puedo precompilar el motor de prueba a un archivo de objeto .o .a. Y a un enlace en el código de escritura usando el JIT?

Finalmente, idealmente, quisiera que el código de scripting implemente métodos específicos como subclases para una clase de C++ específica. Entonces, el motor de prueba de C++ solo vería los objetos de C++ mientras el código de configuración de JIT compiló el código de scripting que implementó algunos de los métodos para los objetos. Parece que si utilicé el algoritmo correcto de creación de nombres, sería relativamente fácil configurar la generación de LLVM para que el lenguaje de scripts se parezca a una llamada de método de C++ que luego podría vincularse al motor de prueba.

Así, la etapa de vinculación sería ir en dos direcciones, las llamadas desde el lenguaje de scripts en los objetos de pruebas de motor para recuperar la información de precios y la información de estado de prueba y las llamadas desde el motor de prueba de los métodos de algunos objetos particulares de C++, donde se suministra el código no desde C++ sino desde el lenguaje de scripting.

En resumen:

1) ¿Puedo vincular en (ya sea, .o, o .a) .BC archivos precompilados como parte del proceso de generación de código de compilación JIT?

2) ¿Puedo vincular el código usando el proceso en 1) anterior de tal forma que pueda crear código que actúe como si estuviera escrito en C++?

Respuesta

14
  1. Sí, podemos! Dependiendo de la versión de LLVM que use, hay diferentes llamadas API. necesitarás llvm :: getBitcodeModuleProvider en 2.5.
  2. La forma más fácil de llamar a las funciones de C++ es crear una función (llvm :: Function :: Create) utilizando el indicador llvm :: Function :: ExternalLinkage y luego agregarGlobalMapping para que apunte a su función C++.
+0

Gracias por su ayuda. Lo comprobaré. – inflector

3
  1. Creo que sí.
  2. Esto es peludo. Debe coincidir con el ABI de C++ de las funciones a las que llama y debe asegurarse de que el código generado utilice las mismas estructuras de datos, clases, diseño, etc. (a través de un equivalente de archivos de encabezado). El C++ ABI tiene un buen número de problemas de numeración y portabilidad. Quizás prototipo con hacer interoperabilidad con C primero. clang tiene soporte limitado para C++ en este momento.
1

1) Puede cargar y vincular archivos .bc, archivos .o si se han comnpilado en un .so archivo debe ser cargable y los símbolos en ellos deben poderse utilizar.

2) Siempre que no desee hacer cosas horribles con las devoluciones de llamada, probablemente solo pueda pasar los punteros de función C estándar y hacer devoluciones de llamada mediante punteros de función. También puede hacer otras cosas, pero tratar de definir objetos o plantillas C++ o llamar a funciones miembro sin ser un compilador C++ es algo que no quiere hacer.

debes conocer el C++ ABI, debes conocer la plataforma a la que te diriges, debes saber todo tipo de cosas, efectivamente debes ser un compilador de C++ para generar código que se ve como si fuera C++. El nombre mangler es una de las partes más molestas.

Cuestiones relacionadas