Pourquoi la représentation intermédiaire de LLVM (LLVM IR) ressemble-t-elle à un assemblage plutôt qu'à un arbre?
Sinon, pourquoi les implémentations de langage ciblent-elles l'IR LLVM plutôt que l'AST de Clang?
Je n'essaie pas de poser deux questions différentes à la fois si cela semble ainsi. Pour moi, il semble simplement que les programmeurs client et bibliothèque se sont mis d'accord sur le fait que l'API de LLVM, rien de plus et rien de moins, est évidemment une bonne conception logicielle et ma question est "pourquoi?".
La raison pour laquelle je demande, c'est qu'il semble que LLVM pourrait fournir plus de fonctionnalités aux frontaux si son IR était de type AST, car les outils basés sur AST de clang pourraient être utilisés pour n'importe quel frontend. Alternativement, les langages qui ciblent LLVM IR pourraient obtenir plus de fonctionnalités s'ils ciblaient l'AST de clang.
Clang a des classes et des fonctions pour créer et travailler avec des AST et c'est le seul projet frontal fortement lié au projet LLVM, alors pourquoi la fonctionnalité AST de clang est-elle externe à LLVM?
Du haut de ma tête, je sais que Rust (rustc), D (ldc) et Haskell (GHC) peuvent tous utiliser LLVM comme backend mais ils n'utilisent pas le Clang AST (pour autant que je sache, je pourrais se tromper). Je ne connais pas tous les détails internes de ces compilateurs mais au moins Rust et D semblent certainement pouvoir être compilés selon AST de clang. Peut-être que Haskell le pourrait aussi, mais j'en suis beaucoup moins sûr.
Est-ce pour des raisons historiques (LLVM étant à l'origine une "machine virtuelle de bas niveau" et des cliquetis arriveront plus tard)? Est-ce parce que d'autres frontaux veulent avoir autant de contrôle que possible sur ce qu'ils fournissent à LLVM? Y a-t-il des raisons fondamentales pour lesquelles l'AST de clang est inapproprié pour les langages "non-C-like"?
Je n'ai pas l'intention que cette question soit un exercice de lecture d'esprit. Je veux juste que cela soit utile à ceux d'entre nous qui sont curieux de la conception du compilateur, mais qui ne le maîtrisent pas déjà. Étant donné que les projets LLVM et clang sont développés en public, j'espère que quelqu'un familier avec le développement de ces projets pourra répondre ou que la réponse est suffisamment évidente pour certains nerds de compilation qu'ils se sentent suffisamment confiants pour répondre.
Pour anticiper certaines réponses évidentes mais insatisfaisantes:
Oui, avoir un IR de type assemblage donne plus de contrôle à quiconque crée l'IR (peut-être que X lang a un meilleur code et format AST que clang) mais si c'est la seule réponse, alors la question devient "pourquoi LLVM n'a -t-il qu'un assemblage- comme l'IR au lieu d'un IR de type arbre de haut niveau et d'un IR de type assemblage de bas niveau? ".
Oui, ce n'est pas si difficile d'analyser un langage de programmation dans un AST (au moins par rapport aux autres étapes de compilation). Néanmoins, pourquoi utiliser des AST séparés? Si rien d'autre, utiliser le même AST vous permet d'utiliser des outils qui fonctionnent sur les AST (même des choses simples comme les imprimantes AST).
Oui, je suis tout à fait d' accord pour dire que le fait d'être plus modulaire est une bonne chose, mais si c'est la seule raison, alors pourquoi les autres implémentations de langage ont-elles tendance à cibler LLVM IR au lieu de l'AST de Clang?
Ces préemptions peuvent être erronées ou négliger des détails, alors n'hésitez pas à donner ces réponses si vous avez plus de détails ou si mes hypothèses sont erronées.
Pour tous ceux qui souhaitent répondre à une question plus définitive: quels sont les avantages et les inconvénients d'un IR de type assemblage par rapport à un IR de type arbre?