/*
 * Copyright (c) 2013 - 2015 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * 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.
 */

/**
 * @file This file describes a trace component which is a cpu probe listener
 * used to generate elastic cpu traces. It registers listeners to probe points
 * in the fetch, rename, iew and commit stages of the O3CPU. It processes the
 * dependency graph of the cpu execution and writes out a protobuf trace. It
 * also generates a protobuf trace of the instruction fetch requests.
 */

#ifndef __CPU_O3_PROBE_ELASTIC_TRACE_HH__
#define __CPU_O3_PROBE_ELASTIC_TRACE_HH__

#include <set>
#include <unordered_map>
#include <utility>

#include "base/statistics.hh"
#include "cpu/o3/dyn_inst_ptr.hh"
#include "cpu/reg_class.hh"
#include "mem/request.hh"
#include "params/ElasticTrace.hh"
#include "proto/inst_dep_record.pb.h"
#include "proto/packet.pb.h"
#include "proto/protoio.hh"
#include "sim/eventq.hh"
#include "sim/probe/probe.hh"

namespace gem5
{

namespace o3
{

class CPU;

/**
 * The elastic trace is a type of probe listener and listens to probe points
 * in multiple stages of the O3CPU. The notify method is called on a probe
 * point typically when an instruction successfully progresses through that
 * stage.
 *
 * As different listener methods mapped to the different probe points execute,
 * relevant information about the instruction, e.g. timestamps and register
 * accesses, are captured and stored in temporary data structures. When the
 * instruction progresses through the commit stage, the timing as well as
 * dependency information about the instruction is finalised and encapsulated in
 * a struct called TraceInfo. TraceInfo objects are collected in a list instead
 * of writing them out to the trace file one a time. This is required as the
 * trace is processed in chunks to evaluate order dependencies and computational
 * delay in case an instruction does not have any register dependencies. By this
 * we achieve a simpler algorithm during replay because every record in the
 * trace can be hooked onto a record in its past. The trace is written out as
 * a protobuf format output file.
 *
 * The output trace can be read in and played back by the TraceCPU.
 */
class ElasticTrace : public ProbeListenerObject
{

  public:
    typedef typename std::pair<InstSeqNum, RegIndex> SeqNumRegPair;

    /** Trace record types corresponding to instruction node types */
    typedef ProtoMessage::InstDepRecord::RecordType RecordType;
    typedef ProtoMessage::InstDepRecord Record;

    /** Constructor */
    ElasticTrace(const ElasticTraceParams &params);

    /**
     * Register the probe listeners that is the methods called on a probe point
     * notify() call.
     */
    void regProbeListeners();

    /** Register all listeners. */
    void regEtraceListeners();

    /**
     * Process any outstanding trace records, flush them out to the protobuf
     * output streams and delete the streams at simulation exit.
     */
    void flushTraces();

    /**
     * Take the fields of the request class object that are relevant to create
     * an instruction fetch request. It creates a protobuf message containing
     * the request fields and writes it to instTraceStream.
     *
     * @param req pointer to the fetch request
     */
    void fetchReqTrace(const RequestPtr &req);

    /**
     * Populate the execute timestamp field in an InstExecInfo object for an
     * instruction in flight.
     *
     * @param dyn_inst pointer to dynamic instruction in flight
     */
    void recordExecTick(const DynInstConstPtr& dyn_inst);

    /**
     * Populate the timestamp field in an InstExecInfo object for an
     * instruction in flight when it is execution is complete and it is ready
     * to commit.
     *
     * @param dyn_inst pointer to dynamic instruction in flight
     */
    void recordToCommTick(const DynInstConstPtr& dyn_inst);

    /**
     * Record a Read After Write physical register dependency if there has
     * been a write to the source register and update the physical register
     * map. For this look up the physRegDepMap with this instruction as the
     * writer of its destination register. If the dependency falls outside the
     * window it is assumed as already complete. Duplicate entries are avoided.
     *
     * @param dyn_inst pointer to dynamic instruction in flight
     */
    void updateRegDep(const DynInstConstPtr& dyn_inst);

    /**
     * When an instruction gets squashed the destination register mapped to it
     * is freed up in the rename stage. Remove the register entry from the
     * physRegDepMap as well to avoid dependencies on squashed instructions.
     *
     * @param inst_reg_pair pair of inst. sequence no. and the register
     */
    void removeRegDepMapEntry(const SeqNumRegPair &inst_reg_pair);

