Forum: Compiler & IDEs Optimierung über mehrer Dateien


von foxrider (Gast)


Lesenswert?

Hallo Zusammen.
Ich benutze den WinAVR mit dem eclipse-plugin.
Nun hab ich modularisierten code, welcher zum Teil mehrer Aufrufe von 
Funktionen beinhaltet, welche nur eine weitere aufrufen.
z.B.
void test(int x){
 c(x);
}
Der compiler übersetzt diesen code logischerweise mit einem einfachen 
call. und ret.
Die Funktion c befindet sich in einem anderen File.
und sieh so aus:
void c(int x){
  b(x);
}
b() wiederum befindet sich wieder in einem anderen file und macht z.B.
void b(int x);
  PORTA=(char)x;
}
Befinden sich alle funktionen in einer Datei, so werden alle jumps und 
calls erwartungsgemäss eliminiert und es bleibt nur noch die Funktion, 
b() bestehen.
Wenn die Funktionen jedoch auf verschiedene Dateien verteilt werden 
werden die calls und rets nicht weg optimiert.
Kann der AVRGCC nicht über mehrere Files optimieren?
Wie bringe ich dem Compiler bei, dass er mir solche "sinlosen" calls und 
rets eliminiert?
Die Funktionen müssen auf Grund der Modularität auf verschiedene Dateien 
aufgeteilt werden.
z.B. eine Lib kann eine Linie zeichnen. und diese Funktion soll in eine 
draw-Lib übernommen (so ähnlich wie bei c++ Vererbung) übernommen 
werden. die graphs lib greift auf eine draw-Lib und soll ebenfalls die 
Line function wieder zur Verfügung stellen.
Muss ich das mit #defines lösen oder gibt es da eine Möglichkeit das der 
Compiler das optimiert?
Danke für eure Inputs

von holger (Gast)


Lesenswert?

>Die Funktionen müssen auf Grund der Modularität auf verschiedene Dateien
>aufgeteilt werden.

Müssen sie? Ich glaube nicht.

Dann mach doch einfach ein #include "modulx.c"
Würde ich niemals tun, aber wenn es nicht anders geht ;)
Das #include "modulx.c" aber nur in einer *.c machen.
Der Linker mag es nicht wenn das in mehreren *.c gemacht wird.

von Stefan E. (sternst)


Lesenswert?

> Kann der AVRGCC nicht über mehrere Files optimieren?

Nein, das geht prinzipiell nicht.

> void c(int x){
>   b(x);
> }

Verlagere die Funktionen, die so aussehen, von der C-Datei in die 
jeweilige Header-Datei und deklariere sie als static inline. Dann klappt 
das auch mit den Optimierungen wieder.

von foxrider (Gast)


Lesenswert?

Der Grund für diese Sache ist folgender, nun ev gibt es eine besser 
Möglichkeit:
Ich habe eine S1D13700.c, welche eine Line() zur Verfügung stellt. Die 
BoardsupportLib übernimmt diese und stellt sie als Line() zur Verfügung. 
Meine draw.c wiederum übernimmt diese Line() von der bslDisplay.c
Ich mache das so damit ich nun über die draw.c unabhängig vom Board oder 
Displaytriber code schreiben kann. z.B. meine chart.c, welche Line() 
verwendet. Ich will aber nicht für jedes Board oder jedes Projekt eine 
neue chart.c schreiben. Dass muss ich au nicht, da ich die chart.c für 
jedes Board verwenden kann, egal welcher Chip oder welches Display drauf 
sitzt und wie die verbunden sind. Trotzdem will ich eine draw.c haben, 
welche mir ebenfalls die gleichen Möglichkeiten gibt, und mich direkt 
auf die Line() Funktion zugreifen lässt, ohne im Code die von der 
S1D13700.c zu verwenden, den dann ist mein Code nicht mehr unabhängig 
vom Board. über die draw.c ist er das aber. In meinem Projekt brauche 
ich nun nur noch die richtigen files über externals einzubinden und mit 
zu kompilieren und schon habe ich mein Programm. Wechsle ich das board, 
bleibt der Main code erhalten und ich ändere nur die darunterliegenden 
libs, binde diese anstelle der anderen ein, compilieren und fertig.

So kann ich nun ein Programm schreiben, welches theoretisch auf jedem 
board laufen kann, wenn die entsprechenden bslDisplay.c da ist. Weiter 
kann ich die s1d13700.c lib wieder verwenden, für jedes board, wo ein 
solcher drauf ist.
Ich hoffe ihr seht, was ich haben will. Ich sehe für das nur 2 
Möglichkeiten.
1. so wie ich das gemacht habe, oder
2. über defines, welche einfach die Line() von der draw auf die Line() 
von er bslDisplay.c definiert. -> #define Line bslDisplayline
Die 2 Variante ist nicht top, weil dadurch  die Autocompletion (Content 
Asisst) von Eclipse nicht mer zurecht kommt.
Eigendlich sollte ja der Compiler solcher sachen weg optimieren, aber 
wenn er nur die einzelnen Files optimiert, dann kann er das nicht.
Die Idee ist, dass ich möglichst viel code wiederverwenden kann, 
unabhänig vom Board und Applikation. (mit momentaner beschränkung auf 
den AVRGCC)

von foxrider (Gast)


Lesenswert?

Nachtrag: natürlich heissen diese Line() nicht in jeder lib gleich

s1d13700.h -> s1d13700Line()
bslDisplay.h ->bslDisplayLine()
draw.h ->drawLine();

in meinem Main code include ich nur noch die "draw.h" meine drawLib.
und fertig.
Das sollen alles so eine Art Libraries sein.

von Stefan E. (sternst)


Lesenswert?

Und was stört dich an meinem Vorschlag? Oder habe ich dein Vorhaben nur 
falsch verstanden?

Statt:

draw.h:
1
void Line (...);
draw.c:
1
void Line (...) {
2
    bslDisplayline(...);
3
}

machst du:

draw.h
1
static inline void Line (...) __attribute__ ((always_inline));
2
void Line (...) {
3
    bslDisplayline(...);
4
}

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Du könntest die Aufrufe auch über den Präprozessor auflösen lassen.

"line" existiert nur als #define, das --je nach verwendetem Display-- 
daraus direkt ein "s1d13700Line" oder entsprechend anders erzeugt.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.