LLVM hat Phi- Anweisungen mit ziemlich seltsamen Erklärungen:
Der Befehl 'phi' wird verwendet, um den φ-Knoten in dem SSA-Graphen zu implementieren, der die Funktion darstellt.
In der Regel wird es zum Implementieren der Verzweigung verwendet. Wenn ich es richtig verstanden habe, ist es erforderlich, eine Abhängigkeitsanalyse zu ermöglichen, und in einigen Fällen kann dies dazu beitragen, unnötiges Laden zu vermeiden. Es ist jedoch immer noch schwer zu verstehen, was es genau tut.
Das Kaleidoskop- Beispiel erklärt es ziemlich gut für den if
Fall. Es ist jedoch nicht so klar, wie logische Operationen wie &&
und implementiert werden sollen ||
. Wenn ich Folgendes in den Online-llvm- Compiler eingebe :
void main1(bool r, bool y) {
bool l = y || r;
}
Die letzten paar Zeilen verwirren mich völlig:
; <label>:10 ; preds = %7, %0
%11 = phi i1 [ true, %0 ], [ %9, %7 ]
%12 = zext i1 %11 to i8
Es sieht so aus, als würde der Phi-Knoten ein Ergebnis erzeugen, das verwendet werden kann. Und ich hatte den Eindruck, dass der Phi-Knoten nur definiert, von welchen Pfaden Werte kommen.
Könnte jemand erklären, was ein Phi-Knoten ist und wie man ihn implementiert ||
?
phi
Knoten ist eine Lösung für das Problem bei Compilern, die IR in die Form "Statische Einzelzuweisung" umzuwandeln. Um die Lösung besser zu verstehen, würde ich vorschlagen, das Problem besser zu verstehen. Also werde ich dir eins sagen " Warum istphi
Knoten ".Antworten:
Ein Phi-Knoten ist eine Anweisung, mit der ein Wert abhängig vom Vorgänger des aktuellen Blocks ausgewählt wird (Sehen Sie hier , um die vollständige Hierarchie anzuzeigen - er wird auch als Wert verwendet, der eine der Klassen ist, von denen er erbt).
Phi-Knoten sind aufgrund der Struktur des SSA-Stils (statische Einzelzuweisung) des LLVM-Codes erforderlich - beispielsweise der folgenden C ++ - Funktion
wird in die folgende IR übersetzt: (erstellt durch
clang -c -emit-llvm file.c -o out.bc
- und dann angezeigt durchllvm-dis
)Was passiert hier? Im Gegensatz zum C ++ - Code, bei dem die Variable
bool l
entweder 0 oder 1 sein kann, muss sie im LLVM-IR einmal definiert werden . Also prüfen wir, ob%tobool
es wahr ist und springen dann zulor.end
oderlor.rhs
.In haben
lor.end
wir endlich den Wert des || Operator. Wenn wir vom Eingangsblock angekommen sind, dann ist es einfach wahr. Ansonsten ist es gleich dem Wert von%tobool2
- und genau das erhalten wir aus der folgenden IR-Zeile:quelle
Sie müssen Phi überhaupt nicht verwenden. Erstellen Sie einfach eine Reihe von temporären Variablen. LLVM-Optimierungsdurchläufe kümmern sich um die Optimierung temporärer Variablen und verwenden dafür automatisch den Phi-Knoten.
Zum Beispiel, wenn Sie dies tun möchten:
Sie können dafür den Phi-Knoten verwenden (im Pseudocode):
Sie können jedoch auf Phi-Knoten (im Pseudocode) verzichten:
Durch Ausführen von Optimierungsdurchläufen mit llvm wird dieser zweite Code auf den ersten Code optimiert.
quelle