aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2019-11-13 22:02:11 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2019-11-13 21:02:11 +0000
commitb914768c1968d924d77bbe3f4e707c6105f3682c (patch)
tree8f86df5d2117969032167f987ff195a4f553fe26 /gcc
parent7b34a284cab5d533552c1df995a88f7167d243bd (diff)
downloadgcc-b914768c1968d924d77bbe3f4e707c6105f3682c.zip
gcc-b914768c1968d924d77bbe3f4e707c6105f3682c.tar.gz
gcc-b914768c1968d924d77bbe3f4e707c6105f3682c.tar.bz2
re PR ipa/92421 (ICE in inline_small_functions, at ipa-inline.c:2001 since r277759)
PR c++/92421 * ipa-prop.c (update_indirect_edges_after_inlining): Mark parameter as used. * ipa-inline.c (recursive_inlining): Reset node cache after inlining. (inline_small_functions): Remove checking ifdef. * ipa-inline-analysis.c (do_estimate_edge_time): Verify cache consistency. * g++.dg/torture/pr92421.C: New testcase. From-SVN: r278159
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/ipa-inline-analysis.c13
-rw-r--r--gcc/ipa-inline.c10
-rw-r--r--gcc/ipa-prop.c5
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/torture/pr92421.C174
6 files changed, 213 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6d8e7c6..42229be 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,16 @@
2019-11-13 Jan Hubicka <hubicka@ucw.cz>
+ PR c++/92421
+ * ipa-prop.c (update_indirect_edges_after_inlining):
+ Mark parameter as used.
+ * ipa-inline.c (recursive_inlining): Reset node cache
+ after inlining.
+ (inline_small_functions): Remove checking ifdef.
+ * ipa-inline-analysis.c (do_estimate_edge_time): Verify
+ cache consistency.
+
+2019-11-13 Jan Hubicka <hubicka@ucw.cz>
+
PR ipa/92498
* ipa-profile.c (check_argument_count): Do not ICE when descriptors
is NULL.
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
index 2acb2be..b45063b 100644
--- a/gcc/ipa-inline-analysis.c
+++ b/gcc/ipa-inline-analysis.c
@@ -210,6 +210,19 @@ do_estimate_edge_time (struct cgraph_edge *edge)
time = e->entry.time;
nonspec_time = e->entry.nonspec_time;
hints = e->entry.hints;
+ if (flag_checking)
+ {
+ sreal chk_time, chk_nonspec_time;
+ int chk_size, chk_min_size;
+
+ ipa_hints chk_hints;
+ ctx.estimate_size_and_time (&chk_size, &chk_min_size,
+ &chk_time, &chk_nonspec_time,
+ &chk_hints);
+ gcc_assert (chk_size == size && chk_time == time
+ && chk_nonspec_time == nonspec_time
+ && chk_hints == hints);
+ }
}
else
{
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index f3e880c..78ec0ec 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -1633,6 +1633,7 @@ recursive_inlining (struct cgraph_edge *edge,
}
inline_call (curr, false, new_edges, &overall_size, true);
+ reset_node_cache (node);
lookup_recursive_calls (node, curr->callee, &heap);
n++;
}
@@ -1982,11 +1983,10 @@ inline_small_functions (void)
if (!edge->inline_failed || !edge->callee->analyzed)
continue;
-#if CHECKING_P
/* Be sure that caches are maintained consistent.
This check is affected by scaling roundoff errors when compiling for
IPA this we skip it in that case. */
- if (!edge->callee->count.ipa_p ()
+ if (flag_checking && !edge->callee->count.ipa_p ()
&& (!max_count.initialized_p () || !max_count.nonzero_p ()))
{
sreal cached_badness = edge_badness (edge, false);
@@ -1997,6 +1997,9 @@ inline_small_functions (void)
if (edge_growth_cache != NULL)
edge_growth_cache->remove (edge);
+ reset_node_cache (edge->caller->inlined_to
+ ? edge->caller->inlined_to
+ : edge->caller);
gcc_assert (old_size_est == estimate_edge_size (edge));
gcc_assert (old_time_est == estimate_edge_time (edge));
/* FIXME:
@@ -2021,9 +2024,6 @@ inline_small_functions (void)
}
else
current_badness = edge_badness (edge, false);
-#else
- current_badness = edge_badness (edge, false);
-#endif
if (current_badness != badness)
{
if (edge_heap.min () && current_badness > edge_heap.min_key ())
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 312b2108..2cb8c58 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -3537,6 +3537,11 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
if (ici->polymorphic
&& !ipa_get_jf_ancestor_type_preserved (jfunc))
ici->vptr_changed = true;
+ ipa_set_param_used_by_indirect_call (new_root_info,
+ ici->param_index, true);
+ if (ici->polymorphic)
+ ipa_set_param_used_by_polymorphic_call (new_root_info,
+ ici->param_index, true);
}
}
else
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 33c16d5..3778788 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2019-11-13 Jan Hubicka <hubicka@ucw.cz>
+
+ PR c++/92421
+ * g++.dg/torture/pr92421.C: New testcase.
+
2019-11-13 David Edelsohn <dje.gcc@gmail.com>
* gcc.target/powerpc/pr92090.c: Limit -mbig to powerpc64le-*-*.
diff --git a/gcc/testsuite/g++.dg/torture/pr92421.C b/gcc/testsuite/g++.dg/torture/pr92421.C
new file mode 100644
index 0000000..7adf53f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr92421.C
@@ -0,0 +1,174 @@
+/* { dg-do compile } */
+typedef long a;
+void *b, *c;
+template <typename, typename> class d {};
+template <typename e, typename f> bool operator!=(d<e, f>, d<e, f>);
+class g {
+public:
+ g(char *);
+};
+class j {
+public:
+ j();
+ void h();
+ void i();
+ void aj();
+};
+class m {
+public:
+ m(bool);
+};
+class n {
+public:
+ operator a();
+};
+class o {
+public:
+ long am();
+};
+class H {
+public:
+ class p {};
+ virtual bool accept(const char *, unsigned long, p *, bool);
+};
+class q : H {
+public:
+ class r {
+ public:
+ enum at { au, av, aw };
+ };
+ enum { ax };
+ virtual void ay(char *, int, const char *, r::at, char *);
+ virtual bool az(const g &, unsigned = ax);
+ virtual bool ba(const int &, p *, bool);
+ void bb(char *bc, long bd, char *, long be) {
+ class bf : public p {
+ public:
+ bf(long);
+ } bg(be);
+ accept(bc, bd, &bg, true);
+ }
+};
+class s {
+ q *bi;
+ bool bj();
+};
+template <class bk> class t : q {
+ bool accept(const char *, unsigned long bd, p *bg, bool) {
+ bool k(bp || bq), cl = false, err = false;
+ if (br)
+ ay("", 1, __func__, r::au, "");
+ if (bs)
+ ay("", 6, __func__, r::av, "");
+ char bt[1], cd[1];
+ long bu = sizeof(int) + bd, ce = sizeof(L) + bd;
+ char *bw = bu > sizeof(bt) ? new char : bt,
+ *cf = ce > sizeof(cd) ? new char : cd;
+ __builtin___memcpy_chk(b, c, bd, 0);
+ a by[1];
+ int bz = 0;
+ u cb = *cc((int *)bw, true, by, &bz);
+ ay("", 1, __func__, r::aw, "");
+ if (bw != bt)
+ delete bw;
+ __builtin___memcpy_chk(b, c, bd, 0);
+ cb.ch.i();
+ bool ci = cj((L *)cf, bg);
+ bool atran = bq && bp && cb.ck;
+ if (atran && !ci && cm(&cb))
+ if (cn > co) {
+ int cp = cb.cq % 6;
+ v cs = *(ct + cp);
+ if (cu(&cs))
+ cl = true;
+ }
+ if (ci)
+ if (k)
+ cv.aj();
+ cv.h();
+ b = cc((int *)bw, false, by, &bz);
+ if (b)
+ if (cw(&cb, by, bz))
+ if (atran && bp && cx())
+ cv.aj();
+ if (cl)
+ if (k)
+ cv.aj();
+ cv.h();
+ int cp = cb.cq % 6;
+ v cs = *(ct + cp);
+ if (cy())
+ err = true;
+ O da = *(db + cp);
+ if (da.dc->am() > cs.dc->am() + cs.dd->am() + 1 && de(&da))
+ cv.aj();
+ return !err;
+ }
+ bool ba(const int &, p *, bool) {
+ d<int, int> kit, df;
+ while (kit != df)
+ ;
+ cx();
+ }
+ bool az(const g &, unsigned) {
+ t dj;
+ int cur;
+ while (cur) {
+ int dk, dl;
+ char dbuf;
+ dj.bb(&dbuf, dl, &dbuf, dk);
+ }
+ }
+ struct L {};
+ struct u {
+ j ch;
+ a cq;
+ bool ck;
+ };
+ struct v {
+ o *dd;
+ o *dc;
+ };
+ struct O {
+ o *dc;
+ };
+ bool cy();
+ bool cu(v *);
+ bool cj(L *, p *);
+ bool de(O *);
+ u *cc(int *, bool, a *, int *);
+ bool cw(u *, a *, int);
+ bool cx() {
+ dm.dn();
+ bool err = false;
+ if (dm.l())
+ err = true;
+ return !err;
+ }
+ bool cm(u *);
+ j cv;
+ int br;
+ bool bs;
+ bool bq;
+ bk dm;
+ a co;
+ n cn;
+ v ct[6];
+ O db[6];
+ bool bp;
+};
+class w : q {
+public:
+ void dn();
+ bool l() {
+ m(true);
+ if (br)
+ ay("", 1087, __func__, r::au, "");
+ return false;
+ }
+ int br;
+};
+bool s::bj() {
+ bi->az("");
+ new t<w>;
+}