Mi aplicación necesita ejecutar muchos contextos separados en el mismo proceso (de un único subproceso). Todos ellos comparten un solo LLVMContext
.sugerencia de diseño: llvm contextos de tiempo de ejecución múltiples
El proceso se ejecutará en muchos contextos (en el sentido del hilo); es decir, cada uno ejecuta una función en un objeto de continuación basado en boost::context
(todavía en bóveda, lib preaprobada) significa que cada contexto puede ceder, pero básicamente se ejecutan en el mismo proceso de subproceso único. Cada uno debe ejecutarse básicamente de forma independiente del otro, y lo que es más importante, un error de compilación en cada uno no debe afectar la ejecución de los demás.
Cada uno de estos contextos invocará el código dinámicamente que abarca varias unidades de traducción (TU). algunas unidades de traducción se pueden compartir en muchos de estos contextos. los errores de compilación en una unidad de traducción nueva o modificada no deberían afectar a otros contextos.
Aclaración Edición: Por ejemplo, T.U. A puede compartirse entre dos contextos, el contexto X e Y. solo por el hecho de tener una imagen completa, digamos que X también ejecutará código de otras unidades de traducción, es decir, B y D, mientras que Y también tendrá C. En algún punto, X decide hacer una modificación a A, por lo que crea una nueva TU A.1, que es una copia de A, y aplica la modificación allí, por lo que no afectará el contexto Y. Espero que este ejemplo aclare la requisito.
Mi impulso inicial era asociar una llvm::Module
para cada contexto, pero desde su indefinida en LLVM lo que sucede con un módulo en un estado intermedio de compilación, que decidió añadir una llvm::Module
para cada unidad de traducción (ver this question for the reason), además de la política de copia sobre escritura que expliqué anteriormente para cuando las modificaciones de una unidad de traducción ocurren localmente en un contexto, con el fin de evitar una modificación que afecte a otros contextos.
La principal pregunta de dos veces que he tengo es:
¿Cómo se enlazan entre sí los diferentes módulos en un contexto con el fin de invocarlos como una biblioteca unificada? Estoy usando la API de C++. Soy particularmente cauteloso con this nasty, old bug que afecta esta funcionalidad. ¿Esta falla aún me afectaría si transfiere la propiedad de todos los módulos al JIT con
ExecutionEngine::addModule()
?¿Cuáles son los pasos necesarios una vez que una modificación en una unidad de traducción fuerza la actualización de uno de los módulos? ¿Debo soltar/eliminar el antiguo objeto del módulo y crear uno nuevo? ¿Existe una política de reciclaje que no haya leído?
Una cuestión secundaria que tengo de este es:
- ¿Cuántas
ExecutionEngine
necesito? uno para toda la aplicación? uno por contexto? uno por módulo?
Espero que el alcance de la pregunta no sea demasiado abrumador.
No soy un experto, pero creo que puedo agregar algo aquí para al menos comenzar. A la pregunta 1a: la parte inferior de [su enlace] (http://llvm.org/bugs/show_bug.cgi?id=2606) parece afirmativa que arrojar sus módulos en JIT funcionará efectivamente alrededor del error. Para 1b: los [documentos de API] (http://llvm.org/docs/doxygen/html/classllvm_1_1Module.html) sugieren que no hay reciclaje de recursos, solo una [estructura de paso] (http://llvm.org/docs/WritingAnLLVMPass) .html). Entonces, depende de la mutación de tus módulos. A 2: digo, deje que su diseño y necesidades lo determinen, dadas las soluciones a sus primeras dos preguntas. ¡Buena suerte! – MrGomez
Y eso es tan expresamente escueto como puedo hacer mi pseudo-respuesta. Avíseme si prefiere formalizar esto en una respuesta real, a pesar de mi error admitido a través de las notas de diseño, la documentación y la teoría de compilación detrás de cómo opera LLVM. – MrGomez