skip to main content

kiesler.at
You are NOT logged in. ( login | New Account Signup | Forgot Your Password? ) Why log in?

Codeoptimierung mit BURG
updated by rck, 2006-03-26

Im Sommersemester 2004 galt es, wie schon viele Jahre davor, im Rahmen der Übung Übersetzerbau einen codeerzeugenden Compiler zu schreiben und zu optimieren. Ich möchte hier ein paar der von mir eingesetzten naheliegenden und weniger naheliegenden Tricks vorstellen.

1 | 2 | 3 | 4 | 5 | 6 | 7

Registerbibliothek in der Anwendung

Ich habe für jeden Knoten eine eigene Behandlungsroutine geschrieben, die Folgende ist beispielsweise für die Behandlung von "add"-Befehlen zuständig. Das gezeigte Prinzip sollte aber für so ziemlich alle binären Operationen anwendbar sein.

83 /*              arithmetics
84 */
85 
86 
87 node_add(treenodep a, treenodep b, treenodep dest) {
88 
89         if((a->regnr!=-1) && (b->regnr!=-1)) {
90 
91                 if(is_work_reg(a->regnr))
92                         dest->regnr=a->regnr;
93                 else
94                 if(is_work_reg(b->regnr))
95                         dest->regnr=b->regnr;
96                 else
97                         dest->regnr=alloc_register();
98 
99                 print_add(a->regnr, b->regnr, dest->regnr);
100 
101         } else
102         if(a->regnr!=-1) {
103 
104                 if(is_work_reg(a->regnr)) {
105 
106                         dest->regnr=a->regnr;
107                         print_add_const(a->regnr, b->num, a->regnr);
108 
109                 } else {
110 
111                         dest->regnr=alloc_register();
112                         print_add_const(a->regnr, b->num, dest->regnr);
113                 }
114 
115         } else
116         if(b->regnr!=-1) {
117 
118 
119                 if(is_work_reg(b->regnr)) {
120 
121                         dest->regnr=b->regnr;
122                         print_add_const(b->regnr, a->num, b->regnr);
123 
124                 } else {
125 
126                         dest->regnr=alloc_register();
127                         print_add_const(b->regnr, a->num, dest->regnr);
128                 }
129 
130         } else {
131 
132                 /* herzlichen Dank an Peter / Informatik-Forum
133                    für diese GENIALE Idee! :-) */
134 
135                 if(((a->num+b->num)>-254) &&
136                    ((a->num+b->num)< 255)) {
137 
138                         dest->num=a->num+b->num;
139                         dest->regnr=-1;
140 
141                 } else {
142 
143                         dest->regnr=alloc_register();
144                         print_store_const(a->num, dest->regnr);
145                         print_add_const(dest->regnr, b->num, dest->regnr);
146 
147                 }
148 
149         }
150 }

Kompliziert?

Sieht im ersten Moment sehr kompliziert aus -- es ist allerdings auch schon heftig optimiert worden darin.

89 - 101 wir haben zwei Register als Operanden. Der Fall ist fast so gut, wie Nummer vier: Lauter Konstanten. Ich habe für nichtvorhandene Register -1 eingesetzt und nicht etwa 0 -- die Nummerierung der Register beginnt ja bei 0 und wir würden dadurch einen der 32 Register nicht ansprechen können.

Hier sehen wir gleich eine wichtige Optimierung: Register-Recycling. Handelt es sich bei einem der Register nämlich um einen Arbeitsregister, können wir ihn gleich als Zielregister für die Operation definieren (92 bzw. 95). Praktisch!

Wenn nicht: Auch kein Problem, einfach einen neuen aus dem Pool nehmen.

102 - 130 hier das gleiche für nur einen Register. Vermutlich kann man das alles kompakter anschreiben.

130 - 149 im Falle lauter Konstanten braucht man gar keine Operation! Einfach das Ergebnis, wenn es im Rahmen bleibt, als Konstante weitergeben. Sehr effizient, habe ich mir von Peter aka. Risewind aus dem Informatik-Forum abgeschaut. Dankeschön!

1 | 2 | 3 | 4 | 5 | 6 | 7



RSSComments - Make a comment
The comments are owned by the poster. We are not responsible for its content.
RSSAll Articles
2008, 2007, 2006, 2005, 2004