GCC erzeugt unlogischen Code
Ich staune gerade, wie bescheuert der C Compiler diesen Code optimiert:
Code:
ISR(TIMER0_COMP_vect) {
if (++ICR1L==100) {
ICR1L=0;
system_time++;
}
}
Ergibt compiliert:
- push r1
push r0
in r0, 0x3f
push r0
eor r1, r1
push r24
push r25
push r26
push r27
in r24, 0x26
subi r24, 0xFF
out 0x26, r24
in r24, 0x26
cpi r24, 0x64
brne .+40
out 0x26, r1
lds r24, 0x006A
lds r25, 0x006B
lds r26, 0x006C
lds r27, 0x006D
adiw r24, 0x01
adc r26, r1
adc r27, r1
sts 0x006A, r24
sts 0x006B, r25
sts 0x006C, r26
sts 0x006D, r27
pop r2
pop r26
pop r25
pop r24
pop r0
out 0x3f, r0
pop r0
pop r1
reti
1) Mehrfache Ein/Ausgabe in das Register ICR1L (rot):
Wieso wird r24 zuerst in das I/O Register geschrieben und direkt danach wieder eingelesen? Der zweite Befehl ist doch total überflüssig, oder?
2) Schlecht platzierte Push/Pop für Register (blau):
Solange mein prescaler (also ICR1L bzw. r24) nicht 100 ist, werden die Register r25-r27 gar nicht verwendet. Dennoch werden sie schon bei Eintritt in die Funktion auf dem Stapel gesichert.
Das ganze ärgert mich deswegen, weil diese Interrupt Routine mit 100.000 mal pro Sekunde aufgerufen wird, da tut jeder unnötige Befehl richtig weh.
Hat vielleicht jemand eine Idee, wie man den Compiler zu etwas mehr Intelligenz bewegen kann?
Re: GCC erzeugt unlogischen Code
Zitat:
Zitat von s.frings
Ich staune gerade, wie bescheuert der C Compiler diesen Code optimiert:
Und ich staune gerade, wie leichtfertig du die dir kostenlos von anderen zur Verfügung gestellte Arbeit beschimpfst. Schreibe doch mal selber einen Compiler, vielleicht kann der das dann ja besser.
Zitat:
1) Mehrfache Ein/Ausgabe in das Register ICR1L (rot):
Wieso wird r24 zuerst in das I/O Register geschrieben und direkt danach wieder eingelesen? Der zweite Befehl ist doch total überflüssig, oder?
Register sind grundsätzlich volatile deklariert. Wenn du die sich daraus ergebenden zusätzlichen Zugriffe vermeiden willst, dann arbeite mit einer temporären Kopie.
Zitat:
2) Schlecht platzierte Push/Pop für Register (blau):
Solange mein prescaler (also ICR1L bzw. r24) nicht 100 ist, werden die Register r25-r27 gar nicht verwendet. Dennoch werden sie schon bei Eintritt in die Funktion auf dem Stapel gesichert.
So arbeitet der Compiler nun mal. Es gibt nur Pro-/Epiloge am Anfang und Ende der Funktion, keine irgendwo mittendrin.
Zitat:
Das ganze ärgert mich deswegen, weil diese Interrupt Routine mit 100.000 mal pro Sekunde aufgerufen wird, da tut jeder unnötige Befehl richtig weh.
Das hatten wir doch schon im anderen Thread. Dann schreibe halt die ISR als ASM-Funktion selber. Bei dieser simplen ISR ist das doch in ein paar Minuten erledigt.