Introduction aux fonctions d'optimisation de l'éditeur de liens ARM

Éliminer le groupe commun

L'éditeur de liens peut détecter plusieurs copies d'un groupe de sections et en ignorer d'autres.

® Arm Compiler for Embedded génère des objets complets pour la liaison. donc:

  • Si des fonctions en ligne sont présentes dans le code source C et C++, chaque objet contient une copie hors ligne de la fonction en ligne requise par l'objet.
  • Si vous utilisez des modèles dans le code source C++, chaque objet contient les fonctions de modèle dont il a besoin.

Lorsque ces fonctions sont déclarées dans un fichier d'en-tête commun, elles peuvent être définies plusieurs fois dans des objets distincts qui sont ensuite liés entre eux. Pour éliminer la duplication, le compilateur compile ces fonctions dans des instances distinctes du groupe de sections commun.

Les instances individuelles d'un groupe de sections publiques peuvent ne pas être identiques. Par exemple, certaines copies peuvent se trouver dans des bibliothèques créées avec des options de construction différentes mais compatibles, différentes options d'optimisation ou de débogage.

Si les copies ne sont pas identiques, 则 armlink la meilleure variante disponible de chaque groupe de sections commun est retenue en fonction des propriétés de l'objet d'entrée. Armlink Jetez le reste.

Si les copies sont identiques, 则 armlink le premier groupe partiel repéré sera retenu.

Vous pouvez contrôler cette optimisation à l'aide des options de l'éditeur de liens suivantes :

  • Utilisez l'option -pour -bestdebug utiliser le plus grand groupe de données communes (COMDAT) (fournit probablement la meilleure vue de débogage).
  • Utilisez l' -no_bestdebug option - pour utiliser le plus petit groupe COMDAT (fournissant éventuellement la plus petite taille de code). Ce sont les paramètres par défauts.

    Si vous utilisez - g pour compiler tous les fichiers contenant le groupe COMDAT A, -no_bestdebugl'image changera même si - est utilisé.

 Éliminer les pièces inutilisées

L'élimination des parties inutilisées est l'optimisation la plus importante que l'éditeur de liens effectue sur la taille de l'image.

Élimination des pièces inutilisées :

  • Supprimez le code et les données inaccessibles de l’image finale.
  • Supprimé dans des circonstances pouvant entraîner la suppression de toutes les parties.

Pour contrôler cette optimisation, utilisez  armlink les options -- remove, -- no_remove, --first, - -last et - -keep.

L'élimination des portions inutilisées nécessite un point d'entrée. Donc, si aucun point d'entrée n'est spécifié pour l'image, utilisez  armlink l'option -entry -specify Entry Point.

Utiliser  armlink l'option - -info unused demande à l'éditeur de liens de générer une liste des sections inutilisées qu'il supprime.

Avis

armlink  Signale 错误:L6218E:未定义的符号 <symbol> que ce symbole a été supprimé même si la partie inutilisée est supprimée. Ce comportement est différent de celui de l'éditeur de liens GNU  ld  .

La partie d'entrée restera dans l'image finale si :

  • Il contient un point d'entrée ou un symbole accessible de l'extérieur. Par exemple, saisissez les fonctions dans le code de sécurité de l'extension de sécurité Arm® v8-M.
  • C'est le cas SHT_INIT_ARRAY, SHT_FINI_ARRAYou SHT_PREINIT_ARRAYune partie de.
  • Il est spécifié comme première ou dernière partie d'entrée, spécifiée par l' first option  --or --last ou son équivalent à chargement dispersé.
  • Il est  --keep marqué comme non amovible par l'option.
  • Il est référencé directement ou indirectement par une référence non faible à la partie d'entrée contenue dans l'image.
  • Son nom correspond au nom référencé par le symbole de la section d'entrée, et le symbole est référencé à partir de la section conservée dans l'image.

Avis

Les compilateurs collectent généralement des fonctions et des données ensemble et émettent une section pour chaque catégorie. L'éditeur de liens ne peut supprimer que les parties totalement inutilisées.

