This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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: RFA: Merge definitions of get_some_local_dynamic_name


On Tue, Sep 2, 2014 at 8:36 PM, Richard Sandiford
<rdsandiford@googlemail.com> wrote:
> Several targets define a function like i386's get_some_local_dynamic_name.
> The function looks through the current output function and returns the first
> (arbitrary) local-dynamic symbol that it finds.  The result can be used in
> a call to __tls_get_addr, since all local-dynamic symbols have the same base.
>
> This patch replaces the various target functions with a single generic one.
> The only difference between the implementations was that s390 checked
> for constant pool references while the others didn't need to (because
> they don't allow TLS symbols to be forced into the pool).  Checking for
> constant pool references is unnecessary but harmless for the other ports.
> Also, the walk is needed only once per TLS-referencing output function,
> so it's hardly critical in terms of compile time.
>
> All uses of this function are in final.  In general it wouldn't be
> safe to call the function earlier than that, since the symbol reference
> could in principle be deleted by any rtl pass.  I've therefore cached
> it in a variable local to final rather than in cfun (which is where
> the ports used to cache it).
>
> Also, i386 was robust against uses of %& in inline asm.  The patch
> makes sure the other ports are too.  Using %& in inline asm would
> often be a mistake, but it should at least trigger a proper error
> rather than an ICE.
>
> Tested on x86_64-linux-gnu.  Also tested by building cross compilers
> before and after the change on:
>
>   alpha-linux-gnu powerpc64-linux-gnu s390x-linux-gnu sparc64-linux-gnu
>
> OK to install?

Ok.

Thanks,
Richard.