    /**
     * Add an instruction that is at the head of the ROB and is squashed only
     * if it is a load and a request was sent for it.
     *
     * @param head_inst pointer to dynamic instruction to be squashed
     */
    void addSquashedInst(const DynInstConstPtr& head_inst);

    /**
     * Add an instruction that is at the head of the ROB and is committed.
     *
     * @param head_inst pointer to dynamic instruction to be committed
     */
    void addCommittedInst(const DynInstConstPtr& head_inst);

    /** Event to trigger registering this listener for all probe points. */
    EventFunctionWrapper regEtraceListenersEvent;

  private:
    /**
     * Used for checking the first window for processing and writing of
     * dependency trace. At the start of the program there can be dependency-
     * free instructions and such cases are handled differently.
     */
    bool firstWin;

    RegIndex zeroReg;

    /**
     * @defgroup InstExecInfo Struct for storing information before an
     * instruction reaches the commit stage, e.g. execute timestamp.
     */
    struct InstExecInfo
    {
        /**
         * @ingroup InstExecInfo
         * @{
         */
        /** Timestamp when instruction was first processed by execute stage */
        Tick executeTick;
        /**
         * Timestamp when instruction execution is completed in execute stage
         * and instruction is marked as ready to commit
         */
        Tick toCommitTick;
        /**
         * Set of instruction sequence numbers that this instruction depends on
         * due to Read After Write data dependency based on physical register.
         */
        std::set<InstSeqNum> physRegDepSet;
        /** @} */

        /** Constructor */
        InstExecInfo()
          : executeTick(MaxTick),
            toCommitTick(MaxTick)
        { }
    };

    /**
     * Temporary store of InstExecInfo objects. Later on when an instruction
     * is processed for commit or retire, if it is chosen to be written to
     * the output trace then this information is looked up using the instruction
     * sequence number as the key. If it is not chosen then the entry for it in
     * the store is cleared.
     */
    std::unordered_map<InstSeqNum, InstExecInfo*> tempStore;

    /**
     * The last cleared instruction sequence number used to free up the memory
     * allocated in the temporary store.
     */
    InstSeqNum lastClearedSeqNum;

    /**
     * Map for recording the producer of a physical register to check Read
     * After Write dependencies. The key is the renamed physical register and
     * the value is the instruction sequence number of its last producer.
     */
    std::unordered_map<RegIndex, InstSeqNum> physRegDepMap;

    /**
     * @defgroup TraceInfo Struct for a record in the instruction dependency
     * trace. All information required to process and calculate the
     * computational delay is stored in TraceInfo objects. The memory request
     * fields for a load or store instruction are also included here. Note
     * that the structure TraceInfo does not store pointers to children
     * or parents. The dependency trace is maintained as an ordered collection
     * of records for writing to the output trace and not as a tree data
     * structure.
     */
    struct TraceInfo
    {
        /**
         * @ingroup TraceInfo
         * @{
         */
        /* Instruction sequence number. */
        InstSeqNum instNum;
        /** The type of trace record for the instruction node */
        RecordType type;
        /* Tick when instruction was in execute stage. */
        Tick executeTick;
        /* Tick when instruction was marked ready and sent to commit stage. */
        Tick toCommitTick;
        /* Tick when instruction was committed. */
        Tick commitTick;
        /* If instruction was committed, as against squashed. */
        bool commit;
        /* List of order dependencies. */
        std::list<InstSeqNum> robDepList;
        /* List of physical register RAW dependencies. */
        std::list<InstSeqNum> physRegDepList;
        /**
         * Computational delay after the last dependent inst. completed.
         * A value of -1 which means instruction has no dependencies.
         */
        int64_t compDelay;
        /* Number of dependents. */
        uint32_t numDepts;
        /* The instruction PC for a load, store or non load/store. */
        Addr pc;
        /* Request flags in case of a load/store instruction */
        Request::FlagsType reqFlags;
        /* Request physical address in case of a load/store instruction */
        Addr physAddr;
        /* Request virtual address in case of a load/store instruction */
        Addr virtAddr;
        /* Request size in case of a load/store instruction */
        unsigned size;
        /** Default Constructor */
        TraceInfo()
          : type(Record::INVALID)
        { }
        /** Is the record a load */
        bool isLoad() const { return (type == Record::LOAD); }
        /** Is the record a store */
        bool isStore() const { return (type == Record::STORE); }
        /** Is the record a fetch triggering an Icache request */
        bool isComp() const { return (type == Record::COMP); }
        /** Return string specifying the type of the node */
        const std::string& typeToStr() const;
        /** @} */

