diff --git a/src/mapleall/mpl2mpl/BUILD.gn b/src/mapleall/mpl2mpl/BUILD.gn index 4497d8e2a74f649d0b9a069169553482eca229d9..fd3c53c013502da16d75799ad81a67f6601bc2d2 100755 --- a/src/mapleall/mpl2mpl/BUILD.gn +++ b/src/mapleall/mpl2mpl/BUILD.gn @@ -23,7 +23,6 @@ include_directories = [ "${MAPLEALL_ROOT}/mpl2mpl/include", "${MAPLEALL_ROOT}/mempool/include", "${THIRD_PARTY_ROOT}/bounds_checking_function/include", - "${THIRD_PARTY_ROOT}/gcc-linaro-7.5.0-gcov/", ] src_libmpl2mpl = [ diff --git a/src/mapleall/mpl2mpl/include/gcov_parser.h b/src/mapleall/mpl2mpl/include/gcov_parser.h index 9cebb32e7709b87d3d414127396e1137f5e69d49..3c74e913958c8e3edcb441a8ec5d59feac54fd38 100644 --- a/src/mapleall/mpl2mpl/include/gcov_parser.h +++ b/src/mapleall/mpl2mpl/include/gcov_parser.h @@ -1,6 +1,19 @@ +/* + * Copyright (c) [2019-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ #ifndef MAPLE_MPL2MPL_INCLUDE_GCOVPROFUSE_H #define MAPLE_MPL2MPL_INCLUDE_GCOVPROFUSE_H - #include "mempool.h" #include "mempool_allocator.h" #include "bb.h" @@ -9,21 +22,93 @@ namespace maple { +#define CHAR_BIT __CHAR_BIT__ +typedef unsigned gcov_unsigned_t; +typedef int64_t gcov_type; +typedef uint64_t gcov_type_unsigned; +typedef unsigned location_t; +typedef unsigned gcov_unsigned_t; +typedef unsigned gcov_position_t; +// counter defined in gcov-counter.def +enum { + GCOV_COUNTER_ARCS, + GCOV_COUNTER_V_INTERVAL, + GCOV_COUNTER_V_POW2, + GCOV_COUNTER_V_SINGLE, + GCOV_COUNTER_V_INDIR, + GCOV_COUNTER_AVERAGE, + GCOV_COUNTER_IOR, + GCOV_TIME_PROFILER, + GCOV_COUNTER_ICALL_TOPNV, + GCOV_COUNTERS +}; + +class GcovVar { +public: + GcovVar() { + file = nullptr; + buffer = nullptr; + } + FILE *file; + gcov_position_t start; + unsigned offset; + unsigned length; + unsigned overread; + int error; + int mode; + int endian; + size_t alloc; + gcov_unsigned_t* buffer; +}; + class MGcovParser : public AnalysisResult { public: MGcovParser(MIRModule &mirmod, MemPool *memPool, bool debug) : AnalysisResult(memPool), m(mirmod), - alloc(memPool), localMP(memPool), gcovData(nullptr), dumpDetail(debug) {} + alloc(memPool), localMP(memPool), gcovData(nullptr), dumpDetail(debug) { + gcovVar = localMP->New(); + } virtual ~MGcovParser() = default; - int read_count_file(); + int ReadGcdaFile(); void DumpFuncInfo(); - GcovProfileData *GetGcovData() { return gcovData; } private: + typedef struct { + gcov_unsigned_t num_counters; + gcov_type min_value; + gcov_type cum_value; + } gcov_bucket_type; + + struct gcov_ctr_summary { + gcov_unsigned_t num; + gcov_unsigned_t runs; + gcov_type sum_all; + gcov_type run_max; + gcov_type sum_max; + gcov_bucket_type histogram[252]; + }; + struct gcov_summary { + gcov_unsigned_t checksum; + struct gcov_ctr_summary ctrs[(GCOV_COUNTER_ARCS + 1)]; + }; + + int GcovReadMagic(gcov_unsigned_t magic, gcov_unsigned_t expected); + int GcovOpenFile(const char *name, int mode); + gcov_unsigned_t from_file(gcov_unsigned_t value); + const gcov_unsigned_t * GcovReadWords(unsigned words); + void GcovSync(gcov_position_t base, gcov_unsigned_t length); + int GcovCloseFile(void); + void GcovAllocate(unsigned length); + gcov_unsigned_t GcovReadUnsigned(void); + gcov_position_t GcovGetPosition (void); + gcov_type GcovReadCounter(void); + void GcovReadSummary(struct gcov_summary *summary); + MIRModule &m; MapleAllocator alloc; MemPool *localMP; GcovProfileData *gcovData; + GcovVar *gcovVar; bool dumpDetail; }; diff --git a/src/mapleall/mpl2mpl/src/gcov_parser.cpp b/src/mapleall/mpl2mpl/src/gcov_parser.cpp index c1d26e2fd327f772cdf7eefc7258c55a1c2ecace..de83ffd09298a686d37fbc20ce2fb453e843cf50 100644 --- a/src/mapleall/mpl2mpl/src/gcov_parser.cpp +++ b/src/mapleall/mpl2mpl/src/gcov_parser.cpp @@ -1,20 +1,17 @@ -/* Dump a gcov file, for debugging use. - Copyright (C) 2002-2021 Free Software Foundation, Inc. - Contributed by Nathan Sidwell - -Gcov is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. - -Gcov is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Gcov; see the file COPYING3. If not see -. */ +/* + * Copyright (c) [2019-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ #include #include @@ -28,71 +25,237 @@ along with Gcov; see the file COPYING3. If not see #include "mpl_logging.h" #include "gcov_parser.h" -// macro define used in gcov-io -typedef unsigned char boolean; -#define HOST_WIDE_INT long long -#define CHAR_BIT __CHAR_BIT__ - -#ifndef false -#define false 0 -#endif - -#ifndef true -#define true 1 -#endif +namespace maple { +#define GCOV_DATA_MAGIC ((gcov_unsigned_t)0x67636461) /* "gcda" */ +#define GCOV_VERSION ((gcov_unsigned_t)0x4137352a) -typedef unsigned gcov_unsigned_t; -typedef int64_t gcov_type; -typedef uint64_t gcov_type_unsigned; -typedef unsigned location_t; #ifndef ATTRIBUTE_UNUSED #define ATTRIBUTE_UNUSED __attribute__((unused)) #endif -#define XNEWVEC(T, N) ((T *) malloc (sizeof (T) * (N))) -#define XRESIZEVAR(T, P, S) ((T *) realloc ((P), (S))) +/* Convert a magic or version number to a 4 character string. */ +#define GCOV_UNSIGNED2STRING(ARRAY,VALUE) \ + ((ARRAY)[0] = (char)((VALUE) >> 24), \ + (ARRAY)[1] = (char)((VALUE) >> 16), \ + (ARRAY)[2] = (char)((VALUE) >> 8), \ + (ARRAY)[3] = (char)((VALUE) >> 0)) + +#define GCOV_TAG_FUNCTION ((gcov_unsigned_t)0x01000000) +#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) +#define GCOV_TAG_ARCS ((gcov_unsigned_t)0x01430000) +#define GCOV_TAG_ARCS_LENGTH(NUM) (1 + (NUM) * 2) +#define GCOV_TAG_ARCS_NUM(LENGTH) (((LENGTH) - 1) / 2) +#define GCOV_TAG_LINES ((gcov_unsigned_t)0x01450000) +#define GCOV_TAG_COUNTER_BASE ((gcov_unsigned_t)0x01a10000) +#define GCOV_TAG_COUNTER_LENGTH(NUM) ((NUM) * 2) +#define GCOV_TAG_COUNTER_NUM(LENGTH) ((LENGTH) / 2) +#define GCOV_TAG_OBJECT_SUMMARY ((gcov_unsigned_t)0xa1000000) /* Obsolete */ +#define GCOV_TAG_PROGRAM_SUMMARY ((gcov_unsigned_t)0xa3000000) +#define GCOV_TAG_SUMMARY_LENGTH(NUM) \ + (1 + GCOV_COUNTERS_SUMMABLE * (10 + 3 * 2) + (NUM) * 5) +#define GCOV_TAG_AFDO_FILE_NAMES ((gcov_unsigned_t)0xaa000000) +#define GCOV_TAG_AFDO_FUNCTION ((gcov_unsigned_t)0xac000000) +#define GCOV_TAG_AFDO_WORKING_SET ((gcov_unsigned_t)0xaf000000) -/* Return the number of set bits in X. */ -static int popcount_hwi (unsigned HOST_WIDE_INT x) { +// Convert a counter index to a tag +#define GCOV_TAG_FOR_COUNTER(COUNT) \ + (GCOV_TAG_COUNTER_BASE + ((gcov_unsigned_t)(COUNT) << 17)) + +// Return the number of set bits in X +static int popcount_hwi (unsigned long long x) { int i, ret = 0; size_t bits = sizeof (x) * CHAR_BIT; + for (i = 0; i < bits; i += 1) { + ret += x & 1; + x >>= 1; + } + return ret; +} + +gcov_position_t MGcovParser::GcovGetPosition (void) { + ((void)(0 && (gcovVar->mode > 0))); + return gcovVar->start + gcovVar->offset; +} + +int MGcovParser::GcovOpenFile(const char *name, int mode) { + ((void)(0 && (!gcovVar->file))); + gcovVar->start = 0; + gcovVar->offset = gcovVar->length = 0; + gcovVar->overread = -1u; + gcovVar->error = 0; + gcovVar->endian = 0; + gcovVar->alloc = 0; + if (mode >= 0) { + gcovVar->file = fopen(name, (mode > 0) ? "rb" : "r+b"); + } + if (gcovVar->file) { + mode = 1; + } else if (mode <= 0) { + gcovVar->file = fopen(name, "w+b"); + } + if (!gcovVar->file) return 0; + gcovVar->mode = mode ? mode : 1; + setbuf(gcovVar->file, (char *)0); + return 1; +} + +void MGcovParser::GcovAllocate (unsigned length) { + size_t new_size = gcovVar->alloc; + if (!new_size) { + new_size = (1 << 10); + } + new_size += length; + new_size *= 2; + gcovVar->alloc = new_size; + gcovVar->buffer= ((gcov_unsigned_t *) realloc ((gcovVar->buffer), (new_size << 2))); +} + +int MGcovParser::GcovReadMagic(gcov_unsigned_t magic, gcov_unsigned_t expected) { + if (magic == expected) return 1; + magic = (magic >> 16) | (magic << 16); + magic = ((magic & 0xff00ff) << 8) | ((magic >> 8) & 0xff00ff); + if (magic == expected) { + gcovVar->endian = 1; + return -1; + } + return 0; +} + +void MGcovParser::GcovSync(gcov_position_t base, gcov_unsigned_t length) { + ((void)(0 && (gcovVar->mode > 0))); + base += length; + if (base - gcovVar->start <= gcovVar->length) { + gcovVar->offset = base - gcovVar->start; + } else { + gcovVar->offset = gcovVar->length = 0; + fseek (gcovVar->file, base << 2, 0); + gcovVar->start = ftell (gcovVar->file) >> 2; + } +} - for (i = 0; i < bits; i += 1) - { - ret += x & 1; - x >>= 1; +const gcov_unsigned_t * MGcovParser::GcovReadWords (unsigned words) { + const gcov_unsigned_t *result; + unsigned excess = gcovVar->length - gcovVar->offset; + if (gcovVar->mode <= 0) + return nullptr; + if (excess < words) { + gcovVar->start += gcovVar->offset; + if (excess) { + memmove (gcovVar->buffer, gcovVar->buffer + gcovVar->offset, excess * 4); + } + gcovVar->offset = 0; + gcovVar->length = excess; + if (gcovVar->length + words > gcovVar->alloc) { + GcovAllocate(gcovVar->length + words); } + excess = gcovVar->alloc - gcovVar->length; + excess = fread (gcovVar->buffer + gcovVar->length, 1, excess << 2, gcovVar->file) >> 2; + gcovVar->length += excess; + if (gcovVar->length < words) { + gcovVar->overread += words - gcovVar->length; + gcovVar->length = 0; + return 0; + } + } + result = &gcovVar->buffer[gcovVar->offset]; + gcovVar->offset += words; + return result; +} - return ret; +gcov_unsigned_t MGcovParser::from_file(gcov_unsigned_t value) { + if (gcovVar->endian) { + value = (value >> 16) | (value << 16); + value = ((value & 0xff00ff) << 8) | ((value >> 8) & 0xff00ff); + } + return value; } -#define input_location 0 -#define gcc_assert(EXPR) ((void)(0 && (EXPR))) -#define IS_DIR_SEPARATOR_1(dos_based, c) \ - (((c) == '/') \ - || (((c) == '\\') && (dos_based))) -#define IS_UNIX_DIR_SEPARATOR(c) IS_DIR_SEPARATOR_1 (0, c) -#define IS_DIR_SEPARATOR(c) IS_UNIX_DIR_SEPARATOR (c) -#define xmalloc malloc +gcov_unsigned_t MGcovParser::GcovReadUnsigned(void) { + gcov_unsigned_t value; + const gcov_unsigned_t *buffer = GcovReadWords(1); + if (!buffer) return 0; + value = from_file(buffer[0]); + return value; +} -static void fatal_error (location_t loc, const char *gmsgid, ...) { - va_list ap; - va_start (ap, gmsgid); - va_end (ap); - assert(0); +int MGcovParser::GcovCloseFile (void) { + if (gcovVar->file) { + fclose (gcovVar->file); + gcovVar->file = 0; + gcovVar->length = 0; + } + free (gcovVar->buffer); + gcovVar->alloc = 0; + gcovVar->buffer = nullptr; + gcovVar->mode = 0; + return gcovVar->error; } +gcov_type MGcovParser::GcovReadCounter (void) { + gcov_type value; + const gcov_unsigned_t *buffer = GcovReadWords(2); + if (!buffer) return 0; + value = from_file (buffer[0]); + if (sizeof (value) > sizeof (gcov_unsigned_t)) { + value |= ((gcov_type) from_file (buffer[1])) << 32; + } else if (buffer[1]) { + gcovVar->error = -1; + } + return value; +} -#define IN_GCOV (-1) -#include "gcov-io.h" -#include "gcov-io.c" +void MGcovParser::GcovReadSummary (struct gcov_summary *summary) { + unsigned ix, h_ix, bv_ix, h_cnt = 0; + struct gcov_ctr_summary *csum; + unsigned histo_bitvector[(252 + 31) / 32]; + unsigned cur_bitvector; + summary->checksum = GcovReadUnsigned(); + for (csum = summary->ctrs, ix = (GCOV_COUNTER_ARCS + 1); ix--; csum++) { + csum->num = GcovReadUnsigned(); + csum->runs = GcovReadUnsigned(); + csum->sum_all = GcovReadCounter(); + csum->run_max = GcovReadCounter(); + csum->sum_max = GcovReadCounter(); + memset (csum->histogram, 0, sizeof (gcov_bucket_type) * 252); + for (bv_ix = 0; bv_ix < (252 + 31) / 32; bv_ix++) { + histo_bitvector[bv_ix] = GcovReadUnsigned(); + h_cnt += popcount_hwi (histo_bitvector[bv_ix]); + } + bv_ix = 0; + h_ix = 0; + cur_bitvector = 0; + while (h_cnt--) { + while (!cur_bitvector) { + h_ix = bv_ix * 32; + if (bv_ix >= (252 + 31) / 32) { + CHECK_FATAL(false, "corrupted profile info: summary histogram " "bitvector is corrupt"); + } + cur_bitvector = histo_bitvector[bv_ix++]; + } + while (!(cur_bitvector & 0x1)) { + h_ix++; + cur_bitvector >>= 1; + } + if (h_ix >= 252) { + CHECK_FATAL(0, "corrupted profile info: summary histogram " "index is corrupt"); + } + csum->histogram[h_ix].num_counters = GcovReadUnsigned(); + csum->histogram[h_ix].min_value = GcovReadCounter(); + csum->histogram[h_ix].cum_value = GcovReadCounter(); + cur_bitvector >>= 1; + h_ix++; + } + } +} -namespace maple { static unsigned object_runs; static unsigned program_count; //static unsigned bbg_stamp = 0; // reference -int MGcovParser::read_count_file() { +int MGcovParser::ReadGcdaFile() { std::string gcovDataFile = Options::profile; if (gcovDataFile.empty()) { if (const char* env_p = std::getenv("GCOV_PREFIX")) { @@ -104,18 +267,18 @@ int MGcovParser::read_count_file() { gcovDataFile.append(m.GetProfileDataFileName()); } ASSERT(!gcovDataFile.empty(), "null check"); - if (!gcov_open(gcovDataFile.c_str(), 1)) { + if (!GcovOpenFile(gcovDataFile.c_str(), 1)) { LogInfo::MapleLogger() << "no data file " << gcovDataFile << " \n"; Options::profileUse = false; // reset profileUse return 0; } - if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC)) { + if (!GcovReadMagic(GcovReadUnsigned(), GCOV_DATA_MAGIC)) { LogInfo::MapleLogger() << gcovDataFile << " not a gcov data file\n"; - gcov_close (); + GcovCloseFile (); return 1; } - unsigned version = gcov_read_unsigned (); + unsigned version = GcovReadUnsigned(); if (version != GCOV_VERSION) { char v[4], e[4]; GCOV_UNSIGNED2STRING (v, version); @@ -125,37 +288,37 @@ int MGcovParser::read_count_file() { // read stam value, stamp is generated by time function // the value should be same in .gcno file but skip compare here // bbg_stamp - unsigned tag = gcov_read_unsigned (); + unsigned tag = GcovReadUnsigned(); gcovData = localMP->New(&alloc); GcovFuncInfo *funcInfo = nullptr; - while ((tag = gcov_read_unsigned ())) { - unsigned length = gcov_read_unsigned (); - unsigned long base = gcov_position (); + while ((tag = GcovReadUnsigned())) { + unsigned length = GcovReadUnsigned(); + unsigned long base = GcovGetPosition(); if (tag == GCOV_TAG_PROGRAM_SUMMARY) { struct gcov_summary summary; - gcov_read_summary (&summary); + GcovReadSummary(&summary); object_runs += summary.ctrs[GCOV_COUNTER_ARCS].runs; program_count++; } else if (tag == GCOV_TAG_FUNCTION && length == GCOV_TAG_FUNCTION_LENGTH) { unsigned ident; /* Try to find the function in the list. To speed up the search, first start from the last function found. */ - ident = gcov_read_unsigned (); - unsigned lineno_checksum = gcov_read_unsigned (); - unsigned cfg_checksum = gcov_read_unsigned (); + ident = GcovReadUnsigned(); + unsigned lineno_checksum = GcovReadUnsigned(); + unsigned cfg_checksum = GcovReadUnsigned(); funcInfo = localMP->New(&alloc, ident, lineno_checksum, cfg_checksum); (gcovData->funcsCounter)[ident] = funcInfo; } else if (tag == GCOV_TAG_FOR_COUNTER (GCOV_COUNTER_ARCS)) { funcInfo->num_counts = GCOV_TAG_COUNTER_NUM(length); for (int ix = 0; ix != funcInfo->num_counts; ix++) { - funcInfo->counts.push_back(gcov_read_counter()); + funcInfo->counts.push_back(GcovReadCounter()); } } - gcov_sync (base, length); + GcovSync(base, length); } - gcov_close(); + GcovCloseFile(); if (dumpDetail) { DumpFuncInfo(); @@ -184,8 +347,7 @@ void M2MGcovParser::GetAnalysisDependence(AnalysisDep &aDep) const { bool M2MGcovParser::PhaseRun(maple::MIRModule &m) { MemPool *memPool = m.GetMemPool(); // use global pool to store gcov data MGcovParser gcovParser(m, memPool, true); - - int res = gcovParser.read_count_file(); + int res = gcovParser.ReadGcdaFile(); if (res) { // something wrong return false; diff --git a/third_party/gcc-linaro-7.5.0-gcov/gcov-counter.def b/third_party/gcc-linaro-7.5.0-gcov/gcov-counter.def deleted file mode 100644 index 85dcdae593fa11ff53e80c950eaee54ca97768fb..0000000000000000000000000000000000000000 --- a/third_party/gcc-linaro-7.5.0-gcov/gcov-counter.def +++ /dev/null @@ -1,54 +0,0 @@ -/* Definitions for the gcov counters in the GNU compiler. - Copyright (C) 2001-2017 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ - -/* Before including this file, define a macro: - - DEF_GCOV_COUNTER(COUNTER, NAME, FN_TYPE) - - This macro will be expanded to all supported gcov counters, their - names, or the type of handler functions. FN_TYPE will be - expanded to a handler function, like in gcov_merge, it is - expanded to __gcov_merge ## FN_TYPE. */ - -/* Arc transitions. */ -DEF_GCOV_COUNTER(GCOV_COUNTER_ARCS, "arcs", _add) - -/* Histogram of value inside an interval. */ -DEF_GCOV_COUNTER(GCOV_COUNTER_V_INTERVAL, "interval", _add) - -/* Histogram of exact power2 logarithm of a value. */ -DEF_GCOV_COUNTER(GCOV_COUNTER_V_POW2, "pow2", _add) - -/* The most common value of expression. */ -DEF_GCOV_COUNTER(GCOV_COUNTER_V_SINGLE, "single", _single) - -/* The most common indirect address. */ -DEF_GCOV_COUNTER(GCOV_COUNTER_V_INDIR, "indirect_call", _single) - -/* Compute average value passed to the counter. */ -DEF_GCOV_COUNTER(GCOV_COUNTER_AVERAGE, "average", _add) - -/* IOR of the all values passed to counter. */ -DEF_GCOV_COUNTER(GCOV_COUNTER_IOR, "ior", _ior) - -/* Time profile collecting first run of a function */ -DEF_GCOV_COUNTER(GCOV_TIME_PROFILER, "time_profiler", _time_profile) - -/* Top N value tracking for indirect calls. */ -DEF_GCOV_COUNTER(GCOV_COUNTER_ICALL_TOPNV, "indirect_call_topn", _icall_topn) diff --git a/third_party/gcc-linaro-7.5.0-gcov/gcov-io.c b/third_party/gcc-linaro-7.5.0-gcov/gcov-io.c deleted file mode 100644 index 64dedd5528edd7399974890a35a6b1ce80fb1182..0000000000000000000000000000000000000000 --- a/third_party/gcc-linaro-7.5.0-gcov/gcov-io.c +++ /dev/null @@ -1,987 +0,0 @@ -/* File format for coverage information - Copyright (C) 1996-2017 Free Software Foundation, Inc. - Contributed by Bob Manson . - Completely remangled by Nathan Sidwell . - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -. */ - -/* Routines declared in gcov-io.h. This file should be #included by - another source file, after having #included gcov-io.h. */ - -#if !IN_GCOV -static void gcov_write_block (unsigned); -static gcov_unsigned_t *gcov_write_words (unsigned); -#endif -static const gcov_unsigned_t *gcov_read_words (unsigned); -#if !IN_LIBGCOV -static void gcov_allocate (unsigned); -#endif - -/* Optimum number of gcov_unsigned_t's read from or written to disk. */ -#define GCOV_BLOCK_SIZE (1 << 10) - -struct gcov_var -{ - FILE *file; - gcov_position_t start; /* Position of first byte of block */ - unsigned offset; /* Read/write position within the block. */ - unsigned length; /* Read limit in the block. */ - unsigned overread; /* Number of words overread. */ - int error; /* < 0 overflow, > 0 disk error. */ - int mode; /* < 0 writing, > 0 reading */ -#if IN_LIBGCOV - /* Holds one block plus 4 bytes, thus all coverage reads & writes - fit within this buffer and we always can transfer GCOV_BLOCK_SIZE - to and from the disk. libgcov never backtracks and only writes 4 - or 8 byte objects. */ - gcov_unsigned_t buffer[GCOV_BLOCK_SIZE + 1]; -#else - int endian; /* Swap endianness. */ - /* Holds a variable length block, as the compiler can write - strings and needs to backtrack. */ - size_t alloc; - gcov_unsigned_t *buffer; -#endif -} gcov_var; - -/* Save the current position in the gcov file. */ -/* We need to expose this function when compiling for gcov-tool. */ -#ifndef IN_GCOV_TOOL -static inline -#endif -gcov_position_t -gcov_position (void) -{ - gcov_nonruntime_assert (gcov_var.mode > 0); - return gcov_var.start + gcov_var.offset; -} - -/* Return nonzero if the error flag is set. */ -/* We need to expose this function when compiling for gcov-tool. */ -#ifndef IN_GCOV_TOOL -static inline -#endif -int -gcov_is_error (void) -{ - return gcov_var.file ? gcov_var.error : 1; -} - -#if IN_LIBGCOV -/* Move to beginning of file and initialize for writing. */ -GCOV_LINKAGE inline void -gcov_rewrite (void) -{ - gcov_var.mode = -1; - gcov_var.start = 0; - gcov_var.offset = 0; - fseek (gcov_var.file, 0L, SEEK_SET); -} -#endif - -static inline gcov_unsigned_t from_file (gcov_unsigned_t value) -{ -#if !IN_LIBGCOV - if (gcov_var.endian) - { - value = (value >> 16) | (value << 16); - value = ((value & 0xff00ff) << 8) | ((value >> 8) & 0xff00ff); - } -#endif - return value; -} - -/* Open a gcov file. NAME is the name of the file to open and MODE - indicates whether a new file should be created, or an existing file - opened. If MODE is >= 0 an existing file will be opened, if - possible, and if MODE is <= 0, a new file will be created. Use - MODE=0 to attempt to reopen an existing file and then fall back on - creating a new one. If MODE > 0, the file will be opened in - read-only mode. Otherwise it will be opened for modification. - Return zero on failure, non-zero on success. */ - -GCOV_LINKAGE int -#if IN_LIBGCOV -gcov_open (const char *name) -#else -gcov_open (const char *name, int mode) -#endif -{ -#if IN_LIBGCOV - int mode = 0; -#endif -#if GCOV_LOCKED - struct flock s_flock; - int fd; - - s_flock.l_whence = SEEK_SET; - s_flock.l_start = 0; - s_flock.l_len = 0; /* Until EOF. */ - s_flock.l_pid = getpid (); -#endif - - gcov_nonruntime_assert (!gcov_var.file); - gcov_var.start = 0; - gcov_var.offset = gcov_var.length = 0; - gcov_var.overread = -1u; - gcov_var.error = 0; -#if !IN_LIBGCOV - gcov_var.endian = 0; -#endif -#if GCOV_LOCKED - if (mode > 0) - { - /* Read-only mode - acquire a read-lock. */ - s_flock.l_type = F_RDLCK; - /* pass mode (ignored) for compatibility */ - fd = open (name, O_RDONLY, S_IRUSR | S_IWUSR); - } - else - { - /* Write mode - acquire a write-lock. */ - s_flock.l_type = F_WRLCK; - /* Truncate if force new mode. */ - fd = open (name, O_RDWR | O_CREAT | (mode < 0 ? O_TRUNC : 0), 0666); - } - if (fd < 0) - return 0; - - while (fcntl (fd, F_SETLKW, &s_flock) && errno == EINTR) - continue; - - gcov_var.file = fdopen (fd, (mode > 0) ? "rb" : "r+b"); - - if (!gcov_var.file) - { - close (fd); - return 0; - } -#else - if (mode >= 0) - /* Open an existing file. */ - gcov_var.file = fopen (name, (mode > 0) ? "rb" : "r+b"); - - if (gcov_var.file) - mode = 1; - else if (mode <= 0) - /* Create a new file. */ - gcov_var.file = fopen (name, "w+b"); - - if (!gcov_var.file) - return 0; -#endif - - gcov_var.mode = mode ? mode : 1; - - setbuf (gcov_var.file, (char *)0); - - return 1; -} - -/* Close the current gcov file. Flushes data to disk. Returns nonzero - on failure or error flag set. */ - -GCOV_LINKAGE int -gcov_close (void) -{ - if (gcov_var.file) - { -#if !IN_GCOV - if (gcov_var.offset && gcov_var.mode < 0) - gcov_write_block (gcov_var.offset); -#endif - fclose (gcov_var.file); - gcov_var.file = 0; - gcov_var.length = 0; - } -#if !IN_LIBGCOV - free (gcov_var.buffer); - gcov_var.alloc = 0; - gcov_var.buffer = 0; -#endif - gcov_var.mode = 0; - return gcov_var.error; -} - -#if !IN_LIBGCOV -/* Check if MAGIC is EXPECTED. Use it to determine endianness of the - file. Returns +1 for same endian, -1 for other endian and zero for - not EXPECTED. */ - -GCOV_LINKAGE int -gcov_magic (gcov_unsigned_t magic, gcov_unsigned_t expected) -{ - if (magic == expected) - return 1; - magic = (magic >> 16) | (magic << 16); - magic = ((magic & 0xff00ff) << 8) | ((magic >> 8) & 0xff00ff); - if (magic == expected) - { - gcov_var.endian = 1; - return -1; - } - return 0; -} -#endif - -#if !IN_LIBGCOV -static void -gcov_allocate (unsigned length) -{ - size_t new_size = gcov_var.alloc; - - if (!new_size) - new_size = GCOV_BLOCK_SIZE; - new_size += length; - new_size *= 2; - - gcov_var.alloc = new_size; - gcov_var.buffer = XRESIZEVAR (gcov_unsigned_t, gcov_var.buffer, new_size << 2); -} -#endif - -#if !IN_GCOV -/* Write out the current block, if needs be. */ - -static void -gcov_write_block (unsigned size) -{ - if (fwrite (gcov_var.buffer, size << 2, 1, gcov_var.file) != 1) - gcov_var.error = 1; - gcov_var.start += size; - gcov_var.offset -= size; -} - -/* Allocate space to write BYTES bytes to the gcov file. Return a - pointer to those bytes, or NULL on failure. */ - -static gcov_unsigned_t * -gcov_write_words (unsigned words) -{ - gcov_unsigned_t *result; - - gcov_nonruntime_assert (gcov_var.mode < 0); -#if IN_LIBGCOV - if (gcov_var.offset >= GCOV_BLOCK_SIZE) - { - gcov_write_block (GCOV_BLOCK_SIZE); - if (gcov_var.offset) - { - memcpy (gcov_var.buffer, gcov_var.buffer + GCOV_BLOCK_SIZE, 4); - } - } -#else - if (gcov_var.offset + words > gcov_var.alloc) - gcov_allocate (gcov_var.offset + words); -#endif - result = &gcov_var.buffer[gcov_var.offset]; - gcov_var.offset += words; - - return result; -} - -/* Write unsigned VALUE to coverage file. Sets error flag - appropriately. */ - -GCOV_LINKAGE void -gcov_write_unsigned (gcov_unsigned_t value) -{ - gcov_unsigned_t *buffer = gcov_write_words (1); - - buffer[0] = value; -} - -/* Write counter VALUE to coverage file. Sets error flag - appropriately. */ - -#if IN_LIBGCOV -GCOV_LINKAGE void -gcov_write_counter (gcov_type value) -{ - gcov_unsigned_t *buffer = gcov_write_words (2); - - buffer[0] = (gcov_unsigned_t) value; - if (sizeof (value) > sizeof (gcov_unsigned_t)) - buffer[1] = (gcov_unsigned_t) (value >> 32); - else - buffer[1] = 0; -} -#endif /* IN_LIBGCOV */ - -#if !IN_LIBGCOV -/* Write STRING to coverage file. Sets error flag on file - error, overflow flag on overflow */ - -GCOV_LINKAGE void -gcov_write_string (const char *string) -{ - unsigned length = 0; - unsigned alloc = 0; - gcov_unsigned_t *buffer; - - if (string) - { - length = strlen (string); - alloc = (length + 4) >> 2; - } - - buffer = gcov_write_words (1 + alloc); - - buffer[0] = alloc; - - if (alloc > 0) - { - buffer[alloc] = 0; /* place nul terminators. */ - memcpy (&buffer[1], string, length); - } -} -#endif - -#if !IN_LIBGCOV -/* Write a tag TAG and reserve space for the record length. Return a - value to be used for gcov_write_length. */ - -GCOV_LINKAGE gcov_position_t -gcov_write_tag (gcov_unsigned_t tag) -{ - gcov_position_t result = gcov_var.start + gcov_var.offset; - gcov_unsigned_t *buffer = gcov_write_words (2); - - buffer[0] = tag; - buffer[1] = 0; - - return result; -} - -/* Write a record length using POSITION, which was returned by - gcov_write_tag. The current file position is the end of the - record, and is restored before returning. Returns nonzero on - overflow. */ - -GCOV_LINKAGE void -gcov_write_length (gcov_position_t position) -{ - unsigned offset; - gcov_unsigned_t length; - gcov_unsigned_t *buffer; - - gcov_nonruntime_assert (gcov_var.mode < 0); - gcov_nonruntime_assert (position + 2 <= gcov_var.start + gcov_var.offset); - gcov_nonruntime_assert (position >= gcov_var.start); - offset = position - gcov_var.start; - length = gcov_var.offset - offset - 2; - buffer = (gcov_unsigned_t *) &gcov_var.buffer[offset]; - buffer[1] = length; - if (gcov_var.offset >= GCOV_BLOCK_SIZE) - gcov_write_block (gcov_var.offset); -} - -#else /* IN_LIBGCOV */ - -/* Write a tag TAG and length LENGTH. */ - -GCOV_LINKAGE void -gcov_write_tag_length (gcov_unsigned_t tag, gcov_unsigned_t length) -{ - gcov_unsigned_t *buffer = gcov_write_words (2); - - buffer[0] = tag; - buffer[1] = length; -} - -/* Write a summary structure to the gcov file. Return nonzero on - overflow. */ - -GCOV_LINKAGE void -gcov_write_summary (gcov_unsigned_t tag, const struct gcov_summary *summary) -{ - unsigned ix, h_ix, bv_ix, h_cnt = 0; - const struct gcov_ctr_summary *csum; - unsigned histo_bitvector[GCOV_HISTOGRAM_BITVECTOR_SIZE]; - - /* Count number of non-zero histogram entries, and fill in a bit vector - of non-zero indices. The histogram is only currently computed for arc - counters. */ - for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++) - histo_bitvector[bv_ix] = 0; - csum = &summary->ctrs[GCOV_COUNTER_ARCS]; - for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++) - if (csum->histogram[h_ix].num_counters) - { - histo_bitvector[h_ix / 32] |= 1 << (h_ix % 32); - h_cnt++; - } - gcov_write_tag_length (tag, GCOV_TAG_SUMMARY_LENGTH (h_cnt)); - gcov_write_unsigned (summary->checksum); - for (csum = summary->ctrs, ix = GCOV_COUNTERS_SUMMABLE; ix--; csum++) - { - gcov_write_unsigned (csum->num); - gcov_write_unsigned (csum->runs); - gcov_write_counter (csum->sum_all); - gcov_write_counter (csum->run_max); - gcov_write_counter (csum->sum_max); - if (ix != GCOV_COUNTER_ARCS) - { - for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++) - gcov_write_unsigned (0); - continue; - } - for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++) - gcov_write_unsigned (histo_bitvector[bv_ix]); - for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++) - { - if (!csum->histogram[h_ix].num_counters) - continue; - gcov_write_unsigned (csum->histogram[h_ix].num_counters); - gcov_write_counter (csum->histogram[h_ix].min_value); - gcov_write_counter (csum->histogram[h_ix].cum_value); - } - } -} -#endif /* IN_LIBGCOV */ - -#endif /*!IN_GCOV */ - -/* Return a pointer to read BYTES bytes from the gcov file. Returns - NULL on failure (read past EOF). */ - -static const gcov_unsigned_t * -gcov_read_words (unsigned words) -{ - const gcov_unsigned_t *result; - unsigned excess = gcov_var.length - gcov_var.offset; - - if (gcov_var.mode <= 0) - return NULL; - - if (excess < words) - { - gcov_var.start += gcov_var.offset; - if (excess) - { -#if IN_LIBGCOV - memcpy (gcov_var.buffer, gcov_var.buffer + gcov_var.offset, 4); -#else - memmove (gcov_var.buffer, gcov_var.buffer + gcov_var.offset, - excess * 4); -#endif - } - gcov_var.offset = 0; - gcov_var.length = excess; -#if IN_LIBGCOV - excess = GCOV_BLOCK_SIZE; -#else - if (gcov_var.length + words > gcov_var.alloc) - gcov_allocate (gcov_var.length + words); - excess = gcov_var.alloc - gcov_var.length; -#endif - excess = fread (gcov_var.buffer + gcov_var.length, - 1, excess << 2, gcov_var.file) >> 2; - gcov_var.length += excess; - if (gcov_var.length < words) - { - gcov_var.overread += words - gcov_var.length; - gcov_var.length = 0; - return 0; - } - } - result = &gcov_var.buffer[gcov_var.offset]; - gcov_var.offset += words; - return result; -} - -/* Read unsigned value from a coverage file. Sets error flag on file - error, overflow flag on overflow */ - -GCOV_LINKAGE gcov_unsigned_t -gcov_read_unsigned (void) -{ - gcov_unsigned_t value; - const gcov_unsigned_t *buffer = gcov_read_words (1); - - if (!buffer) - return 0; - value = from_file (buffer[0]); - return value; -} - -/* Read counter value from a coverage file. Sets error flag on file - error, overflow flag on overflow */ - -GCOV_LINKAGE gcov_type -gcov_read_counter (void) -{ - gcov_type value; - const gcov_unsigned_t *buffer = gcov_read_words (2); - - if (!buffer) - return 0; - value = from_file (buffer[0]); - if (sizeof (value) > sizeof (gcov_unsigned_t)) - value |= ((gcov_type) from_file (buffer[1])) << 32; - else if (buffer[1]) - gcov_var.error = -1; - - return value; -} - -/* We need to expose the below function when compiling for gcov-tool. */ - -#if !IN_LIBGCOV || defined (IN_GCOV_TOOL) -/* Read string from coverage file. Returns a pointer to a static - buffer, or NULL on empty string. You must copy the string before - calling another gcov function. */ - -GCOV_LINKAGE const char * -gcov_read_string (void) -{ - unsigned length = gcov_read_unsigned (); - - if (!length) - return 0; - - return (const char *) gcov_read_words (length); -} -#endif - -GCOV_LINKAGE void -gcov_read_summary (struct gcov_summary *summary) -{ - unsigned ix, h_ix, bv_ix, h_cnt = 0; - struct gcov_ctr_summary *csum; - unsigned histo_bitvector[GCOV_HISTOGRAM_BITVECTOR_SIZE]; - unsigned cur_bitvector; - - summary->checksum = gcov_read_unsigned (); - for (csum = summary->ctrs, ix = GCOV_COUNTERS_SUMMABLE; ix--; csum++) - { - csum->num = gcov_read_unsigned (); - csum->runs = gcov_read_unsigned (); - csum->sum_all = gcov_read_counter (); - csum->run_max = gcov_read_counter (); - csum->sum_max = gcov_read_counter (); - memset (csum->histogram, 0, - sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE); - for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++) - { - histo_bitvector[bv_ix] = gcov_read_unsigned (); -#if IN_LIBGCOV - /* When building libgcov we don't include system.h, which includes - hwint.h (where popcount_hwi is declared). However, libgcov.a - is built by the bootstrapped compiler and therefore the builtins - are always available. */ - h_cnt += __builtin_popcount (histo_bitvector[bv_ix]); -#else - h_cnt += popcount_hwi (histo_bitvector[bv_ix]); -#endif - } - bv_ix = 0; - h_ix = 0; - cur_bitvector = 0; - while (h_cnt--) - { - /* Find the index corresponding to the next entry we will read in. - First find the next non-zero bitvector and re-initialize - the histogram index accordingly, then right shift and increment - the index until we find a set bit. */ - while (!cur_bitvector) - { - h_ix = bv_ix * 32; - if (bv_ix >= GCOV_HISTOGRAM_BITVECTOR_SIZE) - gcov_error ("corrupted profile info: summary histogram " - "bitvector is corrupt"); - cur_bitvector = histo_bitvector[bv_ix++]; - } - while (!(cur_bitvector & 0x1)) - { - h_ix++; - cur_bitvector >>= 1; - } - if (h_ix >= GCOV_HISTOGRAM_SIZE) - gcov_error ("corrupted profile info: summary histogram " - "index is corrupt"); - - csum->histogram[h_ix].num_counters = gcov_read_unsigned (); - csum->histogram[h_ix].min_value = gcov_read_counter (); - csum->histogram[h_ix].cum_value = gcov_read_counter (); - /* Shift off the index we are done with and increment to the - corresponding next histogram entry. */ - cur_bitvector >>= 1; - h_ix++; - } - } -} - -/* We need to expose the below function when compiling for gcov-tool. */ - -#if !IN_LIBGCOV || defined (IN_GCOV_TOOL) -/* Reset to a known position. BASE should have been obtained from - gcov_position, LENGTH should be a record length. */ - -GCOV_LINKAGE void -gcov_sync (gcov_position_t base, gcov_unsigned_t length) -{ - gcov_nonruntime_assert (gcov_var.mode > 0); - base += length; - if (base - gcov_var.start <= gcov_var.length) - gcov_var.offset = base - gcov_var.start; - else - { - gcov_var.offset = gcov_var.length = 0; - fseek (gcov_var.file, base << 2, SEEK_SET); - gcov_var.start = ftell (gcov_var.file) >> 2; - } -} -#endif - -#if IN_LIBGCOV -/* Move to a given position in a gcov file. */ - -GCOV_LINKAGE void -gcov_seek (gcov_position_t base) -{ - if (gcov_var.offset) - gcov_write_block (gcov_var.offset); - fseek (gcov_var.file, base << 2, SEEK_SET); - gcov_var.start = ftell (gcov_var.file) >> 2; -} -#endif - -#if IN_GCOV > 0 -/* Return the modification time of the current gcov file. */ - -GCOV_LINKAGE time_t -gcov_time (void) -{ - struct stat status; - - if (fstat (fileno (gcov_var.file), &status)) - return 0; - else - return status.st_mtime; -} -#endif /* IN_GCOV */ - -#if !IN_GCOV -/* Determine the index into histogram for VALUE. */ - -#if IN_LIBGCOV -static unsigned -#else -GCOV_LINKAGE unsigned -#endif -gcov_histo_index (gcov_type value) -{ - gcov_type_unsigned v = (gcov_type_unsigned)value; - unsigned r = 0; - unsigned prev2bits = 0; - - /* Find index into log2 scale histogram, where each of the log2 - sized buckets is divided into 4 linear sub-buckets for better - focus in the higher buckets. */ - - /* Find the place of the most-significant bit set. */ - if (v > 0) - { -#if IN_LIBGCOV - /* When building libgcov we don't include system.h, which includes - hwint.h (where floor_log2 is declared). However, libgcov.a - is built by the bootstrapped compiler and therefore the builtins - are always available. */ - r = sizeof (long long) * __CHAR_BIT__ - 1 - __builtin_clzll (v); -#else - /* We use floor_log2 from hwint.c, which takes a HOST_WIDE_INT - that is 64 bits and gcov_type_unsigned is 64 bits. */ - r = floor_log2 (v); -#endif - } - - /* If at most the 2 least significant bits are set (value is - 0 - 3) then that value is our index into the lowest set of - four buckets. */ - if (r < 2) - return (unsigned)value; - - gcov_nonruntime_assert (r < 64); - - /* Find the two next most significant bits to determine which - of the four linear sub-buckets to select. */ - prev2bits = (v >> (r - 2)) & 0x3; - /* Finally, compose the final bucket index from the log2 index and - the next 2 bits. The minimum r value at this point is 2 since we - returned above if r was 2 or more, so the minimum bucket at this - point is 4. */ - return (r - 1) * 4 + prev2bits; -} - -/* Merge SRC_HISTO into TGT_HISTO. The counters are assumed to be in - the same relative order in both histograms, and are matched up - and merged in reverse order. Each counter is assigned an equal portion of - its entry's original cumulative counter value when computing the - new merged cum_value. */ - -static void gcov_histogram_merge (gcov_bucket_type *tgt_histo, - gcov_bucket_type *src_histo) -{ - int src_i, tgt_i, tmp_i = 0; - unsigned src_num, tgt_num, merge_num; - gcov_type src_cum, tgt_cum, merge_src_cum, merge_tgt_cum, merge_cum; - gcov_type merge_min; - gcov_bucket_type tmp_histo[GCOV_HISTOGRAM_SIZE]; - int src_done = 0; - - memset (tmp_histo, 0, sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE); - - /* Assume that the counters are in the same relative order in both - histograms. Walk the histograms from largest to smallest entry, - matching up and combining counters in order. */ - src_num = 0; - src_cum = 0; - src_i = GCOV_HISTOGRAM_SIZE - 1; - for (tgt_i = GCOV_HISTOGRAM_SIZE - 1; tgt_i >= 0 && !src_done; tgt_i--) - { - tgt_num = tgt_histo[tgt_i].num_counters; - tgt_cum = tgt_histo[tgt_i].cum_value; - /* Keep going until all of the target histogram's counters at this - position have been matched and merged with counters from the - source histogram. */ - while (tgt_num > 0 && !src_done) - { - /* If this is either the first time through this loop or we just - exhausted the previous non-zero source histogram entry, look - for the next non-zero source histogram entry. */ - if (!src_num) - { - /* Locate the next non-zero entry. */ - while (src_i >= 0 && !src_histo[src_i].num_counters) - src_i--; - /* If source histogram has fewer counters, then just copy over the - remaining target counters and quit. */ - if (src_i < 0) - { - tmp_histo[tgt_i].num_counters += tgt_num; - tmp_histo[tgt_i].cum_value += tgt_cum; - if (!tmp_histo[tgt_i].min_value || - tgt_histo[tgt_i].min_value < tmp_histo[tgt_i].min_value) - tmp_histo[tgt_i].min_value = tgt_histo[tgt_i].min_value; - while (--tgt_i >= 0) - { - tmp_histo[tgt_i].num_counters - += tgt_histo[tgt_i].num_counters; - tmp_histo[tgt_i].cum_value += tgt_histo[tgt_i].cum_value; - if (!tmp_histo[tgt_i].min_value || - tgt_histo[tgt_i].min_value - < tmp_histo[tgt_i].min_value) - tmp_histo[tgt_i].min_value = tgt_histo[tgt_i].min_value; - } - - src_done = 1; - break; - } - - src_num = src_histo[src_i].num_counters; - src_cum = src_histo[src_i].cum_value; - } - - /* The number of counters to merge on this pass is the minimum - of the remaining counters from the current target and source - histogram entries. */ - merge_num = tgt_num; - if (src_num < merge_num) - merge_num = src_num; - - /* The merged min_value is the sum of the min_values from target - and source. */ - merge_min = tgt_histo[tgt_i].min_value + src_histo[src_i].min_value; - - /* Compute the portion of source and target entries' cum_value - that will be apportioned to the counters being merged. - The total remaining cum_value from each entry is divided - equally among the counters from that histogram entry if we - are not merging all of them. */ - merge_src_cum = src_cum; - if (merge_num < src_num) - merge_src_cum = merge_num * src_cum / src_num; - merge_tgt_cum = tgt_cum; - if (merge_num < tgt_num) - merge_tgt_cum = merge_num * tgt_cum / tgt_num; - /* The merged cum_value is the sum of the source and target - components. */ - merge_cum = merge_src_cum + merge_tgt_cum; - - /* Update the remaining number of counters and cum_value left - to be merged from this source and target entry. */ - src_cum -= merge_src_cum; - tgt_cum -= merge_tgt_cum; - src_num -= merge_num; - tgt_num -= merge_num; - - /* The merged counters get placed in the new merged histogram - at the entry for the merged min_value. */ - tmp_i = gcov_histo_index (merge_min); - gcov_nonruntime_assert (tmp_i < GCOV_HISTOGRAM_SIZE); - tmp_histo[tmp_i].num_counters += merge_num; - tmp_histo[tmp_i].cum_value += merge_cum; - if (!tmp_histo[tmp_i].min_value || - merge_min < tmp_histo[tmp_i].min_value) - tmp_histo[tmp_i].min_value = merge_min; - - /* Ensure the search for the next non-zero src_histo entry starts - at the next smallest histogram bucket. */ - if (!src_num) - src_i--; - } - } - - gcov_nonruntime_assert (tgt_i < 0); - - /* In the case where there were more counters in the source histogram, - accumulate the remaining unmerged cumulative counter values. Add - those to the smallest non-zero target histogram entry. Otherwise, - the total cumulative counter values in the histogram will be smaller - than the sum_all stored in the summary, which will complicate - computing the working set information from the histogram later on. */ - if (src_num) - src_i--; - while (src_i >= 0) - { - src_cum += src_histo[src_i].cum_value; - src_i--; - } - /* At this point, tmp_i should be the smallest non-zero entry in the - tmp_histo. */ - gcov_nonruntime_assert (tmp_i >= 0 && tmp_i < GCOV_HISTOGRAM_SIZE - && tmp_histo[tmp_i].num_counters > 0); - tmp_histo[tmp_i].cum_value += src_cum; - - /* Finally, copy the merged histogram into tgt_histo. */ - memcpy (tgt_histo, tmp_histo, - sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE); -} -#endif /* !IN_GCOV */ - -/* This is used by gcov-dump (IN_GCOV == -1) and in the compiler - (!IN_GCOV && !IN_LIBGCOV). */ -#if IN_GCOV <= 0 && !IN_LIBGCOV -/* Compute the working set information from the counter histogram in - the profile summary. This is an array of information corresponding to a - range of percentages of the total execution count (sum_all), and includes - the number of counters required to cover that working set percentage and - the minimum counter value in that working set. */ - -GCOV_LINKAGE void -compute_working_sets (const struct gcov_ctr_summary *summary, - gcov_working_set_t *gcov_working_sets) -{ - gcov_type working_set_cum_values[NUM_GCOV_WORKING_SETS]; - gcov_type ws_cum_hotness_incr; - gcov_type cum, tmp_cum; - const gcov_bucket_type *histo_bucket; - unsigned ws_ix, c_num, count; - int h_ix; - - /* Compute the amount of sum_all that the cumulative hotness grows - by in each successive working set entry, which depends on the - number of working set entries. */ - ws_cum_hotness_incr = summary->sum_all / NUM_GCOV_WORKING_SETS; - - /* Next fill in an array of the cumulative hotness values corresponding - to each working set summary entry we are going to compute below. - Skip 0% statistics, which can be extrapolated from the - rest of the summary data. */ - cum = ws_cum_hotness_incr; - for (ws_ix = 0; ws_ix < NUM_GCOV_WORKING_SETS; - ws_ix++, cum += ws_cum_hotness_incr) - working_set_cum_values[ws_ix] = cum; - /* The last summary entry is reserved for (roughly) 99.9% of the - working set. Divide by 1024 so it becomes a shift, which gives - almost exactly 99.9%. */ - working_set_cum_values[NUM_GCOV_WORKING_SETS-1] - = summary->sum_all - summary->sum_all/1024; - - /* Next, walk through the histogram in decending order of hotness - and compute the statistics for the working set summary array. - As histogram entries are accumulated, we check to see which - working set entries have had their expected cum_value reached - and fill them in, walking the working set entries in increasing - size of cum_value. */ - ws_ix = 0; /* The current entry into the working set array. */ - cum = 0; /* The current accumulated counter sum. */ - count = 0; /* The current accumulated count of block counters. */ - for (h_ix = GCOV_HISTOGRAM_SIZE - 1; - h_ix >= 0 && ws_ix < NUM_GCOV_WORKING_SETS; h_ix--) - { - histo_bucket = &summary->histogram[h_ix]; - - /* If we haven't reached the required cumulative counter value for - the current working set percentage, simply accumulate this histogram - entry into the running sums and continue to the next histogram - entry. */ - if (cum + histo_bucket->cum_value < working_set_cum_values[ws_ix]) - { - cum += histo_bucket->cum_value; - count += histo_bucket->num_counters; - continue; - } - - /* If adding the current histogram entry's cumulative counter value - causes us to exceed the current working set size, then estimate - how many of this histogram entry's counter values are required to - reach the working set size, and fill in working set entries - as we reach their expected cumulative value. */ - for (c_num = 0, tmp_cum = cum; - c_num < histo_bucket->num_counters && ws_ix < NUM_GCOV_WORKING_SETS; - c_num++) - { - count++; - /* If we haven't reached the last histogram entry counter, add - in the minimum value again. This will underestimate the - cumulative sum so far, because many of the counter values in this - entry may have been larger than the minimum. We could add in the - average value every time, but that would require an expensive - divide operation. */ - if (c_num + 1 < histo_bucket->num_counters) - tmp_cum += histo_bucket->min_value; - /* If we have reached the last histogram entry counter, then add - in the entire cumulative value. */ - else - tmp_cum = cum + histo_bucket->cum_value; - - /* Next walk through successive working set entries and fill in - the statistics for any whose size we have reached by accumulating - this histogram counter. */ - while (ws_ix < NUM_GCOV_WORKING_SETS - && tmp_cum >= working_set_cum_values[ws_ix]) - { - gcov_working_sets[ws_ix].num_counters = count; - gcov_working_sets[ws_ix].min_counter - = histo_bucket->min_value; - ws_ix++; - } - } - /* Finally, update the running cumulative value since we were - using a temporary above. */ - cum += histo_bucket->cum_value; - } - gcov_nonruntime_assert (ws_ix == NUM_GCOV_WORKING_SETS); -} -#endif /* IN_GCOV <= 0 && !IN_LIBGCOV */ diff --git a/third_party/gcc-linaro-7.5.0-gcov/gcov-io.h b/third_party/gcc-linaro-7.5.0-gcov/gcov-io.h deleted file mode 100644 index 6ce5c7d1dc74e738e83eab61ce2317f4b4ef038e..0000000000000000000000000000000000000000 --- a/third_party/gcc-linaro-7.5.0-gcov/gcov-io.h +++ /dev/null @@ -1,425 +0,0 @@ -/* File format for coverage information - Copyright (C) 1996-2017 Free Software Foundation, Inc. - Contributed by Bob Manson . - Completely remangled by Nathan Sidwell . - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -. */ - - -/* Coverage information is held in two files. A notes file, which is - generated by the compiler, and a data file, which is generated by - the program under test. Both files use a similar structure. We do - not attempt to make these files backwards compatible with previous - versions, as you only need coverage information when developing a - program. We do hold version information, so that mismatches can be - detected, and we use a format that allows tools to skip information - they do not understand or are not interested in. - - Numbers are recorded in the 32 bit unsigned binary form of the - endianness of the machine generating the file. 64 bit numbers are - stored as two 32 bit numbers, the low part first. Strings are - padded with 1 to 4 NUL bytes, to bring the length up to a multiple - of 4. The number of 4 bytes is stored, followed by the padded - string. Zero length and NULL strings are simply stored as a length - of zero (they have no trailing NUL or padding). - - int32: byte3 byte2 byte1 byte0 | byte0 byte1 byte2 byte3 - int64: int32:low int32:high - string: int32:0 | int32:length char* char:0 padding - padding: | char:0 | char:0 char:0 | char:0 char:0 char:0 - item: int32 | int64 | string - - The basic format of the files is - - file : int32:magic int32:version int32:stamp record* - - The magic ident is different for the notes and the data files. The - magic ident is used to determine the endianness of the file, when - reading. The version is the same for both files and is derived - from gcc's version number. The stamp value is used to synchronize - note and data files and to synchronize merging within a data - file. It need not be an absolute time stamp, merely a ticker that - increments fast enough and cycles slow enough to distinguish - different compile/run/compile cycles. - - Although the ident and version are formally 32 bit numbers, they - are derived from 4 character ASCII strings. The version number - consists of a two character major version number - (first digit starts from 'A' letter to not to clash with the older - numbering scheme), the single character minor version number, - and a single character indicating the status of the release. - That will be 'e' experimental, 'p' prerelease and 'r' for release. - Because, by good fortune, these are in alphabetical order, string - collating can be used to compare version strings. Be aware that - the 'e' designation will (naturally) be unstable and might be - incompatible with itself. For gcc 17.0 experimental, it would be - 'B70e' (0x42373065). As we currently do not release more than 5 minor - releases, the single character should be always fine. Major number - is currently changed roughly every year, which gives us space - for next 250 years (maximum allowed number would be 259.9). - - A record has a tag, length and variable amount of data. - - record: header data - header: int32:tag int32:length - data: item* - - Records are not nested, but there is a record hierarchy. Tag - numbers reflect this hierarchy. Tags are unique across note and - data files. Some record types have a varying amount of data. The - LENGTH is the number of 4bytes that follow and is usually used to - determine how much data. The tag value is split into 4 8-bit - fields, one for each of four possible levels. The most significant - is allocated first. Unused levels are zero. Active levels are - odd-valued, so that the LSB of the level is one. A sub-level - incorporates the values of its superlevels. This formatting allows - you to determine the tag hierarchy, without understanding the tags - themselves, and is similar to the standard section numbering used - in technical documents. Level values [1..3f] are used for common - tags, values [41..9f] for the notes file and [a1..ff] for the data - file. - - The notes file contains the following records - note: unit function-graph* - unit: header int32:checksum string:source - function-graph: announce_function basic_blocks {arcs | lines}* - 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* - arc: int32:dest_block int32:flags - lines: header int32:block_no line* - int32:0 string:NULL - line: int32:line_no | int32:0 string:filename - - The BASIC_BLOCK record holds per-bb flags. The number of blocks - can be inferred from its data length. There is one ARCS record per - basic block. The number of arcs from a bb is implicit from the - data length. It enumerates the destination bb and per-arc flags. - There is one LINES record per basic block, it enumerates the source - lines which belong to that basic block. Source file names are - introduced by a line number of 0, following lines are from the new - source file. The initial source file for the function is NULL, but - the current source file should be remembered from one LINES record - to the next. The end of a block is indicated by an empty filename - - this does not reset the current source file. Note there is no - ordering of the ARCS and LINES records: they may be in any order, - interleaved in any manner. The current filename follows the order - the LINES records are stored in the file, *not* the ordering of the - blocks they are for. - - The data file contains the following records. - data: {unit summary:object summary:program* function-data*}* - unit: header int32:checksum - function-data: announce_function present counts - announce_function: header int32:ident - int32:lineno_checksum int32:cfg_checksum - present: header int32:present - counts: header int64:count* - summary: int32:checksum {count-summary}GCOV_COUNTERS_SUMMABLE - count-summary: int32:num int32:runs int64:sum - int64:max int64:sum_max histogram - histogram: {int32:bitvector}8 histogram-buckets* - histogram-buckets: int32:num int64:min int64:sum - - The ANNOUNCE_FUNCTION record is the same as that in the note file, - but without the source location. The COUNTS gives the - counter values for instrumented features. The about the whole - program. The checksum is used for whole program summaries, and - disambiguates different programs which include the same - instrumented object file. There may be several program summaries, - each with a unique checksum. The object summary's checksum is - zero. Note that the data file might contain information from - several runs concatenated, or the data might be merged. - - This file is included by both the compiler, gcov tools and the - runtime support library libgcov. IN_LIBGCOV and IN_GCOV are used to - distinguish which case is which. If IN_LIBGCOV is nonzero, - libgcov is being built. If IN_GCOV is nonzero, the gcov tools are - being built. Otherwise the compiler is being built. IN_GCOV may be - positive or negative. If positive, we are compiling a tool that - requires additional functions (see the code for knowledge of what - those functions are). */ - -#ifndef GCC_GCOV_IO_H -#define GCC_GCOV_IO_H - -#ifndef IN_LIBGCOV -/* About the host */ - -typedef unsigned gcov_unsigned_t; -typedef unsigned gcov_position_t; -/* gcov_type is typedef'd elsewhere for the compiler */ -#if IN_GCOV -// #define GCOV_LINKAGE static -typedef int64_t gcov_type; -typedef uint64_t gcov_type_unsigned; -#if IN_GCOV > 0 -#include -#endif -#endif - -#if defined (HOST_HAS_F_SETLKW) -#define GCOV_LOCKED 1 -#else -#define GCOV_LOCKED 0 -#endif - -#define ATTRIBUTE_HIDDEN - -#endif /* !IN_LIBGOCV */ - -#ifndef GCOV_LINKAGE -#define GCOV_LINKAGE extern -#endif - -#if IN_LIBGCOV -#define gcov_nonruntime_assert(EXPR) ((void)(0 && (EXPR))) -#else -#define gcov_nonruntime_assert(EXPR) gcc_assert (EXPR) -#define gcov_error(...) fatal_error (input_location, __VA_ARGS__) -#endif - -/* File suffixes. */ -#define GCOV_DATA_SUFFIX ".gcda" -#define GCOV_NOTE_SUFFIX ".gcno" - -/* File magic. Must not be palindromes. */ -#define GCOV_DATA_MAGIC ((gcov_unsigned_t)0x67636461) /* "gcda" */ -#define GCOV_NOTE_MAGIC ((gcov_unsigned_t)0x67636e6f) /* "gcno" */ - -/* gcov-iov.h is automatically generated by the makefile from - version.c, it looks like - #define GCOV_VERSION ((gcov_unsigned_t)0x89abcdef) -*/ -#define GCOV_VERSION ((gcov_unsigned_t)0x4137352a) -//#include "gcov-iov.h" - -/* Convert a magic or version number to a 4 character string. */ -#define GCOV_UNSIGNED2STRING(ARRAY,VALUE) \ - ((ARRAY)[0] = (char)((VALUE) >> 24), \ - (ARRAY)[1] = (char)((VALUE) >> 16), \ - (ARRAY)[2] = (char)((VALUE) >> 8), \ - (ARRAY)[3] = (char)((VALUE) >> 0)) - -/* The record tags. Values [1..3f] are for tags which may be in either - file. Values [41..9f] for those in the note file and [a1..ff] for - the data file. The tag value zero is used as an explicit end of - file marker -- it is not required to be present. */ - -#define GCOV_TAG_FUNCTION ((gcov_unsigned_t)0x01000000) -#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) -#define GCOV_TAG_ARCS ((gcov_unsigned_t)0x01430000) -#define GCOV_TAG_ARCS_LENGTH(NUM) (1 + (NUM) * 2) -#define GCOV_TAG_ARCS_NUM(LENGTH) (((LENGTH) - 1) / 2) -#define GCOV_TAG_LINES ((gcov_unsigned_t)0x01450000) -#define GCOV_TAG_COUNTER_BASE ((gcov_unsigned_t)0x01a10000) -#define GCOV_TAG_COUNTER_LENGTH(NUM) ((NUM) * 2) -#define GCOV_TAG_COUNTER_NUM(LENGTH) ((LENGTH) / 2) -#define GCOV_TAG_OBJECT_SUMMARY ((gcov_unsigned_t)0xa1000000) /* Obsolete */ -#define GCOV_TAG_PROGRAM_SUMMARY ((gcov_unsigned_t)0xa3000000) -#define GCOV_TAG_SUMMARY_LENGTH(NUM) \ - (1 + GCOV_COUNTERS_SUMMABLE * (10 + 3 * 2) + (NUM) * 5) -#define GCOV_TAG_AFDO_FILE_NAMES ((gcov_unsigned_t)0xaa000000) -#define GCOV_TAG_AFDO_FUNCTION ((gcov_unsigned_t)0xac000000) -#define GCOV_TAG_AFDO_WORKING_SET ((gcov_unsigned_t)0xaf000000) - - -/* Counters that are collected. */ - -#define DEF_GCOV_COUNTER(COUNTER, NAME, MERGE_FN) COUNTER, -enum { -#include "gcov-counter.def" -GCOV_COUNTERS -}; -#undef DEF_GCOV_COUNTER - -/* Counters which can be summaried. */ -#define GCOV_COUNTERS_SUMMABLE (GCOV_COUNTER_ARCS + 1) - -/* The first of counters used for value profiling. They must form a - consecutive interval and their order must match the order of - HIST_TYPEs in value-prof.h. */ -#define GCOV_FIRST_VALUE_COUNTER GCOV_COUNTERS_SUMMABLE - -/* The last of counters used for value profiling. */ -#define GCOV_LAST_VALUE_COUNTER (GCOV_COUNTERS - 1) - -/* Number of counters used for value profiling. */ -#define GCOV_N_VALUE_COUNTERS \ - (GCOV_LAST_VALUE_COUNTER - GCOV_FIRST_VALUE_COUNTER + 1) - -/* The number of hottest callees to be tracked. */ -#define GCOV_ICALL_TOPN_VAL 2 - -/* The number of counter entries per icall callsite. */ -#define GCOV_ICALL_TOPN_NCOUNTS (1 + GCOV_ICALL_TOPN_VAL * 4) - -/* Convert a counter index to a tag. */ -#define GCOV_TAG_FOR_COUNTER(COUNT) \ - (GCOV_TAG_COUNTER_BASE + ((gcov_unsigned_t)(COUNT) << 17)) -/* Convert a tag to a counter. */ -#define GCOV_COUNTER_FOR_TAG(TAG) \ - ((unsigned)(((TAG) - GCOV_TAG_COUNTER_BASE) >> 17)) -/* Check whether a tag is a counter tag. */ -#define GCOV_TAG_IS_COUNTER(TAG) \ - (!((TAG) & 0xFFFF) && GCOV_COUNTER_FOR_TAG (TAG) < GCOV_COUNTERS) - -/* The tag level mask has 1's in the position of the inner levels, & - the lsb of the current level, and zero on the current and outer - levels. */ -#define GCOV_TAG_MASK(TAG) (((TAG) - 1) ^ (TAG)) - -/* Return nonzero if SUB is an immediate subtag of TAG. */ -#define GCOV_TAG_IS_SUBTAG(TAG,SUB) \ - (GCOV_TAG_MASK (TAG) >> 8 == GCOV_TAG_MASK (SUB) \ - && !(((SUB) ^ (TAG)) & ~GCOV_TAG_MASK (TAG))) - -/* Return nonzero if SUB is at a sublevel to TAG. */ -#define GCOV_TAG_IS_SUBLEVEL(TAG,SUB) \ - (GCOV_TAG_MASK (TAG) > GCOV_TAG_MASK (SUB)) - -/* Basic block flags. */ -#define GCOV_BLOCK_UNEXPECTED (1 << 1) - -/* Arc flags. */ -#define GCOV_ARC_ON_TREE (1 << 0) -#define GCOV_ARC_FAKE (1 << 1) -#define GCOV_ARC_FALLTHROUGH (1 << 2) - -/* Structured records. */ - -/* Structure used for each bucket of the log2 histogram of counter values. */ -typedef struct -{ - /* Number of counters whose profile count falls within the bucket. */ - gcov_unsigned_t num_counters; - /* Smallest profile count included in this bucket. */ - gcov_type min_value; - /* Cumulative value of the profile counts in this bucket. */ - gcov_type cum_value; -} gcov_bucket_type; - -/* For a log2 scale histogram with each range split into 4 - linear sub-ranges, there will be at most 64 (max gcov_type bit size) - 1 log2 - ranges since the lowest 2 log2 values share the lowest 4 linear - sub-range (values 0 - 3). This is 252 total entries (63*4). */ - -#define GCOV_HISTOGRAM_SIZE 252 - -/* How many unsigned ints are required to hold a bit vector of non-zero - histogram entries when the histogram is written to the gcov file. - This is essentially a ceiling divide by 32 bits. */ -#define GCOV_HISTOGRAM_BITVECTOR_SIZE (GCOV_HISTOGRAM_SIZE + 31) / 32 - -/* Cumulative counter data. */ -struct gcov_ctr_summary -{ - gcov_unsigned_t num; /* number of counters. */ - gcov_unsigned_t runs; /* number of program runs */ - gcov_type sum_all; /* sum of all counters accumulated. */ - gcov_type run_max; /* maximum value on a single run. */ - gcov_type sum_max; /* sum of individual run max values. */ - gcov_bucket_type histogram[GCOV_HISTOGRAM_SIZE]; /* histogram of - counter values. */ -}; - -/* Object & program summary record. */ -struct gcov_summary -{ - gcov_unsigned_t checksum; /* checksum of program */ - struct gcov_ctr_summary ctrs[GCOV_COUNTERS_SUMMABLE]; -}; - -#if !defined(inhibit_libc) - -/* Functions for reading and writing gcov files. In libgcov you can - open the file for reading then writing. Elsewhere you can open the - file either for reading or for writing. When reading a file you may - use the gcov_read_* functions, gcov_sync, gcov_position, & - gcov_error. When writing a file you may use the gcov_write - functions, gcov_seek & gcov_error. When a file is to be rewritten - you use the functions for reading, then gcov_rewrite then the - functions for writing. Your file may become corrupted if you break - these invariants. */ - -#if !IN_LIBGCOV -GCOV_LINKAGE int gcov_open (const char */*name*/, int /*direction*/); -GCOV_LINKAGE int gcov_magic (gcov_unsigned_t, gcov_unsigned_t); -#endif - -/* Available everywhere. */ -GCOV_LINKAGE int gcov_close (void) ATTRIBUTE_HIDDEN; -GCOV_LINKAGE gcov_unsigned_t gcov_read_unsigned (void) ATTRIBUTE_HIDDEN; -GCOV_LINKAGE gcov_type gcov_read_counter (void) ATTRIBUTE_HIDDEN; -GCOV_LINKAGE void gcov_read_summary (struct gcov_summary *) ATTRIBUTE_HIDDEN; -GCOV_LINKAGE const char *gcov_read_string (void); -GCOV_LINKAGE void gcov_sync (gcov_position_t /*base*/, - gcov_unsigned_t /*length */); - -#if !IN_GCOV -/* Available outside gcov */ -GCOV_LINKAGE void gcov_write_unsigned (gcov_unsigned_t) ATTRIBUTE_HIDDEN; -#endif - -#if !IN_GCOV && !IN_LIBGCOV -/* Available only in compiler */ -GCOV_LINKAGE unsigned gcov_histo_index (gcov_type value); -GCOV_LINKAGE void gcov_write_string (const char *); -GCOV_LINKAGE gcov_position_t gcov_write_tag (gcov_unsigned_t); -GCOV_LINKAGE void gcov_write_length (gcov_position_t /*position*/); -#endif - -#if IN_GCOV <= 0 && !IN_LIBGCOV -/* Available in gcov-dump and the compiler. */ - -/* Number of data points in the working set summary array. Using 128 - provides information for at least every 1% increment of the total - profile size. The last entry is hardwired to 99.9% of the total. */ -#define NUM_GCOV_WORKING_SETS 128 - -/* Working set size statistics for a given percentage of the entire - profile (sum_all from the counter summary). */ -typedef struct gcov_working_set_info -{ - /* Number of hot counters included in this working set. */ - unsigned num_counters; - /* Smallest counter included in this working set. */ - gcov_type min_counter; -} gcov_working_set_t; - -GCOV_LINKAGE void compute_working_sets (const struct gcov_ctr_summary *summary, - gcov_working_set_t *gcov_working_sets); -#endif - -#if IN_GCOV > 0 -/* Available in gcov */ -GCOV_LINKAGE time_t gcov_time (void); -#endif - -#endif /* !inhibit_libc */ - -#endif /* GCC_GCOV_IO_H */