Domanda

Nei tutorial e negli esempi di llvm, il compilatore restituisce LLVM IR effettuando chiamate come questa

return Builder.CreateAdd(L, R, "addtmp");

ma molti interpreti sono scritti così:

switch (opcode) {
     case ADD:
             result = L + R;
             break;
     ...

Come estrarresti ciascuno di questi frammenti di codice per creare un JIT con LLVM senza dover reimplementare ciascun codice operativo in LLVM IR?

È stato utile?

Soluzione

Ok, prima prendi tutti i tuoi frammenti di codice e rifattorizzali nelle rispettive funzioni.Quindi il tuo codice va a:

void addOpcode(uint32_t *result, uint32_t L, uint32_t R) {
    *result = L + R;
}

switch (opcode) {
    case ADD:
            addOpcode(&result, L, R);
            break;
     ....

Ok, quindi dopo aver fatto questo il tuo interprete dovrebbe ancora funzionare.Ora prendi tutte le nuove funzioni e inseriscile nel proprio file.Ora compila quel file usando llvm-gcc o clang e invece di generare codice nativo compilalo usando il comando back-end "cpp". (-marzo -cpp).Ciò genererà codice C++ che istanzia il codice byte per l'unità di compilazione.È possibile specificare le opzioni per limitarlo a funzioni specifiche, ecc.Probabilmente vorrai usare "-cppgen module" .

Ora esegui il loop dell'interprete e incolla insieme le chiamate al codice C++ generato invece di eseguire direttamente il codice originale, quindi passalo ad alcuni ottimizzatori e a un generatore di codice nativo.Gratz sul JIT ;-) Puoi vederne un esempio in un paio di progetti LLVM, come vm_ops in lvm-lua.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top