Penso che tu stia chiedendo di Analisi del flusso di dati .
Prima di SSA, dovremmo usare i vettori bit, dove ciascun bit nel vettore bit rappresenta una variabile nel metodo che viene compilato (potrebbe essere una variabile di programma o un registro cpu reale o virtuale). Useremmo una coppia di vettori bit, uno per i difetti e uno per gli usi, e tali vettori bit sarebbero concettualmente collegati ad ogni istruzione; anche se in pratica, in genere memorizziamo tali vettori di bit all'inizio e alla fine di ogni blocco di base.
Questi vettori di bit vengono inizialmente calcolati attraversando ogni blocco di base: andando avanti attraverso il blocco, la definizione di raggiungimento alla fine del blocco di base ha un bit impostato per ogni variabile impostata (def'd) nel blocco di base e, andando indietro nel blocco, gli usi esposti verso l'alto all'inizio del blocco di base hanno un bit impostato per ciascuna variabile che viene utilizzata all'interno del blocco di base. Durante l'attraversamento all'indietro, una def mask utilizza la stessa variabile, quindi solo le variabili utilizzate e non mascherate lo rendono in quel vettore di bit memorizzato per l'inizio del blocco.
Quindi i vettori di bit per i blocchi di base vengono propagati per tutto il metodo che viene compilato (ad esempio gli altri blocchi di base) attraversando il grafico del flusso di controllo, unendo le informazioni fino a quando non vengono apportate modifiche (le funzioni di unione sono punti fissi, ovvero convergono). Se riconosciamo particolari costrutti del flusso di controllo (while loop, if then, etc ...), possiamo fermare la fusione prima dell'iterazione finale, in cui non si verificano cambiamenti.
Durante l'utilizzo, una volta calcolato il flusso di dati per il metodo, è possibile eseguire l'ottimizzazione come codice morto. Questa ottimizzazione potrebbe iniziare alla fine di un blocco di base, iniziando con l'uso di vettori bit e camminando all'indietro. Attraversando all'indietro, una copia del vettore di bit utilizza potrebbe essere modificata secondo ciascuna istruzione in modo da avere informazioni sul livello di istruzione.
Il codice morto (in termini di variabili assegnate ma non utilizzate) viene quindi rilevato sapendo che, in una def specifica, quella variabile non è nel set di utilizzo. L'istruzione che calcola che def può essere eliminata. Il flusso di dati deve essere aggiornato di conseguenza, ed è normale quindi trovare più istruzioni (in precedenza, quelle che calcolavano i valori per l'istruzione eliminata da usare) che ora sono anche morti.
SSA - introducendo una nuova versione di una variabile (ad esempio ogni volta che viene assegnata) e quindi monitorando le versioni di variabili anziché solo le variabili - consente ad alcune delle informazioni raccolte di flusso di dati di applicarsi all'intero metodo, invece di variare per posizione nel codice come prima di SSA.