/*
 * 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.
 *
 * Authors: Radhika Jagtap
 *          Andreas Hansson
 *          Thomas Grass
 */

/**
 * @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 "cpu/o3/dyn_inst.hh"
#include "cpu/o3/impl.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"

/**
 * 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 O3CPUImpl::DynInstPtr DynInstPtr;
    typedef typename O3CPUImpl::DynInstConstPtr DynInstConstPtr;
    typedef typename std::pair<InstSeqNum, PhysRegIndex> 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();

    /** Returns the name of the trace probe listener. */
    const std::string name() const;

    /**
     * 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);

    /** Register statistics for the elastic trace. */
    void regStats();

    /** 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;

    /**
     * @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<PhysRegIndex, 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;
        /* Address space id in case of a load/store instruction */
        uint32_t asid;
        /* 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 */
    FullO3CPU<O3CPUImpl>* 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;

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

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

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

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

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

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

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

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

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

};
#endif//__CPU_O3_PROBE_ELASTIC_TRACE_HH__
