diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/fwprop.c | 3 | ||||
-rw-r--r-- | gcc/rtl-ssa/accesses.cc | 15 | ||||
-rw-r--r-- | gcc/rtl-ssa/functions.h | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/pr100303.C | 112 |
4 files changed, 129 insertions, 8 deletions
diff --git a/gcc/fwprop.c b/gcc/fwprop.c index d720367..73284a7 100644 --- a/gcc/fwprop.c +++ b/gcc/fwprop.c @@ -606,7 +606,8 @@ try_fwprop_subst (use_info *use, set_info *def, if (def_insn->bb () != use_insn->bb ()) { src_uses = crtl->ssa->make_uses_available (attempt, src_uses, - use_insn->bb ()); + use_insn->bb (), + use_insn->is_debug_insn ()); if (!src_uses.is_valid ()) return false; } diff --git a/gcc/rtl-ssa/accesses.cc b/gcc/rtl-ssa/accesses.cc index de3a29e..a55cc88 100644 --- a/gcc/rtl-ssa/accesses.cc +++ b/gcc/rtl-ssa/accesses.cc @@ -1242,7 +1242,10 @@ function_info::insert_temp_clobber (obstack_watermark &watermark, } // A subroutine of make_uses_available. Try to make USE's definition -// available at the head of BB. On success: +// available at the head of BB. WILL_BE_DEBUG_USE is true if the +// definition will be used only in debug instructions. +// +// On success: // // - If the use would have the same def () as USE, return USE. // @@ -1254,7 +1257,8 @@ function_info::insert_temp_clobber (obstack_watermark &watermark, // // Return null on failure. use_info * -function_info::make_use_available (use_info *use, bb_info *bb) +function_info::make_use_available (use_info *use, bb_info *bb, + bool will_be_debug_use) { set_info *def = use->def (); if (!def) @@ -1270,7 +1274,7 @@ function_info::make_use_available (use_info *use, bb_info *bb) && single_pred (cfg_bb) == use_bb->cfg_bb () && remains_available_on_exit (def, use_bb)) { - if (def->ebb () == bb->ebb ()) + if (def->ebb () == bb->ebb () || will_be_debug_use) return use; resource_info resource = use->resource (); @@ -1314,7 +1318,8 @@ function_info::make_use_available (use_info *use, bb_info *bb) // See the comment above the declaration. use_array function_info::make_uses_available (obstack_watermark &watermark, - use_array uses, bb_info *bb) + use_array uses, bb_info *bb, + bool will_be_debug_uses) { unsigned int num_uses = uses.size (); if (num_uses == 0) @@ -1323,7 +1328,7 @@ function_info::make_uses_available (obstack_watermark &watermark, auto **new_uses = XOBNEWVEC (watermark, access_info *, num_uses); for (unsigned int i = 0; i < num_uses; ++i) { - use_info *use = make_use_available (uses[i], bb); + use_info *use = make_use_available (uses[i], bb, will_be_debug_uses); if (!use) return use_array (access_array::invalid ()); new_uses[i] = use; diff --git a/gcc/rtl-ssa/functions.h b/gcc/rtl-ssa/functions.h index 58755d7..cf68c94 100644 --- a/gcc/rtl-ssa/functions.h +++ b/gcc/rtl-ssa/functions.h @@ -126,8 +126,11 @@ public: // If the operation fails, return an invalid use_array. // // WATERMARK is a watermark returned by new_change_attempt (). + // WILL_BE_DEBUG_USES is true if the returned use_array will be + // used only for debug instructions. use_array make_uses_available (obstack_watermark &watermark, - use_array uses, bb_info *bb); + use_array uses, bb_info *bb, + bool will_be_debug_uses); // If CHANGE doesn't already clobber REGNO, try to add such a clobber, // limiting the movement range in order to make the clobber valid. @@ -196,7 +199,7 @@ private: def_node *need_def_node (def_info *); def_splay_tree need_def_splay_tree (def_info *); - use_info *make_use_available (use_info *, bb_info *); + use_info *make_use_available (use_info *, bb_info *, bool); def_array insert_temp_clobber (obstack_watermark &, insn_info *, unsigned int, def_array); diff --git a/gcc/testsuite/g++.dg/torture/pr100303.C b/gcc/testsuite/g++.dg/torture/pr100303.C new file mode 100644 index 0000000..5af9412 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr100303.C @@ -0,0 +1,112 @@ +/* { dg-additional-options "-w -fcompare-debug -fno-dce -ftracer" } */ + +template < typename _T1 > struct pair +{ + _T1 first; + int second; +}; +struct __aligned_membuf +{ + void _M_ptr (); +}; +struct _Rb_tree_node_base +{ + typedef _Rb_tree_node_base *_Base_ptr; +}; +struct _Rb_tree_node:_Rb_tree_node_base +{ + __aligned_membuf _M_storage; + void _M_valptr () + { + _M_storage._M_ptr (); + } +}; +struct _Rb_tree_iterator +{ + typedef _Rb_tree_node_base::_Base_ptr _Base_ptr; + _Rb_tree_iterator (_Base_ptr __x):_M_node (__x) + { + } + void operator* () + { + static_cast < _Rb_tree_node * >(_M_node)->_M_valptr (); + } + friend bool operator== (_Rb_tree_iterator __x, _Rb_tree_iterator) + { + return __x._M_node; + } + _Base_ptr _M_node; +}; + +template < typename, typename, typename, typename, typename = + int >class _Rb_tree +{ + typedef _Rb_tree_node_base *_Base_ptr; +public: + pair < _Base_ptr > _M_get_insert_hint_unique_pos (int); + void _M_insert_node (_Base_ptr, int); + template < typename ... _Args > + _Rb_tree_iterator _M_emplace_hint_unique (_Args && ...); + _Rb_tree_iterator lower_bound () + { + _Rb_tree_node_base __trans_tmp_2; + return &__trans_tmp_2; + } +}; +template < typename _Key, typename _Val, typename _KeyOfValue, + typename _Compare, + typename _Alloc > template < typename ... _Args > + _Rb_tree_iterator _Rb_tree < _Key, _Val, _KeyOfValue, _Compare, + _Alloc >::_M_emplace_hint_unique (_Args && ...) +{ + int __z; + try + { + auto __res = _M_get_insert_hint_unique_pos (0); + _Rb_tree_node_base *__res_1; + if (__res_1) + _M_insert_node (__res.first, __z); + return __res.first; + } + catch ( ...) + { + } +} + +class map +{ + _Rb_tree < int, int, int, int >_M_t; +public: + _Rb_tree_iterator end (); + void operator[] (int) + { + _Rb_tree_iterator __i = lower_bound (); + if (__i == end ()) + __i = _M_t._M_emplace_hint_unique (__i); + *__i; + } + _Rb_tree_iterator lower_bound () + { + return _M_t.lower_bound (); + } +}; + +class FlowStat +{ +public: + int FlowStat_flow; + FlowStat () + { + shares[FlowStat_flow]; + } + map shares; +}; + +class LinkGraphJob +{ + ~LinkGraphJob (); +}; +LinkGraphJob::~LinkGraphJob () +{ + FlowStat (); +} |