Vous pouvez utiliser  __attribute__(used)) des attributs pour marquer des fonctions ou des variables dans votre code source. Cette propriété provoque  la génération  armclang de symboles  <num> pour chaque fonction ou variable, où  est un compteur utilisé pour distinguer chaque symbole. L'élimination des sections inutilisées ne supprime pas   les sections incluses.__tagsym$$used.<num>__tagsym$$used.<num>

Vous pouvez également utiliser  armclang l'option - ffunction-sections pour demander au compilateur de générer une section ELF pour chaque fonction du fichier source. 

Optimiser à l'aide de la compression de données RW

Les zones de données RW contiennent souvent un grand nombre de valeurs répétitives (telles que des zéros), ce qui les rend adaptées à la compression.

Par défaut, la compression des données RW est activée pour minimiser la taille de la ROM.

L'éditeur de liens compresse les données. Ces données sont ensuite décompressées sur la cible au moment de l'exécution.

La bibliothèque Arm contient un certain nombre d'algorithmes de décompression et l'éditeur de liens choisit le meilleur algorithme à ajouter à l'image afin de décompresser la région de données lors de l'exécution de l'image. L'algorithme sélectionné par l'éditeur de liens peut être remplacé.

Comment l'éditeur de liens sélectionne un compresseur

Armlink Recueillez des informations sur le contenu de certaines parties des données avant de choisir l'algorithme de compression le plus approprié pour produire la plus petite image.

Si la compression est appropriée, armlink un seul compresseur de données peut être utilisé pour toutes les parties de données compressibles de l'image. Différents algorithmes de compression peuvent être essayés sur ces pièces pour produire la meilleure taille globale. La compression est automatiquement appliquée si :

Compressed data size + Size of decompressor < Uncompressed data size

Lorsque vous sélectionnez un compresseur, armlink le décompresseur est ajouté à la zone de code de l'image. Si l'image finale ne contient aucune donnée compressée, aucun décompresseur ne sera ajouté.

Options disponibles pour remplacer l'algorithme de compression utilisé par l'éditeur de liens

L'éditeur de liens propose des options pour désactiver la compression ou spécifier l'algorithme de compression à utiliser.

L'algorithme de compression utilisé par l'éditeur de liens peut être remplacé de l'une des manières suivantes :

  • Utilisez l' -datacompressor off option - pour désactiver la compression.
  • Spécifiez l'algorithme de compression.

Pour spécifier un algorithme de compression, utilisez le numéro du compresseur souhaité sur la ligne de commande de l'éditeur de liens, par exemple :

armlink --datacompressor 2 ...

Utiliser l'option de ligne de commande - -datacompressor list Obtenez une liste des algorithmes de compression disponibles dans l'éditeur de liens :

armlink --datacompressor list
...
Num     Compression algorithm
========================================================
0       Run-length encoding
1       Run-length encoding, with LZ77 on small-repeats
2       Complex LZ77 compression

Lors du choix d'un algorithme de compression, veuillez noter :

  • Le compresseur 0 fonctionne bien avec les données contenant beaucoup d'octets nuls mais moins d'octets non nuls.
  • Compressor 1 fonctionne bien lors du traitement de données avec une duplication d’octet différente de zéro.
  • Compressor 2 fonctionne bien lors du traitement de données contenant des valeurs en double.

L'éditeur de liens préfère le compresseur 0 ou 1, où les données contiennent principalement zéro octet (> 75 %). Lorsque le compresseur 2 est sélectionné, les données contiennent très peu d'octets nuls (<10 %). Si l'image est constituée uniquement de code A32, le décompresseur A32 est automatiquement utilisé. Si l'image contient un code T32, le décompresseur T32 est utilisé. S'il n'y a pas de préférence claire, tous les compresseurs sont testés pour produire la meilleure taille globale.

 

Points à noter lors de l'utilisation de la compression de données RW

Il y a certaines considérations à prendre en compte lors de l'utilisation de la compression de données RW.

