stringtranslate.com

Eliminación de código muerto

En la teoría del compilador , la eliminación de código muerto ( DCE , eliminación de código muerto , eliminación de código muerto o tira de código muerto ) es una optimización del compilador para eliminar el código muerto (código que no afecta los resultados del programa). Eliminar dicho código tiene varios beneficios: reduce el tamaño del programa , una consideración importante en algunos contextos, reduce el uso de recursos como el número de bytes a transferir [1] y permite que el programa en ejecución evite ejecutar operaciones irrelevantes , lo que reduce su tiempo de ejecución . También puede permitir mayores optimizaciones al simplificar la estructura del programa. El código inactivo incluye código que nunca se puede ejecutar ( código inalcanzable ) y código que solo afecta a variables inactivas (escritas en ellas, pero nunca más leídas), es decir, irrelevantes para el programa.

Ejemplos

Considere el siguiente ejemplo escrito en C.

int foo ( vacío ) { int a = 24 ; int b = 25 ; /* Asignación a variable muerta */ int c ; c = un * 4 ; devolver c ; segundo = 24 ; /* Código inalcanzable */ return 0 ; }                          

Un análisis simple de los usos de los valores mostraría que el valor de bdespués de la primera asignación no se usa dentro de foo. Además, bse declara como una variable local en el interior foo, por lo que su valor no se puede utilizar en el exterior foo. Por lo tanto, la variable bestá muerta y un optimizador puede recuperar su espacio de almacenamiento y eliminar su inicialización.

Además, debido a que la primera declaración de retorno se ejecuta incondicionalmente y no hay ninguna etiqueta después de ella a la que pueda llegar un "goto", ninguna ruta de ejecución factible llega a la segunda asignación a b. Por lo tanto, la asignación es inalcanzable y puede eliminarse. Si el procedimiento tuviera un flujo de control más complejo , como una etiqueta después de la declaración de devolución y gotootra parte del procedimiento, entonces podría existir una ruta de ejecución factible para la asignación a b.

Además, aunque algunos cálculos se realizan en la función, sus valores no se almacenan en ubicaciones accesibles fuera del alcance de esta función. Además, dado que la función devuelve un valor estático (96), se puede simplificar al valor que devuelve (esta simplificación se llama plegado constante ).

La mayoría de los compiladores avanzados tienen opciones para activar la eliminación de código muerto, a veces en distintos niveles. Es posible que un nivel inferior solo elimine instrucciones que no se pueden ejecutar. Es posible que un nivel superior tampoco reserve espacio para variables no utilizadas. Un nivel aún más alto podría determinar instrucciones o funciones que no sirven para nada y eliminarlas.

Un uso común de la eliminación de códigos muertos es como alternativa a la inclusión de código opcional a través de un preprocesador . Considere el siguiente código.

int principal ( vacío ) { int a = 5 ; int b = 6 ; intc ; _ c = a * ( segundo / 2 ); if ( 0 ) { /* DEPURACIÓN */ printf ( "%d \n " , c ); } devolver c ; }                            

Debido a que la expresión 0 siempre se evaluará como false , el código dentro de la instrucción if nunca podrá ejecutarse y la eliminación del código muerto lo eliminaría por completo del programa optimizado. Esta técnica es común en la depuración para activar opcionalmente bloques de código; El uso de un optimizador con eliminación de código muerto elimina la necesidad de utilizar un preprocesador para realizar la misma tarea.

En la práctica, gran parte del código muerto que encuentra un optimizador se crea mediante otras transformaciones en el optimizador. Por ejemplo, las técnicas clásicas para reducir la fuerza del operador insertan nuevos cálculos en el código y desactivan los cálculos más antiguos y costosos. [2] La eliminación posterior del código muerto elimina esos cálculos y completa el efecto (sin complicar el algoritmo de reducción de fuerza).

Históricamente, la eliminación de códigos inactivos se realizaba utilizando información derivada del análisis de flujo de datos . [3] Un algoritmo basado en el formulario estático de asignación única (SSA) aparece en el artículo original de la revista sobre el formulario SSA de Ron Cytron et al. [4] Robert Shillingsburg (también conocido como Shillner) mejoró el algoritmo y desarrolló un algoritmo complementario para eliminar operaciones de flujo de control inútiles. [5]

