From 4ad5f7ebfa965fc65acca851e48e9f56e9a2f20d Mon Sep 17 00:00:00 2001 From: marxin Date: Mon, 13 May 2019 07:04:58 +0000 Subject: [PATCH 1/2] Backport r271116 gcc/ChangeLog: 2019-05-13 Martin Liska 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. --- gcc/gcov.c | 53 ++++++++++++++++++----------------------------------- 1 file changed, 18 insertions(+), 35 deletions(-) diff --git a/gcc/gcov.c b/gcc/gcov.c index 1fc37a07c34..6bcd2b23748 100644 --- a/gcc/gcov.c +++ b/gcc/gcov.c @@ -676,27 +676,11 @@ bool function_info::group_line_p (unsigned n, unsigned src_idx) typedef vector arc_vector_t; typedef vector 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 (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_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::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_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; } -- 2.21.0