2012-02-06 18 views
11

Desidero leggere (analizzare) codice LLVM IR (che viene salvato in un file di testo) e aggiungervi un po 'del mio codice. Ho bisogno di qualche esempio per farlo, cioè, come si fa usando le librerie fornite da LLVM per questo scopo. Quindi in pratica quello che voglio è leggere il codice IR da un file di testo nella memoria (forse la libreria LLVM lo rappresenta in forma AST, non lo so), apportare modifiche, come aggiungere altri nodi nell'AST e quindi scrivere finalmente indietro il AST nel file di testo IR.Analisi e modifica codice LLVM IR

Anche se ho bisogno di leggere e modificare il codice IR, sarei molto grato se qualcuno potesse fornirmi o riferirmi ad un esempio che ha appena letto (lo analizza).

risposta

24

In primo luogo, per correggere un evidente fraintendimento: LLVM è un framework per la manipolazione del codice in formato IR. Non ci sono AST in vista (*): si legge IR, si trasforma/manipola/si analizza e si scrive di nuovo IR.

lettura IR è davvero semplice:

int main(int argc, char** argv) 
{ 
    if (argc < 2) { 
     errs() << "Expected an argument - IR file name\n"; 
     exit(1); 
    } 

    LLVMContext &Context = getGlobalContext(); 
    SMDiagnostic Err; 
    Module *Mod = ParseIRFile(argv[1], Err, Context); 

    if (!Mod) { 
     Err.print(argv[0], errs()); 
     return 1; 
    } 

    [...] 
    } 

Questo codice accetta un nome di file. Questo dovrebbe essere un file IR LLVM (testuale). Passa quindi ad analizzarlo in un Module, che rappresenta un modulo di IR nel formato interno di memoria di LLVM. Questo può quindi essere manipolato con i vari pass LLVM o aggiunti da soli. Dai un'occhiata ad alcuni esempi nella base di codice LLVM (come lib/Transforms/Hello/Hello.cpp) e leggi questo - http://llvm.org/docs/WritingAnLLVMPass.html.

L'emissione di IR in un file è ancora più semplice. La classe Module appena si scrive ad un flusso:

some_stream << *Mod; 

Questo è tutto.

Ora, se avete specifici domande su specifiche modifiche che si desidera fare per codice IR, si dovrebbe davvero chiedere qualcosa di più mirato. Spero che questa risposta ti mostri come analizzare IR e scriverlo di nuovo.


(*) IR non ha una rappresentazione AST all'interno LLVM, perché è un semplice linguaggio assembly-like. Se vai avanti di un passo, in C o C++, puoi usare Clang per analizzarlo in AST e poi fare manipolazioni a livello AST. Clang quindi sa come produrre LLVM IR dal suo AST. Tuttavia, devi iniziare con C/C++ qui, e non con LLVM IR. Se LLVM IR è tutto ciò che ti interessa, dimentica gli AST.

+0

Grazie Eli. La tua risposta è stata molto utile. – MetallicPriest

+0

Heads up, penso che dovrebbe essere "parseIRFile" con una p minuscola. http://llvm.org/docs/doxygen/html/IRReader_2IRReader_8h_source.html – user2027722

+0

@ user2027722: sì, le API LLVM cambiano così spesso che è difficile mantenere aggiornati i campioni. Ho un repository Github per questo: https://github.com/eliben/llvm-clang-samples che mantengo il più sincronizzato possibile, ed è più una fonte di verità che un SO casuale risponde all'errore –

1

Il modo più semplice per farlo è guardare uno degli strumenti esistenti e rubare il codice da esso. In questo caso, potresti voler consultare la fonte di llc. Può contenere un codice bit o un file .ll come input. È possibile modificare il file di input nel modo desiderato e quindi scrivere il file utilizzando qualcosa di simile al codice in llvm-dis se si desidera un file di testo.

2

Questo di solito viene eseguito implementando un passaggio/trasformazione LLVM. In questo modo non è necessario analizzare l'IR perché LLVM lo farà per te e opererai su una rappresentazione in memoria orientata OO dell'IR.

This è il punto di ingresso per la scrittura di un pass LLVM. Quindi puoi guardare tutti i passaggi standard già implementati forniti in bundle con LLVM (guarda su lib/Transforms).

+0

Questo sarebbe quello che farò alla fine. Ma in questo momento, dato che sono in fase di apprendimento, voglio essere in grado di vedere l'IR nei file di testo. – MetallicPriest

+3

Non vedo il problema. La maggior parte degli strumenti LLVM può leggere/scrivere la rappresentazione testuale dell'IR. In particolare, per emettere la rappresentazione testuale, aggiungere l'opzione -S alla riga di comando. (Inoltre, ricorda sempre che la rappresentazione binaria e testuale sono assolutamente equivalenti). – CAFxX

1

Lo strumento Opt prende il codice IR llvm, esegue un passaggio su di esso e quindi sputa IR llvm trasformato sull'altro lato.

Il modo più semplice per iniziare l'hacking è lib \ Transforms \ Hello \ Hello.cpp. Hack it, run through opt con il tuo file sorgente come input, ispeziona output.

A parte questo, i documenti per la scrittura dei passaggi sono davvero buoni.

1

Come già detto, il modo migliore per scrivere un passaggio. Ma se vuoi semplicemente scorrere le istruzioni e fare qualcosa con il LLVM fornito una classe InstVisitor. È una classe che implementa il modello di visitatore per le istruzioni. È molto semplice per l'utente, quindi se vuoi evitare di imparare come implementare un pass, potresti ricorrere a quello.