Eliminación dinámica de códigos muertos

El código muerto normalmente se considera muerto incondicionalmente . Por lo tanto, es razonable intentar eliminar el código inactivo mediante la eliminación del código inactivo en el momento de la compilación .

Sin embargo, en la práctica también es común que las secciones de código representen código inactivo o inalcanzable solo bajo ciertas condiciones , que pueden no conocerse en el momento de la compilación o el ensamblaje. Dichas condiciones pueden ser impuestas por diferentes entornos de ejecución (por ejemplo, diferentes versiones de un sistema operativo, o diferentes conjuntos y combinaciones de controladores o servicios cargados en un entorno de destino particular), que pueden requerir diferentes conjuntos de casos especiales en el código, pero al menos al mismo tiempo se convierte en código condicionalmente muerto para los demás casos. [6] [7] Además, el software (por ejemplo, un controlador o un servicio residente) puede configurarse para incluir o excluir ciertas funciones según las preferencias del usuario, lo que hace que las partes de código no utilizadas sean inútiles en un escenario particular. [6] [7] Si bien se puede desarrollar software modular para cargar bibliotecas dinámicamente solo bajo demanda, en la mayoría de los casos, no es posible cargar solo las rutinas relevantes de una biblioteca en particular, e incluso si esto fuera compatible, una rutina puede todavía incluye secciones de código que pueden considerarse código muerto en un escenario determinado, pero que ya no se pueden descartar en el momento de la compilación.

Las técnicas utilizadas para detectar dinámicamente la demanda, identificar y resolver dependencias, eliminar dicho código inactivo condicionalmente y recombinar el código restante durante la carga o el tiempo de ejecución se denominan eliminación dinámica de código inactivo [6] [7] [8] [9] [10 ] [11] [12] [13] [14] [15] [16] [17] [18] o eliminación dinámica de instrucciones muertas . [19]

La mayoría de los lenguajes de programación, compiladores y sistemas operativos ofrecen poco o nada más soporte que la carga dinámica de bibliotecas y los enlaces tardíos , por lo que el software que utiliza la eliminación dinámica de código muerto es muy raro junto con lenguajes compilados de antemano o escritos en lenguaje ensamblador . [8] [12] [9] Sin embargo, las implementaciones de lenguaje que realizan una compilación justo a tiempo pueden optimizar dinámicamente la eliminación del código muerto. [18] [20] [21]

Aunque con un enfoque bastante diferente, a veces también se utilizan enfoques similares para la actualización dinámica de software y la aplicación de parches en caliente .

Ver también

