stringtranslate.com

Análisis de variables en vivo

En los compiladores , el análisis de variables activas (o simplemente análisis de vida ) es un análisis clásico de flujo de datos para calcular las variables que están activas en cada punto del programa. Una variable está activa en algún punto si contiene un valor que puede ser necesario en el futuro o, equivalentemente, si su valor puede leerse antes de la próxima vez que se escriba en la variable.

Ejemplo

Consideremos el siguiente programa:

b = 3c = 5a = f(b * c)

El conjunto de variables vivas entre las líneas 2 y 3 es { b, c} porque ambas se utilizan en la multiplicación en la línea 3. Pero el conjunto de variables vivas después de la línea 1 es solo { b}, ya que variable cse actualiza más tarde, en la línea 2. El valor de variable ano se utiliza en este código.

Tenga en cuenta que la asignación a apuede eliminarse ya que ano se utiliza más adelante, pero no hay suficiente información para justificar la eliminación de toda la línea 3, ya que fpuede tener efectos secundarios (impresión b * c, tal vez).

Expresión en términos de ecuaciones de flujo de datos

El análisis de vitalidad es un análisis "puede ser hacia atrás". El análisis se realiza en orden inverso y el operador de confluencia del flujo de datos se establece como union . En otras palabras, si se aplica el análisis de vitalidad a una función con una cantidad particular de ramas lógicas dentro de ella, el análisis se realiza comenzando desde el final de la función y avanzando hacia el principio (de ahí "hacia atrás"), y una variable se considera activa si alguna de las ramas que avanzan dentro de la función podría potencialmente (de ahí "puede") necesitar el valor actual de la variable. Esto contrasta con un análisis "debe ser hacia atrás" que, en cambio, impondría esta condición en todas las ramas que avancen.

Las ecuaciones de flujo de datos utilizadas para un bloque básico dado s y un bloque de salida f en el análisis de variables en vivo son las siguientes:

:El conjunto de variables que se utilizan en s antes de cualquier asignación en el mismo bloque básico.
:El conjunto de variables a las que se les asigna un valor en s (en muchos libros que tratan sobre el diseño de compiladores, KILL(s) también se define como el conjunto de variables a las que se les asigna un valor en s antes de cualquier uso , pero esto no cambia la solución de la ecuación del flujo de datos):


El estado de entrada de un bloque es el conjunto de variables que están activas al comienzo del bloque. Su estado de salida es el conjunto de variables que están activas al final del mismo. El estado de salida es la unión de los estados de entrada de los sucesores del bloque. La función de transferencia de una instrucción se aplica haciendo que las variables que se escriben queden inactivas y luego haciendo que las variables que se leen queden activas.

Segundo ejemplo

El estado de entrada de b3 solo contiene b y d , ya que c ya se escribió. El estado de salida de b1 es la unión de los estados de entrada de b2 y b3. La definición de c en b2 se puede eliminar, ya que c no está activo inmediatamente después de la declaración.

La solución de las ecuaciones de flujo de datos comienza con la inicialización de todos los estados de entrada y salida en el conjunto vacío. La lista de trabajo se inicializa insertando el punto de salida (b3) en la lista de trabajo (típico para el flujo inverso). Su estado de entrada calculado difiere del anterior, por lo que se insertan sus predecesores b1 y b2 y el proceso continúa. El progreso se resume en la siguiente tabla.

Tenga en cuenta que b1 se introdujo en la lista antes que b2, lo que obligó a procesar b1 dos veces (b1 se volvió a introducir como predecesor de b2). La inserción de b2 antes de b1 habría permitido completarlo antes.

Inicializar con el conjunto vacío es una inicialización optimista: todas las variables comienzan como inactivas. Nótese que los estados externos no pueden reducirse de una iteración a la siguiente, aunque el estado externo puede ser más pequeño que el estado interno. Esto se puede ver en el hecho de que después de la primera iteración el estado externo solo puede cambiar mediante un cambio del estado interno. Dado que el estado interno comienza como el conjunto vacío, solo puede crecer en iteraciones posteriores.

Referencias

Aho, Alfred; Lam, Monica; Sethi, Ravi; Ullman, Jeffrey (2007). Compiladores: principios, técnicas y herramientas (2.ª ed.). pág. 608.