Sto cercando di capire una tecnica per ottimizzare il bytecode per la seguente macchina virtuale:
-
Bytecode è una lista di istruzioni piatte, con esecuzione a partire dalla prima istruzione.
-
Stack bytecode: istruzioni come i ++, a + b, il metodo chiama f (a, b, c), ecc. si verificano nei primi 1, 2, N valori su una pila di operandi, e lasciano il loro risultato su la parte superiore dello stack di operandi
-
Bytecode per eliminare il valore superiore dello stack, ad es. se chiami un metodo per effetti collaterali ma non vuoi il valore restituito
-
Un array di N variabili locali, istruzioni per copiare i valori da una variabile locale a / dalla parte superiore dello stack degli operandi
-
GOTO incondizionato, JUMP condizionali con vari predicati nella parte superiore dello stack degli operandi
-
Istruzioni per l'effetto collaterale: lettura / scrittura del valore superiore della pila di operandi su variabili globali
L'input sarà un codice byte valido per questa macchina virtuale, ma con qualche ridondanza: alcune istruzioni saranno irraggiungibili, alcune variabili che sono calcolate sull'operando-stack verranno spuntate, alcune variabili memorizzate in variabili locali andranno oltre -cristati senza essere mai letti, alcuni GOTO andranno prima a un altro GOTO anziché direttamente alla destinazione finale.
Lo so per cominciare, un traversal in avanti che segue i salti ci dirà dove sono le istruzioni raggiungibili e cerchiamo di eliminare le istruzioni irraggiungibili. Ma che dire degli altri: ottimizzazione dei valori non utilizzati di calcolo del codice di uscita o GOTO ridondanti?
So che per i programmi senza effetti collaterali posso calcolare un grafico del flusso di dati, a partire dal valore restituito, e tornare indietro per vedere quali valori calcolati non sono utilizzati. Ma questo non sembra funzionare nel caso in cui ci sono effetti collaterali di cui ho bisogno di preservare l'ordine, dal momento che un grafico di flusso di dati li ignorerebbe. Presumibilmente avrò bisogno di un grafico di controllo in aggiunta al grafico del flusso di dati, ma non sono sicuro di come i due grafici funzionerebbero insieme per aiutarmi a ottimizzare il bytecode.
Che tipo di tecniche posso utilizzare per ottimizzare quelle via in presenza di flusso di controllo e effetti collaterali globali (sia in lettura che in scrittura) di cui è necessario preservare l'ordine? In questo modo, CPS o SSA o altri formati di rappresentazione intermedi sono di aiuto?