170 votes

Comment faire en sorte que clang compile en llvm IR

Je veux que clang compile mon code C/C++ en code bitcode LLVM au lieu d'un exécutable binaire. Comment puis-je y parvenir ?

Et si j'ai le code bitcode LLVM, comment puis-je le compiler ensuite en exécutable binaire ?

Je veux ajouter une partie de mon propre code au code bitcode LLVM avant de le compiler en un exécutable binaire.

0 votes

Je suppose que cela s'appelle code LLVM.

227voto

Eli Bendersky Points 82298

Étant donné un fichier C/C++ foo.c:

> clang -S -emit-llvm foo.c

Produit foo.ll qui est un fichier LLVM IR.

L'option -emit-llvm peut également être passée directement au front-end du compilateur, et non au driver par le biais de -cc1:

> clang -cc1 foo.c -emit-llvm

Produit foo.ll avec le IR. -cc1 ajoute des options intéressantes comme -ast-print. Consultez -cc1 --help pour plus de détails.


Pour compiler le IR LLVM plus loin en assembleur, utilisez l'outil llc:

> llc foo.ll

Produit foo.s avec l'assembleur (en se basant sur l'architecture de la machine sur laquelle il est exécuté). llc est un des outils LLVM - voici sa documentation.

9 votes

Que fait -S ici?

19 votes

@meawoppl: -S comme dans gcc signifie émettre un assemblage textuel plutôt qu'un binaire assemblé

0 votes

Ahha. J'avais du mal à trouver quoi que ce soit dans la documentation à ce sujet. Est-il judicieux de supposer que de nombreux drapeaux dans clang reflètent la structure des drapeaux de gcc ?

26voto

Kiko Fernandez Points 244

Si vous avez plusieurs fichiers et que vous ne voulez pas avoir à taper chaque fichier, je vous recommande de suivre ces étapes simples (j'utilise clang-3.8 mais vous pouvez utiliser n'importe quelle autre version) :

  1. Générer tous les fichiers .ll

    clang-3.8 -S -emit-llvm *.c
  2. Les lier en un seul

    llvm-link-3.8 -S -v -o single.ll *.ll
  3. (Optionnel) Optimiser votre code (éventuellement une analyse d'alias)

    opt-3.8 -S -O3 -aa -basicaaa -tbaa -licm single.ll -o optimised.ll
  4. Générer l'assembleur (génère un fichier optimised.s)

    llc-3.8 optimised.ll
  5. Créer l'exécutable (nommé a.out)

    clang-3.8 optimised.s

22voto

Christoph Points 64389

Utiliser

clang -emit-llvm -o foo.bc -c foo.c
clang -o foo foo.bc

9 votes

Je recommanderais de garder les significations des extensions intactes. Autrement dit, .o devrait se référer aux fichiers d'objet binaires, .s aux fichiers d'assemblage et quelque chose d'autre (par convention .ll) aux fichiers LLVM IR. Sinon, il est facile de se tromper. Clang/LLVM n'ont actuellement pas de lien pour leurs objets binaires (bien qu'un soit en cours). Le lien LLVM llvm-ld joint simplement plusieurs fichiers IR en un seul.

1 votes

@EliBendersky : vous avez raison en ce qui concerne les extensions de fichier - et le frontal clang fait en fait ce qu'il faut si .bc est utilisé; de plus, gardez à l'esprit que llvm-ld peut agir comme frontal pour la chaîne d'outils système, c'est-à-dire ma réponse précédente en utilisant llvm-ld -native devrait fonctionner comme prévu....

1 votes

@rickfoosusa : cela fonctionne pour moi - foo.bc est un fichier bitcode LLVM

21voto

Jeremy Salwen Points 2451

Si vous avez plusieurs fichiers source, vous voulez probablement utiliser l'optimisation de temps de liaison pour générer un seul fichier bitcode pour l'ensemble du programme. Les autres réponses données vous feront finir avec un fichier bitcode pour chaque fichier source.

À la place, vous voulez compiler avec l'optimisation de temps de liaison

clang -flto -c programme1.c -o programme1.o
clang -flto -c programme2.c -o programme2.o

et pour l'étape finale de liaison, ajoutez l'argument -Wl,-plugin-opt=also-emit-llvm

clang -flto -Wl,-plugin-opt=also-emit-llvm programme1.o programme2.o -o programme

Cela vous donne à la fois un programme compilé et le bitcode correspondant (program.bc). Vous pouvez ensuite modifier program.bc de la manière que vous voulez, et recompiler le programme modifié à tout moment en faisant

clang program.bc -o programme

mais soyez conscient que vous devez inclure à nouveau les drapeaux de liaison nécessaires (pour les bibliothèques externes, etc.) à cette étape.

Notez que vous devez utiliser le linker gold pour que cela fonctionne. Si vous voulez forcer clang à utiliser un linker spécifique, créez un lien symbolique vers ce linker nommé "ld" dans un répertoire spécial appelé "fakebin" quelque part sur votre ordinateur, et ajoutez l'option

-B/home/jeremy/fakebin

à toutes les étapes de liaison ci-dessus.

13voto

rotoglup Points 3662

Avez-vous lu la documentation de clang ? Vous cherchez probablement -emit-llvm.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X