[avr-libc-dev] [RFT] [PATCH] New linker optimizations.

avr-libc-dev

[Top][All Lists] Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

## [avr-libc-dev] [RFT] [PATCH] New linker optimizations.

From: | BjÃrn Haase
Subject: | [avr-libc-dev] [RFT] [PATCH] New linker optimizations.
Date: | Sat, 15 Oct 2005 16:44:51 +0200
User-agent: | KMail/1.7.1

    Hi,

    The following patch adds support for linker relaxation for the avr port. The
    most important issue is to make the linker choose the shorter variant of the
    two call/jump alternatives if the displacement is sufficiently small.

    This small change alone results in 1.5 - 3 per cent code size reduction for
    the applications I have checked so far. E.g. about 500 bytes reduction for an
    application of about 13k. The patch changes gas, bfd and ld.

    The patch is against binutils head. I think that it has no serious bugs, but
    it needs testing.

    In order to test, first step is to
    1.) check that the patched new gas variant does not have bugs. I.e. one would
    have first make sure that when re-compiling/re-assembling everything without
    special linker options the application still works.
    2.) Then one could switch on the --relax option of the linker. (When using gcc
    to link use -Wl,--relax).
    3.) The jumps turn out to be more local if one uses gcc with the switch
    --ffunction-sections. When using this switch linker relaxation helps more.
    4.) The full monty of the optimizations with the patch would then be
    --ffunction-sections -Wl,--relax -Wl,--gc-sections, where the linker also
    removes unused functions and variables from the application.

    Possibly one might want to re-compile avr-libc after the tests: Only the files
    assembled and compiled with the new binutils will benefit from the new
    optimizations.

    Yours,

    Bjoern

    P.S.:
    Here is my mail to the binutils mailing list summing up the changes I have
    made.

    Hi,

    this is the second revision for my suggestions concerning linker relaxation
    support for avr.

    It incorporates the following changes:

    GAS:

    In order to make relaxation work, we need to make gas preserve more
    relocs than it used to preserve. The issue is that all the relative
    instruction
    offsets no longer must be calculated at assembly time but at linke time.
    For this purpose the patch disables the fixups for all of the program-space
    relative relocs by setting linkrelax to the value 1.

    Because there was no way to find out from the object file itself if it is
    suitable for relaxing or not, I have introduced a new flag bit in the
    e_flag portion of the elf header. Bits 0-3 have the same meaning. After the
    change bit #7 is used for signalizing: "This elf object file is suitable for
    linker relaxation since it preserves the local symbols." (new define symbol
    EF_AVR_LINKRELAX_PREPARED).

    In order to be able to leave the fixup for the higher two bytes of 32 bit
    values
    to the linker, I have changed the present workaround. Before my change gas
    internally made use of negated BFD enum values for these higher bytes.
    I replaced this by adding proper new relocs to bfd and the elf files
    (BFD_RELOC_AVR_MS8_LDI and R_AVR_MS8_LDI as well as the negated variants)
    for the most significant byte of 32 bit values.

    BFD:

    I first had to implement a couple of changes in bfd for supporting the new
    relocs for the most significant bytes.

    Three functions for implementing linker relaxation support are now new.
    Before the relaxation machine starts, it is checked that the bfd
    has the EF_AVR_LINKRELAX_PREPARED flag set in the elf header so that we could
    safely continue to link old object files.

    In the ".jumptables" and ".vectors" sections only a reduced relaxation
    machine runs: Jumps and Calls are replaced by the shorter variants
    without changing the relative addresses.

    In elf32-avr.c I then have introduced a new global variable determinating
    the wrap-around value of the avr program memory space. This value is
    presently not valid but if it is filled one day with the correct value,
    the relaxation machine will make use of the wrap-around shortcuts for jumps.
    Possibly one could add later on target-specific options for filling
    this variable with the target hardware's values.

    LD:

    In order to fix the --gc-sections bug I have added the required KEEP()
    statements in the linker script for avr.

    Yours,

    Bjoern.

    P.S.: FYI, here is the mail to the binutils mailing list.

    Hi,

    this is the second revision for my suggestions concerning linker relaxation
    support for avr.

    It incorporates the following changes:

    GAS:

    In order to make relaxation work, we need to make gas preserve more
    relocs than it used to preserve. The issue is that all the relative
    instruction offsets no longer must be calculated at assembly time but at
    linke time.
    For this purpose the patch disables the fixups for all of the program-space
    relative relocs by setting linkrelax to the value 1.

    Because there was no way to find out from the object file itself if it is
    suitable for relaxing or not, I have introduced a new flag bit in the
    e_flag portion of the elf header. Bits 0-3 have the same meaning. After the
    change bit #7 is used for signalizing: "This elf object file is suitable for
    linker relaxation since it preserves the local symbols." (new define symbol
    EF_AVR_LINKRELAX_PREPARED).

    In order to be able to leave the fixup for the higher two bytes of 32 bit
    values
    to the linker, I have changed the present workaround. Before my change gas
    internally made use of negated BFD enum values for these higher bytes.
    I replaced this by adding proper new relocs to bfd and the elf files
    (BFD_RELOC_AVR_MS8_LDI and R_AVR_MS8_LDI as well as the negated variants)
    for the most significant byte of 32 bit values.

    BFD:

    I first had to implement a couple of changes in bfd for supporting the new
    relocs for the most significant bytes.

    Three functions for implementing linker relaxation support are now new.
    Before the relaxation machine starts, it is checked that the bfd
    has the EF_AVR_LINKRELAX_PREPARED flag set in the elf header so that we could
    safely continue to link old object files.

    In the ".jumptables" and ".vectors" sections only a reduced relaxation
    machine runs: Jumps and Calls are replaced by the shorter variants
    without changing the relative addresses.

    In elf32-avr.c I then have introduced a new global variable determinating
    the wrap-around value of the avr program memory space. This value is
    presently not valid but if it is filled one day with the correct value,
    the relaxation machine will make use of the wrap-around shortcuts for jumps.
    Possibly one could add later on target-specific options for filling
    this variable with the target hardware's values.

    LD:

    In order to fix the --gc-sections bug I have added the required KEEP()
    statements in the linker script for avr.

    Yours,

    Bjoern.

    2005-10-15  Bjoern Haase  <address@hidden>

            * include/elf/avr.h:

            R_AVR_MS8_LDI,R_AVR_MS8_LDI_NEG: Add.
            EF_AVR_LINKRELAX_PREPARED: Add.

            * bfd/elf32-avr.c:

            avr_reloc_map:
            insert BFD_RELOC_AVR_MS8_LDI and R_AVR_MS8_LDI
            bfd_elf_avr_final_write_processing:
            set EF_AVR_LINKRELAX_PREPARED in e_flags field.
            elf32_avr_relax_section: add.
            elf32_avr_relax_delete_bytes: add.
            elf32_avr_get_relocated_section_contents: add.
            avr_pc_wrap_around: add.
            avr_relative_distance_considering_wrap_around: add.
            avr_final_link_relocate: Handle negative int8t_t immediate for R_AVR_LDI

            * gas/config/tc-avr.c:

            md_apply_fix, exp_mod:
            Use BFD_RELOC_HH8_LDI and BFD_RELOC_MS8_LDI for hlo8() and hhi8()
            md_begin:
            include inttypes.h, set linkrelax variable to 1, add cast to (intptr_t)
            avr_ldi_expression: use cast to (intptr_t) instead of (int)

            * gas/config/tc-avr.h:
            TC_LINKRELAX_FIXUP, TC_VALIDATE_FIX, tc_fix_adjustable: add.

            * bfd/bfd-in2.h: Add BFD_RELOC_AVR_MS8_LDI and BFD_RELOC_AVR_LDI_NEG
            * bfd/libbfd.h: Ditto.
            * bfd/reloc.c: Ditto.

            * ld/scripttempl/avr.sc:
            add *(.jumptables) *(.lowtext), add KEEP() directives

`relax_avr_rev2.patch`
Description: Text Data

reply via email to

[Prev in Thread] | Current Thread | [Next in Thread]

- [avr-libc-dev] [RFT] [PATCH] New linker optimizations., BjÃrn Haase <=

- Prev by Date: Re: [avr-libc-dev] Re: snprintf bug ?
- Next by Date: [avr-libc-dev] [bug #14798] several IO registers definition issue in header files
- Previous by thread: [avr-libc-dev] [task #4777] Add new devices: AT90CAN32-64
- Next by thread: [avr-libc-dev] [bug #14798] several IO registers definition issue in header files
- Index(es):
  - Date
  - Thread