diff mbox

[2/4,ARC] Cleanup implementation.

Message ID 1479291481-24225-3-git-send-email-claziss@synopsys.com
State New
Headers show

Commit Message

Claudiu Zissulescu Nov. 16, 2016, 10:17 a.m. UTC
gcc/
2016-06-30  Claudiu Zissulescu  <claziss@synopsys.com>

	* config/arc/arc-protos.h (insn_is_tls_gd_dispatch): Remove.
	* config/arc/arc.c (arc_unspec_offset): New function.
	(arc_finalize_pic): Change.
	(arc_emit_call_tls_get_addr): Likewise.
	(arc_legitimize_tls_address): Likewise.
	(arc_legitimize_pic_address): Likewise.
	(insn_is_tls_gd_dispatch): Remove.
	* config/arc/arc.h (INSN_REFERENCES_ARE_DELAYED): Change.
	* config/arc/arc.md (ls_gd_load): Remove.
	(tls_gd_dispatch): Likewise.
---
 gcc/config/arc/arc-protos.h |  1 -
 gcc/config/arc/arc.c        | 41 ++++++++++++++++++-----------------------
 gcc/config/arc/arc.h        |  2 +-
 gcc/config/arc/arc.md       | 34 ----------------------------------
 4 files changed, 19 insertions(+), 59 deletions(-)

Comments

Claudiu Zissulescu Nov. 29, 2016, 12:26 p.m. UTC | #1
Ping.

