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: [PATCH] Avoid some C++ local statics with constructors


On Thu, 22 Sep 2016, Jakub Jelinek wrote:

> Hi!
> 
> The discovered 5 unnecessary C++ static locals with ctors prompted me to
> look at other cases, which from looking at the optimized or non-optimized
> code are just terrible.
> We don't need to initialize static vectors with vNULL, because that implies
> runtime initialization, static vars are zero initialized, which is what we
> want for the vectors.
> In ipa-cp, I understand the vr.min and vr.max is set just so that
> uninitialized vars aren't copied around, but initializing static local
> wide_int from tree and then copying over is significantly more expensive
> than just using wi::zero.
> The only questionable change is the sreal.h one, what it did is certainly
> very inefficient and ugly, but what the patch does is a kind of hack to keep
> it as efficient as possible even for -O0, at -O2 I'd say the compiler should
> just inline sreal::normalize and fold it into nothing.
> So, if preferred, we could go with just
>    inline static sreal min ()
>    {
>      return sreal (-SREAL_MAX_SIG, SREAL_MAX_EXP);
>    }
> which will be at -O2 as efficient as what the patch does - storing 2
> integers.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

While I agree with the goal to reduce the number of static constructors
esp. the vNULL cases I disagree with.  This is just introducing
undefined behavior (uninitialized object use), and in case we end up
making vNULL not all-zeros it's bound to break.  So IMHO your patch
is very much premature optimization here.

Maybe we can change vNULL to sth that avoids the constructor, if only
if C++14 is available (thus in stage2+)?

For cases like this I hope we could make GCC optimize away the static
construction, maybe you can reduce it to a simple testcase and file
a bugreport?  It will require making static constructors "first class"
in the cgraph so we know at some point the function body initializing
a specific global and some later cgraph phase builds up the global
constructor calling all remaining relevant individual constructor
functions (which can then still be inlined into that fn).

Thanks,
Richard.

> 2016-09-22  Jakub Jelinek  <jakub@redhat.com>
> 
> 	* ipa-cp.c (ipcp_store_vr_results): Avoid static local
> 	var zero.
> 	* sreal.h (sreal::min, sreal::max): Avoid static local vars,
> 	construct values without normalization.
> 	* tree-ssa-sccvn.c (vn_reference_lookup_3): Don't initialize
> 	static local lhs_ops to vNULL.
> cp/
> 	* name-lookup.c (store_bindings, store_class_bindings): Don't
> 	initialize static local bindings_need_stored to vNULL.
> 
> --- gcc/ipa-cp.c.jj	2016-09-21 08:54:15.000000000 +0200
> +++ gcc/ipa-cp.c	2016-09-22 13:49:57.638198975 +0200
> @@ -5204,11 +5204,9 @@ ipcp_store_vr_results (void)
>  	 }
>         else
>  	 {
> -	   static wide_int zero = integer_zero_node;
>  	   vr.known = false;
>  	   vr.type = VR_VARYING;
> -	   vr.min = zero;
> -	   vr.max = zero;
> +	   vr.min = vr.max = wi::zero (INT_TYPE_SIZE);
>  	 }
>         ts->m_vr->quick_push (vr);
>       }
> --- gcc/sreal.h.jj	2016-01-04 14:55:52.000000000 +0100
> +++ gcc/sreal.h	2016-09-22 14:09:38.882930801 +0200
> @@ -104,14 +104,20 @@ public:
>    /* Global minimum sreal can hold.  */
>    inline static sreal min ()
>    {
> -    static sreal min = sreal (-SREAL_MAX_SIG, SREAL_MAX_EXP);
> +    sreal min;
> +    /* This never needs normalization.  */
> +    min.m_sig = -SREAL_MAX_SIG;
> +    min.m_exp = SREAL_MAX_EXP;
>      return min;
>    }
>  
>    /* Global minimum sreal can hold.  */
>    inline static sreal max ()
>    {
> -    static sreal max = sreal (SREAL_MAX_SIG, SREAL_MAX_EXP);
> +    sreal max;
> +    /* This never needs normalization.  */
> +    max.m_sig = SREAL_MAX_SIG;
> +    max.m_exp = SREAL_MAX_EXP;
>      return max;
>    }
>  
> --- gcc/tree-ssa-sccvn.c.jj	2016-09-20 15:43:09.000000000 +0200
> +++ gcc/tree-ssa-sccvn.c	2016-09-22 13:40:03.667886908 +0200
> @@ -1786,8 +1786,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree
>    gimple *def_stmt = SSA_NAME_DEF_STMT (vuse);
>    tree base = ao_ref_base (ref);
>    HOST_WIDE_INT offset, maxsize;
> -  static vec<vn_reference_op_s>
> -    lhs_ops = vNULL;
> +  static vec<vn_reference_op_s> lhs_ops;
>    ao_ref lhs_ref;
>    bool lhs_ref_ok = false;
>  
> --- gcc/cp/name-lookup.c.jj	2016-09-14 23:54:25.000000000 +0200
> +++ gcc/cp/name-lookup.c	2016-09-22 13:51:22.459102089 +0200
> @@ -6197,7 +6197,7 @@ store_binding (tree id, vec<cxx_saved_bi
>  static void
>  store_bindings (tree names, vec<cxx_saved_binding, va_gc> **old_bindings)
>  {
> -  static vec<tree> bindings_need_stored = vNULL;
> +  static vec<tree> bindings_need_stored;
>    tree t, id;
>    size_t i;
>  
> @@ -6233,7 +6233,7 @@ static void
>  store_class_bindings (vec<cp_class_binding, va_gc> *names,
>  		      vec<cxx_saved_binding, va_gc> **old_bindings)
>  {
> -  static vec<tree> bindings_need_stored = vNULL;
> +  static vec<tree> bindings_need_stored;
>    size_t i;
>    cp_class_binding *cb;
>  
> 
> 	Jakub
> 
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)


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