Rappresentazione intermedia - Intermediate representation

Una rappresentazione intermedia ( IR ) è la struttura dati o il codice utilizzato internamente da un compilatore o da una macchina virtuale per rappresentare il codice sorgente . Un IR è progettato per favorire ulteriori elaborazioni, come l' ottimizzazione e la traduzione . Un "buono" IR deve essere accurato , in grado di rappresentare il codice sorgente senza perdita di informazioni, e indipendente da una particolare lingua di origine o di destinazione. Un IR può assumere una delle diverse forme: una struttura dati in memoria o un codice speciale basato su tuple o stack leggibile dal programma. In quest'ultimo caso è anche chiamato lingua intermedia .

Un esempio canonico si trova nella maggior parte dei compilatori moderni. Ad esempio, l'interprete CPython trasforma il testo lineare leggibile dall'uomo che rappresenta un programma in una struttura grafica intermedia che consente l' analisi del flusso e la riorganizzazione prima dell'esecuzione. L'uso di una rappresentazione intermedia come questa consente ai sistemi di compilazione come GNU Compiler Collection e LLVM di essere utilizzati da molti linguaggi sorgente diversi per generare codice per molte architetture di destinazione .

Linguaggio intermedio

Un linguaggio intermedio è il linguaggio di una macchina astratta progettata per aiutare nell'analisi dei programmi per computer . Il termine deriva dal loro uso nei compilatori , in cui il codice sorgente di un programma viene tradotto in una forma più adatta a trasformazioni di miglioramento del codice prima di essere utilizzato per generare codice oggetto o macchina per una macchina di destinazione. La progettazione di un linguaggio intermedio tipicamente differisce da quella di un linguaggio macchina pratico in tre modi fondamentali:

Un formato popolare per le lingue intermedie è il codice a tre indirizzi .

Il termine è anche usato per riferirsi a linguaggi usati come intermedi da alcuni linguaggi di programmazione di alto livello che non emettono oggetti o codici macchina stessi, ma emettono solo il linguaggio intermedio. Questo linguaggio intermedio viene inviato a un compilatore per tale linguaggio, che quindi restituisce l'oggetto finito o il codice macchina. Questo è solitamente fatto per facilitare il processo di ottimizzazione o per aumentare la portabilità utilizzando un linguaggio intermedio che ha compilatori per molti processori e sistemi operativi , come ad esempio C . Le lingue utilizzate per questa caduta di complessità tra linguaggi di alto livello e linguaggi di basso livello , come i linguaggi assembly .

Le lingue

Sebbene non sia stato esplicitamente concepito come linguaggio intermedio, la natura del C come astrazione dell'assembly e la sua ubiquità come linguaggio di sistema de facto in sistemi operativi simili a Unix e altri lo hanno reso un popolare linguaggio intermedio: Eiffel , Sather , Esterel , alcuni i dialetti di Lisp ( Lush , Gambit ), Haskell ( Glasgow Haskell Compiler ), Squeak 's Smalltalk-subset Slang, Cython , Seed7 , SystemTap , Vala , V e altri fanno uso del C come linguaggio intermedio. Le varianti di C sono state progettate per fornire le funzionalità del C come linguaggio assembly portatile , inclusi C-- e C Intermediate Language .

Qualsiasi linguaggio destinato a una macchina virtuale o a una macchina con codice p può essere considerato un linguaggio intermedio:

La GNU Compiler Collection (GCC) utilizza internamente diversi linguaggi intermedi per semplificare la portabilità e la compilazione incrociata . Tra queste lingue ci sono

  • lo storico Register Transfer Language (RTL)
  • il linguaggio dell'albero GENERICO
  • il GIMPLE basato su SSA . (Livello inferiore a GENERIC; input per la maggior parte degli ottimizzatori; ha una notazione "bytecode" compatta.)

GCC supporta la generazione di questi IR, come obiettivo finale:

Il framework del compilatore LLVM si basa sul linguaggio intermedio LLVM IR , la cui rappresentazione compatta e binaria serializzata viene anche definita "bitcode" ed è stata prodotta da Apple. Come GIMPLE Bytecode, LLVM Bitcode è utile nell'ottimizzazione del tempo di collegamento. Come GCC, anche LLVM prende di mira alcuni IR destinati alla distribuzione diretta, inclusi PNaCl IR e SPIR di Google . Un ulteriore sviluppo all'interno di LLVM è l'uso della rappresentazione intermedia multilivello (MLIR) con la possibilità di generare codice per diversi obiettivi eterogenei e di combinare gli output di diversi compilatori.

Il linguaggio intermedio ILOC viene utilizzato nelle classi sulla progettazione del compilatore come semplice linguaggio di destinazione.

Altro

Gli strumenti di analisi statica utilizzano spesso una rappresentazione intermedia. Ad esempio, radare2 è una cassetta degli attrezzi per l'analisi dei file binari e il reverse engineering. Utilizza i linguaggi intermedi ESIL e REIL per analizzare i file binari.

Guarda anche

Riferimenti

link esterno