> -----Original Message-----
> From: Claudiu Zissulescu
> Sent: Wednesday, November 16, 2016 11:18 AM
> To: gcc-patches@gcc.gnu.org
> Cc: Claudiu Zissulescu <claziss@synopsys.com>;
> Francois.Bedard@synopsys.com; andrew.burgess@embecosm.com
> Subject: [PATCH 2/4] [ARC] Cleanup implementation.
> 
> gcc/
> 2016-06-30  Claudiu Zissulescu  <claziss@synopsys.com>
> 
> 	* config/arc/arc-protos.h (insn_is_tls_gd_dispatch): Remove.
> 	* config/arc/arc.c (arc_unspec_offset): New function.
> 	(arc_finalize_pic): Change.
> 	(arc_emit_call_tls_get_addr): Likewise.
> 	(arc_legitimize_tls_address): Likewise.
> 	(arc_legitimize_pic_address): Likewise.
> 	(insn_is_tls_gd_dispatch): Remove.
> 	* config/arc/arc.h (INSN_REFERENCES_ARE_DELAYED): Change.
> 	* config/arc/arc.md (ls_gd_load): Remove.
> 	(tls_gd_dispatch): Likewise.
> ---
>  gcc/config/arc/arc-protos.h |  1 -
>  gcc/config/arc/arc.c        | 41 ++++++++++++++++++-----------------------
>  gcc/config/arc/arc.h        |  2 +-
>  gcc/config/arc/arc.md       | 34 ----------------------------------
>  4 files changed, 19 insertions(+), 59 deletions(-)
> 
> diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h
> index 6008744..bda3d46 100644
> --- a/gcc/config/arc/arc-protos.h
> +++ b/gcc/config/arc/arc-protos.h
> @@ -118,6 +118,5 @@ extern bool arc_eh_uses (int regno);
>  extern int regno_clobbered_p (unsigned int, rtx_insn *, machine_mode,
> int);
>  extern bool arc_legitimize_reload_address (rtx *, machine_mode, int, int);
>  extern void arc_secondary_reload_conv (rtx, rtx, rtx, bool);
> -extern bool insn_is_tls_gd_dispatch (rtx_insn *);
>  extern void arc_cpu_cpp_builtins (cpp_reader *);
>  extern rtx arc_eh_return_address_location (void);
> diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
> index 428676f..7eadb3c 100644
> --- a/gcc/config/arc/arc.c
> +++ b/gcc/config/arc/arc.c
> @@ -2893,6 +2893,15 @@ arc_eh_return_address_location (void)
> 
>  /* PIC */
> 
> +/* Helper to generate unspec constant.  */
> +
> +static rtx
> +arc_unspec_offset (rtx loc, int unspec)
> +{
> +  return gen_rtx_CONST (Pmode, gen_rtx_UNSPEC (Pmode, gen_rtvec (1,
> loc),
> +					       unspec));
> +}
> +
>  /* Emit special PIC prologues and epilogues.  */
>  /* If the function has any GOTOFF relocations, then the GOTBASE
>     register has to be setup in the prologue
> @@ -2918,9 +2927,7 @@ arc_finalize_pic (void)
>    gcc_assert (flag_pic != 0);
> 
>    pat = gen_rtx_SYMBOL_REF (Pmode, "_DYNAMIC");
> -  pat = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, pat), ARC_UNSPEC_GOT);
> -  pat = gen_rtx_CONST (Pmode, pat);
> -
> +  pat = arc_unspec_offset (pat, ARC_UNSPEC_GOT);
>    pat = gen_rtx_SET (baseptr_rtx, pat);
> 
>    emit_insn (pat);
> @@ -4989,8 +4996,7 @@ arc_emit_call_tls_get_addr (rtx sym, int reloc, rtx
> eqv)
> 
>    start_sequence ();
> 
> -  rtx x = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), reloc);
> -  x = gen_rtx_CONST (Pmode, x);
> +  rtx x = arc_unspec_offset (sym, reloc);
>    emit_move_insn (r0, x);
>    use_reg (&call_fusage, r0);
> 
> @@ -5046,17 +5052,18 @@ arc_legitimize_tls_address (rtx addr, enum
> tls_model model)
>        addr = gen_rtx_CONST (Pmode, addr);
>        base = arc_legitimize_tls_address (base,
> TLS_MODEL_GLOBAL_DYNAMIC);
>        return gen_rtx_PLUS (Pmode, force_reg (Pmode, base), addr);
> +
>      case TLS_MODEL_GLOBAL_DYNAMIC:
>        return arc_emit_call_tls_get_addr (addr, UNSPEC_TLS_GD, addr);
> +
>      case TLS_MODEL_INITIAL_EXEC:
> -      addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_TLS_IE);
> -      addr = gen_rtx_CONST (Pmode, addr);
> +      addr = arc_unspec_offset (addr, UNSPEC_TLS_IE);
>        addr = copy_to_mode_reg (Pmode, gen_const_mem (Pmode, addr));
>        return gen_rtx_PLUS (Pmode, arc_get_tp (), addr);
> +
>      case TLS_MODEL_LOCAL_EXEC:
>      local_exec:
> -      addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
> UNSPEC_TLS_OFF);
> -      addr = gen_rtx_CONST (Pmode, addr);
> +      addr = arc_unspec_offset (addr, UNSPEC_TLS_OFF);
>        return gen_rtx_PLUS (Pmode, arc_get_tp (), addr);
>      default:
>        gcc_unreachable ();
> @@ -5087,14 +5094,11 @@ arc_legitimize_pic_address (rtx orig, rtx oldx)
>        else if (!flag_pic)
>  	return orig;
>        else if (CONSTANT_POOL_ADDRESS_P (addr) || SYMBOL_REF_LOCAL_P
> (addr))
> -	return gen_rtx_CONST (Pmode,
> -			      gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
> -			      ARC_UNSPEC_GOTOFFPC));
> +	return arc_unspec_offset (addr, ARC_UNSPEC_GOTOFFPC);
> 
>        /* This symbol must be referenced via a load from the Global
>  	 Offset Table (@GOTPC).  */
> -      pat = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
> ARC_UNSPEC_GOT);
> -      pat = gen_rtx_CONST (Pmode, pat);
> +      pat = arc_unspec_offset (addr, ARC_UNSPEC_GOT);
>        pat = gen_const_mem (Pmode, pat);
> 
>        if (oldx == NULL)
> @@ -10033,15 +10037,6 @@ arc_dwarf_register_span (rtx rtl)
>     return p;
>  }
> 
> -/* We can't inline this in INSN_REFERENCES_ARE_DELAYED because
> -   resource.h doesn't include the required header files.  */
> -
> -bool
> -insn_is_tls_gd_dispatch (rtx_insn *insn)
> -{
> -  return recog_memoized (insn) == CODE_FOR_tls_gd_dispatch;
> -}
> -
>  /* Return true if OP is an acceptable memory operand for ARCompact
>     16-bit load instructions of MODE.
> 
> diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
> index 642bf73..59b323b 100644
> --- a/gcc/config/arc/arc.h
> +++ b/gcc/config/arc/arc.h
> @@ -1615,7 +1615,7 @@ extern enum arc_function_type
> arc_compute_function_type (struct function *);
>     && (get_attr_type (X) == TYPE_CALL || get_attr_type (X) ==
> TYPE_SFUNC))
> 
>  #define INSN_REFERENCES_ARE_DELAYED(insn)
> 	\
> -  (INSN_SETS_ARE_DELAYED (insn) && !insn_is_tls_gd_dispatch (insn))
> +  (INSN_SETS_ARE_DELAYED (insn))
> 
>  #define CALL_ATTR(X, NAME) \
>    ((CALL_P (X) || NONJUMP_INSN_P (X)) \
> diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
> index 217935c..86de423 100644
> --- a/gcc/config/arc/arc.md
> +++ b/gcc/config/arc/arc.md
> @@ -5410,21 +5410,6 @@
>    [(set_attr "is_sfunc" "yes")
>     (set_attr "predicable" "yes")])
> 
> -(define_insn "tls_gd_load"
> -  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,c")
> -	(unspec:SI [(match_operand:SI 1 "register_operand" "Rcq#q,c")
> -		    (match_operand:SI 2 "symbolic_operand" "X,X")]
> -	 UNSPEC_TLS_GD))]
> -  ""
> -  ".tls_gd_ld %2`ld%? %0,[%1]"
> -  [(set_attr "type" "load")
> -   ; if the linker has to patch this into IE, we need a long insn
> -   ; (FIXME: or two short insn, ld_s / jl_s.  missing -Os optimization.)
> -   (set_attr_alternative "iscompact"
> -     [(cond [(ne (symbol_ref "arc_tp_regno == 30") (const_int 0))
> -	     (const_string "*")] (const_string "maybe"))
> -      (const_string "*")])])
> -
>  (define_insn "tls_gd_get_addr"
>    [(set (reg:SI R0_REG)
>  	(call:SI (mem:SI (unspec:SI [(match_operand:SI 0
> @@ -5438,25 +5423,6 @@
>     ; With TARGET_MEDIUM_CALLS, plt calls are not predicable.
>     (set_attr "predicable" "no")])
> 
> -; We make this call specific to the tls symbol to avoid commoning this
> -; with calls for other symbols; we want the linker to be able to
> -(define_insn "tls_gd_dispatch"
> -  [(set (reg:SI R0_REG)
> -	(unspec:SI
> -	  [(reg:SI R0_REG)
> -	   (call (mem:SI (match_operand:SI 0 "register_operand" "Rcq,q,c"))
> -		 (const_int 0))
> -	   (match_operand:SI 1 "symbolic_operand" "X,X,X")]
> -	 UNSPEC_TLS_GD))
> -   (clobber (reg:SI RETURN_ADDR_REGNUM))
> -   (clobber (reg:DI R10_REG))
> -   (clobber (reg:SI R12_REG))]
> -  ""
> -  ".tls_gd_call %1`jl%!%* [%0]"
> -  [(set_attr "type" "call")
> -   (set_attr "iscompact" "maybe,false,*")
> -   (set_attr "predicable" "no,no,yes")])
> -
>  ;; For thread pointer builtins
>  (define_expand "get_thread_pointersi"
>    [(set (match_operand:SI 0 "register_operand") (match_dup 1))]
> --
> 1.9.1
Andrew Burgess Nov. 30, 2016, 5:05 p.m. UTC | #2
* Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com> [2016-11-16 11:17:59 +0100]:

> gcc/
> 2016-06-30  Claudiu Zissulescu  <claziss@synopsys.com>

There seem to be two sets of changes here:

> 
> 	* config/arc/arc-protos.h (insn_is_tls_gd_dispatch): Remove.
> 	* config/arc/arc.c (arc_unspec_offset): New function.
> 	(arc_finalize_pic): Change.
> 	(arc_emit_call_tls_get_addr): Likewise.
> 	(arc_legitimize_tls_address): Likewise.
> 	(arc_legitimize_pic_address): Likewise.
> 	(insn_is_tls_gd_dispatch): Remove.
> 	* config/arc/arc.h (INSN_REFERENCES_ARE_DELAYED): Change.

This lot seem pretty straight forward.  As always I cringe a little
when I see "Change" as the description, but given that actual change
is straight forward and small it's not that bad..

> 	* config/arc/arc.md (ls_gd_load): Remove.
> 	(tls_gd_dispatch): Likewise.

I don't see the connection between these two parts?  Plus it would be
nice to have some more words _somewhere_ for why these are being
removed.  The commit message is probably the right place I'd have
thought.

But assuming your reason for removing the patterns is solid this patch
looks fine.  You should commit with an extended description.

Thanks,
Andrew


> ---
>  gcc/config/arc/arc-protos.h |  1 -
>  gcc/config/arc/arc.c        | 41 ++++++++++++++++++-----------------------
>  gcc/config/arc/arc.h        |  2 +-
>  gcc/config/arc/arc.md       | 34 ----------------------------------
>  4 files changed, 19 insertions(+), 59 deletions(-)
> 
> diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h
> index 6008744..bda3d46 100644
> --- a/gcc/config/arc/arc-protos.h
> +++ b/gcc/config/arc/arc-protos.h
> @@ -118,6 +118,5 @@ extern bool arc_eh_uses (int regno);
>  extern int regno_clobbered_p (unsigned int, rtx_insn *, machine_mode, int);
>  extern bool arc_legitimize_reload_address (rtx *, machine_mode, int, int);
>  extern void arc_secondary_reload_conv (rtx, rtx, rtx, bool);
> -extern bool insn_is_tls_gd_dispatch (rtx_insn *);
>  extern void arc_cpu_cpp_builtins (cpp_reader *);
>  extern rtx arc_eh_return_address_location (void);
> diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
> index 428676f..7eadb3c 100644
> --- a/gcc/config/arc/arc.c
> +++ b/gcc/config/arc/arc.c
> @@ -2893,6 +2893,15 @@ arc_eh_return_address_location (void)
>  
>  /* PIC */
>  
> +/* Helper to generate unspec constant.  */
> +
> +static rtx
> +arc_unspec_offset (rtx loc, int unspec)
> +{
> +  return gen_rtx_CONST (Pmode, gen_rtx_UNSPEC (Pmode, gen_rtvec (1, loc),
> +					       unspec));
> +}
> +
>  /* Emit special PIC prologues and epilogues.  */
>  /* If the function has any GOTOFF relocations, then the GOTBASE
>     register has to be setup in the prologue
> @@ -2918,9 +2927,7 @@ arc_finalize_pic (void)
>    gcc_assert (flag_pic != 0);
>  
>    pat = gen_rtx_SYMBOL_REF (Pmode, "_DYNAMIC");
> -  pat = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, pat), ARC_UNSPEC_GOT);
> -  pat = gen_rtx_CONST (Pmode, pat);
> -
> +  pat = arc_unspec_offset (pat, ARC_UNSPEC_GOT);
>    pat = gen_rtx_SET (baseptr_rtx, pat);
>  
>    emit_insn (pat);
> @@ -4989,8 +4996,7 @@ arc_emit_call_tls_get_addr (rtx sym, int reloc, rtx eqv)
>  
>    start_sequence ();
>  
> -  rtx x = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), reloc);
> -  x = gen_rtx_CONST (Pmode, x);
> +  rtx x = arc_unspec_offset (sym, reloc);
>    emit_move_insn (r0, x);
>    use_reg (&call_fusage, r0);
>  
> @@ -5046,17 +5052,18 @@ arc_legitimize_tls_address (rtx addr, enum tls_model model)
>        addr = gen_rtx_CONST (Pmode, addr);
>        base = arc_legitimize_tls_address (base, TLS_MODEL_GLOBAL_DYNAMIC);
>        return gen_rtx_PLUS (Pmode, force_reg (Pmode, base), addr);
> +
>      case TLS_MODEL_GLOBAL_DYNAMIC:
>        return arc_emit_call_tls_get_addr (addr, UNSPEC_TLS_GD, addr);
> +
>      case TLS_MODEL_INITIAL_EXEC:
> -      addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_TLS_IE);
> -      addr = gen_rtx_CONST (Pmode, addr);
> +      addr = arc_unspec_offset (addr, UNSPEC_TLS_IE);
>        addr = copy_to_mode_reg (Pmode, gen_const_mem (Pmode, addr));
>        return gen_rtx_PLUS (Pmode, arc_get_tp (), addr);
> +
>      case TLS_MODEL_LOCAL_EXEC:
>      local_exec:
> -      addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_TLS_OFF);
> -      addr = gen_rtx_CONST (Pmode, addr);
> +      addr = arc_unspec_offset (addr, UNSPEC_TLS_OFF);
>        return gen_rtx_PLUS (Pmode, arc_get_tp (), addr);
>      default:
>        gcc_unreachable ();
> @@ -5087,14 +5094,11 @@ arc_legitimize_pic_address (rtx orig, rtx oldx)
>        else if (!flag_pic)
>  	return orig;
>        else if (CONSTANT_POOL_ADDRESS_P (addr) || SYMBOL_REF_LOCAL_P (addr))
> -	return gen_rtx_CONST (Pmode,
> -			      gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
> -			      ARC_UNSPEC_GOTOFFPC));
> +	return arc_unspec_offset (addr, ARC_UNSPEC_GOTOFFPC);
>  
>        /* This symbol must be referenced via a load from the Global
>  	 Offset Table (@GOTPC).  */
> -      pat = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), ARC_UNSPEC_GOT);
> -      pat = gen_rtx_CONST (Pmode, pat);
> +      pat = arc_unspec_offset (addr, ARC_UNSPEC_GOT);
>        pat = gen_const_mem (Pmode, pat);
>  
>        if (oldx == NULL)
> @@ -10033,15 +10037,6 @@ arc_dwarf_register_span (rtx rtl)
>     return p;
>  }
>  
> -/* We can't inline this in INSN_REFERENCES_ARE_DELAYED because
> -   resource.h doesn't include the required header files.  */
> -
> -bool
> -insn_is_tls_gd_dispatch (rtx_insn *insn)
> -{
> -  return recog_memoized (insn) == CODE_FOR_tls_gd_dispatch;
> -}
> -
>  /* Return true if OP is an acceptable memory operand for ARCompact
>     16-bit load instructions of MODE.
>  
> diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
> index 642bf73..59b323b 100644
> --- a/gcc/config/arc/arc.h
> +++ b/gcc/config/arc/arc.h
> @@ -1615,7 +1615,7 @@ extern enum arc_function_type arc_compute_function_type (struct function *);
>     && (get_attr_type (X) == TYPE_CALL || get_attr_type (X) == TYPE_SFUNC))
>  
>  #define INSN_REFERENCES_ARE_DELAYED(insn)				\
> -  (INSN_SETS_ARE_DELAYED (insn) && !insn_is_tls_gd_dispatch (insn))
> +  (INSN_SETS_ARE_DELAYED (insn))
>  
>  #define CALL_ATTR(X, NAME) \
>    ((CALL_P (X) || NONJUMP_INSN_P (X)) \
> diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
> index 217935c..86de423 100644
> --- a/gcc/config/arc/arc.md
> +++ b/gcc/config/arc/arc.md
> @@ -5410,21 +5410,6 @@
>    [(set_attr "is_sfunc" "yes")
>     (set_attr "predicable" "yes")])
>  
> -(define_insn "tls_gd_load"
> -  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,c")
> -	(unspec:SI [(match_operand:SI 1 "register_operand" "Rcq#q,c")
> -		    (match_operand:SI 2 "symbolic_operand" "X,X")]
> -	 UNSPEC_TLS_GD))]
> -  ""
> -  ".tls_gd_ld %2`ld%? %0,[%1]"
> -  [(set_attr "type" "load")
> -   ; if the linker has to patch this into IE, we need a long insn
> -   ; (FIXME: or two short insn, ld_s / jl_s.  missing -Os optimization.)
> -   (set_attr_alternative "iscompact"
> -     [(cond [(ne (symbol_ref "arc_tp_regno == 30") (const_int 0))
> -	     (const_string "*")] (const_string "maybe"))
> -      (const_string "*")])])
> -
>  (define_insn "tls_gd_get_addr"
>    [(set (reg:SI R0_REG)
>  	(call:SI (mem:SI (unspec:SI [(match_operand:SI 0
> @@ -5438,25 +5423,6 @@
>     ; With TARGET_MEDIUM_CALLS, plt calls are not predicable.
>     (set_attr "predicable" "no")])
>  
> -; We make this call specific to the tls symbol to avoid commoning this
> -; with calls for other symbols; we want the linker to be able to
> -(define_insn "tls_gd_dispatch"
> -  [(set (reg:SI R0_REG)
> -	(unspec:SI
> -	  [(reg:SI R0_REG)
> -	   (call (mem:SI (match_operand:SI 0 "register_operand" "Rcq,q,c"))
> -		 (const_int 0))
> -	   (match_operand:SI 1 "symbolic_operand" "X,X,X")]
> -	 UNSPEC_TLS_GD))
> -   (clobber (reg:SI RETURN_ADDR_REGNUM))
> -   (clobber (reg:DI R10_REG))
> -   (clobber (reg:SI R12_REG))]
> -  ""
> -  ".tls_gd_call %1`jl%!%* [%0]"
> -  [(set_attr "type" "call")
> -   (set_attr "iscompact" "maybe,false,*")
> -   (set_attr "predicable" "no,no,yes")])
> -
>  ;; For thread pointer builtins
>  (define_expand "get_thread_pointersi"
>    [(set (match_operand:SI 0 "register_operand") (match_dup 1))]
> -- 
> 1.9.1
>
Claudiu Zissulescu Dec. 5, 2016, 11:21 a.m. UTC | #3
Hi,

> > 	* config/arc/arc.md (ls_gd_load): Remove.
> > 	(tls_gd_dispatch): Likewise.
> 
> I don't see the connection between these two parts?  Plus it would be
> nice to have some more words _somewhere_ for why these are being
> removed.  The commit message is probably the right place I'd have
> thought.
> 
> But assuming your reason for removing the patterns is solid this patch
> looks fine.  You should commit with an extended description.

The two patterns in question are not used by our backend. I've updated the message like: Remove unused pattern. 

Patch committed, thank you for your review, 
Claudiu
diff mbox

Patch

diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h
index 6008744..bda3d46 100644
--- a/gcc/config/arc/arc-protos.h
+++ b/gcc/config/arc/arc-protos.h
@@ -118,6 +118,5 @@  extern bool arc_eh_uses (int regno);
 extern int regno_clobbered_p (unsigned int, rtx_insn *, machine_mode, int);
 extern bool arc_legitimize_reload_address (rtx *, machine_mode, int, int);
 extern void arc_secondary_reload_conv (rtx, rtx, rtx, bool);
-extern bool insn_is_tls_gd_dispatch (rtx_insn *);
 extern void arc_cpu_cpp_builtins (cpp_reader *);
 extern rtx arc_eh_return_address_location (void);
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 428676f..7eadb3c 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -2893,6 +2893,15 @@  arc_eh_return_address_location (void)
 
 /* PIC */
 
