This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] gas: xtensa: limit size of auto litpools


On Sun, Feb 11, 2018 at 4:18 PM, Max Filippov <jcmvbkbc@gmail.com> wrote:
> Literal movement code may grow auto litpool so big that it won't be
> possible to jump around it. Limit the size of auto litpools by 1/2 of
> the jump range.

Ping?

> gas/
> 2018-02-08  Max Filippov  <jcmvbkbc@gmail.com>
>
>         * config/tc-xtensa.c (struct litpool_frag): Add new field
>         literal_count.
>         (MAX_AUTO_POOL_LITERALS, MAX_EXPLICIT_POOL_LITERALS)
>         (MAX_POOL_LITERALS): New macro definitions.
>         (auto_litpool_limit): Initialize to 0.
>         (md_parse_option): Set auto_litpool_limit in the presence of
>         --auto-litpools option.
>         (xtensa_maybe_create_literal_pool_frag): Zero-initialize
>         literal_count field.
>         (xg_find_litpool): New function. Make sure that found literal
>         pool size is within the limit.
>         (xtensa_move_literals): Extract literal pool search code into
>         the new function.
>         * testsuite/gas/xtensa/all.exp: Add auto-litpools-2 test.
>         * testsuite/gas/xtensa/auto-litpools-2.d: New file.
>         * testsuite/gas/xtensa/auto-litpools-2.s: New file.
>         * testsuite/gas/xtensa/auto-litpools.d: Fix up changed
>         addresses.
>         * testsuite/gas/xtensa/auto-litpools.s: Change literal value so
>         that objdump doesn't get out of sync.
> ---
>  gas/config/tc-xtensa.c                     | 119 +++++++++++++++++++----------
>  gas/testsuite/gas/xtensa/all.exp           |   1 +
>  gas/testsuite/gas/xtensa/auto-litpools-2.d |   6 ++
>  gas/testsuite/gas/xtensa/auto-litpools-2.s |   9 +++
>  gas/testsuite/gas/xtensa/auto-litpools.d   |   4 +-
>  gas/testsuite/gas/xtensa/auto-litpools.s   |   2 +-
>  6 files changed, 96 insertions(+), 45 deletions(-)
>  create mode 100644 gas/testsuite/gas/xtensa/auto-litpools-2.d
>  create mode 100644 gas/testsuite/gas/xtensa/auto-litpools-2.s
>
> diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c
> index 1dbb73aa55c7..74a55019bdd9 100644
> --- a/gas/config/tc-xtensa.c
> +++ b/gas/config/tc-xtensa.c
> @@ -438,6 +438,7 @@ struct litpool_frag
>    addressT addr;
>    short priority; /* 1, 2, or 3 -- 1 is highest  */
>    short original_priority;
> +  int literal_count;
>  };
>
>  /* Map a segment to its litpool_frag list.  */
> @@ -451,6 +452,14 @@ struct litpool_seg
>
>  static struct litpool_seg litpool_seg_list;
>
> +/* Limit maximal size of auto litpool by half of the j range.  */
> +#define MAX_AUTO_POOL_LITERALS 16384
> +
> +/* Limit maximal size of explicit literal pool by l32r range.  */
> +#define MAX_EXPLICIT_POOL_LITERALS 65536
> +
> +#define MAX_POOL_LITERALS \
> +  (auto_litpools ? MAX_AUTO_POOL_LITERALS : MAX_EXPLICIT_POOL_LITERALS)
>
>  /* Directive functions.  */
>
> @@ -488,7 +497,7 @@ static int init_trampoline_frag (fragS *);
>  static fixS *xg_append_jump (fragS *fragP, symbolS *sym, offsetT offset);
>  static void xtensa_maybe_create_literal_pool_frag (bfd_boolean, bfd_boolean);
>  static bfd_boolean auto_litpools = FALSE;
> -static int auto_litpool_limit = 10000;
> +static int auto_litpool_limit = 0;
>
>  /* Alignment Functions.  */
>
> @@ -984,6 +993,8 @@ md_parse_option (int c, const char *arg)
>      case option_auto_litpools:
>        auto_litpools = TRUE;
>        use_literal_section = FALSE;
> +      if (auto_litpool_limit <= 0)
> +       auto_litpool_limit = MAX_AUTO_POOL_LITERALS / 2;
>        return 1;
>
>      case option_no_auto_litpools:
> @@ -7912,6 +7923,7 @@ xtensa_maybe_create_literal_pool_frag (bfd_boolean create,
>    lpf->fragP = fragP;
>    lpf->priority = (needed) ? (only_if_needed) ? 3 : 2 : 1;
>    lpf->original_priority = lpf->priority;
> +  lpf->literal_count = 0;
>
>    lps->frag_count = 0;
>  }
> @@ -11187,6 +11199,66 @@ xg_promote_candidate_litpool (struct litpool_seg *lps,
>    /* Rest is done in xtensa_relax_frag.  */
>  }
>
> +static struct litpool_frag *xg_find_litpool (struct litpool_seg *lps,
> +                                            struct litpool_frag *lpf,
> +                                            addressT addr)
> +{
> +  struct litpool_frag *lp = lpf->prev;
> +
> +  gas_assert (lp->fragP);
> +
> +  while (lp->fragP->fr_subtype == RELAX_LITERAL_POOL_CANDIDATE_BEGIN)
> +    {
> +      lp = lp->prev;
> +      if (lp->fragP == NULL)
> +       {
> +         /* End of list; have to bite the bullet.
> +            Take the nearest.  */
> +         lp = lpf->prev;
> +         break;
> +       }
> +      /* Does it (conservatively) reach?  */
> +      if (addr - lp->addr <= 128 * 1024)
> +       {
> +         if (lp->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN &&
> +             lp->literal_count < MAX_POOL_LITERALS)
> +           {
> +             /* Found a good one.  */
> +             break;
> +           }
> +         else if (lp->prev->fragP &&
> +                  addr - lp->prev->addr > 128 * 1024 &&
> +                  lp->prev->literal_count < MAX_POOL_LITERALS)
> +           {
> +             /* This is still a "candidate" but the next one
> +                will be too far away, so revert to the nearest
> +                one, convert it and add the jump around.  */
> +             lp = lpf->prev;
> +             break;
> +           }
> +       }
> +    }
> +
> +  if (lp->literal_count >= MAX_POOL_LITERALS)
> +    {
> +      lp = lpf->prev;
> +      while (lp && lp->fragP && lp->literal_count >= MAX_POOL_LITERALS)
> +       {
> +         lp = lp->prev;
> +       }
> +      gas_assert (lp);
> +    }
> +
> +  gas_assert (lp && lp->fragP && lp->literal_count < MAX_POOL_LITERALS);
> +  ++lp->literal_count;
> +
> +  /* Convert candidate and add the jump around.  */
> +  if (lp->fragP->fr_subtype == RELAX_LITERAL_POOL_CANDIDATE_BEGIN)
> +    xg_promote_candidate_litpool (lps, lp);
> +
> +  return lp;
> +}
> +
>  static void
>  xtensa_move_literals (void)
>  {
> @@ -11244,49 +11316,12 @@ xtensa_move_literals (void)
>                              preferring non-"candidate" positions to avoid
>                              the jump-around.  */
>                           fragS *litfrag = fragP->tc_frag_data.literal_frags[slot];
> -                         struct litpool_frag *lp = lpf->prev;
> -                         if (!lp->fragP)
> -                           {
> -                             break;
> -                           }
> -                         while (lp->fragP->fr_subtype ==
> -                                RELAX_LITERAL_POOL_CANDIDATE_BEGIN)
> -                           {
> -                             lp = lp->prev;
> -                             if (lp->fragP == NULL)
> -                               {
> -                                 /* End of list; have to bite the bullet.
> -                                    Take the nearest.  */
> -                                 lp = lpf->prev;
> -                                 break;
> -                               }
> -                             /* Does it (conservatively) reach?  */
> -                             if (addr - lp->addr <= 128 * 1024)
> -                               {
> -                                 if (lp->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN)
> -                                   {
> -                                     /* Found a good one.  */
> -                                     break;
> -                                   }
> -                                 else if (lp->prev->fragP &&
> -                                          addr - lp->prev->addr > 128 * 1024)
> -                                   {
> -                                     /* This is still a "candidate" but the next one
> -                                        will be too far away, so revert to the nearest
> -                                        one, convert it and add the jump around.  */
> -                                     lp = lpf->prev;
> -                                     break;
> -                                   }
> -                               }
> -                           }
>
> -                         /* Convert candidate and add the jump around.  */
> -                         if (lp->fragP->fr_subtype ==
> -                             RELAX_LITERAL_POOL_CANDIDATE_BEGIN)
> -                           xg_promote_candidate_litpool (lps, lp);
> -
> -                         if (! litfrag->tc_frag_data.literal_frag)
> +                         if (!litfrag->tc_frag_data.literal_frag)
>                             {
> +                             struct litpool_frag *lp;
> +
> +                             lp = xg_find_litpool (lps, lpf, addr);
>                               /* Take earliest use of this literal to avoid
>                                  forward refs.  */
>                               litfrag->tc_frag_data.literal_frag = lp->fragP;
> diff --git a/gas/testsuite/gas/xtensa/all.exp b/gas/testsuite/gas/xtensa/all.exp
> index c0dd8a5fa025..650a93223d46 100644
> --- a/gas/testsuite/gas/xtensa/all.exp
> +++ b/gas/testsuite/gas/xtensa/all.exp
> @@ -102,6 +102,7 @@ if [istarget xtensa*-*-*] then {
>      run_list_test "trampoline-2"
>      run_dump_test "first_frag_align"
>      run_dump_test "auto-litpools"
> +    run_dump_test "auto-litpools-2"
>      run_dump_test "auto-litpools-first1"
>      run_dump_test "auto-litpools-first2"
>      run_dump_test "loc"
> diff --git a/gas/testsuite/gas/xtensa/auto-litpools-2.d b/gas/testsuite/gas/xtensa/auto-litpools-2.d
> new file mode 100644
> index 000000000000..d153c2bdac95
> --- /dev/null
> +++ b/gas/testsuite/gas/xtensa/auto-litpools-2.d
> @@ -0,0 +1,6 @@
> +#as: --auto-litpools
> +#objdump: -d
> +#name: auto litpool size limitation
> +
> +.*: +file format .*xtensa.*
> +#...
> diff --git a/gas/testsuite/gas/xtensa/auto-litpools-2.s b/gas/testsuite/gas/xtensa/auto-litpools-2.s
> new file mode 100644
> index 000000000000..30b1383d009c
> --- /dev/null
> +++ b/gas/testsuite/gas/xtensa/auto-litpools-2.s
> @@ -0,0 +1,9 @@
> +       .text
> +       .global _start
> +_start:
> +       j       1f
> +       .rep    33000
> +       movi    a2, 0xf03df03d
> +       .endr
> +1:
> +       ret
> diff --git a/gas/testsuite/gas/xtensa/auto-litpools.d b/gas/testsuite/gas/xtensa/auto-litpools.d
> index fc6f5cbbc308..8eadd1f08cf6 100644
> --- a/gas/testsuite/gas/xtensa/auto-litpools.d
> +++ b/gas/testsuite/gas/xtensa/auto-litpools.d
> @@ -6,7 +6,7 @@
>  #...
>  .*8:.*l32r.a2, 4 .*
>  #...
> -.*3e43b:.*j.3e444 .*
> +.*3f029:.*j.3f030 .*
>  #...
> -.*40754:.*l32r.a2, 3e440 .*
> +.*40752:.*l32r.a2, 3f02c .*
>  #...
> diff --git a/gas/testsuite/gas/xtensa/auto-litpools.s b/gas/testsuite/gas/xtensa/auto-litpools.s
> index 9a5b26ba16c9..aa4241533027 100644
> --- a/gas/testsuite/gas/xtensa/auto-litpools.s
> +++ b/gas/testsuite/gas/xtensa/auto-litpools.s
> @@ -1,7 +1,7 @@
>         .text
>         .align  4
>         .literal        .L0, 0x12345
> -       .literal        .L1, 0x12345
> +       .literal        .L1, 0x78f078f0
>
>  f:
>         l32r    a2, .L0
> --
> 2.1.4
>



-- 
Thanks.
-- Max


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]