DE3586234T2 - Datenverarbeitungsmaschine zur kompilation von computerprogrammen. - Google Patents
Datenverarbeitungsmaschine zur kompilation von computerprogrammen.Info
- Publication number
- DE3586234T2 DE3586234T2 DE19853586234 DE3586234T DE3586234T2 DE 3586234 T2 DE3586234 T2 DE 3586234T2 DE 19853586234 DE19853586234 DE 19853586234 DE 3586234 T DE3586234 T DE 3586234T DE 3586234 T2 DE3586234 T2 DE 3586234T2
- Authority
- DE
- Germany
- Prior art keywords
- instruction
- register
- bits
- significant
- significant bit
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Expired - Lifetime
Links
- 238000004458 analytical method Methods 0.000 claims description 26
- 238000000034 method Methods 0.000 claims description 14
- 238000003860 storage Methods 0.000 claims description 2
- 230000015572 biosynthetic process Effects 0.000 claims 1
- 238000012854 evaluation process Methods 0.000 claims 1
- 238000005457 optimization Methods 0.000 description 13
- 239000011159 matrix material Substances 0.000 description 6
- 230000008569 process Effects 0.000 description 5
- 230000008859 change Effects 0.000 description 3
- 238000010586 diagram Methods 0.000 description 3
- 230000008901 benefit Effects 0.000 description 2
- 230000006870 function Effects 0.000 description 2
- 239000003550 marker Substances 0.000 description 2
- 239000006227 byproduct Substances 0.000 description 1
- 230000000295 complement effect Effects 0.000 description 1
- 238000004590 computer program Methods 0.000 description 1
- 230000008030 elimination Effects 0.000 description 1
- 238000003379 elimination reaction Methods 0.000 description 1
- 230000006872 improvement Effects 0.000 description 1
- 238000004519 manufacturing process Methods 0.000 description 1
- 239000000758 substrate Substances 0.000 description 1
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/40—Transformation of program code
- G06F8/41—Compilation
- G06F8/44—Encoding
- G06F8/447—Target code generation
Landscapes
- Engineering & Computer Science (AREA)
- General Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Software Systems (AREA)
- Physics & Mathematics (AREA)
- General Physics & Mathematics (AREA)
- Devices For Executing Special Programs (AREA)
Description
- Die vorliegende Erfindung betrifft Datenverarbeitungsmaschinen, die dazu eingesetzt werden, Computerprogramme zu kompilieren und einen Maschinencode aus einem eingegebenen Quellcode zu erzeugen.
- Die vorliegende Erfindung ist besonders nützlich in einem Compiler für einen Digitalrechner, in dem Optimierungsalgorithmen zur Verbesserung der Codequalität eingesetzt werden. Sie könnte auch in einem Assembler eingesetzt werden, obwohl Optimierungsassembler nicht üblich sind. Die Erfindung verbessert die Qualität des Maschinencodes, der vom Compiler bzw. Assembler erzeugt wird.
- Die Erfindung ist anwendbar auf Rechner, die einen Akkumulator oder einen Satz allgemeine Register benutzen und die eine oder mehrere Befehlstypen verwenden, die in zwei oder mehr Formen vorkommen, wobei sich die Formen in der Länge der Operanden unterscheiden. Ferner muß es für die Anwendung der vorliegenden Erfindung einen Grund geben, die Kurzform eines Befehls vorzuziehen, wenn diese angewandt werden kann. Bei vielen Maschinen sind die Kurzformen vorzuziehen, weil sie schneller arbeiten oder weniger Speicherplatz benötigen oder beides.
- Die Qualität der von Compilern produzierten Codes war schon immer ein wichtiger Punkt, seit der erste Compiler hergestellt wurde. Eine Hauptaufgabe des FORTRAN I Compilers von IBM, dem ersten im Handel erhältlichen Compiler, war es, einen Maschinencode für wissenschaftliche Berechnungen zu erzeugen, dessen Code-Qualität mit dem von den in Assembler- Sprache arbeitenden Programmierern direkt "von Hand" eingegebenen Codes vergleichbar war.
- Heute gibt es höhere Programmiersprachen auf jedem Gebiet, auf dem Rechner einsetzbar sind. Sogar die ursprüngliche FORTRAN-Sprache wurde angereichert, um sie für eine große Reihe Programmieraufgaben einsetzbar zu machen. Es ist jedoch nach wie vor bedeutsam, daß der Compiler einen Hochqualitätscode erzeugt, besonders wenn der zu erzeugende Code in einem Produktionsumfeld eingesetzt werden soll. Immer noch ist der von einem geschickten Programmierer in Assemblersprache produzierte Code der Maßstab, an dem der vom Compiler produzierte Code gemessen wird.
- Seit den Fünfziger Jahren wurde eine große Zahl Optimierungstechniken entwickelt und verfeinert, um die Qualität des vom Compiler generierten Codes zu verbessern. Viele solche Optimierungen sind im Grundsatz wohlbekannt und wurden in gewisser Weise auch von dem Team angewandt, das den ersten FORTRAN-Compiler geschaffen hat.
- Optimierungen, die beim Optimieren von Compilern häufig eingesetzt werden, lassen sich in zwei Klassen einteilen, die allgemein als "Global"- und als "Guckloch"-Optimierungen bekannt sind. Global-Optimierungen sind solche, die sich auf die Analyse des gesamten zu kompilierenden Programms stützen. Beispiele dafür sind "Code motion" (Code aus Schleifen herausnehmen) und die "Eliminierung allgemeiner Unterausdrücke". Guckloch-Optimierungen sind solche, die sich auf die Analyse eines verhältnismäßig kleinen Gebiets des Programms wie einen "Programmblock" oder vielleicht auch nur auf zwei hintereinanderliegende Befehle stützen.
- Die vorliegende Erfindung kann als Global-Optimierung oder auch auf Programmblockebene implementiert werden, oder sie verwendet eine teilweise globale Information, die von der Globalanalyse im Normalfall leicht erfaßt wird und verfeinert dann diese Information auf Programmblockebene. Wenn mehr Informationen verfügbar sind, wird sie effektiver arbeiten.
- Die Information aus der Globalanalyse, die sie vorteilhaft benutzen kann, ist die Lebend/Tot-Information. Diese Information sagt für jeden Registeroperand eines Befehls aus, ob dieses Register wieder benutzt werden kann, bevor es mit einem neuen Wert geladen wird, oder nicht.
- Wen ein Registeroperand eines Befehls "tot" ist, heißt das, der Befehl ist die "letzte Anwendung" dieses Registers, und nach Durchführung des Befehls kann der Inhalt des Registers beliebig geändert werden, ohne die Programmausführung zu beeinflussen. Wenn andererseits der Registeroperand eines Befehls "lebt", heißt das, der Inhalt des Registers darf nach Ausführung des Befehls nicht verändert werden, weil es noch einen Ausführungspfad geben kann, in dem der Registerinhalt gebraucht wird.
- Die folgenden Hinweise diskutieren die Analyse lebender Variabler:
- J.D.Ullman, A Survey of Data Flow Analysis Techniques, [Übersicht über Datenfluß-Analysetechniken], second USA-Japan Computer Conference Proceedings, AFIPS Press, Montvale, New Jersey (1975), Seiten 335 - 342 (enthält 37 Hinweise).
- A.V.Aho und J.D.Ullman, Principles of Compiler Design, [Grundlagen des Compileraufbaus], Addison-Wesley, (1977).
- M.S.Hecht, Flow Analysis of Computer Programms [Analyse von Rechnerprogrammabläufen], Elsevier North-Holland, New York (1977).
- Der Motorola MC68000 ist ein Beispiel für einen Rechnertyp, auf den die Erfindung anwendbar ist. Dieser Rechner hat drei Additionsfunktionen ("add") und drei unmittelbare Additionsfunktionen ("add immediate"), wie nachstehend gezeigt wird.
- ADD.L r1,r2 ADDI.L #123,r1
- ADD.W r1,r2 ADDI.W #123,r1
- Add.B r1,r2 ADDI.B #123,r1
- ADD.L (add long) addiert den kompletten, 32 Bit langen Inhalt des Registers r1 zu Register r2 und speichert das Ergebnis in r2. ADD.W (add word) addiert die 16 am rechten Ende von r1 stehenden Bits zu den 16 am rechten Ende von r2 stehenden Bits und läßt die linken 16 Bits von r2 unverändert. ADD.B (add byte) addiert die am rechten Ende von r1 stehenden acht Bits zu den am rechten Ende von r2 stehenden acht Bits und läßt die linken 24 Bits von r2 unverändert. Auf ähnliche Weise addiert ADDI.L (add immediate long) eine Zahl (im obigen Beispiel 123) zum gesamten, 32 Bits langen Inhalt des Registers r1, ADDI.W addiert sie zu den am rechten Ende stehenden 16 Bits und ADDI.B addiert sie zu den am rechten Ende stehenden acht Bits.
- Die Befehle ADD.W und ADD.B sind schneller als ADD.L, und werden daher bevorzugt in einer Situation, in der jeder Befehl möglich ist. Die Befehle ADDI.W und ADDI.B sind schneller und brauchen weniger Speicherplatz als ADDI.L, und werden daher gegenüber ADDI.L vorgezogen.
- Es gibt jedoch ein besonderes Problem, das die ersetzbaren Befehlsklassen einschränken kann. (Dieses Problem tritt nicht auf im Zusammenhang mit den beispielsweise angeführten Architekturen und Compilern), nämlich daß ein Austausch den Anzeigeregisterstand oder Statuscode unterschiedlich einstellen kann. Zum Beispiel kann eine 8-Bit-Addition das Übertragsbit vor das Bit 8 setzen während die 32-Bit-Addition es vor das Bit 32 setzt, was eine Ersetzung unsicher macht.
- Der Motorola MC68000 hat noch viele weitere Befehlstypen, die in einer "langen" und einer "kurzen" Form vorhanden sind, wobei die Kurzform schneller ausgeführt wird und häufig weniger Speicherplatz einnimmt. Weitere Einzelheiten, einschließlich Befehlsausführungszeiten, siehe in:
- MC68000 16-bit Microprocessor User's Manual, zweite Ausgabe, Motorola Inc., (Januar 1980).
- Die Erfindung ist in den beiliegenden Ansprüchen definiert.
- Als Beispiel für die von der Erfindung erzielte Code-Verbesserung soll ein Compiler die folgende Befehlsfolge generiert haben:
- ADD.L R2,R1
- SUBI.L #16,r1
- MOVE.W r1,6(r5)
- und nehmen wir ferner an, daß der Befehl MOVE.W, der die am rechten Ende stehenden 16 Bits des Registers r1 in eine Speicherzelle einspeichert, deren Adresse durch die Inhalte der Register r5 plus 6 gegeben ist, die letzte Anwendung des Registers 1 war. Die Erfindung wird dann den ADD.L Befehl durch ADD.W und den Befehl SUBI.L durch SUBI.W ersetzen. Die letzteren Formen sind schneller als die ersteren und der Befehl SUBI.W verbraucht weniger Speicherplatz als SUBI.L.
- Zwecks besseren Verständnisses der Erfindung soll jetzt anhand der begleitenden Zeichnungen eine bevorzugte Ausführungsform beschrieben werden; in diesen sind:
- Fig. 1 ein Funktionsflußdiagramm eines optimierenden Compilers auf sehr hoher Ebene, in dem die vorliegende Erfindung besonders sinnvoll ist;
- Fig. 2 ein Flußdiagramm auf hoher Ebene des hier geoffenbarten Compilermoduls zur Durchführung der gewünschten Analyse der signifikanten Bits;
- Fig. 3 ein mehr ins Detail gehendes Flußdiagramm, das zeigt, wie einige der Befehle vom Rechentyp durch das hier geoffenbarte Compilermodul verarbeitet werden.
- Die Erfindung wird angepaßt an einen Optimierungscompiler und für den Motorola MC68000 als Zielmaschine beschrieben.
- Der erste Schritt bei der Anwendung dieser Erfindung ist die Durchführung einer "Signifikant-Bit-Analyse" des zu kompilierenden Programms. Das ist ein Prozeß der Bestimmung bei jedem einzelnen Befehl, welche Bits des Ergebnisses dieses Befehls "signifikant" sind (zwecks Vereinfachung nehmen wir hier an, daß es immer nur ein einziges Ergebnis gibt). Ein Bit ist signifikant, wenn es vom Programm nach der Berechnung benützt wird. Es handelt sich hier um das gleiche Konzept wie bei dem bekannten "Lebendigsein", mit dem Unterschied, daß jedes Bit des Resultats geprüft wird zwecks Bestimmung, ob es "lebendig" bzw. "signifikant" ist. Bei der herkömmlichen Analyse auf Lebendigsein wird für jeden Befehl nur ein einziges zusammenfassendes Bit berechnet, das angibt, ob es im Ergebnis Bits gibt, die "lebendig" bzw. "signifikant" sind.
- Es gibt drei Ebenen, auf denen die Signifikanzanalyse durchgeführt werden kann:
- 1. Global, wie die gewöhnliche Analyse auf Lebendigsein durchgeführt wird,
- 2. Auf Programmblockebene (in der Praxis von Verzweigung zu Verzweigung) mit Unterstützung durch die globale Analyse auf Lebendigsein, oder
- 3. Auf Programmblockebene (von Verzweigung zu Verzweigung) ohne Hilfe.
- Die obige erste Wahl ist am aufwendigsten zu berechnen, ergibt jedoch auch die besten Resultate. Die letzte ist die billigste, ergibt aber die schlechtesten Resultate. Die zweite ist ein Kompromiß, der nur wenig teuerer zu berechnen ist als (3), wenn die Lebend-Analyse sowieso schon durchgeführt wurde, und bringt Ergebnisse einer mittleren Qualität. Wahl (2) wird hier beschrieben, jedoch beschränkt sich die Erfindung keineswegs auf diese bestimmte Anwendung.
- Fig. 1 zeigt, wo die Signifikant-Bit-Analyse der Ebene (2) (Block 5) innerhalb des Rahmens eines typischen Optimierungscompilers am praktischsten durchgeführt wird. Das Wichtige dabei ist, daß die globale Code-Optimierung (Block 3) vor der Siginifikant-Bit-Analyse gemacht wird. Das ist deswegen, weil die konventionelle Lebendanalyse Teil der globalen Codeoptimierung ist, und wir brauchen die "letztverwendeten" Bits, die ein Nebenerzeugnis der Lebendanalyse sind.
- Vorzugsweise, wenn auch nicht notwendig, sollte die Registerzuweisung (Block 4) vor der Signifikant-Bit-Analyse durchgeführt werden. Das ermöglicht einen effizienter arbeitenden Compiler, weil bei vorheriger Registerzuweisung die Signifikant-Bit-Analyse an den reellen Registern der Maschine durchgeführt werden kann und davon gibt es gewöhnlich eine verhältnismäßig geringe Anzahl (z.B. 16 beim Motorola MC68000).
- Die Signifikant-Bit-Analyse muß vor der endgültigen Code- Generierung durchgeführt werden (Block 6). Das Modul zum Generieren des endgültigen Code des Compilers benötigt die Ergebnisse der Signifikant-Bit-Analyse zum Festlegen, in welcher Form (8-Bit, 16-Bit oder 32-Bit) die einzelnen Befehle generiert werden müssen.
- Fig. 2 ist ein Flußdiagramm der Signifikant-Bit-Analyse gemäß Block 5 in Fig. 1 auf hoher Ebene. Die Analyse wird in einem einzigen Rückwärtsdurchlauf durch das Programm durchgeführt. Obwohl die hier gezeigte Verarbeitung auf einer Programmblockbasis gemacht werden könnte, wird sie, wie gezeigt wird, auf der Grundlage Verzweigung-zu-Verzweigung gemacht. Das läßt sich genauso leicht programmieren und führt manchmal zu einer Generierung eines Codes mit besserer Qualität. So werden Markierungspunkte im Programm ignoriert (Block 23). Aber Sprungbefehle (Block 25) führen dazu, daß die Kenntnis der Maschine, welche Bits in den einzelnen Registern signifikant sind, auf den Zustand "Alle Bits aller Register sind vermutlich signifikant" rückgestellt wird. Das ist der Zustand einer sicheren Annahme bei allen Punkten, von denen die Maschine keine Information hat.
- Wenn ein Befehl keinen Markierungspunkt darstellt und keine Verzweigung oder der "Return"-Befehl einer Subroutine ist, dann ist er ein gewöhnlicher Rechenbefehl wie "add", "load", "store", "shift" usw. Die Verarbeitung von Rechenbefehlen, gezeigt in Block 26 der Fig. 2, wird in größeren Einzelheiten in Fig. 3 gezeigt.
- Dieses Programm arbeitet mit einer Bit-Matrix (Signifikanzwerte), die nachstehend als Signifikant-Bit-Tabelle (SBT) bezeichnet wird und die eine Anzahl Reihen, die gleich ist der Anzahl der Register in der Maschine (z.B. 16 beim Motorola MC68000), und einer Anzahl Spalten, die gleich der Registerlänge der Maschine ist (32 beim MC68000), aufweist. An einem Punkt der Verarbeitung kann diese Matrix z.B. so aussehen: 32 Bits
- Hier sind die Bits in Hexadezimalschreibweise dargestellt, z.B. bedeutet "0000FFFF" 16 0-Bits gefolgt von 16 1-Bits. Die Werte in der Matrix ändern sich beim Rückwärtsdurchlauf des Programms im Befehlsstrom. Wenn zu einem bestimmten Punkt die Matrix die obigen Werte annimmt, bedeutet das, daß an diesem Punkt die 16 Bits am linken Ende des Registers 0 nicht signifikant (d.h. "tot") sind, daß aber die 16 Bits an rechten Ende signifikant sind. Ein Signifikanzwert "FFFFFFFF" bedeutet, daß alle Bits im zugehörigen Register signifikant sind usw.
- Nun wollen wir unter Bezugnahme auf Fig. 3 sehen, wie ein Befehl verarbeitet wird, um die signifikanten Bits seines Ergebnisses zu bestimmen. Der Prozeß ist, die signifikanten Bits aus einem Ergebnis zu den Eingabeoperanden eines Befehls zu schicken. Dann läuft es von den Eingabeoperanden eines aktuellen Befehls zu den Ergebnisoperanden früherer Befehle, weil das Programm den Prozessor so steuert, daß er rückwärts durch den Befehlsstrom läuft. Wie die Bits aus einem Ergebnis zu den Eingangsoperanden laufen, hängt vom Befehlstyp ab (add, shift, store, usw.), wie in Fig. 3 gezeigt wird. Zum Start muß die Maschine wissen, oder annehmen können, welche Ergebnisbits des zuerst aufgefundenen Befehls signifikant sind. Für den hier beschriebenen Prozeß wird angenommen, daß beim ersten angetroffenen Befehl alle Ergebnisbits signifikant sind. Das wird aufgezeichnet durch die Initialisierung der gesamten 16x32 Bit-Matrix auf jeweils 1, wenn ein Sprungbefehl angetroffen wird, d.i. Signifikanzwerte für alle Register sind gleich "FFFFFFFF".
- Nehmen wir jetzt an, es wird gerade die Mitte eines Codeabschnitts zwischen zwei Verzweigungen verarbeitet und ein Additions-, Substrat- oder Subtraktionsbefehl wird angetroffen. Im einzelnen soll dieser Befehl wie folgt angenommen werden:
- ADD.L r1,r2
- Das heißt, addiere den Inhalt des Registers r1 zum Inhalt des Registers r2. Register r2 ist sowohl ein Eingang als auch das Ergebnis des Befehls. Es wird leichter, wenn man hier in der Form eines Dreiadressen-Befehls denkt:
- ADD.L R1,r2,3
- wobei r3 das Ergebnisregister ist.
- Zuerst muß man sich auf die Signifikant-Bit-Tabelle in Position r3 beziehen, um zu sehen, welche Bits des Ergebnisses signifikant sind. Die von der Tabelle abgenommene Bit-Maske wird mit dem Additionsbefehl assoziiert (gespeichert), so daß sie später vom Assemblierungs- und Endcode-Generierungsmodul benützt werden kann, um die optimale Form des Additionsbefehls zu generieren. Für den Augenblick genügt es, nur zwei Bits mit der Additionsbefehl zusammenzubringen, um aufzuzeichnen, ob der Befehl in Langform (32 Bits), Wortform (16 Bits) oder Byteform (8 Bits) generiert werden soll, diese drei Formen werden als einzige auf dem MC68000 angeboten. Diese Assoziierung von zwei Bits mit dem Befehl wird nachstehend als "Markierung" des Befehls bezeichnet.
- Nehmen wir an, die signifikanten Bits des Ergebnisregisters r3 (wie für den SBT bestimmt) sind X700008012'. Dann können wir den Addierbefehl als "Wort", d.i. 16-Bit Form, markieren, weil alle signifikanten Bits des Ergebnisses in den 16 rechtsstehenden Bits des Registers r3 liegen. Dann, weil ja die Addition ein Rechts-links-Prozeß ist (durchwegs wird die Zweierkomplement-Arithmetik angenommen), können die in den 16 linksstehenden Positionen des Registers r1 und r2 kein signifikantes Bit des Ergebnisses beeinflussen, aber Bits irgendwo in den rechten 16 Positionen können. Daher sind die signifikanten Bits der Register r1 und r2 für diesen Befehl X'0000FFFF'. Das wird als nächstes in der SBT-Tabelle, in den Zeilen für die Register r1 und r2 vermerkt. Wenn der Addierbefehl der letztverwendete in r1 (bzw. r2) in diesem Block ist, dann wird die Tabellenposition für r1 (oder r2) auf X'0000FFFF' gesetzt. Das wird bestimmt durch Ansehen des obigen Lebendigkeitsbits, das während der "Code-Optimierungs-Phase" gesetzt werden kann. Andererseits, wenn der Additionsbefehl nicht die letzte Verwendung für r1 (bzw. r2) ist, dann setzen wir X'0000FFFF' mit einer ODER-Verknüpfung in die Tabelle auf Position r1 (bzw. r2). Dabei kann es vorkommen, daß r1 und r2 bestimmte Bits signifikant haben wegen der Anwendungen dieser Register unterhalb des Additionsbefehls, d.i. Anwendungen, die bereits früher im Rückwärtsdurchlauf verarbeitet wurden und wobei diese signifikanten Anwendungen nicht "vergessen" werden dürfen. Diese Verarbeitung eines Additionsbefehls (oder Subtraktionsbefehls) wird in den Blöcken 31 und 32 der Fig. 3 gezeigt.
- Der Rückwärtsdurchlauf wird dann wahrscheinlich auf einen Befehl stoßen, der r1 auf r2 setzt. Jetzt bezieht er sich auf Position r1 bzw. r2 der Tabelle, um zu bestimmen, welche Bits dieses Registers signifikant sind. Dann überträgt er diese Information zurück auf den Eingabeoperanden, ähnlich wie der oben beschriebene Additions-Befehl.
- Nehmen wir als weiteres Beispiel an, daß ein Befehl "store byte" gefunden wird (Fig.3 Block 39 und 40). Dieser Befehl würde geschrieben werden:
- MOVE.B r1,d(r2,r3)
- in welchem das Register r1 das abzuspeichernde Byte enthält, und r2 und r3 "Basis"- und "Index"-Register sind, die zur Speicher-Adressierung dienen. "d" ist eine Distanz (eine Konstante), die bei der Signifikanzanalyse keine Rolle spielt. Der Befehl MOVE hat kein Ergebnisregister (er ändert keinen Registerinhalt). Er benutzt nur die acht rechten Bits des Registers r1. Daher wird eine Maske X'000000FF' mit ODER- Verknüpfung in die Tabelle an Position r1 eingegeben. Der Befehl MOVE benutzt die 24 rechten Bits des Basis- und Index- Registers, deshalb wird eine Maske X'00FFFFFF' in ODER-Verknüpfung in die Tabelle an Position r2 und r3 eingegeben.
- Fig. 3 zeigt die Verarbeitung von sechs Befehlstypen. Der gesamte Prozeß sollte erweitert werden, um noch andere Befehlstypen zu erfassen, die in Fig. 3 nicht gezeigt sind, wie z.B. die Befehle "load" und "shift" usw.
- Um jetzt ein umfangreicheres Beispiel zu geben, nehmen wir an, daß eine Codesequenz zwischen Verzweigungen wie folgt ist: Signifikanz von r1
- Das Programm liest ein Langwort (32 Bits) aus dem Speicher, verschiebt seine rechten acht Stellen (LSR = logical shift right), verknüpft es in UND-Verknüpfung mit der Maske X'000000FF' und speichert das äußerste rechte Byte des Registers r1 in den Hauptspeicher. Die Spalte mit der Überschrift "Signifikanz von r1" zeigt eine Reihe der Signifikanzmatrix, die für r1, beim weiteren Rückwärtsdurchlauf der Verarbeitung. Nachstehend wird beschrieben, was bei der weiteren Verarbeitung der Befehlssequenz mit der Signifikanz von r1 geschieht.
- Anfänglich (unterste Reihe) wird die Signifikanz von r1 auf X'FFFFFFFF' gesetzt, was angenommen werden muß, wenn keine weiteren Erkenntnisse vorliegen. Dann wird der Befehl MOVE.B gefunden. Für unser Beispiel nehmen wir an, daß die Verwendung von r1 in diesem Befehl das Flag "last use" aufweist, das nach r1 mit einem Strich (') angezeigt wird. Dann wird in der Tabelle nach Fig. 3 Block 40 die Signifikanz auf X'000000FF' gesetzt.
- Dann wird ANDI.L gefunden. Dieser Befehl benutzt r1 sowohl als Eingangs- als auch als Ergebnisregister. Die Signifikanz von r1 als Ergebnis, X'000000FF', wird mit der Maske in UND- Verknüpfung verknüpft, auch wird X'000000FF' an die Tabellenposition r1 in ODER-Verknüpfung gesetzt. Das Ergebnis ist X'000000FF' (keine Änderung der Signifikanz von r1). Diese Schritte sind in Fig. 3 Block 42 zusammengefaßt.
- Zu diesem Zeitpunkt könnte das Signifikanzanalyseprogramm beobachten, daß der Befehl nur insignifikante Bits ausgibt und daher weggelassen werden kann. Alternativ würde der Befehl als Byte-Form markiert sein und die Endcodegenerierung könnte ihn löschen, da die Direkt-Maske auf acht "1"-Bits endet.
- Als nächstes wird der Befehl LSR.L gefunden. Dieser ist als Byte-Form markiert, weil der Signifikanzwert des Ergebnisses X'000000FF' ist. Die Signifikanz des Eingaberegisters, r1, ist gleich der Signifikanz des Ergebnisregisters, auch r1, um acht Stellen nach links verschoben (Fig. 3 zeigt das Verschieben nicht an).
- Als letztes wird MOVE.L gefunden. Dieser Befehl ist als Wortform (16 Bits) markiert, denn die Signifikanz des Ergebnisregisters (r1) ist X'0000FF00', d.h. nur Bits in den 16 rechten Stellen sind signifikant.
- Unter Verwendung der oben berechneten Markierungen kann die Endcodegenerierung die folgenden Befehle als schnelleres und kürzeres Äquivalent der oben gezeigten Befehle ausgeben:
- MOVE.W 6(r2),r1 (Befehl vom Speicher laden)
- LSR.W #8,r1
- MOVE.B r1',0(r2) (Befehl in Speicher abspeichern)
- Es gibt zwei Dinge, die die Endcodegenerierung erkennen muß und die im obigen Beispiel auftreten: (1) MOVE.L kann nicht zu MOVE.W umgeändert werden, es sei denn, die Erhöhung der Verschiebung um zwei (im Beispiel von 4 auf 6) ergibt eine Verschiebung innerhalb der vom Befehl zugelassenen Grenzen (32767 beim MC68000), und (2) die Auswahl der leistungsfähigsten Form des Befehls LSR hängt ab vom Signifikanzwert des Ergebnisses und vom Verschiebungsbetrag. Im Beispiel ist der Signifikanzwert des Ergebnisses X'000000FF', aber der LSR-Befehl kann nicht zu LSR.B gemacht werden, weil die Bits in den Positionen 16-23 des Registers r1 in die Positionen 24-31 verschoben werden. Er kann jedoch zu LSR.W umgeformt werden, der schneller ist als der ursprüngliche LSR.L.
- Anhang I zeigt eine komplette Arbeitssubroutine zur Durchführung der Signifikanzanalyse. Sie beinhaltet die in den Fig. 2 und 3 gezeigten Schritte. Sie wurde bei verschiedenen Zielmaschinen erfolgreich eingesetzt: Motorola MC68000, IBM System/370, und bei mehreren experimentell reduzierten Befehlssatzmaschinen-Aritekturen. Sie ist in einer PL/I ähnlichen Sprache geschrieben und hinreichend mit Anmerkungen versehen, daß ein erfahrener Programmierer die vorliegende Erfindung in einen Optimierungscompiler der Form gemäß Fig. 2 einbauen kann, oder die Subroutine in eine andere Sprache oder für eine andere Zielmaschine oder einen Assembler- Compiler unterschiedlicher Struktur umschreiben kann.
- Es wird natürlich anerkannt, daß die in die Bit-Tabelle eingeführten spezifischen Signifikanzwerte auf eine spezifische Systemarchitektur und ein besonderes Befehlsformat zugeschnitten werden müssen. Die Erfindung ist gleichermaßen anwendbar auf z.B. eine 16-Bit Vollwortmaschine sowie auf eine 45- bis 64-Bit Maschinenarchitektur. Insbesondere muß angemerkt werden, daß die Vorteile der vorliegenden Erfindung in einer Maschinenarchitektur zur Geltung kommen, in der die Befehle in Kurzform weniger Maschinenzeit oder Speicherraum benötigen als die Langformen, unabhängig von den zugrundeliegenden Maschinenlängen.
Claims (7)
1. Verfahren zum Optimieren eines Codes, das nach der
Registerzuordnungsphase eines optimierenden Compilers
innerhalb desselben durchgeführt werden kann,
wobei das Verfahren durchgeführt werden kann, um eine Analyse
für signifikante Bits zu liefern, die Ergebnisse der Analyse
während der Phase einer Endcodeerzeugung der
Compilerarbeitsgänge verwendet werden, um die leistungsfähigste Form
eines Rechnerbefehls zu bilden, der zum Erzeugen des
gewünschten Ergebnisses verfügbar ist, und das Verfahren
folgendes umfaßt:
Festlegen einer Tabelle für signifikante Bits in einem
Speicher, die eine Speicherstelle mit Bezug auf jedes
Arbeitsregister für ein Zielsystem ist, und von Mitteln zum Zugreifen
auf die Tabelle bei einer Stelle, die aus der
Registernummerzuweisung der Operanden eines Befehls erhalten werden
kann,
Prüfen eines Stroms mit linearem Code, der optimiert werden
soll aufeinanderfolgend in umgekehrter Reihenfolge,
falls ein ausgewerteter Befehl keine Rechen-"Marke" ist,
Erhalten des nächsten Befehls,
falls ein Befehl ein Rücksprung- oder ein Sprungbefehl ist,
Initialisieren aller Signifikanzwerte, welche die Eintragungen
in der Tabelle für signifikante Bits sind, auf "alle
signifikant" ("FFFFFFFF"), wodurch angezeigt wird, daß die
Werte irgendeines der Bits irgendeines der Register beim
Bestimmen von Eingangsoperanden von Befehlen später in der
Ausführung des Programms erforderlich sein können und sodann
Erhalten des nächsten Befehls,
für jeden Befehl der Rechenart:
a) Markieren des Befehls entsprechend dem Signifikanzwert
seines entsprechenden Ergebnisregisters, um die maximale
Anzahl von Bits in Operanden und Ergebnissen anzuzeigen, die
zum Ausführen des Befehls erforderlich sind,
b) Verwenden des Signifikanzwerts des entsprechenden
Ergebnisregisters und der Einzelheiten des Befehls, um zu bestimmen,
welche Bits der enthaltenen Werte in welchen Registern beim
Berechnen der signifikanten Bits des Ergebnisses signifikant
sind und entsprechendes Ändern der Tabelle für signifikante
Bits und
Fortsetzen des Auswerteverfahrens solange, bis alle Befehle in
einem speziellen Befehlsstrom verarbeitet wurden.
2. Verfahren nach Anspruch 1, bei welchem ein "Addition"- oder
"Subtraktion"-Befehl erhalten wird und welches das Setzen
aller Bits bei dem höchstwertigen signifikanten Bit des
Ergebnisregisters und rechts desselben oder das Addieren
derselben zu den signifikanten Bits jedes Eingangsregisters in
der Tabelle für signifikante Bits umfaßt.
3. Verfahren nach Anspruch 1 oder 2, bei welchem der
Rechenbefehl ein "Bewegen eines Registers"-oder einen "AND, OR
oder EXOR"-logischen Arbeitsgang enthält, einschließlich
des Setzens der signifikanten Bits des Ergebnisregisters oder
des Addierens derselben zu den signifikanten Bits jedes
Eingangsregisters des Befehls.
4. Verfahren nach einem der Ansprüche 1 bis 3, bei welchem der
Rechenbefehl einen "Vergleichen von Registern"-Arbeitsgang
enthält, einschließlich:
des Setzens der signifikanten Bits jedes Eingangsregisters als
"alle signifikant".
5. Verfahren nach irgendeinem der Ansprüche 1 bis 4, bei
welchem der Rechenbefehl einen "Speichern eines Wortes"
-Arbeitsgang enthält, einschließlich:
des Setzens oder Addierens eines Signifikanzwertes zu der
Tabelle für signifikante Bits bei der Stelle mit Bezug auf das
Register, das gespeichert werden soll, der gleich ist der
Feldlänge eines Wortes in dem Zielsystem und des Setzens oder
Addierens eines Signifikanzwertes zu der Tabelle für
signifikante Bits bei Stellen mit Bezug auf die Basis- und
Indexregister, eines Wertes, der gleich ist der Feldlänge der
Basis- und Indexfelder, die von dem Zielsystemspeicher
erforderlich sind.
6. Verfahren nach irgendeinem der Ansprüche 1 bis 5, bei
welchem der Rechenbefehl einen "Speichern eines Bytes" -
Arbeitsgang enthält, einschließlich
des Setzens oder Addierens eines Signifikanzwertes zu der
Tabelle für signifikante Bits bei der Stelle mit Bezug auf das
Register, das gespeichert werden soll, der gleich ist der
Feldlänge eines Bytes in dem Zielsystem und des Setzens oder
Addierens eines Signifikanzwertes zu der Tabelle für
signifikante Bits bei Stellen mit Bezug auf die Basis- und
Indexregister, eines Wertes, der gleich ist der Feldlänge der
Basis- und Indexfelder, die von dem Zielsystemspeicher
erforderlich sind.
7. Verfahren nach irgendeinem der Ansprüche 1 bis 6, bei
welchem der Rechenbefehl einen "AND-unmittelbar" Befehl
enthält, einschließlich:
des Setzens des Signifikanzwertes des Ergebnisses des Befehls,
der einer "AND"-Bildung mit der "unmittelbare Maske"
unterworfen
wurde und des Addierens desselben zu dem
Signifikanzwert in der Tabelle für signifikante Bits bei der
Stelle mit Bezug auf das Register.
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
US66680084A | 1984-10-31 | 1984-10-31 |
Publications (2)
Publication Number | Publication Date |
---|---|
DE3586234D1 DE3586234D1 (de) | 1992-07-23 |
DE3586234T2 true DE3586234T2 (de) | 1992-12-10 |
Family
ID=24675539
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
DE19853586234 Expired - Lifetime DE3586234T2 (de) | 1984-10-31 | 1985-10-11 | Datenverarbeitungsmaschine zur kompilation von computerprogrammen. |
Country Status (3)
Country | Link |
---|---|
EP (1) | EP0180077B1 (de) |
JP (1) | JPS61110240A (de) |
DE (1) | DE3586234T2 (de) |
Families Citing this family (5)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US5132972A (en) * | 1989-11-29 | 1992-07-21 | Honeywell Bull Inc. | Assembly language programming potential error detection scheme sensing apparent inconsistency with a previous operation |
EP1164479B1 (de) | 1993-05-27 | 2007-05-09 | Matsushita Electric Industrial Co., Ltd. | Programmumsetzungseinheit |
JP3233245B2 (ja) * | 1993-07-01 | 2001-11-26 | 日本電気株式会社 | 言語処理方法 |
WO1995031767A1 (en) * | 1994-05-11 | 1995-11-23 | Vlsi Technology, Inc. | Floating-point processor with apparent-precision based selection of execution-precision |
AU2001278329A1 (en) * | 2000-11-20 | 2002-05-27 | Zucotto Wireless, Inc. | System and methods providing runtime byte code simplification for platform independent languages |
Family Cites Families (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
JPS584371B2 (ja) * | 1975-04-04 | 1983-01-26 | 株式会社日立製作所 | オブゼクト命令生成における相対アドレス決定方式 |
JPS5854449A (ja) * | 1981-09-28 | 1983-03-31 | Fujitsu Ltd | 分岐命令短縮化処理方式 |
JPS58161045A (ja) * | 1982-03-19 | 1983-09-24 | Fujitsu Ltd | コンパイラにおけるレジスタ管理方式 |
-
1985
- 1985-09-04 JP JP19403485A patent/JPS61110240A/ja active Pending
- 1985-10-11 EP EP19850112899 patent/EP0180077B1/de not_active Expired
- 1985-10-11 DE DE19853586234 patent/DE3586234T2/de not_active Expired - Lifetime
Also Published As
Publication number | Publication date |
---|---|
EP0180077A3 (en) | 1988-06-22 |
EP0180077A2 (de) | 1986-05-07 |
JPS61110240A (ja) | 1986-05-28 |
EP0180077B1 (de) | 1992-06-17 |
DE3586234D1 (de) | 1992-07-23 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
DE69432445T2 (de) | Verbesserter Prozessor für Adressierung | |
EP0689694B1 (de) | Verfahren zur maschinellen erzeugung von nebenläufig bearbeitbaren befehlsgruppen aus einem programm für superskalare mikroprozessoren | |
DE68921906T2 (de) | Verfahren für ein Multiprozessorsystem mit sich selbst zuordnenden Prozessoren. | |
DE69800686T2 (de) | Verfahren und Gerät für effizienten Operationen auf primären Typwerten ohne statisches Überladen | |
DE69230707T2 (de) | An das Ziel anpassbares Informationsverarbeitungssystem | |
DE69024068T2 (de) | Verfahren und Datenverarbeitungseinheit zur Pipeline- Verarbeitung von Register- und Registeränderungs- Spezifizierern in dem gleichen Befehl | |
DE68925646T2 (de) | Pipeline-multiprozessorsystem | |
DE69534113T2 (de) | Kompression der Befehlswörter eines Rechners | |
DE69115344T2 (de) | Vorverarbeitungsprozessor zur Verbindung von Befehlen für einen Cache-Speicher | |
DE69132675T2 (de) | Parallelfliessband-Befehlsverarbeitungssystem für sehr lange Befehlswörter | |
DE3689389T2 (de) | Datenverarbeitungsprozessor. | |
DE68926956T2 (de) | Anordnung zur teilung eines generischen kodes für ein digitales datenverarbeitungssystem | |
DE69933088T2 (de) | Vliw-verarbeiter verarbeitet befehle von verschiedenen breiten | |
DE3688824T2 (de) | Datenverarbeitungssystem. | |
DE69832932T2 (de) | Programmkonvertiergerät für konstantenrekonstruierenden VLIW Prozessor | |
DE2230102A1 (de) | Rechenwerk fuer variable wortlaengen | |
DE2847934A1 (de) | Datenverarbeitungseinrichtung mit einem mikrobefehlsspeicher | |
DE4342250A1 (de) | Rechnerarchitektur und Verfahren zum Betreiben eines Parallelrechners | |
DE3750951T2 (de) | Verfahren zur Kodeerzeugung für Rechner mit beschränktem Befehlssatz. | |
DE69133571T2 (de) | Datenprozessor mit der Fähigkeit, zwei Befehle gleichzeitig auszuführen | |
DE69616867T2 (de) | Prozessor, der schnell von Unterprogrammen zurückkehrt, und Programmübersetzungsgerät, das Maschinenprogramme erzeugt, die schnell von Unterprogrammen zurückkehren | |
DE69229771T2 (de) | Datenverarbeitungsverfahren und -vorrichtung | |
EP0825540B1 (de) | Prozessor mit Pipelining-Aufbau | |
DE69616718T4 (de) | Vorrichtung und verfahren zur bestimmung von adressen fehlausgerichteter daten | |
DE3855524T2 (de) | Arithmetik-Parallelverarbeitungseinheit und zugehöriger Kompilator |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
8364 | No opposition during term of opposition | ||
8339 | Ceased/non-payment of the annual fee |