Recompute domonators in DSE when removing dead edges (PR rtl-optimization/91164)

Message ID 20190716091308.GS2125@tucnak
State New
Headers show
Series
  • Recompute domonators in DSE when removing dead edges (PR rtl-optimization/91164)
Related show

Commit Message

Jakub Jelinek July 16, 2019, 9:13 a.m.
Hi!

When DSEing stmts with EH edges, we can invalidate through that dominator
info.  Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
ok for trunk?

2019-07-16  Jakub Jelinek  <jakub@redhat.com>

	PR rtl-optimization/91164
	* dse.c (rest_of_handle_dse): If dead edges have been purged,
	invalidate dominance info.

	* g++.dg/opt/pr91164.C: New test.


	Jakub

Comments

Richard Biener July 16, 2019, 10:53 a.m. | #1
On Tue, 16 Jul 2019, Jakub Jelinek wrote:

> Hi!

> 

> When DSEing stmts with EH edges, we can invalidate through that dominator

> info.  Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,

> ok for trunk?


OK.

Richard.

> 2019-07-16  Jakub Jelinek  <jakub@redhat.com>

> 

> 	PR rtl-optimization/91164

> 	* dse.c (rest_of_handle_dse): If dead edges have been purged,

> 	invalidate dominance info.

> 

> 	* g++.dg/opt/pr91164.C: New test.

> 

> --- gcc/dse.c.jj	2019-07-10 15:52:56.753588824 +0200

> +++ gcc/dse.c	2019-07-15 12:26:05.264010493 +0200

> @@ -3621,7 +3621,10 @@ rest_of_handle_dse (void)

>    if ((locally_deleted || globally_deleted)

>        && cfun->can_throw_non_call_exceptions

>        && purge_all_dead_edges ())

> -    cleanup_cfg (0);

> +    {

> +      free_dominance_info (CDI_DOMINATORS);

> +      cleanup_cfg (0);

> +    }

>  

>    return 0;

>  }

> --- gcc/testsuite/g++.dg/opt/pr91164.C.jj	2019-07-15 13:03:56.449304956 +0200

> +++ gcc/testsuite/g++.dg/opt/pr91164.C	2019-07-15 13:04:58.641354884 +0200

> @@ -0,0 +1,89 @@

> +// PR rtl-optimization/91164

> +// { dg-do compile { target c++11 } }

> +// { dg-options "-O2 -fdelete-dead-exceptions -fnon-call-exceptions -fno-rerun-cse-after-loop -fno-tree-forwprop" }

> +

> +template <typename, typename = int> class b;

> +template <int v> struct d { static constexpr int e = v; };

> +template <bool, typename f> using g = f;

> +struct h { template <typename i> using j = i; };

> +template <typename, typename f> using k = h::j<f>;

> +void *operator new(__SIZE_TYPE__, void *);

> +struct l { l(); };

> +struct m;

> +template <typename n> n aa(m);

> +struct o { template <typename> using ab = l; };

> +template <typename, typename> struct b {

> +  struct q : o::ab<int> { q(int, l = l()) : p() {} int p; } ac;

> +  void ad();

> +  b() : ac(0) {}

> +  ~b() { bool r = ac.p == 0; if (r) ad(); }

> +  const wchar_t *ae();

> +};

> +struct m {};

> +struct t { virtual void f(); };

> +struct u { l a; };

> +struct af : t {

> +  struct ag { ag(l); };

> +  af(l ah) : ai(ah) {}

> +  ag ai;

> +};

> +struct w {

> +  template <typename f, typename x> w(f, x y) { new (0) af(y.a); }

> +};

> +struct z {

> +  using aj = int;

> +  template <typename x> z(x ah) : ak(al, ah) {}

> +  aj al;

> +  w ak;

> +};

> +struct am : z { template <typename x> am(x ah) : z(ah) {} };

> +template <typename, typename x> am an(x) { return u{}; }

> +template <typename> am ao() { return an<int>(l()); }

> +struct ap {

> +  k<int, int> aq;

> +  k<int, int> ar;

> +  k<int, int> as;

> +};

> +struct at { ap a; long au; ap av; ap aw; };

> +struct ax { at c; ax() : c() {} };

> +enum ay : int;

> +ay az, ba;

> +struct bb { bb(wchar_t *, wchar_t *, ay, m); };

> +template <typename bc> struct bd {

> +  typedef typename bc::be *bf;

> +  bd(bf, bf, const typename bc::bg &, ay);

> +  ay bh;

> +  bb bi;

> +  am bj;

> +  typename bc::bk e;

> +  ax bl;

> +  int bm;

> +};

> +template <typename, typename> using bn = g<d<false>::e, am>;

> +template <typename bc>

> +bd<bc>::bd(bf ah, bf y, const typename bc::bg &bu, ay)

> +    : bi(ah, y, bh, bu), bj(ao<bc>()), bm(aa<int>(bu)) {}

> +struct bt { typedef wchar_t be; typedef b<be> bk; typedef m bg; };

> +template <typename bc, typename bo> bn<bo, bc> bar();