> Thanks,
> Richard
>
>
> gcc/
>         * output.h (get_some_local_dynamic_name): Declare.
>         * final.c (some_local_dynamic_name): New variable.
>         (get_some_local_dynamic_name): New function.
>         (final_end_function): Clear some_local_dynamic_name.
>         * config/alpha/alpha.c (machine_function): Remove some_ld_name.
>         (get_some_local_dynamic_name, get_some_local_dynamic_name_1): Delete.
>         (print_operand): Report an error if '%&' is used inappropriately.
>         * config/i386/i386.c (get_some_local_dynamic_name): Delete.
>         (get_some_local_dynamic_name_1): Delete.
>         * config/rs6000/rs6000.c (machine_function): Remove some_ld_name.
>         (rs6000_get_some_local_dynamic_name): Delete.
>         (rs6000_get_some_local_dynamic_name_1): Delete.
>         (print_operand): Report an error if '%&' is used inappropriately.
>         * config/s390/s390.c (machine_function): Remove some_ld_name.
>         (get_some_local_dynamic_name, get_some_local_dynamic_name_1): Delete.
>         (print_operand): Assert that get_some_local_dynamic_name is nonnull.
>         * config/sparc/sparc.c: Include rtl-iter.h.
>         (machine_function): Remove some_ld_name.
>         (sparc_print_operand): Report an error if '%&' is used inappropriately.
>         (get_some_local_dynamic_name, get_some_local_dynamic_name_1): Delete.
>
> Index: gcc/output.h
> ===================================================================
> --- gcc/output.h        2014-08-31 21:05:04.701330252 +0100
> +++ gcc/output.h        2014-09-02 19:02:59.820482510 +0100
> @@ -52,6 +52,8 @@ extern int get_attr_min_length (rtx);
>     any branches of variable length if possible.  */
>  extern void shorten_branches (rtx_insn *);
>
> +const char *get_some_local_dynamic_name ();
> +
>  /* Output assembler code for the start of a function,
>     and initialize some of the variables in this file
>     for the new function.  The label for the function and associated
> Index: gcc/final.c
> ===================================================================
> --- gcc/final.c 2014-08-31 21:05:04.701330252 +0100
> +++ gcc/final.c 2014-09-02 19:17:08.573876805 +0100
> @@ -1719,6 +1719,38 @@ reemit_insn_block_notes (void)
>    reorder_blocks ();
>  }
>
> +static const char *some_local_dynamic_name;
> +
> +/* Locate some local-dynamic symbol still in use by this function
> +   so that we can print its name in local-dynamic base patterns.
> +   Return null if there are no local-dynamic references.  */
> +
> +const char *
> +get_some_local_dynamic_name ()
> +{
> +  subrtx_iterator::array_type array;
> +  rtx_insn *insn;
> +
> +  if (some_local_dynamic_name)
> +    return some_local_dynamic_name;
> +
> +  for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
> +    if (NONDEBUG_INSN_P (insn))
> +      FOR_EACH_SUBRTX (iter, array, PATTERN (insn), ALL)
> +       {
> +         const_rtx x = *iter;
> +         if (GET_CODE (x) == SYMBOL_REF)
> +           {
> +             if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
> +               return some_local_dynamic_name = XSTR (x, 0);
> +             if (CONSTANT_POOL_ADDRESS_P (x))
> +               iter.substitute (get_pool_constant (x));
> +           }
> +       }
> +
> +  return 0;
> +}
> +
>  /* Output assembler code for the start of a function,
>     and initialize some of the variables in this file
>     for the new function.  The label for the function and associated
> @@ -1904,6 +1936,8 @@ final_end_function (void)
>    if (!dwarf2_debug_info_emitted_p (current_function_decl)
>        && dwarf2out_do_frame ())
>      dwarf2out_end_epilogue (last_linenum, last_filename);
> +
> +  some_local_dynamic_name = 0;
>  }
>
>
> Index: gcc/config/alpha/alpha.c
> ===================================================================
> --- gcc/config/alpha/alpha.c    2014-08-31 21:05:04.701330252 +0100
> +++ gcc/config/alpha/alpha.c    2014-09-02 19:02:59.552479551 +0100
> @@ -4858,9 +4858,6 @@ struct GTY(()) alpha_links;
>
>  struct GTY(()) machine_function
>  {
> -  /* For OSF.  */
> -  const char *some_ld_name;
> -
>    /* For flag_reorder_blocks_and_partition.  */
>    rtx gp_save_rtx;
>
> @@ -5120,40 +5117,6 @@ get_round_mode_suffix (void)
>    gcc_unreachable ();
>  }
>
> -/* Locate some local-dynamic symbol still in use by this function
> -   so that we can print its name in some movdi_er_tlsldm pattern.  */
> -
> -static int
> -get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
> -{
> -  rtx x = *px;
> -
> -  if (GET_CODE (x) == SYMBOL_REF
> -      && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
> -    {
> -      cfun->machine->some_ld_name = XSTR (x, 0);
> -      return 1;
> -    }
> -
> -  return 0;
> -}
> -
> -static const char *
> -get_some_local_dynamic_name (void)
> -{
> -  rtx_insn *insn;
> -
> -  if (cfun->machine->some_ld_name)
> -    return cfun->machine->some_ld_name;
> -
> -  for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
> -    if (INSN_P (insn)
> -       && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
> -      return cfun->machine->some_ld_name;
> -
> -  gcc_unreachable ();
> -}
> -
>  /* Print an operand.  Recognize special options, documented below.  */
>
>  void
> @@ -5169,7 +5132,11 @@ print_operand (FILE *file, rtx x, int co
>        break;
>
>      case '&':
> -      assemble_name (file, get_some_local_dynamic_name ());
> +      if (const char *name = get_some_local_dynamic_name ())
> +       assemble_name (file, name);
> +      else
> +       output_operand_lossage ("'%%&' used without any "
> +                               "local dynamic TLS references");
>        break;
>
>      case '/':
> Index: gcc/config/i386/i386.c
> ===================================================================
> --- gcc/config/i386/i386.c      2014-08-31 21:05:04.701330252 +0100
> +++ gcc/config/i386/i386.c      2014-09-02 19:02:59.669480843 +0100
> @@ -14756,41 +14756,6 @@ print_reg (rtx x, int code, FILE *file)
>      }
>  }
>
> -/* Locate some local-dynamic symbol still in use by this function
> -   so that we can print its name in some tls_local_dynamic_base
> -   pattern.  */
> -
> -static int
> -get_some_local_dynamic_name_1 (rtx *px, void *)
> -{
> -  rtx x = *px;
> -
> -  if (GET_CODE (x) == SYMBOL_REF
> -      && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
> -    {
> -      cfun->machine->some_ld_name = XSTR (x, 0);
> -      return 1;
> -    }
> -
> -  return 0;
> -}
> -
> -static const char *
> -get_some_local_dynamic_name (void)
> -{
> -  rtx_insn *insn;
> -
> -  if (cfun->machine->some_ld_name)
> -    return cfun->machine->some_ld_name;
> -
> -  for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
> -    if (NONDEBUG_INSN_P (insn)
> -       && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
> -      return cfun->machine->some_ld_name;
> -
> -  return NULL;
> -}
> -
>  /* Meaning of CODE:
>     L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
>     C -- print opcode suffix for set/cmov insn.
> Index: gcc/config/rs6000/rs6000.c
> ===================================================================
> --- gcc/config/rs6000/rs6000.c  2014-08-31 21:05:04.701330252 +0100
> +++ gcc/config/rs6000/rs6000.c  2014-09-02 19:02:59.699481175 +0100
> @@ -142,8 +142,6 @@ typedef struct rs6000_stack {
>     This is added to the cfun structure.  */
>  typedef struct GTY(()) machine_function
>  {
> -  /* Some local-dynamic symbol.  */
> -  const char *some_ld_name;
>    /* Whether the instruction chain has been scanned already.  */
>    int insn_chain_scanned_p;
>    /* Flags if __builtin_return_address (n) with n >= 1 was used.  */
> @@ -1103,7 +1101,6 @@ static void is_altivec_return_reg (rtx,
>  int easy_vector_constant (rtx, enum machine_mode);
>  static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
>  static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
> -static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
>  static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree,
>                                        bool, bool);
>  #if TARGET_MACHO
> @@ -17937,46 +17934,6 @@ extract_ME (rtx op)
>    return i;
>  }
>
> -/* Locate some local-dynamic symbol still in use by this function
> -   so that we can print its name in some tls_ld pattern.  */
> -
> -static const char *
> -rs6000_get_some_local_dynamic_name (void)
> -{
> -  rtx_insn *insn;
> -
> -  if (cfun->machine->some_ld_name)
> -    return cfun->machine->some_ld_name;
> -
> -  for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
> -    if (INSN_P (insn)
> -       && for_each_rtx (&PATTERN (insn),
> -                        rs6000_get_some_local_dynamic_name_1, 0))
> -      return cfun->machine->some_ld_name;
> -
> -  gcc_unreachable ();
> -}
> -
> -/* Helper function for rs6000_get_some_local_dynamic_name.  */
> -
> -static int
> -rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
> -{
> -  rtx x = *px;
> -
> -  if (GET_CODE (x) == SYMBOL_REF)
> -    {
> -      const char *str = XSTR (x, 0);
> -      if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
> -       {
> -         cfun->machine->some_ld_name = str;
> -         return 1;
> -       }
> -    }
> -
> -  return 0;
> -}
> -
>  /* Write out a function code label.  */
>
>  void
> @@ -18652,7 +18609,11 @@ print_operand (FILE *file, rtx x, int co
>        return;
>
>      case '&':
> -      assemble_name (file, rs6000_get_some_local_dynamic_name ());
> +      if (const char *name = get_some_local_dynamic_name ())
> +       assemble_name (file, name);
> +      else
> +       output_operand_lossage ("'%%&' used without any "
> +                               "local dynamic TLS references");
>        return;
>
>      default:
> Index: gcc/config/s390/s390.c
> ===================================================================
> --- gcc/config/s390/s390.c      2014-08-31 21:05:04.701330252 +0100
> +++ gcc/config/s390/s390.c      2014-09-02 19:02:59.742481649 +0100
> @@ -387,9 +387,6 @@ struct GTY(()) machine_function
>    /* True if we may need to perform branch splitting.  */
>    bool split_branches_pending_p;
>
> -  /* Some local-dynamic TLS symbol name.  */
> -  const char *some_ld_name;
> -
>    bool has_landing_pad_p;
>
>    /* True if the current function may contain a tbegin clobbering
> @@ -5197,48 +5194,6 @@ print_shift_count_operand (FILE *file, r
>      fprintf (file, "(%s)", reg_names[REGNO (base)]);
>  }
>
> -/* See 'get_some_local_dynamic_name'.  */
> -
> -static int
> -get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
> -{
> -  rtx x = *px;
> -
> -  if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
> -    {
> -      x = get_pool_constant (x);
> -      return for_each_rtx (&x, get_some_local_dynamic_name_1, 0);
> -    }
> -
> -  if (GET_CODE (x) == SYMBOL_REF
> -      && tls_symbolic_operand (x) == TLS_MODEL_LOCAL_DYNAMIC)
> -    {
> -      cfun->machine->some_ld_name = XSTR (x, 0);
> -      return 1;
> -    }
> -
> -  return 0;
> -}
> -
> -/* Locate some local-dynamic symbol still in use by this function
> -   so that we can print its name in local-dynamic base patterns.  */
> -
> -static const char *
> -get_some_local_dynamic_name (void)
> -{
> -  rtx_insn *insn;
> -
> -  if (cfun->machine->some_ld_name)
> -    return cfun->machine->some_ld_name;
> -
> -  for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
> -    if (INSN_P (insn)
> -        && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
> -      return cfun->machine->some_ld_name;
> -
> -  gcc_unreachable ();
> -}
> -
>  /* Returns -1 if the function should not be made hotpatchable.  Otherwise it
>     returns a number >= 0 that is the desired size of the hotpatch trampoline
>     in halfwords. */
> @@ -5508,7 +5463,9 @@ print_operand (FILE *file, rtx x, int co
>        else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSLDM)
>         {
>           fprintf (file, "%s", ":tls_ldcall:");
> -         assemble_name (file, get_some_local_dynamic_name ());
> +         const char *name = get_some_local_dynamic_name ();
> +         gcc_assert (name);
> +         assemble_name (file, name);
>         }
>        else
>         output_operand_lossage ("invalid reference for 'J' output modifier");
> Index: gcc/config/sparc/sparc.c
> ===================================================================
> --- gcc/config/sparc/sparc.c    2014-08-31 21:05:04.701330252 +0100
> +++ gcc/config/sparc/sparc.c    2014-09-02 19:02:59.800482290 +0100
> @@ -70,6 +70,7 @@ the Free Software Foundation; either ver
>  #include "context.h"
>  #include "wide-int.h"
>  #include "builtins.h"
> +#include "rtl-iter.h"
>
>  /* Processor costs */
>
> @@ -500,9 +501,6 @@ struct GTY(()) machine_function
>    rtx frame_base_reg;
>    HOST_WIDE_INT frame_base_offset;
>
> -  /* Some local-dynamic TLS symbol name.  */
> -  const char *some_ld_name;
> -
>    /* Number of global or FP registers to be saved (as 4-byte quantities).  */
>    int n_global_fp_regs;
>
> @@ -584,8 +582,6 @@ static struct machine_function * sparc_i
>  static bool sparc_cannot_force_const_mem (enum machine_mode, rtx);
>  static rtx sparc_tls_get_addr (void);
>  static rtx sparc_tls_got (void);
> -static const char *get_some_local_dynamic_name (void);
> -static int get_some_local_dynamic_name_1 (rtx *, void *);
>  static int sparc_register_move_cost (enum machine_mode,
>                                      reg_class_t, reg_class_t);
>  static bool sparc_rtx_costs (rtx, int, int, int, int *, bool);
> @@ -8790,7 +8786,11 @@ sparc_print_operand (FILE *file, rtx x,
>        return;
>      case '&':
>        /* Print some local dynamic TLS name.  */
> -      assemble_name (file, get_some_local_dynamic_name ());
> +      if (const char *name = get_some_local_dynamic_name ())
> +       assemble_name (file, name);
> +      else
> +       output_operand_lossage ("'%%&' used without any "
> +                               "local dynamic TLS references");
>        return;
>
>      case 'Y':
> @@ -11484,41 +11484,6 @@ sparc_init_machine_status (void)
>    return ggc_cleared_alloc<machine_function> ();
>  }
>
> -/* Locate some local-dynamic symbol still in use by this function
> -   so that we can print its name in local-dynamic base patterns.  */
> -
> -static const char *
> -get_some_local_dynamic_name (void)
> -{
> -  rtx_insn *insn;
> -
> -  if (cfun->machine->some_ld_name)
> -    return cfun->machine->some_ld_name;
> -
> -  for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
> -    if (INSN_P (insn)
> -       && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
> -      return cfun->machine->some_ld_name;
> -
> -  gcc_unreachable ();
> -}
> -
> -static int
> -get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
> -{
> -  rtx x = *px;
> -
> -  if (x
> -      && GET_CODE (x) == SYMBOL_REF
> -      && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
> -    {
> -      cfun->machine->some_ld_name = XSTR (x, 0);
> -      return 1;
> -    }
> -
> -  return 0;
> -}
> -
>  /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
>     We need to emit DTP-relative relocations.  */
>


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