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: Allow __sync_synchronize to use an external function


On Thu, Jun 26, 2008 at 10:47 PM, Richard Sandiford
<rdsandiford@googlemail.com> wrote:
> Most of the __sync_* builtins fall back to external routines if
> the target has no native support for them.  The exception is
> __sync_synchronize, which simply becomes an empty volatile asm
> with a memory clobber attached.  This default implementation
> is (in general) ineffective for SMP.
>
> The default implementation of __sync_lock_release is a call to
> __sync_synchronize followed by a store of zero.  Thus the fallback
> definition of __sync_lock_release is an empty volatile asm followed
> by a store of zero.
>
> This is usually not a problem, as most targets either have
> native synchronisation instructions or don't support SMP at all.
> Unfortunately, MIPS16 is one exception to this.  The MIPS16 ISA
> doesn't have a synchronisation instruction itself, but the full
> non-MIPS16 ISA does.  The MIPS16 implementation of __sync_synchronize
> must therefore call an external non-MIPS16 routine.
>
> I could handle this as a special case in the MIPS backend, but I can
> imagine that other ports might eventually need an external call too.
> I'd therefore like to add a new global libfunc that can be filled in
> by targetm.init_libfuncs.
>
> Tested on mipsisa64-elfoabi and x86_64-linux-gnu.  OK to install?

Reasonable.  This is ok.

Thanks,
Richard.

> Richard
>
>
> gcc/
>        * libfuncs.h (LTI_synchronize): New libfunc_index.
>        (synchronize_libfunc): Declare.
>        * builtins.c (expand_builtin_synchronize): Consider using
>        synchronize_libfunc before falling back on an asm blockage.
>        * config/mips/mips.c: Include libfuncs.h
>        (mips_init_libfuncs): Initialize synchronize_libfunc for TARGET_MIPS16.
>
> Index: gcc/libfuncs.h
> ===================================================================
> --- gcc/libfuncs.h      2008-06-25 05:13:52.000000000 +0100
> +++ gcc/libfuncs.h      2008-06-25 05:16:08.000000000 +0100
> @@ -40,6 +40,8 @@ enum libfunc_index
>   LTI_profile_function_entry,
>   LTI_profile_function_exit,
>
> +  LTI_synchronize,
> +
>   LTI_gcov_flush,
>
>   LTI_MAX
> @@ -69,6 +71,8 @@ #define unwind_sjlj_unregister_libfunc \
>  #define profile_function_entry_libfunc (libfunc_table[LTI_profile_function_entry])
>  #define profile_function_exit_libfunc  (libfunc_table[LTI_profile_function_exit])
>
> +#define synchronize_libfunc    (libfunc_table[LTI_synchronize])
> +
>  #define gcov_flush_libfunc     (libfunc_table[LTI_gcov_flush])
>
>  #endif /* GCC_LIBFUNCS_H */
> Index: gcc/builtins.c
> ===================================================================
> --- gcc/builtins.c      2008-06-25 05:13:52.000000000 +0100
> +++ gcc/builtins.c      2008-06-25 05:16:08.000000000 +0100
> @@ -5993,6 +5993,12 @@ expand_builtin_synchronize (void)
>     }
>  #endif
>
> +  if (synchronize_libfunc != NULL_RTX)
> +    {
> +      emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode, 0);
> +      return;
> +    }
> +
>   /* If no explicit memory barrier instruction is available, create an
>      empty asm stmt with a memory clobber.  */
>   x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
> Index: gcc/config/mips/mips.c
> ===================================================================
> --- gcc/config/mips/mips.c      2008-06-25 05:15:49.000000000 +0100
> +++ gcc/config/mips/mips.c      2008-06-25 05:18:04.000000000 +0100
> @@ -42,6 +42,7 @@ the Free Software Foundation; either ver
>  #include "function.h"
>  #include "expr.h"
>  #include "optabs.h"
> +#include "libfuncs.h"
>  #include "flags.h"
>  #include "reload.h"
>  #include "tm_p.h"
> @@ -9402,6 +9403,11 @@ mips_init_libfuncs (void)
>   else
>     /* Register the gofast functions if selected using --enable-gofast.  */
>     gofast_maybe_init_libfuncs ();
> +
> +  /* The MIPS16 ISA does not have an encoding for "sync", so we rely
> +     on an external non-MIPS16 routine to implement __sync_synchronize.  */
> +  if (TARGET_MIPS16)
> +    synchronize_libfunc = init_one_libfunc ("__sync_synchronize");
>  }
>
>  /* Return the length of INSN.  LENGTH is the initial length computed by
>


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