2010-05-10 17 views
16

Sono in procinto di implementare un'applicazione multipiattaforma (Mac OS X, Windows e Linux) che eseguirà un'analisi intensiva della CPU dei dati finanziari. La maggior parte del motore di analisi verrà scritta in C++ per motivi di velocità, con un motore di scripting accessibile all'utente che si interfaccia con il motore di test C++. Voglio scrivere diversi front-end di scripting nel tempo per emulare altri software popolari con basi di utenti di grandi dimensioni esistenti. Il primo fronte sarà un linguaggio di scripting simile a VisualBasic.Collegamento del codice JIT LLVM alle librerie statiche LLVM?

Sto pensando che LLVM sarebbe perfetto per le mie esigenze. Le prestazioni sono molto importanti a causa della mole di dati; possono essere necessarie ore o giorni per eseguire una singola serie di test per ottenere una risposta. Credo che l'utilizzo di LLVM mi consentirà anche di utilizzare un'unica soluzione di back-end mentre implemento diversi front-end per diversi aspetti del linguaggio di scripting nel tempo.

Il motore di test stesso verrà separato dall'interfaccia e il test verrà eseguito anche in un processo separato con i progressi e i risultati riportati all'interfaccia di gestione dei test. I test saranno costituiti da codice di scripting integrato con il codice del motore di test.

In una precedente implementazione di un analogo sistema di test commerciale che ho scritto, ho creato un interprete veloce che si interfacciava facilmente con la libreria di test perché era scritto in C++ e collegato direttamente alla libreria del motore di test. Le richiamate dal codice di scripting agli oggetti della libreria di test hanno implicato la conversione tra i formati con un sovraccarico significativo.

Sto immaginando che con LLVM, potrei implementare i callback in C++ direttamente in modo che potessi far funzionare il codice di script come se fosse stato scritto in C++. Allo stesso modo, se tutto il codice è stato compilato in formato byte-code LLVM, sembra che gli ottimizzatori di LLVM possano ottimizzare i confini tra il linguaggio di scripting e il codice del motore di test che è stato scritto in C++.

Non voglio dover compilare il motore di test ogni volta. Idealmente, mi piacerebbe che JIT compilasse solo il codice di scripting. Per i test di piccole dimensioni, saltavo alcuni passaggi di ottimizzazione, mentre per i test di grandi dimensioni eseguivo ottimizzazioni complete durante il collegamento.

Quindi è possibile? Posso precompilare il motore di test in un file .o object o .a un file di libreria e quindi collegare il codice di scripting utilizzando il JIT?

Infine, idealmente, mi piacerebbe che il codice di scripting implementasse metodi specifici come sottoclassi per una specifica classe C++. Quindi il motore di test C++ vedrebbe solo oggetti C++ mentre il codice di installazione JIT ha compilato codice di script che ha implementato alcuni dei metodi per gli oggetti. Sembra che se avessi usato il giusto algoritmo di mangling dei nomi sarebbe stato relativamente facile impostare la generazione LLVM affinché il linguaggio di scripting assomigliasse a una chiamata al metodo C++ che potrebbe quindi essere collegata al motore di test.

Così la fase di collegamento andrebbe in due direzioni, chiamate dal linguaggio di scripting negli oggetti del motore di test per recuperare informazioni sui prezzi e testare le informazioni sullo stato e le chiamate dal motore di test dei metodi di alcuni particolari oggetti C++ in cui il codice è stato fornito non da C++ ma dal linguaggio di scripting.

In sintesi:

1) Posso collegare in precompilati (sia .BC, .o o .a) file come parte della compilazione JIT, processo di generazione di codice?

2) Posso collegare il codice utilizzando il processo in 1) sopra in modo tale che sono in grado di creare codice che funzioni come se fosse stato scritto interamente in C++?

risposta

14
  1. Sì, possiamo! A seconda della versione di LLVM che usi ci sono diverse chiamate API. avrai bisogno di llvm :: getBitcodeModuleProvider su 2.5.
  2. Il modo più semplice per chiamare le funzioni C++ è creare una funzione (llvm :: Function :: Create) utilizzando flag llvm :: Function :: ExternalLinkage e quindi addGlobalMapping per fare in modo che punti alla funzione C++.
+0

Grazie per il vostro aiuto. Lo controllerò. – inflector

3
  1. Credo di sì.
  2. Questo è peloso. Devi abbinare l'ABI C++ delle funzioni che stai chiamando, e devi assicurarti che il codice generato usi le stesse strutture dati, classi, layout, ecc. (Tramite un equivalente di file header). L'ABI C++ ha un numero piuttosto elevato di sfumature e problemi di portabilità. Forse il prototipo con in primo piano interop da C. clang ha un supporto limitato per C++ in questo momento.
1

1) È possibile caricare e collegare file .bc, .o i file se sono stati associati a un archivio .so dovrebbero essere caricabili e i simboli in essi dovrebbero essere in grado di essere utilizzati.

2) Finché non si desidera eseguire azioni orribili con i callback, è possibile passare semplicemente i puntatori di funzione C standard e richiamare mediante i puntatori di funzione. Puoi anche fare certe altre cose, ma occuparti di cercare di definire oggetti o modelli C++ o chiamare funzioni membro mentre non sei un compilatore C++ è qualcosa che non vuoi fare.

è necessario conoscere l'ABI C++, è necessario conoscere la piattaforma desiderata, è necessario conoscere tutti i tipi di cose, è effettivamente necessario essere un compilatore C++ per generare codice simile a C++. Il nome mangler è una delle parti più fastidiose.