Пример #1
0
int* inform_black_box(int const *series, size_t l, size_t n, size_t m,
    int const *b, size_t const *r, size_t const *s, int *box, inform_error *err)
{
    if (check_arguments(series, l, n, m, b, r, s, err))
    {
        return NULL;
    }
    size_t max_r, max_s;
    compute_lengths(r, s, l, &max_r, &max_s);

    bool allocate = (box == NULL);
    if (allocate)
    {
        box = calloc(n * (m - max_r - max_s + 1), sizeof(int));
        if (box == NULL)
        {
            INFORM_ERROR_RETURN(err, INFORM_ENOMEM, NULL);
        }
    }

    size_t *data = calloc(2 * l, sizeof(size_t));
    if (data == NULL)
    {
        if (allocate) free(box);
        INFORM_ERROR_RETURN(err, INFORM_ENOMEM, NULL);
    }

    size_t *history = data;
    if (r == NULL)
    {
        for (size_t i = 0; i < l; ++i) history[i] = 1;
    }
    else
    {
        memcpy(history, r, l * sizeof(size_t));
    }

    size_t *future = data + l;
    if (s != NULL)
    {
        memcpy(future, s, l * sizeof(size_t));
    }

    accumulate(series, l, n, m, b, history, future, max_r, max_s, box, err);

    if (inform_failed(err))
    {
        if (allocate) free(box);
        box = NULL;
    }
    free(data);
    return box;
}
void gooda::convert_to_afdo(const gooda::gooda_report& report, gooda::afdo_data& data, boost::program_options::variables_map& vm){
    bool lbr;
    if(vm.count("auto")){
        auto total_count_lbr = total_count(report, BB_EXEC);
        lbr = total_count_lbr > 0;
    } else {
        lbr = vm.count("lbr");
    }

    //Choose the correct counter
    std::string counter_name = lbr ? BB_EXEC : UNHALTED_CORE_CYCLES;

    //Verify that the file has the correct column
    if(!vm.count("auto") && total_count(report, counter_name) == 0){
        throw gooda::gooda_exception("The file is not valid for the current mode");
    }

    //Empty each cache
    inlining_cache.clear();
    discriminator_cache.clear();

    auto filter = get_process_filter(report, vm, counter_name);
    log::emit<log::Debug>() << "Filter by \"" << filter << "\"" << log::endl;

    for(std::size_t i = 0; i < report.functions(); ++i){
        auto& line = report.hotspot_function(i);

        //Only if the function passes the filters
        if(filter.empty() || line.get_string(report.get_hotspot_file().column(PROCESS)) == filter){
            auto string_cycles = line.get_string(report.get_hotspot_file().column(counter_name));

            //Some functions are filled empty by Gooda for some reason
            //In some case, it means 0, in that case, it is not a problem to ignore it either, cause not really hotspot
            if(string_cycles.empty()){
                continue;
            }

            gooda::afdo_function function;
            function.i = i;
            function.executable_file = get_application_file(report, i);
            function.name = line.get_string(report.get_hotspot_file().column(FUNCTION_NAME));

            if(lbr){
                function.total_count = line.get_counter(report.get_hotspot_file().column(SW_INST_RETIRED));
            } else {
                auto count =
                        report.get_hotspot_file().multiplex_line().get_double(report.get_hotspot_file().column(UNHALTED_CORE_CYCLES))
                      * line.get_counter(report.get_hotspot_file().column(UNHALTED_CORE_CYCLES));

                function.total_count = static_cast<gcov_type>(count);
            }

            //We need the asm file to continue

            if(!report.has_asm_file(function.i)){
                continue;
            }

            //Check that the function file is correctly set

            auto& file = report.asm_file(function.i);

            bool invalid = false;

            for(std::size_t j = 0; j < file.lines(); ++j){
                auto& line = file.line(j);

                //Basic Block have no file
                if(boost::starts_with(line.get_string(file.column(DISASSEMBLY)), "Basic Block")){
                    continue;
                }

                //Line without addresses have special meaning
                if(line.get_string(file.column(ADDRESS)).empty()){
                    continue;
                }

                //Gooda does not always found the source file of a function
                //In that case, declare the function as invalid and return quickly
                auto princ_file = line.get_string(file.column(PRINC_FILE));
                if(princ_file == "null"){
                    log::emit<log::Warning>() << function.name << " is invalid (null file)" << log::endl;

                    invalid = true;
                    break;
                }

                if(princ_file.empty()){
                    log::emit<log::Warning>() << function.name << " is invalid (empty file)" << log::endl;

                    invalid = true;
                    break;
                }
            }

            if(invalid){
                continue;
            }

            //Add the function

            data.functions.push_back(std::move(function));
        }
    }

    //Update function names (replace unmangled with mangled names)
    update_function_names(report, data, vm);

    //Fill the inlining cache (gets inlined function names)
    fill_inlining_cache(report, data, vm);

    //Fill the discriminator cache (gets the discriminators of each lines)
    fill_discriminator_cache(report, data, vm);

    //Generate the inline stacks

    for(auto& function : data.functions){
        //Collect function.file and function.entry_count
        auto bbs = collect_basic_blocks(report, function, lbr);

        if(lbr){
            lbr_annotate(report, function, bbs);
        } else {
            ca_annotate(report, function, bbs);
        }
    }

    //Prune uncounted functions
    prune_uncounted_functions(data);

    //Strip current directory from paths
    strip_paths(data);

    //Fill the file name table with the strings from the AFDO profile
    fill_file_name_table(data);

    //Compute the working set
    compute_working_set(report, data, vm, lbr);

    //Set the sizes of the different sections
    compute_lengths(data);

    //Note: No need to fill the modules because it is not used by GCC
    //It will be automatically written empty by the AFDO generator
}