2012-10-31 15 views
13

Beim Kompilieren eines Codes bemerkte ich große Unterschiede im Assembler zwischen -O0 und -O1. Ich wollte Optimierungen durchlaufen, bis ich herausgefunden habe, was eine bestimmte Änderung im Assembler verursacht hat.Unterschiede zwischen -O0 und -O1 in GCC

Wenn ich -fverbose-asm verwende, um genau herauszufinden, welche Flags O1 im Vergleich zu O0 aktiviert und dann manuell deaktiviert, warum ist der Assembler dann noch so massiv anders? Selbst wenn ich gcc mit O0 starte und manuell alle Flags hinzufüge, die nach fverbose-asm mit O1 aktiviert wurden, bekomme ich nicht den gleichen Assembler, den ich mit O1 bekommen hätte.

Gibt es etwas außer '-f ...' und '-m ...', das geändert werden kann?

Oder ist nur, dass 'O1' etwas Magie im Vergleich zu 'O0' hat, die nicht ausgeschaltet werden kann.


Sorry für die Hintergründigkeit - dies Reducing stack usage during recursion with GCC + ARM Zusammenhang wurde jedoch die Erwähnung es wurde die Frage ein bisschen schwer zu verstehen machen.

+0

Das Problem ist also, dass Sie nicht den Namen wissen (oder Killer-Kombination) der „säumige Optimierung“, die Stapel Nutzung erhöht, und Sie * * auch nicht kennen Sie die Namen der Optimierungen aus '-Os', die Sie benötigen? Wenn "Name nicht wissen" die Möglichkeit einschließt, dass sie überhaupt keine Namen haben, sind es verschiedene zusätzliche Optimierungen, die durch 'O1' oder' Os' aktiviert werden, die nicht einzeln gesteuert werden können. –

+0

Ja - im Grunde kenne ich alle Flags, die GCC sagt, dass es aktiviert wurde (via -fverbose-asm). Wenn Sie sie jedoch manuell deaktivieren, wird das Problem nicht behoben. Es muss also eine "Magie" sein, die ich nicht kontrollieren kann. JEDOCH habe ich gerade entdeckt (siehe verbundene Frage), dass das Problem immer noch mit O0 existierte, nur auf eine andere Art und Weise. Es wäre dennoch gut zu wissen, ob es eine Antwort auf diese Frage gibt - weil es beängstigend ist, die Optimierungen nicht kontrollieren zu können. –

+0

Haben Sie versucht, GCCs Attribut (()) zu verwenden oder eine Funktion auf andere Weise neu zu schreiben (z. B. Variablen statisch zu machen oder ihren Platz manuell zuzuordnen)? Als letzte Lösung kann problematische Funktion in Assembly neu geschrieben werden. – Vovanium

Antwort

3

Nicht, dass dies hilft, anders als einige Beweise für Ihre Vermutungen über -O1 Magie bieten, die ausgeschaltet werden kann nicht einge:

  • Von http://gcc.gnu.org/ml/gcc-help/2007-11/msg00214.html:

    CAVEAT nicht alle Optimierungen aktiviert von -O1 haben ein Befehlszeilen-Umschaltflag, um sie zu deaktivieren.

  • Von Hagens "Definitive Guide to GCC, 2. Auflage":

    Hinweis: Nicht alle Optimierungen des GCC kann mit einem Flag gesteuert werden. GCC einige Optimierungen führt automatisch und, kurz, den Quellcode ändern, können Sie nicht diese Optimierungen deaktivieren, wenn Sie anfordern Optimierung mit -O

Leider habe ich keine klare Aussage darüber, was diese Hard- gefunden codierte Optimierungen könnten sein. Hoffentlich kann jemand, der über die Interna von GCC Bescheid weiß, eine Antwort mit einigen Informationen darüber schreiben.

5

Wenn alles, was Sie wollen, ist zu sehen, welche bei O1 verläuft aktiviert, die nicht an O0 aktiviert sind Sie so etwas wie laufen könnte:

gcc -O0 test.c -fdump-tree-all -da 
ls > O0 
rm -f test.c.* 
gcc -O1 test.c -fdump-tree-all -da 
ls > O1 
diff O0 O1 

Ein ähnliches Verfahren, um den Satz von Flags verwendet, die Sie entdeckt, wird Lasst euch sehen, welche zusätzlichen Magiepassagen, die nicht von Flaggen gesteuert werden, von GCC bei O1 unternommen werden.

EDIT:

A weniger chaotisch Weise könnte sein, die Ausgabe von -fdump Bypässe zu vergleichen, die listet die verstreicht, sind ON oder OFF zu Stderr.

So etwas wie:

gcc -O0 test.c -fdump-passes |& grep ON > O0 
gcc -O1 test.c -fdump-passes |& grep ON > O1 
diff O0 O1 
Verwandte Themen