mirror of git://gcc.gnu.org/git/gcc.git
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
|
|
@ -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>
|
2012-12-18 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
PR tree-optimization/55555
|
PR tree-optimization/55555
|
||||||
|
|
|
||||||
|
|
@ -1793,6 +1793,40 @@ fix_loop_structure (bitmap changed_bbs)
|
||||||
record_exits = true;
|
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
|
/* 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
|
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
|
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))
|
if (!loops_state_satisfies_p (LOOPS_MAY_HAVE_MULTIPLE_LATCHES))
|
||||||
disambiguate_loops_with_multiple_latches ();
|
disambiguate_loops_with_multiple_latches ();
|
||||||
|
|
||||||
if (loops_state_satisfies_p (LOOPS_HAVE_PREHEADERS))
|
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))
|
if (loops_state_satisfies_p (LOOPS_HAVE_SIMPLE_LATCHES))
|
||||||
force_single_succ_latches ();
|
force_single_succ_latches ();
|
||||||
|
|
|
||||||
|
|
@ -133,6 +133,7 @@ loop_optimizer_finalize (void)
|
||||||
| LOOPS_HAVE_PREHEADERS
|
| LOOPS_HAVE_PREHEADERS
|
||||||
| LOOPS_HAVE_SIMPLE_LATCHES
|
| LOOPS_HAVE_SIMPLE_LATCHES
|
||||||
| LOOPS_HAVE_FALLTHRU_PREHEADERS);
|
| LOOPS_HAVE_FALLTHRU_PREHEADERS);
|
||||||
|
loops_state_set (LOOPS_MAY_HAVE_MULTIPLE_LATCHES);
|
||||||
goto loop_fini_done;
|
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>
|
2012-12-18 Andreas Schwab <schwab@linux-m68k.org>
|
||||||
|
|
||||||
* lib/go.exp (go_link_flags): Add libatomic location to flags and
|
* lib/go.exp (go_link_flags): Add libatomic location to flags and
|
||||||
|
|
|
||||||
|
|
@ -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…
Reference in New Issue