diff options
author | Alexandre Oliva <aoliva@redhat.com> | 2011-01-19 22:07:14 +0000 |
---|---|---|
committer | Alexandre Oliva <aoliva@gcc.gnu.org> | 2011-01-19 22:07:14 +0000 |
commit | 23d5ed5dcf5305653fc67dddf0a2ea53ca81add6 (patch) | |
tree | cc4d61e9e6bc2658197fbb19d9f459bca47f0f94 | |
parent | 37d6a488a470eb9447ac51f434621ad979e5b4f3 (diff) | |
download | gcc-23d5ed5dcf5305653fc67dddf0a2ea53ca81add6.zip gcc-23d5ed5dcf5305653fc67dddf0a2ea53ca81add6.tar.gz gcc-23d5ed5dcf5305653fc67dddf0a2ea53ca81add6.tar.bz2 |
re PR debug/46240 (ice in maybe_register_def)
gcc/ChangeLog:
PR debug/46240
* tree-into-ssa.c (maybe_register_def): Do not attempt to add
debug bind stmt on merge edges.
gcc/testsuite/ChangeLog:
PR debug/46240
* g++.dg/debug/pr46240.cc: New.
From-SVN: r169035
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/debug/pr46240.cc | 172 | ||||
-rw-r--r-- | gcc/tree-into-ssa.c | 26 |
4 files changed, 204 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index af91c9a..fc8e90c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2011-01-19 Alexandre Oliva <aoliva@redhat.com> + PR debug/46240 + * tree-into-ssa.c (maybe_register_def): Do not attempt to add + debug bind stmt on merge edges. + +2011-01-19 Alexandre Oliva <aoliva@redhat.com> + PR debug/47079 PR debug/46724 * function.c (instantiate_expr): Instantiate incoming rtl of diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0962b70..332b1eb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-01-19 Alexandre Oliva <aoliva@redhat.com> + + PR debug/46240 + * g++.dg/debug/pr46240.cc: New. + 2011-01-19 Jakub Jelinek <jakub@redhat.com> PR c++/47303 diff --git a/gcc/testsuite/g++.dg/debug/pr46240.cc b/gcc/testsuite/g++.dg/debug/pr46240.cc new file mode 100644 index 0000000..c12a698 --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/pr46240.cc @@ -0,0 +1,172 @@ +// { dg-do compile } +// { dg-options "-O3 -g" } + +template <typename T> +T &max (T &a, T &b) +{ + if (a < b) return b; else return a; +} +int foo (double); +struct S +{ + struct T + { + int dims, count; + T (int, int) : dims (), count () {} + }; + T *rep; + S () {} + S (int r, int c) : rep (new T (r, c)) {} + ~S () { delete rep; } +}; +template <typename T> +struct U +{ + static T epsilon () throw (); +}; +template <class T> +struct V +{ + struct W + { + T * data; + int count; + W (int n) : data (new T[n]), count () {} + }; + V::W *rep; + S dimensions; + int slice_len; + V (S s) : rep (new V <T>::W (get_size (s))) {} + int capacity () { return slice_len; } + int get_size (S); +}; +template <class T> +struct Z : public V <T> +{ + Z () : V <T> (S (0, 0)) {} + Z (int r, int c) : V <T> (S (r, c)) {} +}; +template <class T> +struct A : public Z <T> +{ + A () : Z <T> () {} + A (int n, int m) : Z <T> (n, m) {} +}; +template <class T> +struct B : public V <T> +{ +}; +struct C : public A <double> +{ + C () : A <double> () {} + C (int r, int c) : A <double> (r, c) {} +}; +struct D : public B <double> +{ +}; +template <class T> +struct E +{ +}; +template <class T> +struct G : public E <T> +{ +}; +struct H : public G <double> +{ +}; +template <class R> +struct I +{ + R scl, sum; + void accum (R val) + { + R t = __builtin_fabs (val); + if (scl == t) + sum += 1; + } + operator R () { __builtin_sqrt (sum); return R (); } +}; +template <class R> +struct J +{ + template < class U > void accum (U val) {} + operator R () { return R (); } +}; +template <class R> +struct K +{ + R max; + template <class U> void accum (U val) + { + double z = __builtin_fabs (val); + max = ::max (max, z); + } + operator R () { return max; } +}; +template <class R> +struct L +{ + unsigned num; + template <class U> void accum (U) {} + operator R () { return num; } +}; +template <class T, class R, class S> +void bar (V <T> &v, R &res, S acc) +{ + for (int i = 0; i < v.capacity (); i++) + acc.accum ((i)); + res = acc; +} +template <class T, class R> +void bar (B <T> &v, R) +{ + R res; + bar (v, res, I <R> ()); +} +template <class T, class R> +R bar (A <T> &v, R p) +{ + R res; + if (p == 2) + bar (v, res, I <R> ()); + else if (p == 1) + bar (v, res, J <R> ()); + else if (p == sizeof (float) ? (p) : foo (p)) + { + if (p > 0) + bar (v, res, K <R> ()); + } + else if (p == 0) + bar (v, res, L <R> ()); + return res; +} +template <class CT, class VectorT, class R> +void +baz (CT m, R p, R tol, int maxiter, VectorT) +{ + VectorT y (0, 0), z (0, 1); + R q = 0; + R gamma = 0, gamma1 = 0; + gamma = bar (y, p); + (void) (bar (z, q) <= (gamma1 <= gamma)); +} +int a = 100; +template <class CT, class VectorT, class R> +void +test (CT m, R p, VectorT) +{ + VectorT x; + R sqrteps (U <R>::epsilon ()); + baz (m, p, sqrteps, a, x); +} +void +fn (D x, double p) +{ + bar (x, p); +} +void +fn (H x, double p) +{ + test (x, p, C ()); +} diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c index 8d31fe7..c425586 100644 --- a/gcc/tree-into-ssa.c +++ b/gcc/tree-into-ssa.c @@ -1869,11 +1869,27 @@ maybe_register_def (def_operand_p def_p, gimple stmt, gcc_assert (!ef); ef = e; } - gcc_assert (ef - && single_pred_p (ef->dest) - && !phi_nodes (ef->dest) - && ef->dest != EXIT_BLOCK_PTR); - gsi_insert_on_edge_immediate (ef, note); + /* If there are other predecessors to ef->dest, then + there must be PHI nodes for the modified + variable, and therefore there will be debug bind + stmts after the PHI nodes. The debug bind notes + we'd insert would force the creation of a new + block (diverging codegen) and be redundant with + the post-PHI bind stmts, so don't add them. + + As for the exit edge, there wouldn't be redundant + bind stmts, but there wouldn't be a PC to bind + them to either, so avoid diverging the CFG. */ + if (ef && single_pred_p (ef->dest) + && ef->dest != EXIT_BLOCK_PTR) + { + /* If there were PHI nodes in the node, we'd + have to make sure the value we're binding + doesn't need rewriting. But there shouldn't + be PHI nodes in a single-predecessor block, + so we just add the note. */ + gsi_insert_on_edge_immediate (ef, note); + } } else gsi_insert_after (&gsi, note, GSI_SAME_STMT); |