> +template <typename bc, typename bo> bn<bo, bc> bq(bo) {

> +  typename bc::bg bp;

> +  auto bs = nullptr;

> +  using br = bd<bc>;

> +  br(bs, bs, bp, ba);

> +  return bar<bc, bo>();

> +}

> +struct bw {

> +  bw();

> +  template <typename bv, typename x> void assign(b<bv, x> ah) {

> +    const wchar_t by = *ah.ae();

> +    bw(&by, ah.ae(), bp, az);

> +  }

> +  template <typename bo> bw(bo, bo y, m, ay) : automaton(bq<bt>(y)) {}

> +  m bp;

> +  am automaton;

> +};

> +void bx() {

> +  b<wchar_t> s;

> +  bw ca;

> +  ca.assign(s);

> +}

> 

> 	Jakub

> 


-- 
Richard Biener <rguenther@suse.de>
SUSE Linux GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany;
GF: Felix Imend├Ârffer, Mary Higgins, Sri Rasiah; HRB 21284 (AG N├╝rnberg)

Patch

--- gcc/dse.c.jj	2019-07-10 15:52:56.753588824 +0200
+++ gcc/dse.c	2019-07-15 12:26:05.264010493 +0200
@@ -3621,7 +3621,10 @@  rest_of_handle_dse (void)
   if ((locally_deleted || globally_deleted)
       && cfun->can_throw_non_call_exceptions
       && purge_all_dead_edges ())
-    cleanup_cfg (0);
+    {
+      free_dominance_info (CDI_DOMINATORS);
+      cleanup_cfg (0);
+    }
 
   return 0;
 }
--- gcc/testsuite/g++.dg/opt/pr91164.C.jj	2019-07-15 13:03:56.449304956 +0200
+++ gcc/testsuite/g++.dg/opt/pr91164.C	2019-07-15 13:04:58.641354884 +0200
@@ -0,0 +1,89 @@ 
+// PR rtl-optimization/91164
+// { dg-do compile { target c++11 } }
+// { dg-options "-O2 -fdelete-dead-exceptions -fnon-call-exceptions -fno-rerun-cse-after-loop -fno-tree-forwprop" }
+
+template <typename, typename = int> class b;
+template <int v> struct d { static constexpr int e = v; };
+template <bool, typename f> using g = f;
+struct h { template <typename i> using j = i; };
+template <typename, typename f> using k = h::j<f>;
+void *operator new(__SIZE_TYPE__, void *);
+struct l { l(); };
+struct m;
+template <typename n> n aa(m);
+struct o { template <typename> using ab = l; };
+template <typename, typename> struct b {
+  struct q : o::ab<int> { q(int, l = l()) : p() {} int p; } ac;
+  void ad();
+  b() : ac(0) {}
+  ~b() { bool r = ac.p == 0; if (r) ad(); }
+  const wchar_t *ae();
+};
+struct m {};
+struct t { virtual void f(); };
+struct u { l a; };
+struct af : t {
+  struct ag { ag(l); };
+  af(l ah) : ai(ah) {}
+  ag ai;
+};
+struct w {
+  template <typename f, typename x> w(f, x y) { new (0) af(y.a); }
+};
+struct z {
+  using aj = int;
+  template <typename x> z(x ah) : ak(al, ah) {}
+  aj al;
+  w ak;
+};
+struct am : z { template <typename x> am(x ah) : z(ah) {} };
+template <typename, typename x> am an(x) { return u{}; }
+template <typename> am ao() { return an<int>(l()); }
+struct ap {
+  k<int, int> aq;
+  k<int, int> ar;
+  k<int, int> as;
+};
+struct at { ap a; long au; ap av; ap aw; };
+struct ax { at c; ax() : c() {} };
+enum ay : int;
+ay az, ba;
+struct bb { bb(wchar_t *, wchar_t *, ay, m); };
+template <typename bc> struct bd {
+  typedef typename bc::be *bf;
+  bd(bf, bf, const typename bc::bg &, ay);
+  ay bh;
+  bb bi;
+  am bj;
+  typename bc::bk e;
+  ax bl;
+  int bm;
+};
+template <typename, typename> using bn = g<d<false>::e, am>;
+template <typename bc>
+bd<bc>::bd(bf ah, bf y, const typename bc::bg &bu, ay)
+    : bi(ah, y, bh, bu), bj(ao<bc>()), bm(aa<int>(bu)) {}
+struct bt { typedef wchar_t be; typedef b<be> bk; typedef m bg; };
+template <typename bc, typename bo> bn<bo, bc> bar();
+template <typename bc, typename bo> bn<bo, bc> bq(bo) {
+  typename bc::bg bp;
+  auto bs = nullptr;
+  using br = bd<bc>;
+  br(bs, bs, bp, ba);
+  return bar<bc, bo>();
+}
+struct bw {
+  bw();
+  template <typename bv, typename x> void assign(b<bv, x> ah) {
+    const wchar_t by = *ah.ae();
+    bw(&by, ah.ae(), bp, az);
+  }
+  template <typename bo> bw(bo, bo y, m, ay) : automaton(bq<bt>(y)) {}
+  m bp;
+  am automaton;
+};
+void bx() {
+  b<wchar_t> s;
+  bw ca;
+  ca.assign(s);
+}