/*
 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "mem/ruby/profiler/AddressProfiler.hh"

#include <vector>

#include "base/stl_helpers.hh"
#include "mem/protocol/RubyRequest.hh"
#include "mem/ruby/profiler/Profiler.hh"

using namespace std;
typedef AddressProfiler::AddressMap AddressMap;

using m5::stl_helpers::operator<<;

// Helper functions
AccessTraceForAddress&
lookupTraceForAddress(Addr addr, AddressMap& record_map)
{
    // we create a static default object here that is used to insert
    // since the insertion will create a copy of the object in the
    // process.  Perhaps this is optimizing early, but it doesn't seem
    // like it could hurt.
    static const AccessTraceForAddress dflt;

    pair<AddressMap::iterator, bool> r =
        record_map.insert(make_pair(addr, dflt));
    AddressMap::iterator i = r.first;
    AccessTraceForAddress &access_trace = i->second;
    if (r.second) {
        // there was nothing there and the insert succeed, so we need
        // to actually set the address.
        access_trace.setAddress(addr);
    }

    return access_trace;
}

void
printSorted(ostream& out, int num_of_sequencers, const AddressMap &record_map,
            string description, Profiler *profiler)
{
    const int records_printed = 100;

    uint64_t misses = 0;
    std::vector<const AccessTraceForAddress *> sorted;

    AddressMap::const_iterator i = record_map.begin();
    AddressMap::const_iterator end = record_map.end();
    for (; i != end; ++i) {
        const AccessTraceForAddress* record = &i->second;
        misses += record->getTotal();
        sorted.push_back(record);
    }
    sort(sorted.begin(), sorted.end(), AccessTraceForAddress::less_equal);

    out << "Total_entries_" << description << ": " << record_map.size()
        << endl;
    if (profiler->getAllInstructions())
        out << "Total_Instructions_" << description << ": " << misses << endl;
    else
        out << "Total_data_misses_" << description << ": " << misses << endl;

    out << "total | load store atomic | user supervisor | sharing | touched-by"
        << endl;

    Histogram remaining_records(1, 100);
    Histogram all_records(1, 100);
    Histogram remaining_records_log(-1);
    Histogram all_records_log(-1);

    // Allows us to track how many lines where touched by n processors
    std::vector<int64_t> m_touched_vec;
    std::vector<int64_t> m_touched_weighted_vec;
    m_touched_vec.resize(num_of_sequencers+1);
    m_touched_weighted_vec.resize(num_of_sequencers+1);
    for (int j = 0; j < m_touched_vec.size(); j++) {
        m_touched_vec[j] = 0;
        m_touched_weighted_vec[j] = 0;
    }

    int counter = 0;
    int max = sorted.size();
    while (counter < max && counter < records_printed) {
        const AccessTraceForAddress* record = sorted[counter];
        double percent = 100.0 * (record->getTotal() / double(misses));
        out << description << " | " << percent << " % " << *record << endl;
        all_records.add(record->getTotal());
        all_records_log.add(record->getTotal());
        counter++;
        m_touched_vec[record->getTouchedBy()]++;
        m_touched_weighted_vec[record->getTouchedBy()] += record->getTotal();
    }

    while (counter < max) {
        const AccessTraceForAddress* record = sorted[counter];
        all_records.add(record->getTotal());
        remaining_records.add(record->getTotal());
        all_records_log.add(record->getTotal());
        remaining_records_log.add(record->getTotal());
        m_touched_vec[record->getTouchedBy()]++;
        m_touched_weighted_vec[record->getTouchedBy()] += record->getTotal();
    }
    out << endl;
    out << "all_records_" << description << ": "
        << all_records << endl
        << "all_records_log_" << description << ": "
        << all_records_log << endl
        << "remaining_records_" << description << ": "
        << remaining_records << endl
        << "remaining_records_log_" << description << ": "
        << remaining_records_log << endl
        << "touched_by_" << description << ": "
        << m_touched_vec << endl
        << "touched_by_weighted_" << description << ": "
        << m_touched_weighted_vec << endl
        << endl;
}

AddressProfiler::AddressProfiler(int num_of_sequencers, Profiler *profiler)
    : m_profiler(profiler)
{
    m_num_of_sequencers = num_of_sequencers;
    clearStats();
}

AddressProfiler::~AddressProfiler()
{
}

void
AddressProfiler::setHotLines(bool hot_lines)
{
    m_hot_lines = hot_lines;
}

void
AddressProfiler::setAllInstructions(bool all_instructions)
{
    m_all_instructions = all_instructions;
}

void
AddressProfiler::printStats(ostream& out) const
{
    if (m_hot_lines) {
        out << endl;
        out << "AddressProfiler Stats" << endl;
        out << "---------------------" << endl;

        out << endl;
        out << "sharing_misses: " << m_sharing_miss_counter << endl;
        out << "getx_sharing_histogram: " << m_getx_sharing_histogram << endl;
        out << "gets_sharing_histogram: " << m_gets_sharing_histogram << endl;

        out << endl;
        out << "Hot Data Blocks" << endl;
        out << "---------------" << endl;
        out << endl;
        printSorted(out, m_num_of_sequencers, m_dataAccessTrace,
                    "block_address", m_profiler);

        out << endl;
        out << "Hot MacroData Blocks" << endl;
        out << "--------------------" << endl;
        out << endl;
        printSorted(out, m_num_of_sequencers, m_macroBlockAccessTrace,
                    "macroblock_address", m_profiler);

        out << "Hot Instructions" << endl;
        out << "----------------" << endl;
        out << endl;
        printSorted(out, m_num_of_sequencers, m_programCounterAccessTrace,
                    "pc_address", m_profiler);
    }

    if (m_all_instructions) {
        out << endl;
        out << "All Instructions Profile:" << endl;
        out << "-------------------------" << endl;
        out << endl;
        printSorted(out, m_num_of_sequencers, m_programCounterAccessTrace,
                    "pc_address", m_profiler);
        out << endl;
    }

    if (m_retryProfileHisto.size() > 0) {
        out << "Retry Profile" << endl;
        out << "-------------" << endl;
        out << endl;
        out << "retry_histogram_absolute: " << m_retryProfileHisto << endl;
        out << "retry_histogram_write: " << m_retryProfileHistoWrite << endl;
        out << "retry_histogram_read: " << m_retryProfileHistoRead << endl;

        out << "retry_histogram_percent: ";
        m_retryProfileHisto.printPercent(out);
        out << endl;

        printSorted(out, m_num_of_sequencers, m_retryProfileMap,
                    "block_address", m_profiler);
        out << endl;
    }
}

void
AddressProfiler::clearStats()
{
    // Clear the maps
    m_sharing_miss_counter = 0;
    m_dataAccessTrace.clear();
    m_macroBlockAccessTrace.clear();
    m_programCounterAccessTrace.clear();
    m_retryProfileMap.clear();
    m_retryProfileHisto.clear();
    m_retryProfileHistoRead.clear();
    m_retryProfileHistoWrite.clear();
    m_getx_sharing_histogram.clear();
    m_gets_sharing_histogram.clear();
}

void
AddressProfiler::profileGetX(Addr datablock, Addr PC,
                             const Set& owner, const Set& sharers,
                             NodeID requestor)
{
    Set indirection_set;
    indirection_set.addSet(sharers);
    indirection_set.addSet(owner);
    indirection_set.remove(requestor);
    int num_indirections = indirection_set.count();

    m_getx_sharing_histogram.add(num_indirections);
    bool indirection_miss = (num_indirections > 0);

    addTraceSample(datablock, PC, RubyRequestType_ST, RubyAccessMode(0),
                   requestor, indirection_miss);
}

void
AddressProfiler::profileGetS(Addr datablock, Addr PC,
                             const Set& owner, const Set& sharers,
                             NodeID requestor)
{
    Set indirection_set;
    indirection_set.addSet(owner);
    indirection_set.remove(requestor);
    int num_indirections = indirection_set.count();

    m_gets_sharing_histogram.add(num_indirections);
    bool indirection_miss = (num_indirections > 0);

    addTraceSample(datablock, PC, RubyRequestType_LD, RubyAccessMode(0),
                   requestor, indirection_miss);
}

void
AddressProfiler::addTraceSample(Addr data_addr, Addr pc_addr,
                                RubyRequestType type,
                                RubyAccessMode access_mode, NodeID id,
                                bool sharing_miss)
{
    if (m_all_instructions) {
        if (sharing_miss) {
            m_sharing_miss_counter++;
        }

        // record data address trace info
        data_addr = makeLineAddress(data_addr);
        lookupTraceForAddress(data_addr, m_dataAccessTrace).
            update(type, access_mode, id, sharing_miss);

        // record macro data address trace info

        // 6 for datablock, 4 to make it 16x more coarse
        Addr macro_addr = maskLowOrderBits(data_addr, 10);
        lookupTraceForAddress(macro_addr, m_macroBlockAccessTrace).
            update(type, access_mode, id, sharing_miss);

        // record program counter address trace info
        lookupTraceForAddress(pc_addr, m_programCounterAccessTrace).
            update(type, access_mode, id, sharing_miss);
    }

    if (m_all_instructions) {
        // This code is used if the address profiler is an
        // all-instructions profiler record program counter address
        // trace info
        lookupTraceForAddress(pc_addr, m_programCounterAccessTrace).
            update(type, access_mode, id, sharing_miss);
    }
}

void
AddressProfiler::profileRetry(Addr data_addr, AccessType type, int count)
{
    m_retryProfileHisto.add(count);
    if (type == AccessType_Read) {
        m_retryProfileHistoRead.add(count);
    } else {
        m_retryProfileHistoWrite.add(count);
    }
    if (count > 1) {
        lookupTraceForAddress(data_addr, m_retryProfileMap).addSample(count);
    }
}