+/* Helper to generate unspec constant.  */
+
+static rtx
+arc_unspec_offset (rtx loc, int unspec)
+{
+  return gen_rtx_CONST (Pmode, gen_rtx_UNSPEC (Pmode, gen_rtvec (1, loc),
+					       unspec));
+}
+
 /* Emit special PIC prologues and epilogues.  */
 /* If the function has any GOTOFF relocations, then the GOTBASE
    register has to be setup in the prologue
@@ -2918,9 +2927,7 @@  arc_finalize_pic (void)
   gcc_assert (flag_pic != 0);
 
   pat = gen_rtx_SYMBOL_REF (Pmode, "_DYNAMIC");
-  pat = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, pat), ARC_UNSPEC_GOT);
-  pat = gen_rtx_CONST (Pmode, pat);
-
+  pat = arc_unspec_offset (pat, ARC_UNSPEC_GOT);
   pat = gen_rtx_SET (baseptr_rtx, pat);
 
   emit_insn (pat);
@@ -4989,8 +4996,7 @@  arc_emit_call_tls_get_addr (rtx sym, int reloc, rtx eqv)
 
   start_sequence ();
 
-  rtx x = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), reloc);
-  x = gen_rtx_CONST (Pmode, x);
+  rtx x = arc_unspec_offset (sym, reloc);
   emit_move_insn (r0, x);
   use_reg (&call_fusage, r0);
 
@@ -5046,17 +5052,18 @@  arc_legitimize_tls_address (rtx addr, enum tls_model model)
       addr = gen_rtx_CONST (Pmode, addr);
       base = arc_legitimize_tls_address (base, TLS_MODEL_GLOBAL_DYNAMIC);
       return gen_rtx_PLUS (Pmode, force_reg (Pmode, base), addr);
+
     case TLS_MODEL_GLOBAL_DYNAMIC:
       return arc_emit_call_tls_get_addr (addr, UNSPEC_TLS_GD, addr);
+
     case TLS_MODEL_INITIAL_EXEC:
-      addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_TLS_IE);
-      addr = gen_rtx_CONST (Pmode, addr);
+      addr = arc_unspec_offset (addr, UNSPEC_TLS_IE);
       addr = copy_to_mode_reg (Pmode, gen_const_mem (Pmode, addr));
       return gen_rtx_PLUS (Pmode, arc_get_tp (), addr);
+
     case TLS_MODEL_LOCAL_EXEC:
     local_exec:
-      addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_TLS_OFF);
-      addr = gen_rtx_CONST (Pmode, addr);
+      addr = arc_unspec_offset (addr, UNSPEC_TLS_OFF);
       return gen_rtx_PLUS (Pmode, arc_get_tp (), addr);
     default:
       gcc_unreachable ();
@@ -5087,14 +5094,11 @@  arc_legitimize_pic_address (rtx orig, rtx oldx)
       else if (!flag_pic)
 	return orig;
       else if (CONSTANT_POOL_ADDRESS_P (addr) || SYMBOL_REF_LOCAL_P (addr))
-	return gen_rtx_CONST (Pmode,
-			      gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
-			      ARC_UNSPEC_GOTOFFPC));
+	return arc_unspec_offset (addr, ARC_UNSPEC_GOTOFFPC);
 
       /* This symbol must be referenced via a load from the Global
 	 Offset Table (@GOTPC).  */
