2012-10-31 12 views
13

Durante la compilazione del codice ho notato grandi differenze nell'assemblatore create tra -O0 e -O1. Volevo eseguire abilitando/disabilitando le ottimizzazioni fino a quando ho scoperto che cosa stava causando un certo cambiamento nell'assemblatore.Differenze tra -O0 e -O1 in GCC

Se uso -fverbose-asm per scoprire esattamente quali flag O1 è abilitato rispetto a O0, e quindi li disabilito manualmente, perché l'assemblatore è prodotto ancora così enormemente diverso? Anche se eseguo gcc con O0 e aggiungo manualmente tutti i flag che fverbose-asm ha detto che sono abilitati con O1, non ho lo stesso assemblatore che avrei avuto usando O1.

C'è qualcosa oltre a "-f ..." e "-m ..." che può essere modificato?

O è solo che 'O1' ha un po 'di magia rispetto a' O0 'che non può essere disattivato.


Ci scusiamo per l'crypticness - questo era legato a Reducing stack usage during recursion with GCC + ARM tuttavia la menzione di esso stava facendo la domanda un po 'difficile da capire.

+0

Quindi il problema è che non si conosce il nome (o combinazione letale) della "ottimizzazione incriminata" che aumenta l'utilizzo dello stack, e * anche * non lo fai conosci i nomi delle ottimizzazioni da '-Os 'di cui hai bisogno? Dove "non so il nome" include la possibilità che non abbiano nomi, sono varie ottimizzazioni extra abilitate da 'O1' o' Os' che non possono essere controllati individualmente. –

+0

Sì, in pratica conosco tutti i flag che GCC afferma di aver abilitato (tramite -fverbose-asm). Tuttavia disabilitarli manualmente non risolve il problema, quindi deve essere un po '"magico" che non riesco a controllare. TUTTAVIA ho appena scoperto (vedi domanda collegata) che il problema esisteva ancora con O0, solo in un modo diverso. Sarebbe comunque bello sapere se c'è una risposta a questa domanda - poiché è spaventoso non essere in grado di controllare le ottimizzazioni. –

+0

Hai provato a utilizzare GCC's 'attribute (())' o riscrivere una funzione in un altro modo (ad esempio, rendere statiche le variabili o allocare il loro spazio manualmente)? Come soluzione dell'ultima possibilità, la funzione problematica può essere riscritta in assembly. – Vovanium

risposta

3

Non che questo aiuta, altro che fornire alcune prove per i vostri sospetti su -O1 magia che non può essere spento:

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

    avvertimento, non tutte le ottimizzazioni abilitate by -O1 ha un flag di attivazione da riga di comando per disabilitarli.

  • da "guida definitiva a GCC, 2 ° Ed" di Hagen:

    Nota: Non tutte le ottimizzazioni di GCC possono essere gestite tramite una bandiera. GCC esegue alcune ottimizzazioni in modo automatico e, a meno di modificare il codice sorgente, non è possibile disattivare queste ottimizzazioni quando si richiede l'ottimizzazione utilizzando -O

Purtroppo, non ho trovato alcuna dichiarazione chiara su ciò che questi hardware potrebbero essere ottimizzazioni codificate. Spero che qualcuno che è ben informato sugli interni di GCC possa pubblicare una risposta con alcune informazioni al riguardo.

5

Se invece si è interessati a vedere che passa sono abilitati a O1 che non sono abilitati a O0 è possibile eseguire qualcosa di simile:

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 

Un processo simile, utilizzando il set di indicatori che avete scoperto, volontà lascia che tu veda quali passaggi extra di magia non controllati dai flag vengono intrapresi da GCC in O1.

EDIT:

Un modo meno disordinato potrebbe essere quello di confrontare l'output di -fdump-pass, che elencherà che passa sono ON o OFF per stderr.

Quindi qualcosa di simile:

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