split checksum into cfg checksum and line checksum

From-SVN: r173147
This commit is contained in:
Xinliang David Li 2011-04-29 00:19:35 +00:00
parent 112cee354d
commit 10adac5108
13 changed files with 264 additions and 82 deletions

View File

@ -1,3 +1,29 @@
2011-04-28 David Li <davidxl@google.com>
* tree.c (crc32_string): Use crc32_byte.
(crc32_byte): New function.
* tree.h (crc32_byte): New function.
* gcov.c (read_graph_file): Handle new cfg_cksum.
(read_count_file): Ditto.
* profile.c (instrument_values): Ditto.
(get_exec_counts): Ditto.
(read_profile_edge_counts): Ditto.
(compute_branch_probabilities): Ditto.
(compute_value_histograms): Ditto.
(branch_prob): Ditto.
(end_branch_prob): Ditto.
* coverage.c (read_counts_file): Ditto.
(get_coverage_counts): Ditto.
(tree_coverage_counter_addr): Ditto.
(coverage_checksum_string): Ditto.
(coverage_begin_output): Ditto.
(coverage_end_function): Ditto.
(build_fn_info_type): Ditto.
(build_fn_info_value): Ditto.
* libgcov.c (gcov_exit): Ditto.
* gcov-dump.c (tag_function): Ditto.
(compute_checksum): Remove.
2011-04-29 Alan Modra <amodra@gmail.com>
* config/rs6000/rs6000.c (rs6000_delegitimize_address): Handle

View File