        /**
         * Get the execute tick of the instruction.
         *
         * @return Tick when instruction was executed
         */
        Tick getExecuteTick() const;
    };

    /**
     * The instruction dependency trace containing TraceInfo objects. The
     * container implemented is sequential as dependencies obey commit
     * order (program order). For example, if B is dependent on A then B must
     * be committed after A. Thus records are updated with dependency
     * information and written to the trace in commit order. This ensures that
     * when a graph is reconstructed from the  trace during replay, all the
     * dependencies are stored in the graph before  the dependent itself is
     * added. This facilitates creating a tree data structure during replay,
     * i.e. adding children as records are read from the trace in an efficient
     * manner.
     */
    std::vector<TraceInfo*> depTrace;

    /**
     * Map where the instruction sequence number is mapped to the pointer to
     * the TraceInfo object.
     */
    std::unordered_map<InstSeqNum, TraceInfo*> traceInfoMap;

    /** Typedef of iterator to the instruction dependency trace. */
    typedef typename std::vector<TraceInfo*>::iterator depTraceItr;

    /** Typedef of the reverse iterator to the instruction dependency trace. */
    typedef typename std::reverse_iterator<depTraceItr> depTraceRevItr;

    /**
     * The maximum distance for a dependency and is set by a top level
     * level parameter. It must be equal to or greater than the number of
     * entries in the ROB. This variable is used as the length of the sliding
     * window for processing the dependency trace.
     */
    uint32_t depWindowSize;

    /** Protobuf output stream for data dependency trace */
    ProtoOutputStream* dataTraceStream;

    /** Protobuf output stream for instruction fetch trace. */
    ProtoOutputStream* instTraceStream;

    /** Number of instructions after which to enable tracing. */
    const InstSeqNum startTraceInst;

    /**
     * Whther the elastic trace listener has been registered for all probes.
     *
     * When enabling tracing after a specified number of instructions have
     * committed, check this to prevent re-registering the listener.
     */
    bool allProbesReg;

    /** Whether to trace virtual addresses for memory requests. */
    const bool traceVirtAddr;

    /** Pointer to the O3CPU that is this listener's parent a.k.a. manager */
    CPU *cpu;

    /**
     * Add a record to the dependency trace depTrace which is a sequential
     * container. A record is inserted per committed instruction and in the same
     * order as the order in which instructions are committed.
     *
     * @param head_inst     Pointer to the instruction which is head of the
     *                      ROB and ready to commit
     * @param exec_info_ptr Pointer to InstExecInfo for that instruction
     * @param commit        True if instruction is committed, false if squashed
     */
    void addDepTraceRecord(const DynInstConstPtr& head_inst,
                           InstExecInfo* exec_info_ptr, bool commit);

    /**
     * Clear entries in the temporary store of execution info objects to free
     * allocated memory until the present instruction being added to the trace.
     *
     * @param head_inst pointer to dynamic instruction
     */
    void clearTempStoreUntil(const DynInstConstPtr& head_inst);

    /**
     * Calculate the computational delay between an instruction and a
     * subsequent instruction that has an ROB (order) dependency on it
     *
     * @param past_record   Pointer to instruction
     *
     * @param new_record    Pointer to subsequent instruction having an ROB
     *                      dependency on the instruction pointed to by
     *                      past_record
     */
    void compDelayRob(TraceInfo* past_record, TraceInfo* new_record);

    /**
     * Calculate the computational delay between an instruction and a
     * subsequent instruction that has a Physical Register (data) dependency on
     * it.
     *
     * @param past_record   Pointer to instruction
     *
     * @param new_record    Pointer to subsequent instruction having a Physical
     *                      Register dependency on the instruction pointed to
     *                      by past_record
     */
    void compDelayPhysRegDep(TraceInfo* past_record, TraceInfo* new_record);

