re PR middle-end/54838 (ICE: in merge_latch_edges, at cfgloop.c:678 with -ftracer)
2012-12-18 Richard Biener <rguenther@suse.de> PR middle-end/54838 * cfgloopmanip.c (fix_loop_structure): Re-discover latch edges first and mark loops for removal if no latch edges remain. Properly re-create LOOPS_HAVE_FALLTHRU_PREHEADERS. * loop-init.c (loop_optimizer_finalize): Set LOOPS_MAY_HAVE_MULTIPLE_LATCHES. * g++.dg/torture/pr54838.C: New testcase. From-SVN: r194582
This commit is contained in:
parent
0b8ca8fefe
commit
867fdd05e4
5 changed files with 159 additions and 24 deletions
|
@ -1,3 +1,12 @@
|
|||
2012-12-18 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR middle-end/54838
|
||||
* cfgloopmanip.c (fix_loop_structure): Re-discover latch
|
||||
edges first and mark loops for removal if no latch edges remain.
|
||||
Properly re-create LOOPS_HAVE_FALLTHRU_PREHEADERS.
|
||||
* loop-init.c (loop_optimizer_finalize): Set
|
||||
LOOPS_MAY_HAVE_MULTIPLE_LATCHES.
|
||||
|
||||
2012-12-18 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/55555
|
||||
|
|
|
@ -1793,6 +1793,40 @@ fix_loop_structure (bitmap changed_bbs)
|
|||
record_exits = true;
|
||||
}
|
||||
|
||||
/* First re-compute loop latches. */
|
||||
FOR_EACH_LOOP (li, loop, 0)
|
||||
{
|
||||
edge_iterator ei;
|
||||
edge e, first_latch = NULL, latch = NULL;
|
||||
|
||||
if (!loop->header)
|
||||
continue;
|
||||
|
||||
FOR_EACH_EDGE (e, ei, loop->header->preds)
|
||||
if (dominated_by_p (CDI_DOMINATORS, e->src, loop->header))
|
||||
{
|
||||
if (!first_latch)
|
||||
first_latch = latch = e;
|
||||
else
|
||||
{
|
||||
latch = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* If there was no latch, schedule the loop for removal. */
|
||||
if (!first_latch)
|
||||
loop->header = NULL;
|
||||
/* If there was a single latch and it belongs to the loop of the
|
||||
header, record it. */
|
||||
else if (latch
|
||||
&& latch->src->loop_father == loop)
|
||||
loop->latch = latch->src;
|
||||
/* Otherwise there are multiple latches which are eventually
|
||||
disambiguated below. */
|
||||
else
|
||||
loop->latch = NULL;
|
||||
}
|
||||
|
||||
/* Remove the dead loops from structures. We start from the innermost
|
||||
loops, so that when we remove the loops, we know that the loops inside
|
||||
are preserved, and do not waste time relinking loops that will be
|
||||
|
@ -1849,34 +1883,18 @@ fix_loop_structure (bitmap changed_bbs)
|
|||
}
|
||||
}
|
||||
|
||||
/* Then re-compute the single latch if there is one. */
|
||||
FOR_EACH_LOOP (li, loop, 0)
|
||||
{
|
||||
edge_iterator ei;
|
||||
edge e, latch = NULL;
|
||||
FOR_EACH_EDGE (e, ei, loop->header->preds)
|
||||
if (dominated_by_p (CDI_DOMINATORS, e->src, loop->header))
|
||||
{
|
||||
if (!latch)
|
||||
latch = e;
|
||||
else
|
||||
{
|
||||
latch = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (latch
|
||||
&& latch->src->loop_father == loop)
|
||||
loop->latch = latch->src;
|
||||
else
|
||||
loop->latch = NULL;
|
||||
}
|
||||
|
||||
if (!loops_state_satisfies_p (LOOPS_MAY_HAVE_MULTIPLE_LATCHES))
|
||||
disambiguate_loops_with_multiple_latches ();
|
||||
|
||||
if (loops_state_satisfies_p (LOOPS_HAVE_PREHEADERS))
|
||||
create_preheaders (CP_SIMPLE_PREHEADERS);
|
||||
{
|
||||
int cp_flags = CP_SIMPLE_PREHEADERS;
|
||||
|
||||
if (loops_state_satisfies_p (LOOPS_HAVE_FALLTHRU_PREHEADERS))
|
||||
cp_flags |= CP_FALLTHRU_PREHEADERS;
|
||||
|
||||
create_preheaders (cp_flags);
|
||||
}
|
||||
|
||||
if (loops_state_satisfies_p (LOOPS_HAVE_SIMPLE_LATCHES))
|
||||
force_single_succ_latches ();
|
||||
|
|
|
@ -133,6 +133,7 @@ loop_optimizer_finalize (void)
|
|||
| LOOPS_HAVE_PREHEADERS
|
||||
| LOOPS_HAVE_SIMPLE_LATCHES
|
||||
| LOOPS_HAVE_FALLTHRU_PREHEADERS);
|
||||
loops_state_set (LOOPS_MAY_HAVE_MULTIPLE_LATCHES);
|
||||
goto loop_fini_done;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2012-12-18 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR middle-end/54838
|
||||
* g++.dg/torture/pr54838.C: New testcase.
|
||||
|
||||
2012-12-18 Andreas Schwab <schwab@linux-m68k.org>
|
||||
|
||||
* lib/go.exp (go_link_flags): Add libatomic location to flags and
|
||||
|
|
102
gcc/testsuite/g++.dg/torture/pr54838.C
Normal file
102
gcc/testsuite/g++.dg/torture/pr54838.C
Normal file
|
@ -0,0 +1,102 @@
|
|||
// { dg-do compile }
|
||||
// { dg-options "-ftracer -fno-tree-dce -fno-tree-sra" }
|
||||
|
||||
struct bidirectional_iterator_tag
|
||||
{};
|
||||
struct random_access_iterator_tag:bidirectional_iterator_tag
|
||||
{};
|
||||
template < typename _Category, typename, typename _Distance, typename > struct iterator
|
||||
{
|
||||
typedef _Distance difference_type;
|
||||
};
|
||||
template < typename _Iterator > struct iterator_traits
|
||||
{
|
||||
typedef typename _Iterator::difference_type difference_type;
|
||||
};
|
||||
template < typename _Tp > struct iterator_traits <_Tp * >
|
||||
{
|
||||
typedef random_access_iterator_tag iterator_category;
|
||||
typedef _Tp value_type;
|
||||
typedef int difference_type;
|
||||
typedef _Tp reference;
|
||||
};
|
||||
template < typename _Iterator > class reverse_iterator:
|
||||
public
|
||||
iterator < typename iterator_traits < _Iterator >::iterator_category,
|
||||
typename iterator_traits < _Iterator >::value_type,
|
||||
typename iterator_traits < _Iterator >::difference_type, typename iterator_traits < _Iterator >::reference >
|
||||
{
|
||||
_Iterator current;
|
||||
public:
|
||||
typedef _Iterator iterator_type;
|
||||
reverse_iterator (const reverse_iterator & __x):current (__x.current)
|
||||
{}
|
||||
iterator_type base ()
|
||||
{
|
||||
return current;
|
||||
}
|
||||
reverse_iterator operator++ ()
|
||||
{
|
||||
--current;
|
||||
}
|
||||
};
|
||||
template
|
||||
<
|
||||
typename
|
||||
_Iterator
|
||||
>
|
||||
bool
|
||||
operator
|
||||
==
|
||||
(reverse_iterator < _Iterator > __x, reverse_iterator < _Iterator > __y)
|
||||
{
|
||||
return __x.base () == __y.base ();
|
||||
}
|
||||
|
||||
template
|
||||
<
|
||||
typename
|
||||
_Iterator
|
||||
>
|
||||
typename
|
||||
reverse_iterator
|
||||
<
|
||||
_Iterator
|
||||
>::difference_type
|
||||
operator
|
||||
- (reverse_iterator < _Iterator >, reverse_iterator < _Iterator >)
|
||||
{}
|
||||
template
|
||||
<
|
||||
typename
|
||||
_RandomAccessIterator
|
||||
>
|
||||
_RandomAccessIterator
|
||||
__find
|
||||
(_RandomAccessIterator
|
||||
__first, _RandomAccessIterator __last)
|
||||
{
|
||||
typename
|
||||
iterator_traits
|
||||
<
|
||||
_RandomAccessIterator
|
||||
>::difference_type __trip_count (__last - __first);
|
||||
for (; __trip_count; --__trip_count)
|
||||
++__first;
|
||||
return __last;
|
||||
}
|
||||
typedef reverse_iterator < int* > _ForwardIterator1;
|
||||
_ForwardIterator1
|
||||
search
|
||||
(_ForwardIterator1
|
||||
__first1,
|
||||
_ForwardIterator1
|
||||
__last1)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
__first1 = __find (__first1, __last1);
|
||||
if (__first1 == __last1)
|
||||
return __last1;
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue