Que fait exactement l’instruction PHI et comment l’utiliser dans LLVM?

LLVM a une instruction phi avec une explication assez étrange:

L’instruction ‘phi’ est utilisée pour implémenter le noeud φ dans le graphe SSA représentant la fonction.

En général, il est utilisé pour implémenter des twigments. Si j’ai bien compris, il est nécessaire d’parsingr les dépendances et, dans certains cas, d’éviter un chargement inutile. Cependant, il est toujours difficile de comprendre ce que cela fait exactement.

Kaleidoscope exemple l’ explique assez bien pour if cas Cependant, la manière de mettre en œuvre des opérations logiques telles que && et || . Si je tape ce qui suit sur le compilateur llvm en ligne :

 void main1(bool r, bool y) { bool l = y || r; } 

Plusieurs dernières lignes me confondent complètement:

 ;  

On dirait que le noeud phi produit un résultat qui peut être utilisé. Et j’avais l’impression que le nœud phi définissait simplement à partir de quels chemins les valeurs à venir.

Quelqu’un pourrait-il expliquer ce qu’est un nœud Phi, et comment implémenter || avec ça?

Un nœud phi est une instruction utilisée pour sélectionner une valeur en fonction du prédécesseur du bloc en cours (regardez ici pour voir la hiérarchie complète – elle est également utilisée comme valeur, qui est l’une des classes dont elle hérite).

Les nœuds Phi sont nécessaires en raison de la structure du style SSA (assignation unique statique) du code LLVM – par exemple, la fonction C ++ suivante

 void m(bool r, bool y){ bool l = y || r ; } 

se traduit dans l’IR suivant: (créé par clang -c -emit-llvm fichier.c -o out.bc – et ensuite visualisé par llvm-dis)

 define void @_Z1mbb(i1 zeroext %r, i1 zeroext %y) nounwind { entry: %r.addr = alloca i8, align 1 %y.addr = alloca i8, align 1 %l = alloca i8, align 1 %frombool = zext i1 %r to i8 store i8 %frombool, i8* %r.addr, align 1 %frombool1 = zext i1 %y to i8 store i8 %frombool1, i8* %y.addr, align 1 %0 = load i8* %y.addr, align 1 %tobool = trunc i8 %0 to i1 br i1 %tobool, label %lor.end, label %lor.rhs lor.rhs: ; preds = %entry %1 = load i8* %r.addr, align 1 %tobool2 = trunc i8 %1 to i1 br label %lor.end lor.end: ; preds = %lor.rhs, %entry %2 = phi i1 [ true, %entry ], [ %tobool2, %lor.rhs ] %frombool3 = zext i1 %2 to i8 store i8 %frombool3, i8* %l, align 1 ret void } 

Alors que se passe-t-il ici? Contrairement au code C ++, où la variable l peut être 0 ou 1, dans le LLVM IR, elle doit être définie une fois . Nous vérifions donc si% tobool est vrai, puis sautons à lor.end ou lor.rhs.

Dans lor.end nous avons enfin la valeur du || opérateur. Si nous sums arrivés du bloc d’entrée – alors c’est juste vrai. Sinon, il est égal à la valeur de% tobool2 – et c’est exactement ce que nous obtenons de la ligne IR suivante:

 %2 = phi i1 [ true, %entry ], [ %tobool2, %lor.rhs ] 

Vous n’avez pas besoin d’utiliser phi du tout. Créez simplement un groupe de variables temporaires. Les passes d’optimisation LLVM s’occuperont d’optimiser les variables temporaires et utiliseront le nœud phi pour cela automatiquement.

Par exemple, si vous voulez faire ceci:

 x = 4; if (something) x = x + 2; print(x); 

Vous pouvez utiliser le noeud phi pour cela (en pseudocode):

  1. atsortingbuer 4 à x1
  2. si (! quelque chose) twig à 4
  3. calculer x2 à partir de x1 en ajoutant 2
  4. assigne x3 phi de x1 et x2
  5. impression d’appel avec x3

Mais vous pouvez faire sans noeud phi (en pseudocode):

  1. allouer une variable locale sur la stack appelée x
  2. charger dans temp x1 valeur 4
  3. stocker x1 à x
  4. si (! quelque chose) twig à 8
  5. charger x à temp x2
  6. append x2 avec 4 à la température x3
  7. stocker x3 à x
  8. charger x à temp x4
  9. impression d’appel avec x4

En exécutant des passes d’optimisation avec llvm, ce second code sera optimisé pour le premier code.

Le nœud phi est une solution du problème dans les compilateurs pour convertir le fichier IR en formulaire “Affectation unique statique”. Pour mieux comprendre la solution, je suggère de mieux comprendre le problème.

Donc, je vais vous up ” Pourquoi est phi node “.