2017-08-25 1 views
2

Je suis intéressé par la façon dont ce qui suit est sexuée:Ajouter un nouvel attribut sur le code source qui se propage jusqu'au niveau MC dans LLVM?

void foo(int __attribute__((aligned(16)))* p) { ... } 

Dans ce cas, le « alignedness » du pointeur est disponible au niveau MC, mais il est évidemment pas en utilisant l'approche des métadonnées LLVM-IR pour atteindre ce. Les informations d'alignement sont très importantes pour certaines cibles qui vont changer de génération de code dépendant de cette valeur, et je pense que ce dont j'ai besoin est plus proche de cet attribut.

Comment serait-il difficile d'ajouter un nouvel attribut tel qu'il se propage à travers le compilateur de la même manière que 'aligné'? Donc, j'ai déjà ajouté un nouvel élément à la LLVM-IR pour le faire. Je m'attends aussi à ce que le plus dur soit de faire en sorte que d'autres parties de LLVM ignorent ce nouvel élément quand elles s'en fichent.

Il est vraiment dommage que LLVM ne dispose pas d'une manière générique de manière indépendante de transmettre des informations dépendantes de la cible de l'analyseur au back-end. L'utilisation de l'approche 'DebugLoc' a été suggérée dans un question similaire, mais je pense que c'est un peu un hack puisque ce n'est pas lié au débogage. Mais si la mise en œuvre est moins difficile de cette façon, le piratage peut être acceptable.

MISE À JOUR: L'assemblage en ligne au lieu de l'utilisation d'un nouvel attribut fonctionnerait-il ici? Si oui, quels sont les avantages/inconvénients?

Répondre

2

Comme vous l'avez démontré, l'alignement n'utilise pas de métadonnées.

  • Pour ceux qui ne savent pas: l'alignement est mentionné (implicitement ou explicitement) dans toutes les instructions pertinentes, donc par exemple cette fonction dans la question sera compilé à quelque chose comme ceci (notez le aligne):

     
    define void @foo(i32*) { 
        %2 = alloca i32*, align 16  ; Allocate a 16-aligned pointer 
        store i32* %0, i32** %2, align 16 ; An aligned store to place the arg there 
        ... 
    

maintenant, si vous voulez joindre des informations aux instructions existantes et ont la plupart du reste du compilateur les ignorer, en utilisant des métadonnées est une bonne idée. Cependant, étant donné que les métadonnées sont une chose abstraite interne au compilateur, à un moment donné, vous devrez faire quelque chose avec lui. Typiquement, en ajoutant une passe de votre choix pour la consommer et faire quelque chose en conséquence.

Quant à placer votre carte et comment à mettre en œuvre, cela dépend vraiment de l'information réelle que vous essayez de passer et l'effet escompté.

+0

btw ... mon autre question est de savoir comment les espaces d'adressage d'OpenCL fonctionnent sur ce cas ... il me semble que c'est peut-être exactement ce que je recherche. (J'ai tort?) – eternalStudent

+1

@eternalStudent LLVM a ses propres modificateurs addrspace sur certaines valeurs. Vous pourriez être intéressé par SPIR, un IR basé sur LLVM pour OpenCL, qui s'appuie dessus (https://www.khronos.org/registry/SPIR/specs/spir_spec-2.0.pdf, section 2.2). Donc je suppose que la réponse à votre question est que des choses comme ça sont cuites dans la langue, donc les ajouter n'est pas simple. – Oak

+0

Merci @Oak :) Excellente explication! D'après vous, je comprends qu'il n'est donc pas possible pour une cible de prendre des décisions de génération de code basées sur l'espace d'adressage d'OpenCL? Les métadonnées sont plus simples à manipuler, il suffit de les transformer en plus spécifiques à la cible plus tard pour qu'elles soient disponibles dans l'info-opérande mémoire. L'ajout d'une passe pour consommer les métadonnées LLVM-IR est tout à fait acceptable.J'ai juste besoin de comprendre ce que je devrais le transformer pour qu'il persiste dans la planification. Des idées ici? :) – eternalStudent