-      pat = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), ARC_UNSPEC_GOT);
-      pat = gen_rtx_CONST (Pmode, pat);
+      pat = arc_unspec_offset (addr, ARC_UNSPEC_GOT);
       pat = gen_const_mem (Pmode, pat);
 
       if (oldx == NULL)
@@ -10033,15 +10037,6 @@  arc_dwarf_register_span (rtx rtl)
    return p;
 }
 
-/* We can't inline this in INSN_REFERENCES_ARE_DELAYED because
-   resource.h doesn't include the required header files.  */
-
-bool
-insn_is_tls_gd_dispatch (rtx_insn *insn)
-{
-  return recog_memoized (insn) == CODE_FOR_tls_gd_dispatch;
-}
-
 /* Return true if OP is an acceptable memory operand for ARCompact
    16-bit load instructions of MODE.
 
diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index 642bf73..59b323b 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -1615,7 +1615,7 @@  extern enum arc_function_type arc_compute_function_type (struct function *);
    && (get_attr_type (X) == TYPE_CALL || get_attr_type (X) == TYPE_SFUNC))
 
 #define INSN_REFERENCES_ARE_DELAYED(insn)				\
-  (INSN_SETS_ARE_DELAYED (insn) && !insn_is_tls_gd_dispatch (insn))
+  (INSN_SETS_ARE_DELAYED (insn))
 
 #define CALL_ATTR(X, NAME) \
   ((CALL_P (X) || NONJUMP_INSN_P (X)) \
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index 217935c..86de423 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -5410,21 +5410,6 @@ 
   [(set_attr "is_sfunc" "yes")
    (set_attr "predicable" "yes")])
 
-(define_insn "tls_gd_load"
-  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,c")
-	(unspec:SI [(match_operand:SI 1 "register_operand" "Rcq#q,c")
-		    (match_operand:SI 2 "symbolic_operand" "X,X")]
-	 UNSPEC_TLS_GD))]
-  ""
-  ".tls_gd_ld %2`ld%? %0,[%1]"
-  [(set_attr "type" "load")
-   ; if the linker has to patch this into IE, we need a long insn
-   ; (FIXME: or two short insn, ld_s / jl_s.  missing -Os optimization.)
-   (set_attr_alternative "iscompact"
-     [(cond [(ne (symbol_ref "arc_tp_regno == 30") (const_int 0))
-	     (const_string "*")] (const_string "maybe"))
-      (const_string "*")])])
-
 (define_insn "tls_gd_get_addr"
   [(set (reg:SI R0_REG)
 	(call:SI (mem:SI (unspec:SI [(match_operand:SI 0
@@ -5438,25 +5423,6 @@ 
    ; With TARGET_MEDIUM_CALLS, plt calls are not predicable.
    (set_attr "predicable" "no")])
 
-; We make this call specific to the tls symbol to avoid commoning this
-; with calls for other symbols; we want the linker to be able to
-(define_insn "tls_gd_dispatch"
-  [(set (reg:SI R0_REG)
-	(unspec:SI
-	  [(reg:SI R0_REG)
-	   (call (mem:SI (match_operand:SI 0 "register_operand" "Rcq,q,c"))
-		 (const_int 0))
-	   (match_operand:SI 1 "symbolic_operand" "X,X,X")]
-	 UNSPEC_TLS_GD))
-   (clobber (reg:SI RETURN_ADDR_REGNUM))
-   (clobber (reg:DI R10_REG))
-   (clobber (reg:SI R12_REG))]
-  ""
-  ".tls_gd_call %1`jl%!%* [%0]"
-  [(set_attr "type" "call")
-   (set_attr "iscompact" "maybe,false,*")
-   (set_attr "predicable" "no,no,yes")])
-
 ;; For thread pointer builtins
 (define_expand "get_thread_pointersi"
   [(set (match_operand:SI 0 "register_operand") (match_dup 1))]