@ -51,13 +51,15 @@ along with GCC; see the file COPYING3. If not see
#include "intl.h"
#include "filenames.h"
#include "gcov-io.h"
#include "gcov-io.c"
struct function_list
{
struct function_list *next; /* next function */
unsigned ident; /* function ident */
unsigned checksum; /* function checksum */
unsigned lineno_checksum; /* function lineno checksum */
unsigned cfg_checksum; /* function cfg checksum */
unsigned n_ctrs[GCOV_COUNTERS];/* number of counters. */
};
@ -69,7 +71,8 @@ typedef struct counts_entry
unsigned ctr;
/* Store */
unsigned checksum;
unsigned lineno_checksum;
unsigned cfg_checksum;
gcov_type *counts;
struct gcov_ctr_summary summary;
@ -114,8 +117,6 @@ static hashval_t htab_counts_entry_hash (const void *);
static int htab_counts_entry_eq (const void *, const void *);
static void htab_counts_entry_del (void *);
static void read_counts_file (void);
static unsigned compute_checksum (void);
static unsigned coverage_checksum_string (unsigned, const char *);
static tree build_fn_info_type (unsigned);
static tree build_fn_info_value (const struct function_list *, tree);
static tree build_ctr_info_type (void);
@ -171,11 +172,12 @@ static void
read_counts_file (void)
{
gcov_unsigned_t fn_ident = 0;
gcov_unsigned_t checksum = -1;
counts_entry_t *summaried = NULL;
unsigned seen_summary = 0;
gcov_unsigned_t tag;
int is_error = 0;
unsigned lineno_checksum = 0;
unsigned cfg_checksum = 0;
if (!gcov_open (da_file_name, 1))
return;
@ -215,7 +217,8 @@ read_counts_file (void)
if (tag == GCOV_TAG_FUNCTION)
{
fn_ident = gcov_read_unsigned ();
checksum = gcov_read_unsigned ();
lineno_checksum = gcov_read_unsigned ();
cfg_checksum = gcov_read_unsigned ();
if (seen_summary)
{
/* We have already seen a summary, this means that this
@ -265,24 +268,26 @@ read_counts_file (void)
if (!entry)
{
*slot = entry = XCNEW (counts_entry_t);
entry->ident = elt.ident;
entry->ident = fn_ident;
entry->ctr = elt.ctr;
entry->checksum = checksum;
entry->lineno_checksum = lineno_checksum;
entry->cfg_checksum = cfg_checksum;
entry->summary.num = n_counts;
entry->counts = XCNEWVEC (gcov_type, n_counts);
}
else if (entry->checksum != checksum)
else if (entry->lineno_checksum != lineno_checksum
|| entry->cfg_checksum != cfg_checksum)
{
error ("coverage mismatch for function %u while reading execution counters",
fn_ident);
error ("checksum is %x instead of %x", entry->checksum, checksum);
error ("Profile data for function %u is corrupted", fn_ident);
error ("checksum is (%x,%x) instead of (%x,%x)",
entry->lineno_checksum, entry->cfg_checksum,
lineno_checksum, cfg_checksum);
htab_delete (counts_hash);
break;
}
else if (entry->summary.num != n_counts)
{
error ("coverage mismatch for function %u while reading execution counters",
fn_ident);
error ("Profile data for function %u is corrupted", fn_ident);
error ("number of counters is %d instead of %d", entry->summary.num, n_counts);
htab_delete (counts_hash);
break;
@ -324,10 +329,10 @@ read_counts_file (void)
gcov_type *
get_coverage_counts (unsigned counter, unsigned expected,
unsigned cfg_checksum, unsigned lineno_checksum,
const struct gcov_ctr_summary **summary)
{
counts_entry_t *entry, elt;
gcov_unsigned_t checksum = -1;
/* No hash table, no counts. */
if (!counts_hash)
@ -352,26 +357,21 @@ get_coverage_counts (unsigned counter, unsigned expected,
return NULL;
}
checksum = compute_checksum ();
if (entry->checksum != checksum
if (entry->cfg_checksum != cfg_checksum
|| entry->summary.num != expected)
{
static int warned = 0;
bool warning_printed = false;
tree id = DECL_ASSEMBLER_NAME (current_function_decl);
warning_printed =
warning_at (input_location, OPT_Wcoverage_mismatch,
"coverage mismatch for function "
"%qE while reading counter %qs", id, ctr_names[counter]);
warning_printed =
warning_at (input_location, OPT_Wcoverage_mismatch,
"The control flow of function %qE does not match "
"its profile data (counter %qs)", id, ctr_names[counter]);
if (warning_printed)
{
if (entry->checksum != checksum)
inform (input_location, "checksum is %x instead of %x",
entry->checksum, checksum);
else
inform (input_location, "number of counters is %d instead of %d",
entry->summary.num, expected);
inform (input_location, "Use -Wno-error=coverage-mismatch to tolerate "
"the mismatch but performance may drop if the function is hot");
if (!seen_error ()
&& !warned++)
@ -388,6 +388,12 @@ get_coverage_counts (unsigned counter, unsigned expected,
return NULL;
}
else if (entry->lineno_checksum != lineno_checksum)
{
warning (0, "Source location for function %qE have changed,"
" the profile data may be out of date",
DECL_ASSEMBLER_NAME (current_function_decl));
}
if (summary)
*summary = &entry->summary;
@ -467,6 +473,7 @@ tree_coverage_counter_addr (unsigned counter, unsigned no)
NULL, NULL));
}
/* Generate a checksum for a string. CHKSUM is the current
checksum. */
@ -529,8 +536,8 @@ coverage_checksum_string (unsigned chksum, const char *string)
/* Compute checksum for the current function. We generate a CRC32. */
static unsigned
compute_checksum (void)
unsigned
coverage_compute_lineno_checksum (void)
{
expanded_location xloc
= expand_location (DECL_SOURCE_LOCATION (current_function_decl));
@ -542,6 +549,36 @@ compute_checksum (void)
return chksum;
}
/* Compute cfg checksum for the current function.
The checksum is calculated carefully so that
source code changes that doesn't affect the control flow graph
won't change the checksum.
This is to make the profile data useable across source code change.
The downside of this is that the compiler may use potentially
wrong profile data - that the source code change has non-trivial impact
on the validity of profile data (e.g. the reversed condition)
but the compiler won't detect the change and use the wrong profile data. */
unsigned
coverage_compute_cfg_checksum (void)
{
basic_block bb;
unsigned chksum = n_basic_blocks;
FOR_EACH_BB (bb)
{
edge e;
edge_iterator ei;
chksum = crc32_byte (chksum, bb->index);
FOR_EACH_EDGE (e, ei, bb->succs)
{
chksum = crc32_byte (chksum, e->dest->index);
}
}
return chksum;
}
/* Begin output to the graph file for the current function.
Opens the output file, if not already done. Writes the
@ -549,7 +586,7 @@ compute_checksum (void)
should be output. */
int
coverage_begin_output (void)
coverage_begin_output (unsigned lineno_checksum, unsigned cfg_checksum)
{
/* We don't need to output .gcno file unless we're under -ftest-coverage
(e.g. -fprofile-arcs/generate/use don't need .gcno to work). */
@ -575,12 +612,14 @@ coverage_begin_output (void)
bbg_file_opened = 1;
}
/* Announce function */
offset = gcov_write_tag (GCOV_TAG_FUNCTION);
gcov_write_unsigned (current_function_funcdef_no + 1);
gcov_write_unsigned (compute_checksum ());
gcov_write_unsigned (lineno_checksum);
gcov_write_unsigned (cfg_checksum);
gcov_write_string (IDENTIFIER_POINTER
(DECL_ASSEMBLER_NAME (current_function_decl)));
(DECL_ASSEMBLER_NAME (current_function_decl)));
gcov_write_string (xloc.file);
gcov_write_unsigned (xloc.line);
gcov_write_length (offset);
@ -594,7 +633,7 @@ coverage_begin_output (void)
error has occurred. Save function coverage counts. */
void
coverage_end_function (void)
coverage_end_function (unsigned lineno_checksum, unsigned cfg_checksum)
{
unsigned i;
@ -613,9 +652,11 @@ coverage_end_function (void)
*functions_tail = item;
functions_tail = &item->next;
item->next = 0;
item->ident = current_function_funcdef_no + 1;
item->checksum = compute_checksum ();
item->lineno_checksum = lineno_checksum;
item->cfg_checksum = cfg_checksum;
for (i = 0; i != GCOV_COUNTERS; i++)
{
item->n_ctrs[i] = fn_n_ctrs[i];
@ -640,13 +681,18 @@ build_fn_info_type (unsigned int counters)
/* ident */
fields = build_decl (BUILTINS_LOCATION,
FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
/* checksum */
/* lineno_checksum */
field = build_decl (BUILTINS_LOCATION,
FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
DECL_CHAIN (field) = fields;
fields = field;
/* cfg checksum */
field = build_decl (BUILTINS_LOCATION,
FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
DECL_CHAIN (field) = fields;
fields = field;
array_type = build_int_cst (NULL_TREE, counters - 1);
array_type = build_index_type (array_type);
array_type = build_array_type (get_gcov_unsigned_t (), array_type);
@ -680,10 +726,16 @@ build_fn_info_value (const struct function_list *function, tree type)
function->ident));
fields = DECL_CHAIN (fields);
/* checksum */
/* lineno_checksum */
CONSTRUCTOR_APPEND_ELT (v1, fields,
build_int_cstu (get_gcov_unsigned_t (),
function->checksum));
function->lineno_checksum));
fields = DECL_CHAIN (fields);
/* cfg_checksum */
CONSTRUCTOR_APPEND_ELT (v1, fields,
build_int_cstu (get_gcov_unsigned_t (),
function->cfg_checksum));
fields = DECL_CHAIN (fields);
/* counters */

View File

@ -28,11 +28,17 @@ extern void coverage_finish (void);
/* Complete the coverage information for the current function. Once
per function. */
extern void coverage_end_function (void);
extern void coverage_end_function (unsigned, unsigned);
/* Start outputting coverage information for the current
function. Repeatable per function. */
extern int coverage_begin_output (void);
extern int coverage_begin_output (unsigned, unsigned);
/* Compute the control flow checksum for the current function. */
extern unsigned coverage_compute_cfg_checksum (void);
/* Compute the line number checksum for the current function. */
extern unsigned coverage_compute_lineno_checksum (void);
/* Allocate some counters. Repeatable per function. */
extern int coverage_counter_alloc (unsigned /*counter*/, unsigned/*num*/);
@ -44,6 +50,8 @@ extern tree tree_coverage_counter_addr (unsigned /*counter*/, unsigned/*num*/);
/* Get all the counters for the current function. */
extern gcov_type *get_coverage_counts (unsigned /*counter*/,
unsigned /*expected*/,
unsigned /*cfg_checksum*/,
unsigned /*lineno_checksum*/,
const struct gcov_ctr_summary **);
extern tree get_gcov_type (void);

View File

@ -267,7 +267,8 @@ tag_function (const char *filename ATTRIBUTE_UNUSED,
unsigned long pos = gcov_position ();
printf (" ident=%u", gcov_read_unsigned ());
printf (", checksum=0x%08x", gcov_read_unsigned ());
printf (", lineno_checksum=0x%08x", gcov_read_unsigned ());
printf (", cfg_checksum_checksum=0x%08x", gcov_read_unsigned ());
if (gcov_position () - pos < length)
{

View File

@ -103,7 +103,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
note: unit function-graph*
unit: header int32:checksum string:source
function-graph: announce_function basic_blocks {arcs | lines}*
announce_function: header int32:ident int32:checksum
announce_function: header int32:ident
int32:lineno_checksum int32:cfg_checksum
string:name string:source int32:lineno
basic_block: header int32:flags*
arcs: header int32:block_no arc*
@ -132,7 +133,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
data: {unit function-data* summary:object summary:program*}*
unit: header int32:checksum
function-data: announce_function arc_counts
announce_function: header int32:ident int32:checksum
announce_function: header int32:ident
int32:lineno_checksum int32:cfg_checksum
arc_counts: header int64:count*
summary: int32:checksum {count-summary}GCOV_COUNTERS
count-summary: int32:num int32:runs int64:sum
@ -294,7 +296,7 @@ typedef HOST_WIDEST_INT gcov_type;
file marker -- it is not required to be present. */
#define GCOV_TAG_FUNCTION ((gcov_unsigned_t)0x01000000)
#define GCOV_TAG_FUNCTION_LENGTH (2)
#define GCOV_TAG_FUNCTION_LENGTH (3)
#define GCOV_TAG_BLOCKS ((gcov_unsigned_t)0x01410000)
#define GCOV_TAG_BLOCKS_LENGTH(NUM) (NUM)
#define GCOV_TAG_BLOCKS_NUM(LENGTH) (LENGTH)
@ -412,10 +414,12 @@ struct gcov_summary
idiom. The number of counters is determined from the counter_mask
in gcov_info. We hold an array of function info, so have to
explicitly calculate the correct array stride. */
struct gcov_fn_info
{
gcov_unsigned_t ident; /* unique ident of function */
gcov_unsigned_t checksum; /* function checksum */
gcov_unsigned_t lineno_checksum; /* function lineo_checksum */
gcov_unsigned_t cfg_checksum; /* function cfg checksum */
unsigned n_ctrs[0]; /* instrumented counters */
};

View File

@ -54,6 +54,13 @@ along with Gcov; see the file COPYING3. If not see
some places we make use of the knowledge of how profile.c works to
select particular algorithms here. */
/* The code validates that the profile information read in corresponds
to the code currently being compiled. Rather than checking for
identical files, the code below computes a checksum on the CFG
(based on the order of basic blocks and the arcs in the CFG). If
the CFG checksum in the gcda file match the CFG checksum for the
code currently being compiled, the profile data will be used. */
/* This is the size of the buffer used to read in source file lines. */
#define STRING_SIZE 200
@ -161,7 +168,8 @@ typedef struct function_info
/* Name of function. */
char *name;
unsigned ident;
unsigned checksum;
unsigned lineno_checksum;
unsigned cfg_checksum;
/* Array of basic blocks. */
block_t *blocks;
@ -807,12 +815,14 @@ read_graph_file (void)
if (tag == GCOV_TAG_FUNCTION)
{
char *function_name;
unsigned ident, checksum, lineno;
unsigned ident, lineno;
unsigned lineno_checksum, cfg_checksum;
source_t *src;
function_t *probe, *prev;
ident = gcov_read_unsigned ();
checksum = gcov_read_unsigned ();
lineno_checksum = gcov_read_unsigned ();
cfg_checksum = gcov_read_unsigned ();
function_name = xstrdup (gcov_read_string ());
src = find_source (gcov_read_string ());
lineno = gcov_read_unsigned ();
@ -820,7 +830,8 @@ read_graph_file (void)
fn = XCNEW (function_t);
fn->name = function_name;
fn->ident = ident;
fn->checksum = checksum;
fn->lineno_checksum = lineno_checksum;
fn->cfg_checksum = cfg_checksum;
fn->src = src;
fn->line = lineno;
@ -1107,7 +1118,8 @@ read_count_file (void)
if (!fn)
;
else if (gcov_read_unsigned () != fn->checksum)
else if (gcov_read_unsigned () != fn->lineno_checksum
|| gcov_read_unsigned () != fn->cfg_checksum)
{
mismatch:;
fnotice (stderr, "%s:profile mismatch for '%s'\n",

View File

@ -372,9 +372,10 @@ gcov_exit (void)
/* Check function. */
if (tag != GCOV_TAG_FUNCTION
|| length != GCOV_TAG_FUNCTION_LENGTH
|| length != GCOV_TAG_FUNCTION_LENGTH
|| gcov_read_unsigned () != fi_ptr->ident
|| gcov_read_unsigned () != fi_ptr->checksum)
|| gcov_read_unsigned () != fi_ptr->lineno_checksum
|| gcov_read_unsigned () != fi_ptr->cfg_checksum)
{
read_mismatch:;
fprintf (stderr, "profiling:%s:Merge mismatch for %s\n",
@ -517,7 +518,8 @@ gcov_exit (void)
/* Announce function. */
gcov_write_tag_length (GCOV_TAG_FUNCTION, GCOV_TAG_FUNCTION_LENGTH);
gcov_write_unsigned (fi_ptr->ident);
gcov_write_unsigned (fi_ptr->checksum);
gcov_write_unsigned (fi_ptr->lineno_checksum);
gcov_write_unsigned (fi_ptr->cfg_checksum);
c_ix = 0;
for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)

View File

@ -102,13 +102,6 @@ static int total_num_branches;
/* Forward declarations. */
static void find_spanning_tree (struct edge_list *);
static unsigned instrument_edges (struct edge_list *);
static void instrument_values (histogram_values);
static void compute_branch_probabilities (void);
static void compute_value_histograms (histogram_values);
static gcov_type * get_exec_counts (void);
static basic_block find_group (basic_block);
static void union_groups (basic_block, basic_block);
/* Add edge instrumentation code to the entire insn chain.
@ -233,10 +226,12 @@ instrument_values (histogram_values values)
}
/* Computes hybrid profile for all matching entries in da_file. */
/* Computes hybrid profile for all matching entries in da_file.
CFG_CHECKSUM is the precomputed checksum for the CFG. */
static gcov_type *
get_exec_counts (void)
get_exec_counts (unsigned cfg_checksum, unsigned lineno_checksum)
{
unsigned num_edges = 0;
basic_block bb;
@ -253,7 +248,8 @@ get_exec_counts (void)
num_edges++;
}
counts = get_coverage_counts (GCOV_COUNTER_ARCS, num_edges, &profile_info);
counts = get_coverage_counts (GCOV_COUNTER_ARCS, num_edges, cfg_checksum,
lineno_checksum, &profile_info);
if (!counts)
return NULL;
@ -442,10 +438,12 @@ read_profile_edge_counts (gcov_type *exec_counts)
}
/* Compute the branch probabilities for the various branches.
Annotate them accordingly. */
Annotate them accordingly.
CFG_CHECKSUM is the precomputed checksum for the CFG. */
static void
compute_branch_probabilities (void)
compute_branch_probabilities (unsigned cfg_checksum, unsigned lineno_checksum)
{
basic_block bb;
int i;
@ -454,7 +452,7 @@ compute_branch_probabilities (void)
int passes;
int hist_br_prob[20];
int num_branches;
gcov_type *exec_counts = get_exec_counts ();
gcov_type *exec_counts = get_exec_counts (cfg_checksum, lineno_checksum);
int inconsistent = 0;
/* Very simple sanity checks so we catch bugs in our profiling code. */
@ -772,10 +770,13 @@ compute_branch_probabilities (void)
}
/* Load value histograms values whose description is stored in VALUES array
from .gcda file. */
from .gcda file.
CFG_CHECKSUM is the precomputed checksum for the CFG. */
static void
compute_value_histograms (histogram_values values)
compute_value_histograms (histogram_values values, unsigned cfg_checksum,
unsigned lineno_checksum)
{
unsigned i, j, t, any;
unsigned n_histogram_counters[GCOV_N_VALUE_COUNTERS];
@ -803,7 +804,8 @@ compute_value_histograms (histogram_values values)
histogram_counts[t] =
get_coverage_counts (COUNTER_FOR_HIST_TYPE (t),
n_histogram_counters[t], NULL);
n_histogram_counters[t], cfg_checksum,
lineno_checksum, NULL);
if (histogram_counts[t])
any = 1;
act_count[t] = histogram_counts[t];
@ -905,6 +907,7 @@ branch_prob (void)
unsigned num_instrumented;
struct edge_list *el;
histogram_values values = NULL;
unsigned cfg_checksum, lineno_checksum;
total_num_times_called++;
@ -1058,11 +1061,19 @@ branch_prob (void)
if (dump_file)
fprintf (dump_file, "%d ignored edges\n", ignored_edges);
/* Compute two different checksums. Note that we want to compute
the checksum in only once place, since it depends on the shape
of the control flow which can change during
various transformations. */
cfg_checksum = coverage_compute_cfg_checksum ();
lineno_checksum = coverage_compute_lineno_checksum ();
/* Write the data from which gcov can reconstruct the basic block
graph. */
/* Basic block flags */
if (coverage_begin_output ())
if (coverage_begin_output (lineno_checksum, cfg_checksum))
{
gcov_position_t offset;
@ -1079,7 +1090,7 @@ branch_prob (void)
EXIT_BLOCK_PTR->index = last_basic_block;
/* Arcs */
if (coverage_begin_output ())
if (coverage_begin_output (lineno_checksum, cfg_checksum))
{
gcov_position_t offset;
@ -1120,7 +1131,7 @@ branch_prob (void)
}
/* Line numbers. */
if (coverage_begin_output ())
if (coverage_begin_output (lineno_checksum, cfg_checksum))
{
/* Initialize the output. */
output_location (NULL, 0, NULL, NULL);
@ -1175,9 +1186,9 @@ branch_prob (void)
if (flag_branch_probabilities)
{
compute_branch_probabilities ();
compute_branch_probabilities (cfg_checksum, lineno_checksum);
if (flag_profile_values)
compute_value_histograms (values);
compute_value_histograms (values, cfg_checksum, lineno_checksum);
}
remove_fake_edges ();
@ -1205,7 +1216,7 @@ branch_prob (void)
VEC_free (histogram_value, heap, values);
free_edge_list (el);
coverage_end_function ();
coverage_end_function (lineno_checksum, cfg_checksum);
}
/* Union find algorithm implementation for the basic blocks using
@ -1372,4 +1383,3 @@ end_branch_prob (void)
}
}
}

View File

@ -1,3 +1,8 @@
2011-04-28 Xinliang David Li <davidxl@google.com>
* testsuite/gcc.dg/tree-prof/prof-robust-1.c: New test.
* testsuite/g++.dg/prof-robust-1.C: New test.
2011-04-28 Ira Rosen <ira.rosen@linaro.org>
PR tree-optimization/48765

View File

@ -0,0 +1,24 @@
/* { dg-options "-O2 -fno-weak" } */
#include <stdio.h>
namespace {
namespace {
class MyClass {
public:
void foo() const;
~MyClass() { foo(); }
};
void MyClass::foo() const { printf("Goodbye World\n"); }
}
static MyClass variable;
}
int main() {
return 0;
}

View File

@ -0,0 +1,25 @@
/* { dg-options "-O2 -w" } */
#include <stdio.h>
#include <stdlib.h>
#ifdef _PROFILE_USE
int foo(int x) {
return 3 * x;
}
#else
int foo(int x) {
return 3 * x;
}
#endif
int x = 1000;
int main(int argc, char *argv[]) {
int i;
int sum = 0;
for (i = 0; i < x; i++)
sum += i;
printf("%d\n", sum);
return 0;
}

View File

@ -8510,14 +8510,12 @@ dump_tree_statistics (void)
#define FILE_FUNCTION_FORMAT "_GLOBAL__%s_%s"
/* Generate a crc32 of a string. */
/* Generate a crc32 of a byte. */
unsigned
crc32_string (unsigned chksum, const char *string)
crc32_byte (unsigned chksum, char byte)
{
do
{
unsigned value = *string << 24;
unsigned value = (unsigned) byte << 24;
unsigned ix;
for (ix = 8; ix--; value <<= 1)
@ -8528,6 +8526,18 @@ crc32_string (unsigned chksum, const char *string)
chksum <<= 1;
chksum ^= feedback;
}
return chksum;
}
/* Generate a crc32 of a string. */
unsigned
crc32_string (unsigned chksum, const char *string)
{
do
{
chksum = crc32_byte (chksum, *string);
}
while (*string++);
return chksum;
@ -8551,8 +8561,10 @@ clean_symbol_name (char *p)
*p = '_';
}
/* Generate a name for a special-purpose function function.
/* Generate a name for a special-purpose function.
The generated name may need to be unique across the whole link.
Changes to this function may also require corresponding changes to
xstrdup_mask_random.
TYPE is some string to identify the purpose of this function to the
linker or collect2; it must start with an uppercase letter,
one of:

View File

@ -5001,6 +5001,7 @@ inlined_function_outer_scope_p (const_tree block)
/* In tree.c */
extern unsigned crc32_string (unsigned, const char *);
extern unsigned crc32_byte (unsigned, char);
extern void clean_symbol_name (char *);
extern tree get_file_function_name (const char *);
extern tree get_callee_fndecl (const_tree);