Lors de l'utilisation de la compression de données RW :

  • Utiliser les options de l'éditeur de liens - -map Découvrez où la compression est appliquée aux zones de votre code.
  • S'il existe une référence d'une zone compressée à un symbole défini par l'éditeur de liens utilisant une adresse de chargement, l'éditeur de liens désactive la compression RW.
  • Si vous utilisez un processeur Arm® avec cache sur puce, activez le cache après la décompression pour éviter les problèmes de cohérence du code.

Les segments de données compressés sont automatiquement décompressés au moment de l'exécution s'ils sont exécutés à l'aide du code de la bibliothèque Arm __main. Ce code doit être placé dans la zone racine. InRoot$$Sections Il est préférable d'utiliser un fichier scatter  .

Si vous utilisez des fichiers scatter, vous pouvez  NOCOMPRESS spécifier que les régions de chargement ou d'exécution ne sont pas compressées en ajoutant des attributs.

Fonctions en ligne avec l'éditeur de liens

Les capacités d'intégration de l'éditeur de liens dépendent des options que vous spécifiez et du contenu des fichiers d'entrée.

L'éditeur de liens peut intégrer une petite fonction à la place de l'instruction de branchement pour cette fonction. Pour que l'éditeur de liens puisse faire cela, la fonction (sans instruction de retour) doit tenir dans les quatre octets de l'instruction de branchement.

Utilisez les options de ligne de commande -- inline et -- -no_inline pour contrôler l'inline de branche. Cependant, -no_inline désactive uniquement l'intégration des objets fournis par l'utilisateur. Par défaut, l'éditeur de liens intègre toujours les fonctions dans la bibliothèque standard Arm.

Si l’optimisation de l’inline de branche est activée, l’éditeur de liens analyse chaque appel de fonction dans l’image et l’intègre si nécessaire. Lorsque l'éditeur de liens trouve une fonction appropriée à intégrer, il remplace l'appel de fonction par les instructions de la fonction appelée.

L'éditeur de liens applique l'optimisation de l'inline des branches avant d'éliminer toutes les sections inutilisées afin que les sections en ligne puissent également être supprimées lorsqu'elles ne sont plus appelées.

Avis

  • Pour Arm®v7-A, l'éditeur de liens peut intégrer deux instructions Thumb codées en 16 bits à la place des  BL instructions Thumb® codées en 32 bits.
  • Pour Armv8-A et Armv8-M, l'éditeur de liens peut intégrer deux instructions T32 16 bits au lieu d'instructions T32 32 bits  BL .

Utilisez l'option de ligne de commande - -info=inline pour répertorier toutes les fonctions en ligne.

À propos de l'optimisation de la branche vers NOP

Bien que l'éditeur de liens puisse remplacer les branches  NOP, dans certains cas, vous souhaiterez peut-être empêcher que cela se produise.

Par défaut, l'éditeur de liens remplace toute branche par une relocalisation qui se résout à l'  NOP instruction suivante avec l'instruction. Cette optimisation peut également être appliquée si l'éditeur de liens réorganise la section d'appel final.

Cependant, dans certains cas, vous souhaiterez peut-être désactiver cette option, par exemple lors de l'exécution d'une validation ou d'une actualisation du pipeline.

Pour contrôler cette optimisation, utilisez les  options de ligne de commande - -branchnop et  .--no_branchnop

Réorganisation de l'éditeur de liens des sections d'appel de queue

Dans certains cas, vous souhaiterez peut-être que l'éditeur de liens réorganise la section d'appel final.

La section d'appel de queue est la section qui contient les instructions de branchement à la fin de la section. Si l'instruction de branchement a une relocalisation qui cible une fonction qui commence dans une autre section, l'éditeur de liens peut placer la section appelante de queue avant la section appelée. L'éditeur de liens peut ensuite optimiser les instructions de branchement à la fin de la section d'appel de queue en  NOP instructions.

Pour profiter de ce comportement, utilisez l'option de ligne de commande -tailreorder -déplacez la section d'appel de fin avant sa cible.

