PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : GCC/MinGW Kaputtoptimierung [Bug?]


liquid
2004-05-19, 21:36:57
Hiho,

ich habe ein kleines Problem mit dem MinGW (basierend auf dem neusten GCC 3.4) - und zwar wenn die höchste Optimierungsstufe aktiviert ist.

Und zwar...

habe ich mehrere memcpy Funktionen, die Daten in den ulkigsten Art und Weisen durch die Gegend schaufeln. Diese Funktionen bestehen alle im Kern aus Inline-Assembler.

Jetzt habe ich eine weitere Funktion, die zur Performancemessung da ist. In dieser soll getestet werden wie schnell die einzelnen memcpys sind. Es ist manchmal schon erstaunlich wie dumm sich die Compiler bei einer simplen For-Schleife anstellen, aber naja...

Der Inline-Assembler Code ist als volatile deklariert, dem Compiler wird also ausdrücklich untersagt den Asm zu verändern, umzustrukturieren und sonstige Späßchen damit zu veranstalten.

Jetzt macht der GCC in der höchsten Optimierungsstufe aber große Scheisse, die zu einer Segfault führt. Ich erkläre kurz wie weit ich mit dem Debuggen schon bin. Ich habe die gesamte Performancemessungsfunktion durch auskommentieren aller irrelevanter Zeilen nur auf Allokation, Kopieren und Deallokation beschränkt.
Sämtliche Ausgabe fallen unter den Tisch, ich dachte mir vielleicht liegt es ja daran. Aber er segfaultet immer noch.

Nun habe ich mir den Asm-Code angeguckt und er hält sich auch schon an das volatile. Was er allerdings macht ist folgendes:

Ich übergebe den memcpy Funktionen ja immer drei Parameter: src, dst und size. Diese sollen in GPRs geladen werden, was auch funktioniert. Allerdings nimmt der GCC fälschlicherweise an, dass sich die GPRs nicht ändern, er also die dort gespeicherten Werte für den nächsten Aufruf weiterverwenden kann.
So lädt er die Werte vom Stack gerade mal einmal in die GPRs rein und benutzt sie dann in allen Funktionen. Das geht natürlich nicht, da ich die Variablen in den GPRs ja verändere. Das scheint er allerdings nicht begreifen zu wollen. Jetzt habe ich es schon mit den + und = Modifiern probiert, aber die mag er bei Input-Registern ja nicht.

Ich weiß nicht was ich machen soll, irgendwie muss man dem Compiler doch verklickern können, dass er die Werte leider mehrmals aus dem Stack fischen muss, da sich die Werte in den Registern ändern. Aber wie?? Oder geht das überhaupt nicht und das ganze ist vielleicht ein Bug im GCC??

Vielen Dank schonmal!!

cya
liquid

maximAL
2004-05-19, 22:46:34
also was ich dazu sagen kann ist, dass alles über O2 als unsicher gilt. (aber mag sein, dass es trotzdem eine andere lösung für das problem gibt)

Gast
2004-05-20, 07:50:47
Original geschrieben von liquid
Ich weiß nicht was ich machen soll, irgendwie muss man dem Compiler doch verklickern können, dass er die Werte leider mehrmals aus dem Stack fischen muss, da sich die Werte in den Registern ändern. Aber wie?? Oder geht das überhaupt nicht und das ganze ist vielleicht ein Bug im GCC??
1. alle Optimierungsstufen sollten keinen falschen Code erstellen
2. das __asm__-Schlüsselwort hat doch neben dem Assemblercode noch 3 durch ":" getrennte Parameter: Output, Input und Clobber. Clobber sind die Register, die verändert werden: http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Extended%20Asm
3. andernfalls Bugreport erstellen: http://gcc.gnu.org/bugzilla/

liquid
2004-05-20, 13:08:36
Ich kenne mittlerweile den extended ASM Syntax des GCC sehr gut und auch das mit Input, Output und Clobbers ist mir bekannt. In der Doku steht dazu auch, dass Register die in Input/Output auftauchen auch gleichzeitig Clobbers sind.

Ich könnte natürlich gegen das Problem "vorbeugen" indem ich die verwendeten GPRs auf dem Stack pushe und nach dem ASM-Code wieder runterpoppe, aber das löst ja nicht das eigentliche Problem.

Aber du hast recht Gast, ich werde wohl nicht darumkommen einen Bugreport zu erstellen. Naja mal sehen.

cya
liquid

Gast
2004-05-20, 13:34:39
oder in den Mailinglists (help) fragen: http://www.gnu.org/software/gcc/lists.html

liquid
2004-05-20, 14:29:27
OMG, Lesen sollte man können...

There is no way for you to specify that an input operand is modified without also specifying it as an output operand. Note that if all the output operands you specify are for this purpose (and hence unused), you will then also need to specify volatile for the asm construct, as described below, to prevent GCC from deleting the asm statement as unused.

Hehehe *schnell verdrückt*

cya
liquid