Commit e2844b13 by Martin Liska Committed by Martin Liska

GCOV: add cache for streamed locations.

2018-07-31  Martin Liska  <mliska@suse.cz>

        PR gcov-profile/85338
        PR gcov-profile/85350
        PR gcov-profile/85372
        * profile.c (struct location_triplet): New.
	(struct location_triplet_hash): Likewise.
	(output_location): Do not output a BB that
        is already recorded for a line.
	(branch_prob): Use streamed_locations.
2018-07-31  Martin Liska  <mliska@suse.cz>

        PR gcov-profile/85338
        PR gcov-profile/85350
        PR gcov-profile/85372
	* gcc.misc-tests/gcov-pr85338.c: New test.
	* gcc.misc-tests/gcov-pr85350.c: New test.
	* gcc.misc-tests/gcov-pr85372.c: New test.

From-SVN: r263113
parent 80dde427
2018-07-31 Martin Liska <mliska@suse.cz>
PR gcov-profile/85338
PR gcov-profile/85350
PR gcov-profile/85372
* profile.c (struct location_triplet): New.
(struct location_triplet_hash): Likewise.
(output_location): Do not output a BB that
is already recorded for a line.
(branch_prob): Use streamed_locations.
2018-07-31 Martin Liska <mliska@suse.cz>
PR gcov-profile/85370
* coverage.c (coverage_begin_function): Do not mark target
clones as artificial functions.
......
......@@ -919,17 +919,90 @@ compute_value_histograms (histogram_values values, unsigned cfg_checksum,
free (histogram_counts[t]);
}
/* Location triplet which records a location. */
struct location_triplet
{
const char *filename;
int lineno;
int bb_index;
};
/* Traits class for streamed_locations hash set below. */
struct location_triplet_hash : typed_noop_remove <location_triplet>
{
typedef location_triplet value_type;
typedef location_triplet compare_type;
static hashval_t
hash (const location_triplet &ref)
{
inchash::hash hstate (0);
if (ref.filename)
hstate.add_int (strlen (ref.filename));
hstate.add_int (ref.lineno);
hstate.add_int (ref.bb_index);
return hstate.end ();
}
static bool
equal (const location_triplet &ref1, const location_triplet &ref2)
{
return ref1.lineno == ref2.lineno
&& ref1.bb_index == ref2.bb_index
&& ref1.filename != NULL
&& ref2.filename != NULL
&& strcmp (ref1.filename, ref2.filename) == 0;
}
static void
mark_deleted (location_triplet &ref)
{
ref.lineno = -1;
}
static void
mark_empty (location_triplet &ref)
{
ref.lineno = -2;
}
static bool
is_deleted (const location_triplet &ref)
{
return ref.lineno == -1;
}
static bool
is_empty (const location_triplet &ref)
{
return ref.lineno == -2;
}
};
/* When passed NULL as file_name, initialize.
When passed something else, output the necessary commands to change
line to LINE and offset to FILE_NAME. */
static void
output_location (char const *file_name, int line,
output_location (hash_set<location_triplet_hash> *streamed_locations,
char const *file_name, int line,
gcov_position_t *offset, basic_block bb)
{
static char const *prev_file_name;
static int prev_line;
bool name_differs, line_differs;
location_triplet triplet;
triplet.filename = file_name;
triplet.lineno = line;
triplet.bb_index = bb ? bb->index : 0;
if (streamed_locations->add (triplet))
return;
if (!file_name)
{
prev_file_name = NULL;
......@@ -1018,6 +1091,8 @@ branch_prob (void)
flow_call_edges_add (NULL);
add_noreturn_fake_exit_edges ();
hash_set <location_triplet_hash> streamed_locations;
/* We can't handle cyclic regions constructed using abnormal edges.
To avoid these we replace every source of abnormal edge by a fake
edge from entry node and every destination by fake edge to exit.
......@@ -1254,7 +1329,7 @@ branch_prob (void)
/* Line numbers. */
/* Initialize the output. */
output_location (NULL, 0, NULL, NULL);
output_location (&streamed_locations, NULL, 0, NULL, NULL);
hash_set<int_hash <location_t, 0, 2> > seen_locations;
......@@ -1268,8 +1343,8 @@ branch_prob (void)
location_t loc = DECL_SOURCE_LOCATION (current_function_decl);
seen_locations.add (loc);
expanded_location curr_location = expand_location (loc);
output_location (curr_location.file, curr_location.line,
&offset, bb);
output_location (&streamed_locations, curr_location.file,
curr_location.line, &offset, bb);
}
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
......@@ -1279,8 +1354,8 @@ branch_prob (void)
if (!RESERVED_LOCATION_P (loc))
{
seen_locations.add (loc);
output_location (gimple_filename (stmt), gimple_lineno (stmt),
&offset, bb);
output_location (&streamed_locations, gimple_filename (stmt),
gimple_lineno (stmt), &offset, bb);
}
}
......@@ -1294,8 +1369,8 @@ branch_prob (void)
&& !seen_locations.contains (loc))
{
expanded_location curr_location = expand_location (loc);
output_location (curr_location.file, curr_location.line,
&offset, bb);
output_location (&streamed_locations, curr_location.file,
curr_location.line, &offset, bb);
}
if (offset)
......
2018-07-31 Martin Liska <mliska@suse.cz>
PR gcov-profile/85338
PR gcov-profile/85350
PR gcov-profile/85372
* gcc.misc-tests/gcov-pr85338.c: New test.
* gcc.misc-tests/gcov-pr85350.c: New test.
* gcc.misc-tests/gcov-pr85372.c: New test.
2018-07-31 Martin Liska <mliska@suse.cz>
PR gcov-profile/83813
PR gcov-profile/84758
PR gcov-profile/85217
......
/* { dg-options "-fprofile-arcs -ftest-coverage" } */
/* { dg-do run { target native } } */
void Test(long long Val, int Amt)
{
__builtin_printf(" lshr: 0x%llx \t\t shl: 0x%llx\n", Val >> Amt, Val << Amt); /* count(1) */
__builtin_printf(" lshr: 0x%llx\t\tshl: 0x%llx\n", /* count(1) */
Val >> Amt, Val << Amt);
__builtin_printf(" lshr: 0x%llx \t\t shl: 0x%llx\n", /* count(1) */
(unsigned long long)Val >> Amt, Val << Amt);
}
int main()
{
Test(10, 4);
return 0;
}
/* { dg-final { run-gcov gcov-pr85338.c } } */
/* { dg-options "-fprofile-arcs -ftest-coverage" } */
/* { dg-do run { target native } } */
int main (void)
{
const int t = 2; /* count(1) */
struct s1 { /* count(1) */
int x;
int g[t];
};
struct s2 {
int x;
int g[2];
};
__builtin_printf("Sucess!\n");
return 0;
}
/* { dg-final { run-gcov gcov-pr85350.c } } */
/* { dg-options "-fprofile-arcs -ftest-coverage" } */
/* { dg-do run { target native } } */
/* { dg-require-effective-target indirect_jumps } */
void *buf[5];
void fjmp (void) {
__builtin_longjmp (buf, 1);
}
int main(void)
{
int last = 0;
if (__builtin_setjmp (buf) == 0) { /* count(2) */
__builtin_printf("True branch\n");
while (1) {
last = 1; /* count(1) */
fjmp (); /* count(1) */
}
} else {
__builtin_printf("False branch\n");
}
return 0;
}
/* { dg-final { run-gcov gcov-pr85372.c } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment