111247Sradhika.jagtap@ARM.com/*
211247Sradhika.jagtap@ARM.com * Copyright (c) 2013 - 2015 ARM Limited
311247Sradhika.jagtap@ARM.com * All rights reserved
411247Sradhika.jagtap@ARM.com *
511247Sradhika.jagtap@ARM.com * The license below extends only to copyright in the software and shall
611247Sradhika.jagtap@ARM.com * not be construed as granting a license to any other intellectual
711247Sradhika.jagtap@ARM.com * property including but not limited to intellectual property relating
811247Sradhika.jagtap@ARM.com * to a hardware implementation of the functionality of the software
911247Sradhika.jagtap@ARM.com * licensed hereunder.  You may use the software subject to the license
1011247Sradhika.jagtap@ARM.com * terms below provided that you ensure that this notice is replicated
1111247Sradhika.jagtap@ARM.com * unmodified and in its entirety in all distributions of the software,
1211247Sradhika.jagtap@ARM.com * modified or unmodified, in source code or in binary form.
1311247Sradhika.jagtap@ARM.com *
1411247Sradhika.jagtap@ARM.com * Redistribution and use in source and binary forms, with or without
1511247Sradhika.jagtap@ARM.com * modification, are permitted provided that the following conditions are
1611247Sradhika.jagtap@ARM.com * met: redistributions of source code must retain the above copyright
1711247Sradhika.jagtap@ARM.com * notice, this list of conditions and the following disclaimer;
1811247Sradhika.jagtap@ARM.com * redistributions in binary form must reproduce the above copyright
1911247Sradhika.jagtap@ARM.com * notice, this list of conditions and the following disclaimer in the
2011247Sradhika.jagtap@ARM.com * documentation and/or other materials provided with the distribution;
2111247Sradhika.jagtap@ARM.com * neither the name of the copyright holders nor the names of its
2211247Sradhika.jagtap@ARM.com * contributors may be used to endorse or promote products derived from
2311247Sradhika.jagtap@ARM.com * this software without specific prior written permission.
2411247Sradhika.jagtap@ARM.com *
2511247Sradhika.jagtap@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2611247Sradhika.jagtap@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2711247Sradhika.jagtap@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2811247Sradhika.jagtap@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2911247Sradhika.jagtap@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3011247Sradhika.jagtap@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3111247Sradhika.jagtap@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3211247Sradhika.jagtap@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3311247Sradhika.jagtap@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3411247Sradhika.jagtap@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3511247Sradhika.jagtap@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3611247Sradhika.jagtap@ARM.com *
3711247Sradhika.jagtap@ARM.com * Authors: Radhika Jagtap
3811247Sradhika.jagtap@ARM.com *          Andreas Hansson
3911247Sradhika.jagtap@ARM.com *          Thomas Grass
4011247Sradhika.jagtap@ARM.com */
4111247Sradhika.jagtap@ARM.com
4211247Sradhika.jagtap@ARM.com/**
4311247Sradhika.jagtap@ARM.com * @file This file describes a trace component which is a cpu probe listener
4411247Sradhika.jagtap@ARM.com * used to generate elastic cpu traces. It registers listeners to probe points
4511247Sradhika.jagtap@ARM.com * in the fetch, rename, iew and commit stages of the O3CPU. It processes the
4611247Sradhika.jagtap@ARM.com * dependency graph of the cpu execution and writes out a protobuf trace. It
4711247Sradhika.jagtap@ARM.com * also generates a protobuf trace of the instruction fetch requests.
4811247Sradhika.jagtap@ARM.com */
4911247Sradhika.jagtap@ARM.com
5011247Sradhika.jagtap@ARM.com#ifndef __CPU_O3_PROBE_ELASTIC_TRACE_HH__
5111247Sradhika.jagtap@ARM.com#define __CPU_O3_PROBE_ELASTIC_TRACE_HH__
5211247Sradhika.jagtap@ARM.com
5311247Sradhika.jagtap@ARM.com#include <set>
5411247Sradhika.jagtap@ARM.com#include <unordered_map>
5511247Sradhika.jagtap@ARM.com#include <utility>
5611247Sradhika.jagtap@ARM.com
5711247Sradhika.jagtap@ARM.com#include "cpu/o3/dyn_inst.hh"
5811247Sradhika.jagtap@ARM.com#include "cpu/o3/impl.hh"
5911247Sradhika.jagtap@ARM.com#include "mem/request.hh"
6011247Sradhika.jagtap@ARM.com#include "params/ElasticTrace.hh"
6111247Sradhika.jagtap@ARM.com#include "proto/inst_dep_record.pb.h"
6211247Sradhika.jagtap@ARM.com#include "proto/packet.pb.h"
6311247Sradhika.jagtap@ARM.com#include "proto/protoio.hh"
6411247Sradhika.jagtap@ARM.com#include "sim/eventq.hh"
6511247Sradhika.jagtap@ARM.com#include "sim/probe/probe.hh"
6611247Sradhika.jagtap@ARM.com
6711247Sradhika.jagtap@ARM.com/**
6811247Sradhika.jagtap@ARM.com * The elastic trace is a type of probe listener and listens to probe points
6911247Sradhika.jagtap@ARM.com * in multiple stages of the O3CPU. The notify method is called on a probe
7011247Sradhika.jagtap@ARM.com * point typically when an instruction successfully progresses through that
7111247Sradhika.jagtap@ARM.com * stage.
7211247Sradhika.jagtap@ARM.com *
7311247Sradhika.jagtap@ARM.com * As different listener methods mapped to the different probe points execute,
7411247Sradhika.jagtap@ARM.com * relevant information about the instruction, e.g. timestamps and register
7511247Sradhika.jagtap@ARM.com * accesses, are captured and stored in temporary data structures. When the
7611247Sradhika.jagtap@ARM.com * instruction progresses through the commit stage, the timing as well as
7711247Sradhika.jagtap@ARM.com * dependency information about the instruction is finalised and encapsulated in
7811247Sradhika.jagtap@ARM.com * a struct called TraceInfo. TraceInfo objects are collected in a list instead
7911247Sradhika.jagtap@ARM.com * of writing them out to the trace file one a time. This is required as the
8011247Sradhika.jagtap@ARM.com * trace is processed in chunks to evaluate order dependencies and computational
8111247Sradhika.jagtap@ARM.com * delay in case an instruction does not have any register dependencies. By this
8211247Sradhika.jagtap@ARM.com * we achieve a simpler algorithm during replay because every record in the
8311247Sradhika.jagtap@ARM.com * trace can be hooked onto a record in its past. The trace is written out as
8411247Sradhika.jagtap@ARM.com * a protobuf format output file.
8511247Sradhika.jagtap@ARM.com *
8611247Sradhika.jagtap@ARM.com * The output trace can be read in and played back by the TraceCPU.
8711247Sradhika.jagtap@ARM.com */
8811247Sradhika.jagtap@ARM.comclass ElasticTrace : public ProbeListenerObject
8911247Sradhika.jagtap@ARM.com{
9011247Sradhika.jagtap@ARM.com
9111247Sradhika.jagtap@ARM.com  public:
9211247Sradhika.jagtap@ARM.com    typedef typename O3CPUImpl::DynInstPtr DynInstPtr;
9313429Srekai.gonzalezalberquilla@arm.com    typedef typename O3CPUImpl::DynInstConstPtr DynInstConstPtr;
9411247Sradhika.jagtap@ARM.com    typedef typename std::pair<InstSeqNum, PhysRegIndex> SeqNumRegPair;
9511247Sradhika.jagtap@ARM.com
9611252Sradhika.jagtap@ARM.com    /** Trace record types corresponding to instruction node types */
9711252Sradhika.jagtap@ARM.com    typedef ProtoMessage::InstDepRecord::RecordType RecordType;
9811252Sradhika.jagtap@ARM.com    typedef ProtoMessage::InstDepRecord Record;
9911252Sradhika.jagtap@ARM.com
10011247Sradhika.jagtap@ARM.com    /** Constructor */
10111247Sradhika.jagtap@ARM.com    ElasticTrace(const ElasticTraceParams *params);
10211247Sradhika.jagtap@ARM.com
10311247Sradhika.jagtap@ARM.com    /**
10411247Sradhika.jagtap@ARM.com     * Register the probe listeners that is the methods called on a probe point
10511247Sradhika.jagtap@ARM.com     * notify() call.
10611247Sradhika.jagtap@ARM.com     */
10711247Sradhika.jagtap@ARM.com    void regProbeListeners();
10811247Sradhika.jagtap@ARM.com
10911247Sradhika.jagtap@ARM.com    /** Register all listeners. */
11011247Sradhika.jagtap@ARM.com    void regEtraceListeners();
11111247Sradhika.jagtap@ARM.com
11211247Sradhika.jagtap@ARM.com    /** Returns the name of the trace probe listener. */
11311247Sradhika.jagtap@ARM.com    const std::string name() const;
11411247Sradhika.jagtap@ARM.com
11511247Sradhika.jagtap@ARM.com    /**
11611247Sradhika.jagtap@ARM.com     * Process any outstanding trace records, flush them out to the protobuf
11711247Sradhika.jagtap@ARM.com     * output streams and delete the streams at simulation exit.
11811247Sradhika.jagtap@ARM.com     */
11911247Sradhika.jagtap@ARM.com    void flushTraces();
12011247Sradhika.jagtap@ARM.com
12111247Sradhika.jagtap@ARM.com    /**
12211247Sradhika.jagtap@ARM.com     * Take the fields of the request class object that are relevant to create
12311247Sradhika.jagtap@ARM.com     * an instruction fetch request. It creates a protobuf message containing
12411247Sradhika.jagtap@ARM.com     * the request fields and writes it to instTraceStream.
12511247Sradhika.jagtap@ARM.com     *
12611247Sradhika.jagtap@ARM.com     * @param req pointer to the fetch request
12711247Sradhika.jagtap@ARM.com     */
12811247Sradhika.jagtap@ARM.com    void fetchReqTrace(const RequestPtr &req);
12911247Sradhika.jagtap@ARM.com
13011247Sradhika.jagtap@ARM.com    /**
13111247Sradhika.jagtap@ARM.com     * Populate the execute timestamp field in an InstExecInfo object for an
13211247Sradhika.jagtap@ARM.com     * instruction in flight.
13311247Sradhika.jagtap@ARM.com     *
13411247Sradhika.jagtap@ARM.com     * @param dyn_inst pointer to dynamic instruction in flight
13511247Sradhika.jagtap@ARM.com     */
13613429Srekai.gonzalezalberquilla@arm.com    void recordExecTick(const DynInstConstPtr& dyn_inst);
13711247Sradhika.jagtap@ARM.com
13811247Sradhika.jagtap@ARM.com    /**
13911247Sradhika.jagtap@ARM.com     * Populate the timestamp field in an InstExecInfo object for an
14011247Sradhika.jagtap@ARM.com     * instruction in flight when it is execution is complete and it is ready
14111247Sradhika.jagtap@ARM.com     * to commit.
14211247Sradhika.jagtap@ARM.com     *
14311247Sradhika.jagtap@ARM.com     * @param dyn_inst pointer to dynamic instruction in flight
14411247Sradhika.jagtap@ARM.com     */
14513429Srekai.gonzalezalberquilla@arm.com    void recordToCommTick(const DynInstConstPtr& dyn_inst);
14611247Sradhika.jagtap@ARM.com
14711247Sradhika.jagtap@ARM.com    /**
14811247Sradhika.jagtap@ARM.com     * Record a Read After Write physical register dependency if there has
14911247Sradhika.jagtap@ARM.com     * been a write to the source register and update the physical register
15011247Sradhika.jagtap@ARM.com     * map. For this look up the physRegDepMap with this instruction as the
15111247Sradhika.jagtap@ARM.com     * writer of its destination register. If the dependency falls outside the
15211247Sradhika.jagtap@ARM.com     * window it is assumed as already complete. Duplicate entries are avoided.
15311247Sradhika.jagtap@ARM.com     *
15411247Sradhika.jagtap@ARM.com     * @param dyn_inst pointer to dynamic instruction in flight
15511247Sradhika.jagtap@ARM.com     */
15613429Srekai.gonzalezalberquilla@arm.com    void updateRegDep(const DynInstConstPtr& dyn_inst);
15711247Sradhika.jagtap@ARM.com
15811247Sradhika.jagtap@ARM.com    /**
15911247Sradhika.jagtap@ARM.com     * When an instruction gets squashed the destination register mapped to it
16011247Sradhika.jagtap@ARM.com     * is freed up in the rename stage. Remove the register entry from the
16111247Sradhika.jagtap@ARM.com     * physRegDepMap as well to avoid dependencies on squashed instructions.
16211247Sradhika.jagtap@ARM.com     *
16311247Sradhika.jagtap@ARM.com     * @param inst_reg_pair pair of inst. sequence no. and the register
16411247Sradhika.jagtap@ARM.com     */
16511247Sradhika.jagtap@ARM.com    void removeRegDepMapEntry(const SeqNumRegPair &inst_reg_pair);
16611247Sradhika.jagtap@ARM.com
16711247Sradhika.jagtap@ARM.com    /**
16811247Sradhika.jagtap@ARM.com     * Add an instruction that is at the head of the ROB and is squashed only
16911247Sradhika.jagtap@ARM.com     * if it is a load and a request was sent for it.
17011247Sradhika.jagtap@ARM.com     *
17111247Sradhika.jagtap@ARM.com     * @param head_inst pointer to dynamic instruction to be squashed
17211247Sradhika.jagtap@ARM.com     */
17313429Srekai.gonzalezalberquilla@arm.com    void addSquashedInst(const DynInstConstPtr& head_inst);
17411247Sradhika.jagtap@ARM.com
17511247Sradhika.jagtap@ARM.com    /**
17611247Sradhika.jagtap@ARM.com     * Add an instruction that is at the head of the ROB and is committed.
17711247Sradhika.jagtap@ARM.com     *
17811247Sradhika.jagtap@ARM.com     * @param head_inst pointer to dynamic instruction to be committed
17911247Sradhika.jagtap@ARM.com     */
18013429Srekai.gonzalezalberquilla@arm.com    void addCommittedInst(const DynInstConstPtr& head_inst);
18111247Sradhika.jagtap@ARM.com
18211247Sradhika.jagtap@ARM.com    /** Register statistics for the elastic trace. */
18311247Sradhika.jagtap@ARM.com    void regStats();
18411247Sradhika.jagtap@ARM.com
18511247Sradhika.jagtap@ARM.com    /** Event to trigger registering this listener for all probe points. */
18612085Sspwilson2@wisc.edu    EventFunctionWrapper regEtraceListenersEvent;
18711247Sradhika.jagtap@ARM.com
18811247Sradhika.jagtap@ARM.com  private:
18911247Sradhika.jagtap@ARM.com    /**
19011247Sradhika.jagtap@ARM.com     * Used for checking the first window for processing and writing of
19111247Sradhika.jagtap@ARM.com     * dependency trace. At the start of the program there can be dependency-
19211247Sradhika.jagtap@ARM.com     * free instructions and such cases are handled differently.
19311247Sradhika.jagtap@ARM.com     */
19411247Sradhika.jagtap@ARM.com    bool firstWin;
19511247Sradhika.jagtap@ARM.com
19611247Sradhika.jagtap@ARM.com    /**
19711247Sradhika.jagtap@ARM.com     * @defgroup InstExecInfo Struct for storing information before an
19811247Sradhika.jagtap@ARM.com     * instruction reaches the commit stage, e.g. execute timestamp.
19911247Sradhika.jagtap@ARM.com     */
20011247Sradhika.jagtap@ARM.com    struct InstExecInfo
20111247Sradhika.jagtap@ARM.com    {
20211247Sradhika.jagtap@ARM.com        /**
20311247Sradhika.jagtap@ARM.com         * @ingroup InstExecInfo
20411247Sradhika.jagtap@ARM.com         * @{
20511247Sradhika.jagtap@ARM.com         */
20611247Sradhika.jagtap@ARM.com        /** Timestamp when instruction was first processed by execute stage */
20711247Sradhika.jagtap@ARM.com        Tick executeTick;
20811247Sradhika.jagtap@ARM.com        /**
20911247Sradhika.jagtap@ARM.com         * Timestamp when instruction execution is completed in execute stage
21011247Sradhika.jagtap@ARM.com         * and instruction is marked as ready to commit
21111247Sradhika.jagtap@ARM.com         */
21211247Sradhika.jagtap@ARM.com        Tick toCommitTick;
21311247Sradhika.jagtap@ARM.com        /**
21411247Sradhika.jagtap@ARM.com         * Set of instruction sequence numbers that this instruction depends on
21511247Sradhika.jagtap@ARM.com         * due to Read After Write data dependency based on physical register.
21611247Sradhika.jagtap@ARM.com         */
21711247Sradhika.jagtap@ARM.com        std::set<InstSeqNum> physRegDepSet;
21811247Sradhika.jagtap@ARM.com        /** @} */
21911247Sradhika.jagtap@ARM.com
22011247Sradhika.jagtap@ARM.com        /** Constructor */
22111247Sradhika.jagtap@ARM.com        InstExecInfo()
22211247Sradhika.jagtap@ARM.com          : executeTick(MaxTick),
22311247Sradhika.jagtap@ARM.com            toCommitTick(MaxTick)
22411247Sradhika.jagtap@ARM.com        { }
22511247Sradhika.jagtap@ARM.com    };
22611247Sradhika.jagtap@ARM.com
22711247Sradhika.jagtap@ARM.com    /**
22811247Sradhika.jagtap@ARM.com     * Temporary store of InstExecInfo objects. Later on when an instruction
22911247Sradhika.jagtap@ARM.com     * is processed for commit or retire, if it is chosen to be written to
23011247Sradhika.jagtap@ARM.com     * the output trace then this information is looked up using the instruction
23111247Sradhika.jagtap@ARM.com     * sequence number as the key. If it is not chosen then the entry for it in
23211247Sradhika.jagtap@ARM.com     * the store is cleared.
23311247Sradhika.jagtap@ARM.com     */
23411247Sradhika.jagtap@ARM.com    std::unordered_map<InstSeqNum, InstExecInfo*> tempStore;
23511247Sradhika.jagtap@ARM.com
23611247Sradhika.jagtap@ARM.com    /**
23711247Sradhika.jagtap@ARM.com     * The last cleared instruction sequence number used to free up the memory
23811247Sradhika.jagtap@ARM.com     * allocated in the temporary store.
23911247Sradhika.jagtap@ARM.com     */
24011247Sradhika.jagtap@ARM.com    InstSeqNum lastClearedSeqNum;
24111247Sradhika.jagtap@ARM.com
24211247Sradhika.jagtap@ARM.com    /**
24311247Sradhika.jagtap@ARM.com     * Map for recording the producer of a physical register to check Read
24411247Sradhika.jagtap@ARM.com     * After Write dependencies. The key is the renamed physical register and
24511247Sradhika.jagtap@ARM.com     * the value is the instruction sequence number of its last producer.
24611247Sradhika.jagtap@ARM.com     */
24711247Sradhika.jagtap@ARM.com    std::unordered_map<PhysRegIndex, InstSeqNum> physRegDepMap;
24811247Sradhika.jagtap@ARM.com
24911247Sradhika.jagtap@ARM.com    /**
25011247Sradhika.jagtap@ARM.com     * @defgroup TraceInfo Struct for a record in the instruction dependency
25111247Sradhika.jagtap@ARM.com     * trace. All information required to process and calculate the
25211247Sradhika.jagtap@ARM.com     * computational delay is stored in TraceInfo objects. The memory request
25311247Sradhika.jagtap@ARM.com     * fields for a load or store instruction are also included here. Note
25411247Sradhika.jagtap@ARM.com     * that the structure TraceInfo does not store pointers to children
25511247Sradhika.jagtap@ARM.com     * or parents. The dependency trace is maintained as an ordered collection
25611247Sradhika.jagtap@ARM.com     * of records for writing to the output trace and not as a tree data
25711247Sradhika.jagtap@ARM.com     * structure.
25811247Sradhika.jagtap@ARM.com     */
25911247Sradhika.jagtap@ARM.com    struct TraceInfo
26011247Sradhika.jagtap@ARM.com    {
26111247Sradhika.jagtap@ARM.com        /**
26211247Sradhika.jagtap@ARM.com         * @ingroup TraceInfo
26311247Sradhika.jagtap@ARM.com         * @{
26411247Sradhika.jagtap@ARM.com         */
26511247Sradhika.jagtap@ARM.com        /* Instruction sequence number. */
26611247Sradhika.jagtap@ARM.com        InstSeqNum instNum;
26711252Sradhika.jagtap@ARM.com        /** The type of trace record for the instruction node */
26811252Sradhika.jagtap@ARM.com        RecordType type;
26911247Sradhika.jagtap@ARM.com        /* Tick when instruction was in execute stage. */
27011247Sradhika.jagtap@ARM.com        Tick executeTick;
27111247Sradhika.jagtap@ARM.com        /* Tick when instruction was marked ready and sent to commit stage. */
27211247Sradhika.jagtap@ARM.com        Tick toCommitTick;
27311247Sradhika.jagtap@ARM.com        /* Tick when instruction was committed. */
27411247Sradhika.jagtap@ARM.com        Tick commitTick;
27511252Sradhika.jagtap@ARM.com        /* If instruction was committed, as against squashed. */
27611252Sradhika.jagtap@ARM.com        bool commit;
27711247Sradhika.jagtap@ARM.com        /* List of order dependencies. */
27811247Sradhika.jagtap@ARM.com        std::list<InstSeqNum> robDepList;
27911247Sradhika.jagtap@ARM.com        /* List of physical register RAW dependencies. */
28011247Sradhika.jagtap@ARM.com        std::list<InstSeqNum> physRegDepList;
28111247Sradhika.jagtap@ARM.com        /**
28211247Sradhika.jagtap@ARM.com         * Computational delay after the last dependent inst. completed.
28311247Sradhika.jagtap@ARM.com         * A value of -1 which means instruction has no dependencies.
28411247Sradhika.jagtap@ARM.com         */
28511247Sradhika.jagtap@ARM.com        int64_t compDelay;
28611247Sradhika.jagtap@ARM.com        /* Number of dependents. */
28711247Sradhika.jagtap@ARM.com        uint32_t numDepts;
28811247Sradhika.jagtap@ARM.com        /* The instruction PC for a load, store or non load/store. */
28911247Sradhika.jagtap@ARM.com        Addr pc;
29011247Sradhika.jagtap@ARM.com        /* Request flags in case of a load/store instruction */
29111247Sradhika.jagtap@ARM.com        Request::FlagsType reqFlags;
29211253Sradhika.jagtap@ARM.com        /* Request physical address in case of a load/store instruction */
29311253Sradhika.jagtap@ARM.com        Addr physAddr;
29411253Sradhika.jagtap@ARM.com        /* Request virtual address in case of a load/store instruction */
29511253Sradhika.jagtap@ARM.com        Addr virtAddr;
29611253Sradhika.jagtap@ARM.com        /* Address space id in case of a load/store instruction */
29711253Sradhika.jagtap@ARM.com        uint32_t asid;
29811247Sradhika.jagtap@ARM.com        /* Request size in case of a load/store instruction */
29911247Sradhika.jagtap@ARM.com        unsigned size;
30011252Sradhika.jagtap@ARM.com        /** Default Constructor */
30111252Sradhika.jagtap@ARM.com        TraceInfo()
30211252Sradhika.jagtap@ARM.com          : type(Record::INVALID)
30311252Sradhika.jagtap@ARM.com        { }
30411252Sradhika.jagtap@ARM.com        /** Is the record a load */
30511252Sradhika.jagtap@ARM.com        bool isLoad() const { return (type == Record::LOAD); }
30611252Sradhika.jagtap@ARM.com        /** Is the record a store */
30711252Sradhika.jagtap@ARM.com        bool isStore() const { return (type == Record::STORE); }
30811252Sradhika.jagtap@ARM.com        /** Is the record a fetch triggering an Icache request */
30911252Sradhika.jagtap@ARM.com        bool isComp() const { return (type == Record::COMP); }
31011252Sradhika.jagtap@ARM.com        /** Return string specifying the type of the node */
31111252Sradhika.jagtap@ARM.com        const std::string& typeToStr() const;
31211247Sradhika.jagtap@ARM.com        /** @} */
31311247Sradhika.jagtap@ARM.com
31411247Sradhika.jagtap@ARM.com        /**
31511247Sradhika.jagtap@ARM.com         * Get the execute tick of the instruction.
31611247Sradhika.jagtap@ARM.com         *
31711247Sradhika.jagtap@ARM.com         * @return Tick when instruction was executed
31811247Sradhika.jagtap@ARM.com         */
31911247Sradhika.jagtap@ARM.com        Tick getExecuteTick() const;
32011247Sradhika.jagtap@ARM.com    };
32111247Sradhika.jagtap@ARM.com
32211247Sradhika.jagtap@ARM.com    /**
32311247Sradhika.jagtap@ARM.com     * The instruction dependency trace containing TraceInfo objects. The
32411247Sradhika.jagtap@ARM.com     * container implemented is sequential as dependencies obey commit
32511247Sradhika.jagtap@ARM.com     * order (program order). For example, if B is dependent on A then B must
32611247Sradhika.jagtap@ARM.com     * be committed after A. Thus records are updated with dependency
32711247Sradhika.jagtap@ARM.com     * information and written to the trace in commit order. This ensures that
32811247Sradhika.jagtap@ARM.com     * when a graph is reconstructed from the  trace during replay, all the
32911247Sradhika.jagtap@ARM.com     * dependencies are stored in the graph before  the dependent itself is
33011247Sradhika.jagtap@ARM.com     * added. This facilitates creating a tree data structure during replay,
33111247Sradhika.jagtap@ARM.com     * i.e. adding children as records are read from the trace in an efficient
33211247Sradhika.jagtap@ARM.com     * manner.
33311247Sradhika.jagtap@ARM.com     */
33411247Sradhika.jagtap@ARM.com    std::vector<TraceInfo*> depTrace;
33511247Sradhika.jagtap@ARM.com
33611247Sradhika.jagtap@ARM.com    /**
33711247Sradhika.jagtap@ARM.com     * Map where the instruction sequence number is mapped to the pointer to
33811247Sradhika.jagtap@ARM.com     * the TraceInfo object.
33911247Sradhika.jagtap@ARM.com     */
34011247Sradhika.jagtap@ARM.com    std::unordered_map<InstSeqNum, TraceInfo*> traceInfoMap;
34111247Sradhika.jagtap@ARM.com
34211247Sradhika.jagtap@ARM.com    /** Typedef of iterator to the instruction dependency trace. */
34311247Sradhika.jagtap@ARM.com    typedef typename std::vector<TraceInfo*>::iterator depTraceItr;
34411247Sradhika.jagtap@ARM.com
34511247Sradhika.jagtap@ARM.com    /** Typedef of the reverse iterator to the instruction dependency trace. */
34611247Sradhika.jagtap@ARM.com    typedef typename std::reverse_iterator<depTraceItr> depTraceRevItr;
34711247Sradhika.jagtap@ARM.com
34811247Sradhika.jagtap@ARM.com    /**
34911247Sradhika.jagtap@ARM.com     * The maximum distance for a dependency and is set by a top level
35011247Sradhika.jagtap@ARM.com     * level parameter. It must be equal to or greater than the number of
35111247Sradhika.jagtap@ARM.com     * entries in the ROB. This variable is used as the length of the sliding
35211247Sradhika.jagtap@ARM.com     * window for processing the dependency trace.
35311247Sradhika.jagtap@ARM.com     */
35411247Sradhika.jagtap@ARM.com    uint32_t depWindowSize;
35511247Sradhika.jagtap@ARM.com
35611247Sradhika.jagtap@ARM.com    /** Protobuf output stream for data dependency trace */
35711247Sradhika.jagtap@ARM.com    ProtoOutputStream* dataTraceStream;
35811247Sradhika.jagtap@ARM.com
35911247Sradhika.jagtap@ARM.com    /** Protobuf output stream for instruction fetch trace. */
36011247Sradhika.jagtap@ARM.com    ProtoOutputStream* instTraceStream;
36111247Sradhika.jagtap@ARM.com
36211247Sradhika.jagtap@ARM.com    /** Number of instructions after which to enable tracing. */
36311247Sradhika.jagtap@ARM.com    const InstSeqNum startTraceInst;
36411247Sradhika.jagtap@ARM.com
36511247Sradhika.jagtap@ARM.com    /**
36611247Sradhika.jagtap@ARM.com     * Whther the elastic trace listener has been registered for all probes.
36711247Sradhika.jagtap@ARM.com     *
36811247Sradhika.jagtap@ARM.com     * When enabling tracing after a specified number of instructions have
36911247Sradhika.jagtap@ARM.com     * committed, check this to prevent re-registering the listener.
37011247Sradhika.jagtap@ARM.com     */
37111247Sradhika.jagtap@ARM.com    bool allProbesReg;
37211247Sradhika.jagtap@ARM.com
37311253Sradhika.jagtap@ARM.com    /** Whether to trace virtual addresses for memory requests. */
37411253Sradhika.jagtap@ARM.com    const bool traceVirtAddr;
37511253Sradhika.jagtap@ARM.com
37611247Sradhika.jagtap@ARM.com    /** Pointer to the O3CPU that is this listener's parent a.k.a. manager */
37711247Sradhika.jagtap@ARM.com    FullO3CPU<O3CPUImpl>* cpu;
37811247Sradhika.jagtap@ARM.com
37911247Sradhika.jagtap@ARM.com    /**
38011247Sradhika.jagtap@ARM.com     * Add a record to the dependency trace depTrace which is a sequential
38111247Sradhika.jagtap@ARM.com     * container. A record is inserted per committed instruction and in the same
38211247Sradhika.jagtap@ARM.com     * order as the order in which instructions are committed.
38311247Sradhika.jagtap@ARM.com     *
38411247Sradhika.jagtap@ARM.com     * @param head_inst     Pointer to the instruction which is head of the
38511247Sradhika.jagtap@ARM.com     *                      ROB and ready to commit
38611247Sradhika.jagtap@ARM.com     * @param exec_info_ptr Pointer to InstExecInfo for that instruction
38711247Sradhika.jagtap@ARM.com     * @param commit        True if instruction is committed, false if squashed
38811247Sradhika.jagtap@ARM.com     */
38913429Srekai.gonzalezalberquilla@arm.com    void addDepTraceRecord(const DynInstConstPtr& head_inst,
39011247Sradhika.jagtap@ARM.com                           InstExecInfo* exec_info_ptr, bool commit);
39111247Sradhika.jagtap@ARM.com
39211247Sradhika.jagtap@ARM.com    /**
39311247Sradhika.jagtap@ARM.com     * Clear entries in the temporary store of execution info objects to free
39411247Sradhika.jagtap@ARM.com     * allocated memory until the present instruction being added to the trace.
39511247Sradhika.jagtap@ARM.com     *
39611247Sradhika.jagtap@ARM.com     * @param head_inst pointer to dynamic instruction
39711247Sradhika.jagtap@ARM.com     */
39813429Srekai.gonzalezalberquilla@arm.com    void clearTempStoreUntil(const DynInstConstPtr& head_inst);
39911247Sradhika.jagtap@ARM.com
40011247Sradhika.jagtap@ARM.com    /**
40111247Sradhika.jagtap@ARM.com     * Calculate the computational delay between an instruction and a
40211247Sradhika.jagtap@ARM.com     * subsequent instruction that has an ROB (order) dependency on it
40311247Sradhika.jagtap@ARM.com     *
40411247Sradhika.jagtap@ARM.com     * @param past_record   Pointer to instruction
40511247Sradhika.jagtap@ARM.com     *
40611247Sradhika.jagtap@ARM.com     * @param new_record    Pointer to subsequent instruction having an ROB
40711247Sradhika.jagtap@ARM.com     *                      dependency on the instruction pointed to by
40811247Sradhika.jagtap@ARM.com     *                      past_record
40911247Sradhika.jagtap@ARM.com     */
41011247Sradhika.jagtap@ARM.com    void compDelayRob(TraceInfo* past_record, TraceInfo* new_record);
41111247Sradhika.jagtap@ARM.com
41211247Sradhika.jagtap@ARM.com    /**
41311247Sradhika.jagtap@ARM.com     * Calculate the computational delay between an instruction and a
41411247Sradhika.jagtap@ARM.com     * subsequent instruction that has a Physical Register (data) dependency on
41511247Sradhika.jagtap@ARM.com     * it.
41611247Sradhika.jagtap@ARM.com     *
41711247Sradhika.jagtap@ARM.com     * @param past_record   Pointer to instruction
41811247Sradhika.jagtap@ARM.com     *
41911247Sradhika.jagtap@ARM.com     * @param new_record    Pointer to subsequent instruction having a Physical
42011247Sradhika.jagtap@ARM.com     *                      Register dependency on the instruction pointed to
42111247Sradhika.jagtap@ARM.com     *                      by past_record
42211247Sradhika.jagtap@ARM.com     */
42311247Sradhika.jagtap@ARM.com    void compDelayPhysRegDep(TraceInfo* past_record, TraceInfo* new_record);
42411247Sradhika.jagtap@ARM.com
42511247Sradhika.jagtap@ARM.com    /**
42611247Sradhika.jagtap@ARM.com     * Write out given number of records to the trace starting with the first
42711247Sradhika.jagtap@ARM.com     * record in depTrace and iterating through the trace in sequence. A
42811247Sradhika.jagtap@ARM.com     * record is deleted after it is written.
42911247Sradhika.jagtap@ARM.com     *
43011247Sradhika.jagtap@ARM.com     * @param num_to_write Number of records to write to the trace
43111247Sradhika.jagtap@ARM.com     */
43211247Sradhika.jagtap@ARM.com    void writeDepTrace(uint32_t num_to_write);
43311247Sradhika.jagtap@ARM.com
43411247Sradhika.jagtap@ARM.com    /**
43511247Sradhika.jagtap@ARM.com     * Reverse iterate through the graph, search for a store-after-store or
43611247Sradhika.jagtap@ARM.com     * store-after-load dependency and update the new node's Rob dependency list.
43711247Sradhika.jagtap@ARM.com     *
43811247Sradhika.jagtap@ARM.com     * If a dependency is found, then call the assignRobDep() method that
43911247Sradhika.jagtap@ARM.com     * updates the store with the dependency information. This function is only
44011247Sradhika.jagtap@ARM.com     * called when a new store node is added to the trace.
44111247Sradhika.jagtap@ARM.com     *
44211247Sradhika.jagtap@ARM.com     * @param new_record    pointer to new store record
44311247Sradhika.jagtap@ARM.com     * @param find_load_not_store true for searching store-after-load and false
44411247Sradhika.jagtap@ARM.com     *                          for searching store-after-store dependency
44511247Sradhika.jagtap@ARM.com     */
44611247Sradhika.jagtap@ARM.com    void updateCommitOrderDep(TraceInfo* new_record, bool find_load_not_store);
44711247Sradhika.jagtap@ARM.com
44811247Sradhika.jagtap@ARM.com    /**
44911247Sradhika.jagtap@ARM.com     * Reverse iterate through the graph, search for an issue order dependency
45011247Sradhika.jagtap@ARM.com     * for a new node and update the new node's Rob dependency list.
45111247Sradhika.jagtap@ARM.com     *
45211247Sradhika.jagtap@ARM.com     * If a dependency is found, call the assignRobDep() method that updates
45311247Sradhika.jagtap@ARM.com     * the node with its dependency information. This function is called in
45411247Sradhika.jagtap@ARM.com     * case a new node to be added to the trace is dependency-free or its
45511247Sradhika.jagtap@ARM.com     * dependency got discarded because the dependency was outside the window.
45611247Sradhika.jagtap@ARM.com     *
45711247Sradhika.jagtap@ARM.com     * @param new_record    pointer to new record to be added to the trace
45811247Sradhika.jagtap@ARM.com     */
45911247Sradhika.jagtap@ARM.com    void updateIssueOrderDep(TraceInfo* new_record);
46011247Sradhika.jagtap@ARM.com
46111247Sradhika.jagtap@ARM.com    /**
46211247Sradhika.jagtap@ARM.com     * The new_record has an order dependency on a past_record, thus update the
46311247Sradhika.jagtap@ARM.com     * new record's Rob dependency list and increment the number of dependents
46411247Sradhika.jagtap@ARM.com     * of the past record.
46511247Sradhika.jagtap@ARM.com     *
46611247Sradhika.jagtap@ARM.com     * @param new_record    pointer to new record
46711247Sradhika.jagtap@ARM.com     * @param past_record   pointer to record that new_record has a rob
46811247Sradhika.jagtap@ARM.com     *                      dependency on
46911247Sradhika.jagtap@ARM.com     */
47011247Sradhika.jagtap@ARM.com    void assignRobDep(TraceInfo* past_record, TraceInfo* new_record);
47111247Sradhika.jagtap@ARM.com
47211247Sradhika.jagtap@ARM.com    /**
47311247Sradhika.jagtap@ARM.com     * Check if past record is a store sent earlier than the execute tick.
47411247Sradhika.jagtap@ARM.com     *
47511247Sradhika.jagtap@ARM.com     * @param past_record   pointer to past store
47611247Sradhika.jagtap@ARM.com     * @param execute_tick  tick with which to compare past store's commit tick
47711247Sradhika.jagtap@ARM.com     *
47811247Sradhika.jagtap@ARM.com     * @return true if past record is store sent earlier
47911247Sradhika.jagtap@ARM.com     */
48011247Sradhika.jagtap@ARM.com    bool hasStoreCommitted(TraceInfo* past_record, Tick execute_tick) const;
48111247Sradhika.jagtap@ARM.com
48211247Sradhika.jagtap@ARM.com    /**
48311247Sradhika.jagtap@ARM.com     * Check if past record is a load that completed earlier than the execute
48411247Sradhika.jagtap@ARM.com     * tick.
48511247Sradhika.jagtap@ARM.com     *
48611247Sradhika.jagtap@ARM.com     * @param past_record   pointer to past load
48711247Sradhika.jagtap@ARM.com     * @param execute_tick  tick with which to compare past load's complete
48811247Sradhika.jagtap@ARM.com     *                      tick
48911247Sradhika.jagtap@ARM.com     *
49011247Sradhika.jagtap@ARM.com     * @return true if past record is load completed earlier
49111247Sradhika.jagtap@ARM.com     */
49211247Sradhika.jagtap@ARM.com    bool hasLoadCompleted(TraceInfo* past_record, Tick execute_tick) const;
49311247Sradhika.jagtap@ARM.com
49411247Sradhika.jagtap@ARM.com    /**
49511247Sradhika.jagtap@ARM.com     * Check if past record is a load sent earlier than the execute tick.
49611247Sradhika.jagtap@ARM.com     *
49711247Sradhika.jagtap@ARM.com     * @param past_record   pointer to past load
49811247Sradhika.jagtap@ARM.com     * @param execute_tick  tick with which to compare past load's send tick
49911247Sradhika.jagtap@ARM.com     *
50011247Sradhika.jagtap@ARM.com     * @return true if past record is load sent earlier
50111247Sradhika.jagtap@ARM.com     */
50211247Sradhika.jagtap@ARM.com    bool hasLoadBeenSent(TraceInfo* past_record, Tick execute_tick) const;
50311247Sradhika.jagtap@ARM.com
50411247Sradhika.jagtap@ARM.com    /**
50511247Sradhika.jagtap@ARM.com     * Check if past record is a comp node that completed earlier than the
50611247Sradhika.jagtap@ARM.com     * execute tick.
50711247Sradhika.jagtap@ARM.com     *
50811247Sradhika.jagtap@ARM.com     * @param past_record   pointer to past comp node
50911247Sradhika.jagtap@ARM.com     * @param execute_tick  tick with which to compare past comp node's
51011247Sradhika.jagtap@ARM.com     *                      completion tick
51111247Sradhika.jagtap@ARM.com     *
51211247Sradhika.jagtap@ARM.com     * @return true if past record is comp completed earlier
51311247Sradhika.jagtap@ARM.com     */
51411247Sradhika.jagtap@ARM.com    bool hasCompCompleted(TraceInfo* past_record, Tick execute_tick) const;
51511247Sradhika.jagtap@ARM.com
51611247Sradhika.jagtap@ARM.com    /** Number of register dependencies recorded during tracing */
51711247Sradhika.jagtap@ARM.com    Stats::Scalar numRegDep;
51811247Sradhika.jagtap@ARM.com
51911247Sradhika.jagtap@ARM.com    /**
52011247Sradhika.jagtap@ARM.com     * Number of stores that got assigned a commit order dependency
52111247Sradhika.jagtap@ARM.com     * on a past load/store.
52211247Sradhika.jagtap@ARM.com     */
52311247Sradhika.jagtap@ARM.com    Stats::Scalar numOrderDepStores;
52411247Sradhika.jagtap@ARM.com
52511247Sradhika.jagtap@ARM.com    /**
52611247Sradhika.jagtap@ARM.com     * Number of load insts that got assigned an issue order dependency
52711247Sradhika.jagtap@ARM.com     * because they were dependency-free.
52811247Sradhika.jagtap@ARM.com     */
52911247Sradhika.jagtap@ARM.com    Stats::Scalar numIssueOrderDepLoads;
53011247Sradhika.jagtap@ARM.com
53111247Sradhika.jagtap@ARM.com    /**
53211247Sradhika.jagtap@ARM.com     * Number of store insts that got assigned an issue order dependency
53311247Sradhika.jagtap@ARM.com     * because they were dependency-free.
53411247Sradhika.jagtap@ARM.com     */
53511247Sradhika.jagtap@ARM.com    Stats::Scalar numIssueOrderDepStores;
53611247Sradhika.jagtap@ARM.com
53711247Sradhika.jagtap@ARM.com    /**
53811247Sradhika.jagtap@ARM.com     * Number of non load/store insts that got assigned an issue order
53911247Sradhika.jagtap@ARM.com     * dependency because they were dependency-free.
54011247Sradhika.jagtap@ARM.com     */
54111247Sradhika.jagtap@ARM.com    Stats::Scalar numIssueOrderDepOther;
54211247Sradhika.jagtap@ARM.com
54311247Sradhika.jagtap@ARM.com    /** Number of filtered nodes */
54411247Sradhika.jagtap@ARM.com    Stats::Scalar numFilteredNodes;
54511247Sradhika.jagtap@ARM.com
54611247Sradhika.jagtap@ARM.com    /** Maximum number of dependents on any instruction */
54711247Sradhika.jagtap@ARM.com    Stats::Scalar maxNumDependents;
54811247Sradhika.jagtap@ARM.com
54911247Sradhika.jagtap@ARM.com    /**
55011247Sradhika.jagtap@ARM.com     * Maximum size of the temporary store mostly useful as a check that it is
55111247Sradhika.jagtap@ARM.com     * not growing
55211247Sradhika.jagtap@ARM.com     */
55311247Sradhika.jagtap@ARM.com    Stats::Scalar maxTempStoreSize;
55411247Sradhika.jagtap@ARM.com
55511247Sradhika.jagtap@ARM.com    /**
55611247Sradhika.jagtap@ARM.com     * Maximum size of the map that holds the last writer to a physical
55711247Sradhika.jagtap@ARM.com     * register.
55811247Sradhika.jagtap@ARM.com     * */
55911247Sradhika.jagtap@ARM.com    Stats::Scalar maxPhysRegDepMapSize;
56011247Sradhika.jagtap@ARM.com
56111247Sradhika.jagtap@ARM.com};
56211247Sradhika.jagtap@ARM.com#endif//__CPU_O3_PROBE_ELASTIC_TRACE_HH__
563