Referencias

  1. ^ Malavolta, Ivano y col. "Identificación, eliminación y evaluación empírica del código muerto de JavaScript". Transacciones IEEE sobre ingeniería de software 49.7 (2023): 3692–3714. Web.
  2. ^ Allen, Frances; Cocke, Juan ; Kennedy, Ken (junio de 1981). "Reducción de la fuerza del operador". En Jones, Neil D .; Muchnick, Steven Stanley (eds.). Análisis de flujo de programas: teoría y aplicación . Prentice Hall . ISBN 0-13729681-9.
  3. ^ Kennedy, Ken (junio de 1981). "Un estudio sobre técnicas de análisis de flujo de datos". En Jones, Neil D .; Muchnick, Steven Stanley (eds.). Análisis de flujo de programas: teoría y aplicación . Prentice Hall . ISBN 0-13729681-9.
  4. ^ Cytron, Ron K.; Ferrante, Juana ; Rosen, Barry K.; Zadeck, F. Kenneth (1991). Computación eficiente del formulario de asignación única estática y el gráfico de dependencia del programa . ACM TOPLAS 13(4).
  5. ^ Cooper, Keith D .; Torczon, Linda (2003) [1 de enero de 2002]. Ingeniería de un compilador . Morgan Kaufman . págs. 498 y siguientes. ISBN 978-1-55860698-2.
  6. ^ abc Paul, Matthias R. (3 de abril de 2002) [18 de junio de 2001]. "[fd-dev] Ctrl+Alt+Supr". freedos-dev . Archivado desde el original el 9 de septiembre de 2017 . Consultado el 9 de septiembre de 2017 . […] cualquiera de las […] opciones se puede excluir "permanentemente" en el momento de la instalación (también guardará la memoria para los extractos de código correspondientes debido a nuestra Eliminación dinámica de códigos muertos ), o se puede habilitar o deshabilitar en cualquier momento posterior. a través de funciones API en caso de que alguien quiera evitar que un usuario pueda reiniciar la máquina. […] estamos considerando agregar más llamadas de vaciado de caché sincrónicas […] Debido a nuestro método de eliminación dinámica de código muerto, esto no causaría ningún tipo de hinchazón cuando no sea necesario en una configuración de destino particular, ya que una llamada de vaciado de caché particular se incluiría en La imagen de tiempo de ejecución de FreeKEYB solo si el caché de disco correspondiente también está cargado o si los interruptores de línea de comando le dijeron a FreeKEYB que cargara el soporte correspondiente.
  7. ^ abc Paul, Matthias R. (6 de abril de 2002). "[fd-dev] Ctrl+Alt+Supr". freedos-dev . Archivado desde el original el 27 de abril de 2019 . Consultado el 27 de abril de 2019 . […] FreeKEYB crea la imagen en tiempo de ejecución del controlador en el momento de la inicialización dependiendo del tipo de máquina en la que se está cargando, el tipo de teclado, diseño, país y página de códigos utilizados, el tipo de mouse y adaptador(es) de video instalados, el otros controladores cargados en ese sistema, el sistema operativo y los métodos de carga y reubicación utilizados, las características individuales incluidas y las opciones de configuración especificadas en la línea de comando. Debido a la gran cantidad de opciones y opciones admitidas en la línea de comandos […] (alrededor de cincuenta opciones […] con múltiples configuraciones posibles) existe una gran cantidad de combinaciones de funciones con incontables dependencias […] lo que resulta en […] un número infinito de [ …] diferentes imágenes de destino. La técnica de eliminación dinámica de códigos muertos de FreeKEYB logra resolver […] estas […] dependencias y […] eliminar códigos y datos muertos […] no se limita a […] incluir o excluir un número algo limitado de módulos o subrutinas completas y arreglar algunas tablas de despacho como en la programación TSR clásica, pero […] funciona […] a […] nivel de bytes […] capaz de eliminar […] instrucciones individuales en medio de rutinas más grandes […] distribuidas por todo el código para manejar un caso particular o admitir una característica específica […] se utilizan herramientas especiales para analizar el código […] y crear […] tablas de reparación […] automatizadas […] utilizando definiciones condicionales […] para declarar los diversos casos […] no sólo es opcional en el momento del ensamblaje sino también en el momento de la inicialización […] sin la […] sobrecarga de tener al menos una cantidad de código inactivo en la imagen en tiempo de ejecución […] para realizar un seguimiento de todas las dependencias entre […] estos condicionales, construyen y reubican dinámicamente la imagen en tiempo de ejecución, arreglan todas las referencias entre estas partes binarias pequeñas, cambiantes y en movimiento […] aún permitiendo usar el pequeño modelo de estilo .COM/.SYS […] […] está listo en el momento de la inicialización […] API para importar y exportar estructuras de objetos entre FreeKEYB y la aplicación que llama […] para cambiar su tamaño y moverlas internamente de forma transparente […] en tiempo de ejecución […]
  8. ^ ab Paul, Matías R.; Frinke, Axel C. (13 de octubre de 1997) [publicado por primera vez en 1991], FreeKEYB: controlador de consola y teclado DOS mejorado (Manual de usuario) (v6.5 ed.)[1] (NB. FreeKEYB es un sucesor dinámicamente configurable basado en Unicode de K3PLUS que admite la mayoría de diseños de teclado , páginas de códigos y códigos de países . Utiliza un ensamblador de macros disponible en el mercado , así como un marco de pre y post-automático. Procesando herramientas de análisis para generar dependencia y metadatos de transformación de código que se incrustarán en el archivo ejecutable junto con el código binario y un cargador que se autodescarta, relaja y reubica , el controlador implementa técnicas granulares dinámicas de eliminación y reubicación de código muerto a nivel de bytes durante la carga. -tiempo , así como código de automodificación y reconfigurabilidad en tiempo de ejecución para minimizar su huella de memoria para cerrar la forma canónica dependiendo del hardware subyacente, el sistema operativo y la configuración del controlador, así como el conjunto de funciones y la configuración regional seleccionadas (alrededor de sesenta configuraciones Switches con cientos de opciones para un número casi ilimitado de combinaciones posibles), esta complejidad y dinámica están ocultas para los usuarios, que manejan un único archivo ejecutable como lo harían con un controlador convencional. K3PLUS era un controlador de teclado extendido para DOS ampliamente distribuido en Alemania en su momento, con adaptaciones a algunos otros idiomas europeos disponibles. Ya admitía un subconjunto de funciones, pero no implementaba la eliminación dinámica de códigos muertos).
  9. ^ ab Paul, Matthias R. (10 de abril de 2001). "[ANN] Lanzamiento de FreeDOS beta 6" (en alemán). Grupo de noticias : de.comp.os.msdos. Archivado desde el original el 9 de septiembre de 2017 . Consultado el 2 de julio de 2017 . […] Brandneue[s] Feature, der dynamischen Dead-Code-Elimination , die die jeweils notwendigen Bestandteile des Treibers erst zum Installationszeitpunkt zusammenbastelt und reloziert, so daß keine ungenutzten Code- oder Datenbereiche mehr residente bleiben (zB wenn jemand ein bestimmtes FreeKEYB- Característica no benötigt). […](NB. Esto representa la primera implementación conocida de eliminación dinámica granular de código muerto a nivel de bytes para software ensamblado o compilado con anticipación ).
  10. ^ Paul, Matías R. (21 de agosto de 2001). "[fd-dev] Cambio de páginas de códigos en FreeDOS". freedos-dev . Archivado desde el original el 19 de abril de 2019 . Consultado el 20 de abril de 2019 . […] una […] característica única […] que llamamos eliminación dinámica de códigos muertos , por lo que puede en el momento de la instalación […] especificar qué componentes del controlador desea y cuáles no. Esto llega hasta un punto de modularización cargable dinámica y vinculación tardía que no he visto en DOS hasta ahora. Si no le gusta el protector de pantalla, las macros, la calculadora o la compatibilidad con el mouse, o <casi cualquier otra cosa>, puede especificar esto en la línea de comando y FreeKEYB, teniendo en cuenta todas las dependencias entre las rutinas, lo hará por completo. elimine todos los fragmentos de código, que tratan con esa característica y no son necesarios para proporcionar la funcionalidad solicitada, antes de que el controlador reubique la imagen en la ubicación de destino y se convierta en residente. Eliminar algunas funciones más pequeñas solo ahorra un par de bytes, pero excluir componentes más complejos puede ahorrarle medio Kb y más. También puede especificar el tamaño de las áreas de datos […]
  11. ^ Paul, Matías R. (30 de diciembre de 2001). "Estructura interna KEYBOARD.SYS". Grupo de noticias : comp.os.msdos.programmer. Archivado desde el original el 9 de septiembre de 2017 . Consultado el 3 de julio de 2017 . […] el cargador optimizará dinámicamente las áreas de datos residentes y las secciones de código a nivel de bytes para eliminar cualquier redundancia del controlador dependiendo de la configuración local y del hardware/software/controlador determinados. […]
  12. ^ ab Paul, Matías R.; Frinke, Axel C. (16 de enero de 2006), FreeKEYB: controlador de consola y teclado DOS internacional avanzado (Manual de usuario) (edición preliminar v7)
  13. ^ Paul, Matías R. (2 de febrero de 2002). "Treiber dynamisch nachladen (Intra-Segment-Offset-Relokation zum Laden von TSRs in die HMA)" [Carga de controladores dinámicamente (reubicación de compensación intrasegmento para cargar TSR en el HMA)] (en alemán). Grupo de noticias : de.comp.os.msdos. Archivado desde el original el 9 de septiembre de 2017 . Consultado el 2 de julio de 2017 .
  14. ^ Paul, Matías R. (24 de febrero de 2002). "¿Información GEOS/NDO para RBIL62?". Grupo de noticias : comp.os.geos.programmer. Archivado desde el original el 2019-04-20 . Consultado el 20 de abril de 2019 . […] Dado que FreeKEYB utiliza nuestra eliminación dinámica de código muerto para optimizar su imagen de memoria para el entorno de destino en el momento de la carga, ciertamente me gustaría agregar soporte especial en FreeKEYB para GEOS , que podría controlarse mediante una opción de línea de comando, de modo que El código adicional solo se carga cuando también se usa GEOS. […]
  15. ^ Paul, Matías R. (15 de marzo de 2002). "¿Capa de teclado AltGr en GEOS?". Grupo de noticias : comp.os.geos.misc. Archivado desde el original el 2019-04-20 . Consultado el 20 de abril de 2019 . […] Estaría dispuesto a agregar ganchos especiales en FreeKEYB, nuestro controlador de teclado DOS muy avanzado, si demostrara mejorar la usabilidad bajo GEOS […] Debido a nuestra nueva y sofisticada tecnología Dynamic Dead Code Elimination que elimina a nivel de bytes cualquier código fragmentos no utilizados en un determinado controlador, usuario o configuración del sistema y entorno de hardware cuando el instalador del controlador crea y reubica la imagen de carga de sí mismo, esto no tendría ningún impacto en la memoria para los usuarios que no son de GEOS, por lo que no hay mucho de qué preocuparse (huella de memoria, etc.) como en los controladores DOS codificados tradicionalmente. […]
  16. ^ Thammanur, Sathyanarayan (31 de enero de 2001). Un marco de optimización de código y asignación de registros justo a tiempo para sistemas integrados (tesis de maestría). Universidad de Cincinnati , Ingeniería: Ingeniería Informática. ucin982089462.[2] Archivado el 28 de julio de 2019 en Wayback Machine [3] Archivado el 28 de julio de 2019 en Wayback Machine
  17. ^ Glew, Andy (2 de marzo de 2011). "Eliminación dinámica de códigos muertos y futuros del hardware".[ enlace muerto permanente ] [4] [5]
  18. ^ ab Conway, Andrew (4 de diciembre de 1995). "Estructuras de datos cíclicas". Grupo de noticias : comp.lang.functional. Archivado desde el original el 9 de septiembre de 2017 . Consultado el 3 de julio de 2017 . […] La evaluación diferida es básicamente una eliminación dinámica de código muerto . […](NB. Posiblemente el primer uso público del término eliminación dinámica de código muerto , aunque solo conceptualmente y con un enfoque en la evaluación diferida en lenguajes funcionales ).
  19. ^ Colillas, J. Adam; Sohi, Guri (octubre de 2002). "Detección y eliminación dinámica de instrucciones muertas" (PDF) . San José, CA, EE.UU.: Departamento de Ciencias de la Computación, Universidad de Wisconsin-Madison . ASPLOS X ACM 1-58113-574-2/02/0010. Archivado (PDF) desde el original el 2019-04-20 . Consultado el 23 de junio de 2017 .
  20. ^ Johng, Yessong; Danielsson, Per; Ehnsiö, Per; Hermansson, Mats; Jolanki, Mika; Moore, Scott; Strander, Lars; Wettergren, Lars (8 de noviembre de 2002). "Capítulo 5. Descripción general de Java e implementación de iSeries - 5.1.1. Componentes varios". Intentia Movex Java en el servidor IBM iSeries - Guía de implementación - Descripción general de Movex Java en el servidor iSeries - Instalación y configuración de Movex Java en iSeries - Consejos y técnicas operativas (PDF) . Libros rojos. IBM Corp. pág. 41.ISBN _ 0-73842461-7. SG24-6545-00. Archivado (PDF) desde el original el 8 de octubre de 2013 . Consultado el 20 de abril de 2019 .[6]
  21. ^ Polito, Guillermo (2015). "Soporte de virtualización para extensión y especialización del tiempo de ejecución de aplicaciones: lenguajes de programación" (PDF) . Universidad de Ciencias y Tecnologías de Lille . págs. 111-124. Identificación HAL: tel-01251173. Archivado (PDF) desde el original el 23 de junio de 2017 . Consultado el 23 de junio de 2017 .

Otras lecturas

enlaces externos