28 Stimmen

Mehrere GCC-Optimierungsflags

Ich habe einige Legacy-Code, der mit beiden -02 und -03 gesetzt kompiliert. Von der GCC man-Datei erhalte ich die Garantie, dass:

-O3 schaltet alle Optimierungen ein, die mit -O2 angegeben wurden, und schaltet außerdem die Funktionen -finline-functions, -funswitch-loops, -fpredictive-commoning, -fgcse-after-reload und -ftree-vectorize ein Optionen.

Auf den ersten Blick scheint es also wahrscheinlich, dass das Aktivieren beider Flags dasselbe ist wie nur -O3. Das hat mich jedoch zum Nachdenken gebracht, ob es richtig ist, in diesem Fall -O2 zu aktivieren, da dies wahrscheinlich die "sicherere" Option ist. Natürlich ist es eine einfache Angelegenheit, etwas Code mit allen Permutationen zu kompilieren und zu sehen, was in jedem Fall passiert, aber ich frage mich, ob jemand weiß, ob es eine bestimmte Richtlinie gibt, die GCC in Bezug auf die Angabe mehrerer Optimierungsstufen hat, und wenn ja, was ist die Begründung dafür?

62voto

ggiroux Punkte 6296

より Manpage :

Wenn Sie mehrere -O-Optionen verwenden, mit oder ohne Ebenennummern, ist die letzte dieser Optionen diejenige, die wirksam ist.

2voto

OrenIshShalom Punkte 4288

Für überbesorgte Benutzer wie mich gibt es hier einen Code, der nach Optimierung schreit:

$ cat dominant_flag.c
#include <stdio.h>
int foo(int i)
{
    return 3*i+122;
}
int main(int argc, char **argv)
{
    return foo(0xface); // meant to be optimized out
}

Und hier sind vier Szenarien für die Zusammenstellung:

$ gcc -g -O0     dominant_flag.c -o flag0
$ gcc -g -O3     dominant_flag.c -o flag3
$ gcc -g -O0 -O3 dominant_flag.c -o flag03
$ gcc -g -O3 -O0 dominant_flag.c -o flag30

Sobald ich nach der Konstante suche 0xface Ich sehe, dass sie in den nicht optimierten Versionen vorhanden ist:

$ objdump -S -D flag0  | grep -w "\$0xface" # 61e: bf ce fa 00 00 mov $0xface,%edi
$ objdump -S -D flag30 | grep -w "\$0xface" # 61e: bf ce fa 00 00 mov $0xface,%edi

und in den optimierten Versionen optimiert:

$ objdump -S -D flag3  | grep -w "\$0xface"
$ objdump -S -D flag03 | grep -w "\$0xface"

Der ganze Foo-Call ist weg:

$ objdump -S -D flag03 | sed -n "297,298p;299q"
 4f0:   b8 e4 f0 02 00          mov    $0x2f0e4,%eax # <--- hex(3*0xface+122)=0x2f0e4
 4f5:   c3                      retq

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X