Dode code eliminatie - Dead code elimination
In compiler theorie , dode code eliminatie (ook bekend als DCE , dode code verwijderen , dode code strippen of dode codestrip ) een compileroptimalisatieruimte code die geen invloed op het programma resultaten te verwijderen. Het verwijderen van dergelijke code heeft verschillende voordelen: het verkleint de programmagrootte, een belangrijke overweging in sommige contexten, en het stelt het draaiende programma in staat om het uitvoeren van irrelevante bewerkingen te vermijden, wat de looptijd verkort. Het kan ook verdere optimalisaties mogelijk maken door de programmastructuur te vereenvoudigen. Dode code omvat code die nooit kan worden uitgevoerd ( onbereikbare code ), en code die alleen dode variabelen beïnvloedt (geschreven naar, maar nooit meer gelezen), dat wil zeggen niet relevant voor het programma.
Voorbeelden
Beschouw het volgende voorbeeld geschreven in C .
int foo(void)
{
int a = 24;
int b = 25; /* Assignment to dead variable */
int c;
c = a * 4;
return c;
b = 24; /* Unreachable code */
return 0;
}
Een eenvoudige analyse van het gebruik van waarden zou aantonen dat de waarde van bna de eerste toewijzing niet binnen wordt gebruikt foo. Verder bwordt gedeclareerd als een lokale variabele inside foo, dus de waarde ervan kan niet outside worden gebruikt foo. De variabele bis dus dood en een optimizer kan zijn opslagruimte terugwinnen en zijn initialisatie elimineren.
Bovendien, omdat de eerste return-instructie onvoorwaardelijk wordt uitgevoerd, bereikt geen haalbaar uitvoeringspad de tweede toewijzing aan b. De opdracht is dus onbereikbaar en kan worden verwijderd. Als de procedure een complexere controlestroom had , zoals een label na de return-instructie en een gotoelders in de procedure, dan zou er een haalbaar uitvoeringspad kunnen bestaan naar de toewijzing aan b.
Ook al worden sommige berekeningen in de functie uitgevoerd, hun waarden worden niet opgeslagen op locaties die toegankelijk zijn buiten het bereik van deze functie. Bovendien, gezien de functie een statische waarde retourneert (96), kan deze worden vereenvoudigd tot de waarde die wordt geretourneerd (deze vereenvoudiging wordt constant vouwen genoemd ).
De meeste geavanceerde compilers hebben opties om de verwijdering van dode code te activeren, soms op verschillende niveaus. Een lager niveau verwijdert mogelijk alleen instructies die niet kunnen worden uitgevoerd. Een hoger niveau reserveert mogelijk ook geen ruimte voor ongebruikte variabelen. Een nog hoger niveau kan instructies of functies bepalen die geen enkel doel dienen en deze elimineren.
Een algemeen gebruik van dode code-eliminatie is als alternatief voor optionele code-opname via een preprocessor . Beschouw de volgende code.
int main(void) {
int a = 5;
int b = 6;
int c;
c = a * (b / 2);
if (0) { /* DEBUG */
printf("%d\n", c);
}
return c;
}
Omdat de uitdrukking 0 altijd naar false evalueert , kan de code in de if-instructie nooit worden uitgevoerd, en het verwijderen van dode code zou deze volledig uit het geoptimaliseerde programma verwijderen. Deze techniek is gebruikelijk bij het debuggen om optioneel codeblokken te activeren; het gebruik van een optimalisatieprogramma met eliminatie van dode code elimineert de noodzaak om een preprocessor te gebruiken om dezelfde taak uit te voeren.
In de praktijk wordt veel van de dode code die een optimizer vindt, gemaakt door andere transformaties in de optimizer. De klassieke technieken voor het verminderen van de sterkte van de operator voegen bijvoorbeeld nieuwe berekeningen in de code in en maken de oudere, duurdere berekeningen dood. Daaropvolgende eliminatie van dode code verwijdert die berekeningen en voltooit het effect (zonder het algoritme voor sterktevermindering te compliceren).
Historisch gezien werd de eliminatie van dode code uitgevoerd met behulp van informatie die was afgeleid van gegevensstroomanalyse . Een algoritme op basis van een statisch enkelvoudig opdrachtformulier (SSA) verschijnt in het originele tijdschriftartikel over SSA- formulier door Ron Cytron et al. Robert Shillingsburg (ook bekend als Shillner) verbeterde het algoritme en ontwikkelde een begeleidend algoritme voor het verwijderen van nutteloze controlestroombewerkingen.
Dynamische eliminatie van dode code
Dode code wordt normaal gesproken als onvoorwaardelijk als dood beschouwd . Daarom is het redelijk om te proberen om dode code te verwijderen door dode code te verwijderen tijdens het compileren .
In de praktijk is het echter ook gebruikelijk dat codesecties alleen dode of onbereikbare code vertegenwoordigen onder bepaalde voorwaarden , die mogelijk niet bekend zijn op het moment van compilatie of assemblage. Dergelijke voorwaarden kunnen worden opgelegd door verschillende runtime-omgevingen (bijvoorbeeld verschillende versies van een besturingssysteem, of verschillende sets en combinaties van stuurprogramma's of services die in een bepaalde doelomgeving zijn geladen), waarvoor mogelijk verschillende sets speciale gevallen in de code nodig zijn, maar tegelijkertijd wordt voorwaardelijk dode code voor de andere gevallen. Ook kan de software (bijvoorbeeld een stuurprogramma of een residente service) configureerbaar zijn om bepaalde functies op te nemen of uit te sluiten, afhankelijk van gebruikersvoorkeuren, waardoor ongebruikte codegedeelten onbruikbaar worden in een bepaald scenario. Hoewel modulaire software kan worden ontwikkeld om bibliotheken alleen op verzoek dynamisch te laden, is het in de meeste gevallen niet mogelijk om alleen de relevante routines uit een bepaalde bibliotheek te laden, en zelfs als dit zou worden ondersteund, kan een routine nog steeds codesecties bevatten die kunnen kan in een bepaald scenario als dode code worden beschouwd, maar kon al tijdens het compileren niet worden uitgesloten.
De technieken gebruikt voor het dynamisch vraag detectie, identificatie en lossen afhankelijkheden, verwijderen dergelijke voorwaardelijk dode code en de resterende code recombineren bij belasting of runtime genoemd dynamische dode code verwijdering of dynamische dode instructie eliminatie .
De meeste programmeertalen, compilers en besturingssystemen bieden niet of weinig meer ondersteuning dan het dynamisch laden van bibliotheken en laat koppelen , daarom is software die dynamische eliminatie van dode code gebruikt, zeer zeldzaam in combinatie met talen die van tevoren zijn gecompileerd of in assembler zijn geschreven . Taalimplementaties die just-in-time-compilatie uitvoeren, kunnen echter dynamisch optimaliseren voor het elimineren van dode code.
Hoewel met een nogal andere focus, worden vergelijkbare benaderingen soms ook gebruikt voor dynamische software-updates en hot patching .
Zie ook
- Redundante code
- Vereenvoudiging (symbolische berekening)
- Gedeeltelijke redundantie eliminatie
- Conjunctie eliminatie
- Dynamische software-update
- Dynamische koppeling (informatica)
- Software cruft
- Boom schudden
- Post-pass optimalisatie
- Profielgestuurde optimalisatie
- Superoptimizer
- Afvalinzameling compacter maken
- Functie multi-versiebeheer
Referenties
Verder lezen
- Bodík, Rastislav; Gupta, Rajiv (juni 1997). "Gedeeltelijke dode code eliminatie met behulp van slicing transformaties". Proceedings van de ACM SIGPLAN 1997 Conferentie over het ontwerpen en implementeren van programmeertaal (PLDI '97) : 682-694.
- Aho, Alfred Vaino ; Sethi, Ravi ; Ullman, Jeffrey David (1986). Compilers - Principes, technieken en hulpmiddelen . Uitgeverij Addison Wesley . ISBN 0-201-0194-7.
- Muchnick, Steven Stanley (1997). Geavanceerd compilerontwerp en -implementatie . Uitgeverij Morgan Kaufmann . ISBN 1-55860-320-4.
- Grune, Dick ; Bal, Henri Elle ; Jacobs, Ceriel JH; Langendoen, Koen G. (2000). Modern compilerontwerp . John Wiley & Sons, Inc. ISBN-nummer 0-471-97697-0.
- Kennedy, Ken ; Allen, Randy (2002). "Hoofdstuk 4.4. Analyse van gegevensstromen - Hoofdstuk 4.4.2. Eliminatie van dode codes". Compilers optimaliseren voor moderne architecturen: een op afhankelijkheid gebaseerde benadering (2011 digitale print van 1st ed.). Academic Press / Morgan Kaufmann Publishers / Elsevier . blz. 137 , 145-147, 167. ISBN 978-1-55860-286-1. LCCN 2001092381 .