    /**
     * Write out given number of records to the trace starting with the first
     * record in depTrace and iterating through the trace in sequence. A
     * record is deleted after it is written.
     *
     * @param num_to_write Number of records to write to the trace
     */
    void writeDepTrace(uint32_t num_to_write);

    /**
     * Reverse iterate through the graph, search for a store-after-store or
     * store-after-load dependency and update the new node's Rob dependency list.
     *
     * If a dependency is found, then call the assignRobDep() method that
     * updates the store with the dependency information. This function is only
     * called when a new store node is added to the trace.
     *
     * @param new_record    pointer to new store record
     * @param find_load_not_store true for searching store-after-load and false
     *                          for searching store-after-store dependency
     */
    void updateCommitOrderDep(TraceInfo* new_record, bool find_load_not_store);

    /**
     * Reverse iterate through the graph, search for an issue order dependency
     * for a new node and update the new node's Rob dependency list.
     *
     * If a dependency is found, call the assignRobDep() method that updates
     * the node with its dependency information. This function is called in
     * case a new node to be added to the trace is dependency-free or its
     * dependency got discarded because the dependency was outside the window.
     *
     * @param new_record    pointer to new record to be added to the trace
     */
    void updateIssueOrderDep(TraceInfo* new_record);

    /**
     * The new_record has an order dependency on a past_record, thus update the
     * new record's Rob dependency list and increment the number of dependents
     * of the past record.
     *
     * @param new_record    pointer to new record
     * @param past_record   pointer to record that new_record has a rob
     *                      dependency on
     */
    void assignRobDep(TraceInfo* past_record, TraceInfo* new_record);

    /**
     * Check if past record is a store sent earlier than the execute tick.
     *
     * @param past_record   pointer to past store
     * @param execute_tick  tick with which to compare past store's commit tick
     *
     * @return true if past record is store sent earlier
     */
    bool hasStoreCommitted(TraceInfo* past_record, Tick execute_tick) const;

    /**
     * Check if past record is a load that completed earlier than the execute
     * tick.
     *
     * @param past_record   pointer to past load
     * @param execute_tick  tick with which to compare past load's complete
     *                      tick
     *
     * @return true if past record is load completed earlier
     */
    bool hasLoadCompleted(TraceInfo* past_record, Tick execute_tick) const;

    /**
     * Check if past record is a load sent earlier than the execute tick.
     *
     * @param past_record   pointer to past load
     * @param execute_tick  tick with which to compare past load's send tick
     *
     * @return true if past record is load sent earlier
     */
    bool hasLoadBeenSent(TraceInfo* past_record, Tick execute_tick) const;

    /**
     * Check if past record is a comp node that completed earlier than the
     * execute tick.
     *
     * @param past_record   pointer to past comp node
     * @param execute_tick  tick with which to compare past comp node's
     *                      completion tick
     *
     * @return true if past record is comp completed earlier
     */
    bool hasCompCompleted(TraceInfo* past_record, Tick execute_tick) const;

    struct ElasticTraceStats : public statistics::Group
    {
        ElasticTraceStats(statistics::Group *parent);

        /** Number of register dependencies recorded during tracing */
        statistics::Scalar numRegDep;

        /**
         * Number of stores that got assigned a commit order dependency
         * on a past load/store.
         */
        statistics::Scalar numOrderDepStores;

        /**
         * Number of load insts that got assigned an issue order dependency
         * because they were dependency-free.
         */
        statistics::Scalar numIssueOrderDepLoads;

        /**
         * Number of store insts that got assigned an issue order dependency
         * because they were dependency-free.
         */
        statistics::Scalar numIssueOrderDepStores;

        /**
         * Number of non load/store insts that got assigned an issue order
         * dependency because they were dependency-free.
         */
        statistics::Scalar numIssueOrderDepOther;

        /** Number of filtered nodes */
        statistics::Scalar numFilteredNodes;

        /** Maximum number of dependents on any instruction */
        statistics::Scalar maxNumDependents;

        /**
         * Maximum size of the temporary store mostly useful as a check that
         * it is not growing
         */
        statistics::Scalar maxTempStoreSize;

        /**
         * Maximum size of the map that holds the last writer to a physical
         * register.
         */
        statistics::Scalar maxPhysRegDepMapSize;
    } stats;

};

} // namespace o3
} // namespace gem5

#endif//__CPU_O3_PROBE_ELASTIC_TRACE_HH__
