KEIL-Code-Optimierung: Wo sieht man die Veränderungen?

Gast #1485959
Lesenswert?

Hallo,

ich habe eine Frage bezüglich der KEIL-Compiler-Optimierung.


---Worum geht es---
Ich habe schon oft gelesen, dass der KEIL-Compiler mit zu den Besten 
gehört in Bezug auf die Optimierungen und dass KEIL dementsprechend auch 
nicht genutzte Codeteile automatisch ausgliedert.
Um mein Problem so einfach wie möglich darstellen zu können, werde ich 
es anhand eines kleinen Beispiels erklären.


---Beispiel---
1
-main.c-
2
#include file1.h
3
test1()  //beliebige Funktion
4
test2()  //beliebige Funktion
5
test3()  //beliebige Funktion
6

7
-file1.h-
8
test3()  //Prototyp
9

10
-file1.c-
11
test3()  //Funktionsbeschreibung

Ich habe eine main.c mit diversen Funktionen. Die test3() hat den 
Prototypen und die Funktionsbeschreibung in der Datei file1.h/file1.c.
Wenn ich kompiliere erstellt KEIL die *.obj und *.ist Dateien. In den 
*.ist-Dateien sehe ich den Code in C und in Assembler zu jeder 
Codedatei.


---Frage---
Wenn ich jetzt den Funktionsaufruf von test3() in der main.c 
auskommentiere, dann werden auch automatisch die Dateien file1.h und 
file1.c überflüssig, dementsprechend auch der #include-Befehl für die 
file1.h.

Ich hätte gedacht, dass dann diese Codeteile jetzt in der *.ist nicht 
mehr auftauchen, bzw. die test3.ist erst gar nicht erstellt wird, weil 
die Codeteile darin nicht mehr benötigt werden.

Wieso wird das nicht rausoptimiert?
Sind die *.ist-Dateien überhaupt schon optimiert?
Kann man irgendwo den optimierten Code sehen?
Wirft KEIL automatisch alle Funktionen, Variablen, Definitionen, Dateien 
(*.c), usw. raus, wenn diese nirgends aufgerufen werden?

Danke im Voraus!
#1485967
Lesenswert?

Erik schrieb:

> Wenn ich jetzt den Funktionsaufruf von test3() in der main.c
> auskommentiere, dann werden auch automatisch die Dateien file1.h und
> file1.c überflüssig, dementsprechend auch der #include-Befehl für die
> file1.h.

Das weiß aber der Compiler nicht.
test3 könnte ja auch noch von irgendwo anders aufgerufen werden, zb von 
einer Funktion in test2.c

Der Compiler hat nicht den Überblick über alle *.c Dateien. Er 
compiliert jedes einzelne *.c für sich.
Erst der Linker fügt die Einzelteile zusammen und erzeugt das fertige 
Programm. Und es ist erst der Linker, der feststellen kann, dass eine 
Funktion test3() überhaupt nicht aufgerufen wird und daher auch nicht im 
fertigen Programm nicht auftauchen muss.
Gast #1485984
Lesenswert?

Achso, dann sind die generierten Dateien zunächst einmal jeweils einzeln 
erstellt worden und nicht als ganzes zusammenhängendes Projekt. Erst der 
LINKER macht das und gliedert die nicht notwendigen Codeteile aus. Dann 
gibt es wohl auch nicht wirklich eine Möglichkeit die optimierte 
Variante sehen zu können.
Gast #1486024
Lesenswert?

Ja, in der HEX-File ist dann alles drin, aber aus der erkenne ich gar 
nichts mehr heraus. Ich hätte gerne die Veränderungen als Code (C oder 
Assembler) gesehen. Ich dachte nämlich, dass der Compiler alle 
Optimierungen durchführt.
#1486046
Lesenswert?

Erik schrieb:
> Ja, in der HEX-File ist dann alles drin, aber aus der erkenne ich gar
> nichts mehr heraus.

Musst du auch nicht.
Es reicht, wenn die kleiner wird :-)

> Ich hätte gerne die Veränderungen als Code (C oder
> Assembler) gesehen.

Assembler hättest du eine Chance.
Aber C-Code ist so nicht möglich. Der Compiler optimiert nämlich auf 
viel tieferen Stufen als auf C-Code Ebene. Da werden ganze Statements 
oder Teile davon umgestellt, konstante Ausdrücke herausgezogen, Code 
fällt ganz oder teilweise weg. Doppelte Berechnungen werden zu einer 
zusammengefasst, Variablen eliminiert, etc.

Kurz und gut: Für den Compiler ist der C-Code nur Input. Zwischendurch 
wird der immer wieder umgeformt in Zwischenebenen für die es keine 
C-Entsprechung gibt. Und ganz zum Schluß kommt hinten irgendwann 
Maschinencode raus. Kurz vor diesem Ende findet zb die 
Peephole-Optimization statt, bei der auf Assemblerebene noch einmal nach 
wiederkehrenden Mustern und Vereinfachungen gesucht wird. Da ist man 
aber von der C-Ebene schon so weit entfernt, dass es praktisch unmöglich 
ist, diese Veränderungen auf C-Ebene abzubilden.

Wenn du deine rausoptimierte Funktion suchst, musst du im Linker Map 
File nachsehen. Dort müsste die Funktion nicht mehr aufscheinen.

> Ich dachte nämlich, dass der Compiler alle
> Optimierungen durchführt.

Das tut er auch.
Nur keine Sorge.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren