diff options
author | Martin Jambor <mjambor@suse.cz> | 2018-04-17 10:48:41 +0200 |
---|---|---|
committer | Martin Jambor <jamborm@gcc.gnu.org> | 2018-04-17 10:48:41 +0200 |
commit | 5bf31c642ec176701629edc19504b79be3c12ee5 (patch) | |
tree | 7c5d23f3669faed876def088a0135a7f05806c10 /gcc | |
parent | 1236cd666661babbcf37820e8e2118e39f476632 (diff) | |
download | gcc-5bf31c642ec176701629edc19504b79be3c12ee5.zip gcc-5bf31c642ec176701629edc19504b79be3c12ee5.tar.gz gcc-5bf31c642ec176701629edc19504b79be3c12ee5.tar.bz2 |
Call expand_all_artificial_thunks in ipa-cp if necessary
2018-04-17 Martin Jambor <mjambor@suse.cz>
PR ipa/85421
* ipa-cp.c (create_specialized_node): Call
expand_all_artificial_thunks if necessary.
testsuite/
* g++.dg/ipa/pr85421.C: New test.
From-SVN: r259432
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/ipa-cp.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ipa/pr85421.C | 131 |
4 files changed, 145 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 186665e..21966a3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2018-04-17 Martin Jambor <mjambor@suse.cz> + + PR ipa/85421 + * ipa-cp.c (create_specialized_node): Call + expand_all_artificial_thunks if necessary. + 2018-04-17 Martin Liska <mliska@suse.cz> PR lto/85405 diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index b2627ff..4e0e20a 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -3863,6 +3863,7 @@ create_specialized_node (struct cgraph_node *node, new_node = node->create_virtual_clone (callers, replace_trees, args_to_skip, "constprop"); + bool have_self_recursive_calls = !self_recursive_calls.is_empty (); for (unsigned j = 0; j < self_recursive_calls.length (); j++) { cgraph_edge *cs = next_edge_clone[self_recursive_calls[j]->uid]; @@ -3870,6 +3871,8 @@ create_specialized_node (struct cgraph_node *node, gcc_assert (cs->caller == new_node); cs->redirect_callee_duplicating_thunks (new_node); } + if (have_self_recursive_calls) + new_node->expand_all_artificial_thunks (); ipa_set_node_agg_value_chain (new_node, aggvals); for (av = aggvals; av; av = av->next) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d1d1560..9e44409 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-04-17 Martin Jambor <mjambor@suse.cz> + + PR ipa/85421 + * g++.dg/ipa/pr85421.C: New test. + 2018-04-17 Martin Liska <mliska@suse.cz> PR lto/85405 diff --git a/gcc/testsuite/g++.dg/ipa/pr85421.C b/gcc/testsuite/g++.dg/ipa/pr85421.C new file mode 100644 index 0000000..517d99a --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr85421.C @@ -0,0 +1,131 @@ +// { dg-do compile } +// { dg-options "-O3 -std=gnu++1y -w" } + +namespace { +template <typename b> b c(b); +template <typename d, typename, template <typename> class> struct f { + using g = d; +}; +template <typename d, template <typename> class aa> using h = f<d, void, aa>; +template <typename d, template <typename> class aa> +using i = typename h<d, aa>::g; +template <typename b> struct j { typedef b k; }; +} // namespace +namespace l { +template <typename b> class m { +public: + typedef b k; +}; +} // namespace l +namespace a { +template <typename b> using n = l::m<b>; +template <typename b> class ac : public n<b> {}; +struct s { + template <typename b> using ad = typename b::e; +}; +template <typename o> struct p : s { + typedef typename o::k k; + using ag = i<k *, ad>; +}; +} // namespace a +namespace l { +template <typename o> struct t : a::p<o> {}; +} // namespace l +namespace a { +template <bool> struct al { + template <typename am> static void an(am ao, am) { c(*ao); } +}; +template <typename am> void aq(am ao, am ap) { + typedef typename j<am>::k ar; + al<__has_trivial_destructor(ar)>::an(ao, ap); +} +namespace { +typedef char au; +} +} // namespace a +typedef char av; +typedef int aw; +typedef av ay; +typedef aw az; +namespace a { +template <typename, typename o> struct ba { + typedef typename l::t<o>::ag ag; + struct { + ag bb; + ag bc; + } bd; +}; +template <typename b, typename o = ac<b>> class be : ba<b, o> { + typedef ba<b, o> bf; + typedef typename bf::ag ag; + +public: + void bh() { bi(this->bd.bb); } + void bi(ag bj) { aq(bj, this->bd.bc); } +}; +} // namespace a +namespace bk { +enum bl {}; +enum bn { bo }; +class q { +public: + static a::au bp(bn); + static bool bq(a::au *br, bn g) { return bs(br, g); } + static bl bs(a::au *br, bn g) { + if (br) { + auto bt = bp(g); + if (bt) + return bl(); + } + } +}; +template <typename, typename> class bu {}; +} // namespace bk +namespace bv { +namespace bw { +class bx; +} +} // namespace bv +namespace bk { +enum by { bz }; +struct ca; +class cb { +public: + class cc { + public: + virtual void cd(by) = 0; + }; + virtual bu<ca, by> e(); + cc *cf; +}; +class cg { +public: + ~cg() { q::bq(ch, bo); } + a::au *ch; +}; +class ci { + cg cj; +}; +namespace ck { +enum cl : ay; +} +class r : ci {}; +class cn { +public: + ck::cl co(); +}; +by cp(ck::cl); +class cq : cb, cb::cc { + bu<ca, by> ce(bv::bw::bx &, az) noexcept; + void cd(by); + void cr(bv::bw::bx &, az, cb::cc *) noexcept; + cn cs; + a::be<r> ct; +}; +} // namespace bk +using bv::bw::bx; +namespace bk { +bu<ca, by> cq::ce(bx &, az) noexcept { ct.bh(); } +void cq::cr(bx &, az, cb::cc *) noexcept { cd(bz); } +void cq::cd(by) { cf->cd(cp(cs.co())); } +} // namespace bk |