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? 2016-09-22 Jakub Jelinek <ja...@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