Utilisez l' -info=tailreorder option de ligne de commande - pour afficher des informations sur les optimisations d'appel final effectuées par l'éditeur de liens.

Limitations sur la réorganisation partielle des appels de queue

Il existe certaines restrictions sur la réorganisation des sections d'appel de fin.

Lien :

  • Pour chaque cible d'appel de queue, une seule partie d'appel de queue peut être déplacée. S'il y a plusieurs appels de queue vers une seule section, la section d'appel de queue portant le même nom de section sera déplacée avant la cible. Si un nom de section n'est pas trouvé dans une section d'appel de fin avec un nom correspondant, l'éditeur de liens déplace la première section qu'il rencontre.
  • La section d'appel de fin ne peut pas être déplacée hors de sa région d'exécution.
  • La queue n'est pas déplacée avant le placage en ligne.

Fusionner des constantes identiques

L'éditeur de liens peut tenter de fusionner des constantes identiques dans des objets ciblant l'état AArch32. Les objets doivent être générés à l’aide du compilateur Arm® pour Embedded 6. armclang -ffunction-sections La fusion est plus efficace si elle est compilée avec  des options. Cette option est celle par défaut.

À propos de cette tâche

La procédure suivante est un exemple illustrant la fonctionnalité de fusion.

Avis

Si vous utilisez un fichier scatter, toutes les zones marquées d'un  attribut OVERLAY ou  PROTECTED affecteront  armlink --merge_litpools le comportement des options.

programme

  1. Créez un fichier source C  litpool.ccontenant le code suivant :
    int f1() {
        return 0xdeadbeef;
    }
    int f2() {
        return 0xdeadbeef;
    }
  2. Utilisez  -S le code source compilé pour créer des fichiers d'assemblage :
    armclang -c -S -target arm-arm-none-eabi -mcpu=cortex-m0 -ffunction-sections \
        litpool.c -o litpool.s

    Avis

    - ffunction-sections est la valeur par défaut.

    Puisqu'il 0xdeadbeefs'agit d'une constante difficile à créer à l'aide d'instructions, un pool de textes est créé, par exemple :

    ...
    f1:
        .fnstart
    @ BB#0:
        ldr    r0, __arm_cp.0_0
        bx     lr
        .p2align    2
    @ BB#1:
    __arm_cp.0_0:
        .long    3735928559              @ 0xdeadbeef
    ...
        .fnend
    
    ...
        .code    16                      @ @f2
        .thumb_func
    f2:
        .fnstart
    @ BB#0:
        ldr    r0, __arm_cp.1_0
        bx     lr
        .p2align    2
    @ BB#1:
    __arm_cp.1_0:
        .long    3735928559              @ 0xdeadbeef
    ...
        .fnend
    ...

    Avis

    Chaque fonction possède une copie des constantes, puisque  armclang ces constantes ne peuvent pas être partagées entre deux fonctions.
  3. Compilez le code source pour créer l'objet :
    armclang -c -target arm-arm-none-eabi -mcpu=cortex-m0 litpool.c -o litpool.o
  4. --merge_litpools Lier les fichiers objets à l'aide  des options :
    armlink --cpu=Cortex-M0 --merge_litpools litpool.o -o litpool.axf

    Avis

    - -merge_litpools est la valeur par défaut.
  5. Exécutez  fromelf pour afficher la structure de l'image :
    fromelf -c -d -s -t -v -z litpool.axf

    L'exemple suivant montre les résultats combinés :

    ...
        f1
            0x00008000:    4801        .H      LDR      r0,[pc,#4] ; [0x8008] = 0xdeadbeef
            0x00008002:    4770        pG      BX       lr
        f2
            0x00008004:    4800        .H      LDR      r0,[pc,#0] ; [0x8008] = 0xdeadbeef
            0x00008006:    4770        pG      BX       lr
        $d.4
        __arm_cp.1_0
            0x00008008:    deadbeef    ....    DCD    3735928559
    ...

Je suppose que tu aimes

Origine blog.csdn.net/Miao8miao/article/details/135428505
conseillé
Classement