Test for not existence of a negative loop (PR gcov-profile/90380).
2019-05-13 Martin Liska <mliska@suse.cz> PR gcov-profile/90380 * gcov.c (enum loop_type): Remove the enum and the operator. (handle_cycle): Assert that we should not reach a negative count. (circuit): Use loop_found instead of a tri-state loop_type. (get_cycles_count): Do not handle NEGATIVE_LOOP as it can't happen. From-SVN: r271116
This commit is contained in:
parent
15f3429d31
commit
4af3b0ea1b
2 changed files with 29 additions and 35 deletions
|
@ -1,3 +1,14 @@
|
|||
2019-05-13 Martin Liska <mliska@suse.cz>
|
||||
|
||||
PR gcov-profile/90380
|
||||
* gcov.c (enum loop_type): Remove the enum and
|
||||
the operator.
|
||||
(handle_cycle): Assert that we should not reach
|
||||
a negative count.
|
||||
(circuit): Use loop_found instead of a tri-state loop_type.
|
||||
(get_cycles_count): Do not handle NEGATIVE_LOOP as it can't
|
||||
happen.
|
||||
|
||||
2019-05-12 Iain Sandoe <iain@sandoe.co.uk>
|
||||
|
||||
PR target/82920
|
||||
|
|
53
gcc/gcov.c
53
gcc/gcov.c
|
@ -676,27 +676,11 @@ bool function_info::group_line_p (unsigned n, unsigned src_idx)
|
|||
typedef vector<arc_info *> arc_vector_t;
|
||||
typedef vector<const block_info *> block_vector_t;
|
||||
|
||||
/* Enum with types of loop in CFG. */
|
||||
|
||||
enum loop_type
|
||||
{
|
||||
NO_LOOP = 0,
|
||||
LOOP = 1,
|
||||
NEGATIVE_LOOP = 3
|
||||
};
|
||||
|
||||
/* Loop_type operator that merges two values: A and B. */
|
||||
|
||||
inline loop_type& operator |= (loop_type& a, loop_type b)
|
||||
{
|
||||
return a = static_cast<loop_type> (a | b);
|
||||
}
|
||||
|
||||
/* Handle cycle identified by EDGES, where the function finds minimum cs_count
|
||||
and subtract the value from all counts. The subtracted value is added
|
||||
to COUNT. Returns type of loop. */
|
||||
|
||||
static loop_type
|
||||
static void
|
||||
handle_cycle (const arc_vector_t &edges, int64_t &count)
|
||||
{
|
||||
/* Find the minimum edge of the cycle, and reduce all nodes in the cycle by
|
||||
|
@ -712,7 +696,7 @@ handle_cycle (const arc_vector_t &edges, int64_t &count)
|
|||
for (unsigned i = 0; i < edges.size (); i++)
|
||||
edges[i]->cs_count -= cycle_count;
|
||||
|
||||
return cycle_count < 0 ? NEGATIVE_LOOP : LOOP;
|
||||
gcc_assert (cycle_count >= 0);
|
||||
}
|
||||
|
||||
/* Unblock a block U from BLOCKED. Apart from that, iterate all blocks
|
||||
|
@ -743,12 +727,12 @@ unblock (const block_info *u, block_vector_t &blocked,
|
|||
blocked by a block. COUNT is accumulated count of the current LINE.
|
||||
Returns what type of loop it contains. */
|
||||
|
||||
static loop_type
|
||||
static bool
|
||||
circuit (block_info *v, arc_vector_t &path, block_info *start,
|
||||
block_vector_t &blocked, vector<block_vector_t> &block_lists,
|
||||
line_info &linfo, int64_t &count)
|
||||
{
|
||||
loop_type result = NO_LOOP;
|
||||
bool loop_found = false;
|
||||
|
||||
/* Add v to the block list. */
|
||||
gcc_assert (find (blocked.begin (), blocked.end (), v) == blocked.end ());
|
||||
|
@ -763,15 +747,19 @@ circuit (block_info *v, arc_vector_t &path, block_info *start,
|
|||
|
||||
path.push_back (arc);
|
||||
if (w == start)
|
||||
/* Cycle has been found. */
|
||||
result |= handle_cycle (path, count);
|
||||
{
|
||||
/* Cycle has been found. */
|
||||
handle_cycle (path, count);
|
||||
loop_found = true;
|
||||
}
|
||||
else if (find (blocked.begin (), blocked.end (), w) == blocked.end ())
|
||||
result |= circuit (w, path, start, blocked, block_lists, linfo, count);
|
||||
loop_found |= circuit (w, path, start, blocked, block_lists, linfo,
|
||||
count);
|
||||
|
||||
path.pop_back ();
|
||||
}
|
||||
|
||||
if (result != NO_LOOP)
|
||||
if (loop_found)
|
||||
unblock (v, blocked, block_lists);
|
||||
else
|
||||
for (arc_info *arc = v->succ; arc; arc = arc->succ_next)
|
||||
|
@ -788,14 +776,13 @@ circuit (block_info *v, arc_vector_t &path, block_info *start,
|
|||
list.push_back (v);
|
||||
}
|
||||
|
||||
return result;
|
||||
return loop_found;
|
||||
}
|
||||
|
||||
/* Find cycles for a LINFO. If HANDLE_NEGATIVE_CYCLES is set and the line
|
||||
contains a negative loop, then perform the same function once again. */
|
||||
/* Find cycles for a LINFO. */
|
||||
|
||||
static gcov_type
|
||||
get_cycles_count (line_info &linfo, bool handle_negative_cycles = true)
|
||||
get_cycles_count (line_info &linfo)
|
||||
{
|
||||
/* Note that this algorithm works even if blocks aren't in sorted order.
|
||||
Each iteration of the circuit detection is completely independent
|
||||
|
@ -803,7 +790,7 @@ get_cycles_count (line_info &linfo, bool handle_negative_cycles = true)
|
|||
Therefore, operating on a permuted order (i.e., non-sorted) only
|
||||
has the effect of permuting the output cycles. */
|
||||
|
||||
loop_type result = NO_LOOP;
|
||||
bool loop_found = false;
|
||||
gcov_type count = 0;
|
||||
for (vector<block_info *>::iterator it = linfo.blocks.begin ();
|
||||
it != linfo.blocks.end (); it++)
|
||||
|
@ -811,14 +798,10 @@ get_cycles_count (line_info &linfo, bool handle_negative_cycles = true)
|
|||
arc_vector_t path;
|
||||
block_vector_t blocked;
|
||||
vector<block_vector_t > block_lists;
|
||||
result |= circuit (*it, path, *it, blocked, block_lists, linfo,
|
||||
count);
|
||||
loop_found |= circuit (*it, path, *it, blocked, block_lists, linfo,
|
||||
count);
|
||||
}
|
||||
|
||||
/* If we have a negative cycle, repeat the find_cycles routine. */
|
||||
if (result == NEGATIVE_LOOP && handle_negative_cycles)
|
||||
count += get_cycles_count (linfo, false);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue