É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_bestdebug
l'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 GNUld
.
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_ARRAY
ouSHT_PREINIT_ARRAY
une 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érationarmclang
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 attributOVERLAY
ouPROTECTED
affecterontarmlink --merge_litpools
le comportement des options.
programme
- Créez un fichier source C
litpool.c
contenant le code suivant :int f1() { return 0xdeadbeef; } int f2() { return 0xdeadbeef; }
- 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
0xdeadbeef
s'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, puisquearmclang
ces constantes ne peuvent pas être partagées entre deux fonctions. - Compilez le code source pour créer l'objet :
armclang -c -target arm-arm-none-eabi -mcpu=cortex-m0 litpool.c -o litpool.o
--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.- 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 ...