elastic_trace.cc revision 13429
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#include "cpu/o3/probe/elastic_trace.hh" 4311247Sradhika.jagtap@ARM.com 4411247Sradhika.jagtap@ARM.com#include "base/callback.hh" 4511247Sradhika.jagtap@ARM.com#include "base/output.hh" 4611247Sradhika.jagtap@ARM.com#include "base/trace.hh" 4711247Sradhika.jagtap@ARM.com#include "cpu/reg_class.hh" 4811247Sradhika.jagtap@ARM.com#include "debug/ElasticTrace.hh" 4911247Sradhika.jagtap@ARM.com#include "mem/packet.hh" 5011247Sradhika.jagtap@ARM.com 5111247Sradhika.jagtap@ARM.comElasticTrace::ElasticTrace(const ElasticTraceParams* params) 5211247Sradhika.jagtap@ARM.com : ProbeListenerObject(params), 5312085Sspwilson2@wisc.edu regEtraceListenersEvent([this]{ regEtraceListeners(); }, name()), 5411247Sradhika.jagtap@ARM.com firstWin(true), 5511247Sradhika.jagtap@ARM.com lastClearedSeqNum(0), 5611247Sradhika.jagtap@ARM.com depWindowSize(params->depWindowSize), 5711247Sradhika.jagtap@ARM.com dataTraceStream(nullptr), 5811247Sradhika.jagtap@ARM.com instTraceStream(nullptr), 5911247Sradhika.jagtap@ARM.com startTraceInst(params->startTraceInst), 6011253Sradhika.jagtap@ARM.com allProbesReg(false), 6111253Sradhika.jagtap@ARM.com traceVirtAddr(params->traceVirtAddr) 6211247Sradhika.jagtap@ARM.com{ 6311247Sradhika.jagtap@ARM.com cpu = dynamic_cast<FullO3CPU<O3CPUImpl>*>(params->manager); 6411247Sradhika.jagtap@ARM.com fatal_if(!cpu, "Manager of %s is not of type O3CPU and thus does not "\ 6511247Sradhika.jagtap@ARM.com "support dependency tracing.\n", name()); 6611247Sradhika.jagtap@ARM.com 6711247Sradhika.jagtap@ARM.com fatal_if(depWindowSize == 0, "depWindowSize parameter must be non-zero. "\ 6811247Sradhika.jagtap@ARM.com "Recommended size is 3x ROB size in the O3CPU.\n"); 6911247Sradhika.jagtap@ARM.com 7011247Sradhika.jagtap@ARM.com fatal_if(cpu->numThreads > 1, "numThreads = %i, %s supports tracing for"\ 7111247Sradhika.jagtap@ARM.com "single-threaded workload only", cpu->numThreads, name()); 7211247Sradhika.jagtap@ARM.com // Initialize the protobuf output stream 7311247Sradhika.jagtap@ARM.com fatal_if(params->instFetchTraceFile == "", "Assign instruction fetch "\ 7411247Sradhika.jagtap@ARM.com "trace file path to instFetchTraceFile"); 7511247Sradhika.jagtap@ARM.com fatal_if(params->dataDepTraceFile == "", "Assign data dependency "\ 7611247Sradhika.jagtap@ARM.com "trace file path to dataDepTraceFile"); 7711247Sradhika.jagtap@ARM.com std::string filename = simout.resolve(name() + "." + 7811247Sradhika.jagtap@ARM.com params->instFetchTraceFile); 7911247Sradhika.jagtap@ARM.com instTraceStream = new ProtoOutputStream(filename); 8011247Sradhika.jagtap@ARM.com filename = simout.resolve(name() + "." + params->dataDepTraceFile); 8111247Sradhika.jagtap@ARM.com dataTraceStream = new ProtoOutputStream(filename); 8211247Sradhika.jagtap@ARM.com // Create a protobuf message for the header and write it to the stream 8311247Sradhika.jagtap@ARM.com ProtoMessage::PacketHeader inst_pkt_header; 8411247Sradhika.jagtap@ARM.com inst_pkt_header.set_obj_id(name()); 8511247Sradhika.jagtap@ARM.com inst_pkt_header.set_tick_freq(SimClock::Frequency); 8611247Sradhika.jagtap@ARM.com instTraceStream->write(inst_pkt_header); 8711247Sradhika.jagtap@ARM.com // Create a protobuf message for the header and write it to 8811247Sradhika.jagtap@ARM.com // the stream 8911247Sradhika.jagtap@ARM.com ProtoMessage::InstDepRecordHeader data_rec_header; 9011247Sradhika.jagtap@ARM.com data_rec_header.set_obj_id(name()); 9111247Sradhika.jagtap@ARM.com data_rec_header.set_tick_freq(SimClock::Frequency); 9211247Sradhika.jagtap@ARM.com data_rec_header.set_window_size(depWindowSize); 9311247Sradhika.jagtap@ARM.com dataTraceStream->write(data_rec_header); 9411247Sradhika.jagtap@ARM.com // Register a callback to flush trace records and close the output streams. 9511247Sradhika.jagtap@ARM.com Callback* cb = new MakeCallback<ElasticTrace, 9611247Sradhika.jagtap@ARM.com &ElasticTrace::flushTraces>(this); 9711247Sradhika.jagtap@ARM.com registerExitCallback(cb); 9811247Sradhika.jagtap@ARM.com} 9911247Sradhika.jagtap@ARM.com 10011247Sradhika.jagtap@ARM.comvoid 10111247Sradhika.jagtap@ARM.comElasticTrace::regProbeListeners() 10211247Sradhika.jagtap@ARM.com{ 10311247Sradhika.jagtap@ARM.com inform("@%llu: regProbeListeners() called, startTraceInst = %llu", 10411247Sradhika.jagtap@ARM.com curTick(), startTraceInst); 10511247Sradhika.jagtap@ARM.com if (startTraceInst == 0) { 10611247Sradhika.jagtap@ARM.com // If we want to start tracing from the start of the simulation, 10711247Sradhika.jagtap@ARM.com // register all elastic trace probes now. 10811247Sradhika.jagtap@ARM.com regEtraceListeners(); 10911247Sradhika.jagtap@ARM.com } else { 11011247Sradhika.jagtap@ARM.com // Schedule an event to register all elastic trace probes when 11111247Sradhika.jagtap@ARM.com // specified no. of instructions are committed. 11211247Sradhika.jagtap@ARM.com cpu->comInstEventQueue[(ThreadID)0]->schedule(®EtraceListenersEvent, 11311247Sradhika.jagtap@ARM.com startTraceInst); 11411247Sradhika.jagtap@ARM.com } 11511247Sradhika.jagtap@ARM.com} 11611247Sradhika.jagtap@ARM.com 11711247Sradhika.jagtap@ARM.comvoid 11811247Sradhika.jagtap@ARM.comElasticTrace::regEtraceListeners() 11911247Sradhika.jagtap@ARM.com{ 12011247Sradhika.jagtap@ARM.com assert(!allProbesReg); 12111247Sradhika.jagtap@ARM.com inform("@%llu: No. of instructions committed = %llu, registering elastic" 12211247Sradhika.jagtap@ARM.com " probe listeners", curTick(), cpu->numSimulatedInsts()); 12311247Sradhika.jagtap@ARM.com // Create new listeners: provide method to be called upon a notify() for 12411247Sradhika.jagtap@ARM.com // each probe point. 12511247Sradhika.jagtap@ARM.com listeners.push_back(new ProbeListenerArg<ElasticTrace, RequestPtr>(this, 12611247Sradhika.jagtap@ARM.com "FetchRequest", &ElasticTrace::fetchReqTrace)); 12713429Srekai.gonzalezalberquilla@arm.com listeners.push_back(new ProbeListenerArg<ElasticTrace, 12813429Srekai.gonzalezalberquilla@arm.com DynInstConstPtr>(this, "Execute", 12913429Srekai.gonzalezalberquilla@arm.com &ElasticTrace::recordExecTick)); 13013429Srekai.gonzalezalberquilla@arm.com listeners.push_back(new ProbeListenerArg<ElasticTrace, 13113429Srekai.gonzalezalberquilla@arm.com DynInstConstPtr>(this, "ToCommit", 13213429Srekai.gonzalezalberquilla@arm.com &ElasticTrace::recordToCommTick)); 13313429Srekai.gonzalezalberquilla@arm.com listeners.push_back(new ProbeListenerArg<ElasticTrace, 13413429Srekai.gonzalezalberquilla@arm.com DynInstConstPtr>(this, "Rename", 13513429Srekai.gonzalezalberquilla@arm.com &ElasticTrace::updateRegDep)); 13611247Sradhika.jagtap@ARM.com listeners.push_back(new ProbeListenerArg<ElasticTrace, SeqNumRegPair>(this, 13711247Sradhika.jagtap@ARM.com "SquashInRename", &ElasticTrace::removeRegDepMapEntry)); 13813429Srekai.gonzalezalberquilla@arm.com listeners.push_back(new ProbeListenerArg<ElasticTrace, 13913429Srekai.gonzalezalberquilla@arm.com DynInstConstPtr>(this, "Squash", 14013429Srekai.gonzalezalberquilla@arm.com &ElasticTrace::addSquashedInst)); 14113429Srekai.gonzalezalberquilla@arm.com listeners.push_back(new ProbeListenerArg<ElasticTrace, 14213429Srekai.gonzalezalberquilla@arm.com DynInstConstPtr>(this, "Commit", 14313429Srekai.gonzalezalberquilla@arm.com &ElasticTrace::addCommittedInst)); 14411247Sradhika.jagtap@ARM.com allProbesReg = true; 14511247Sradhika.jagtap@ARM.com} 14611247Sradhika.jagtap@ARM.com 14711247Sradhika.jagtap@ARM.comvoid 14811247Sradhika.jagtap@ARM.comElasticTrace::fetchReqTrace(const RequestPtr &req) 14911247Sradhika.jagtap@ARM.com{ 15011247Sradhika.jagtap@ARM.com 15111247Sradhika.jagtap@ARM.com DPRINTFR(ElasticTrace, "Fetch Req %i,(%lli,%lli,%lli),%i,%i,%lli\n", 15211247Sradhika.jagtap@ARM.com (MemCmd::ReadReq), 15311247Sradhika.jagtap@ARM.com req->getPC(), req->getVaddr(), req->getPaddr(), 15411247Sradhika.jagtap@ARM.com req->getFlags(), req->getSize(), curTick()); 15511247Sradhika.jagtap@ARM.com 15611247Sradhika.jagtap@ARM.com // Create a protobuf message including the request fields necessary to 15711247Sradhika.jagtap@ARM.com // recreate the request in the TraceCPU. 15811247Sradhika.jagtap@ARM.com ProtoMessage::Packet inst_fetch_pkt; 15911247Sradhika.jagtap@ARM.com inst_fetch_pkt.set_tick(curTick()); 16011247Sradhika.jagtap@ARM.com inst_fetch_pkt.set_cmd(MemCmd::ReadReq); 16111247Sradhika.jagtap@ARM.com inst_fetch_pkt.set_pc(req->getPC()); 16211247Sradhika.jagtap@ARM.com inst_fetch_pkt.set_flags(req->getFlags()); 16311247Sradhika.jagtap@ARM.com inst_fetch_pkt.set_addr(req->getPaddr()); 16411247Sradhika.jagtap@ARM.com inst_fetch_pkt.set_size(req->getSize()); 16511247Sradhika.jagtap@ARM.com // Write the message to the stream. 16611247Sradhika.jagtap@ARM.com instTraceStream->write(inst_fetch_pkt); 16711247Sradhika.jagtap@ARM.com} 16811247Sradhika.jagtap@ARM.com 16911247Sradhika.jagtap@ARM.comvoid 17013429Srekai.gonzalezalberquilla@arm.comElasticTrace::recordExecTick(const DynInstConstPtr& dyn_inst) 17111247Sradhika.jagtap@ARM.com{ 17211247Sradhika.jagtap@ARM.com 17311247Sradhika.jagtap@ARM.com // In a corner case, a retired instruction is propagated backward to the 17411247Sradhika.jagtap@ARM.com // IEW instruction queue to handle some side-channel information. But we 17511247Sradhika.jagtap@ARM.com // must not process an instruction again. So we test the sequence number 17611247Sradhika.jagtap@ARM.com // against the lastClearedSeqNum and skip adding the instruction for such 17711247Sradhika.jagtap@ARM.com // corner cases. 17811247Sradhika.jagtap@ARM.com if (dyn_inst->seqNum <= lastClearedSeqNum) { 17911247Sradhika.jagtap@ARM.com DPRINTFR(ElasticTrace, "[sn:%lli] Ignoring in execute as instruction \ 18011247Sradhika.jagtap@ARM.com has already retired (mostly squashed)", dyn_inst->seqNum); 18111247Sradhika.jagtap@ARM.com // Do nothing as program has proceeded and this inst has been 18211247Sradhika.jagtap@ARM.com // propagated backwards to handle something. 18311247Sradhika.jagtap@ARM.com return; 18411247Sradhika.jagtap@ARM.com } 18511247Sradhika.jagtap@ARM.com 18611247Sradhika.jagtap@ARM.com DPRINTFR(ElasticTrace, "[sn:%lli] Execute Tick = %i\n", dyn_inst->seqNum, 18711247Sradhika.jagtap@ARM.com curTick()); 18811247Sradhika.jagtap@ARM.com // Either the execution info object will already exist if this 18911247Sradhika.jagtap@ARM.com // instruction had a register dependency recorded in the rename probe 19011247Sradhika.jagtap@ARM.com // listener before entering execute stage or it will not exist and will 19111247Sradhika.jagtap@ARM.com // need to be created here. 19211247Sradhika.jagtap@ARM.com InstExecInfo* exec_info_ptr; 19311247Sradhika.jagtap@ARM.com auto itr_exec_info = tempStore.find(dyn_inst->seqNum); 19411247Sradhika.jagtap@ARM.com if (itr_exec_info != tempStore.end()) { 19511247Sradhika.jagtap@ARM.com exec_info_ptr = itr_exec_info->second; 19611247Sradhika.jagtap@ARM.com } else { 19711247Sradhika.jagtap@ARM.com exec_info_ptr = new InstExecInfo; 19811247Sradhika.jagtap@ARM.com tempStore[dyn_inst->seqNum] = exec_info_ptr; 19911247Sradhika.jagtap@ARM.com } 20011247Sradhika.jagtap@ARM.com 20111247Sradhika.jagtap@ARM.com exec_info_ptr->executeTick = curTick(); 20211247Sradhika.jagtap@ARM.com maxTempStoreSize = std::max(tempStore.size(), 20311247Sradhika.jagtap@ARM.com (std::size_t)maxTempStoreSize.value()); 20411247Sradhika.jagtap@ARM.com} 20511247Sradhika.jagtap@ARM.com 20611247Sradhika.jagtap@ARM.comvoid 20713429Srekai.gonzalezalberquilla@arm.comElasticTrace::recordToCommTick(const DynInstConstPtr& dyn_inst) 20811247Sradhika.jagtap@ARM.com{ 20911247Sradhika.jagtap@ARM.com // If tracing has just been enabled then the instruction at this stage of 21011247Sradhika.jagtap@ARM.com // execution is far enough that we cannot gather info about its past like 21111247Sradhika.jagtap@ARM.com // the tick it started execution. Simply return until we see an instruction 21211247Sradhika.jagtap@ARM.com // that is found in the tempStore. 21311247Sradhika.jagtap@ARM.com auto itr_exec_info = tempStore.find(dyn_inst->seqNum); 21411247Sradhika.jagtap@ARM.com if (itr_exec_info == tempStore.end()) { 21511247Sradhika.jagtap@ARM.com DPRINTFR(ElasticTrace, "recordToCommTick: [sn:%lli] Not in temp store," 21611247Sradhika.jagtap@ARM.com " skipping.\n", dyn_inst->seqNum); 21711247Sradhika.jagtap@ARM.com return; 21811247Sradhika.jagtap@ARM.com } 21911247Sradhika.jagtap@ARM.com 22011247Sradhika.jagtap@ARM.com DPRINTFR(ElasticTrace, "[sn:%lli] To Commit Tick = %i\n", dyn_inst->seqNum, 22111247Sradhika.jagtap@ARM.com curTick()); 22211247Sradhika.jagtap@ARM.com InstExecInfo* exec_info_ptr = itr_exec_info->second; 22311247Sradhika.jagtap@ARM.com exec_info_ptr->toCommitTick = curTick(); 22411247Sradhika.jagtap@ARM.com 22511247Sradhika.jagtap@ARM.com} 22611247Sradhika.jagtap@ARM.com 22711247Sradhika.jagtap@ARM.comvoid 22813429Srekai.gonzalezalberquilla@arm.comElasticTrace::updateRegDep(const DynInstConstPtr& dyn_inst) 22911247Sradhika.jagtap@ARM.com{ 23011247Sradhika.jagtap@ARM.com // Get the sequence number of the instruction 23111247Sradhika.jagtap@ARM.com InstSeqNum seq_num = dyn_inst->seqNum; 23211247Sradhika.jagtap@ARM.com 23311247Sradhika.jagtap@ARM.com assert(dyn_inst->seqNum > lastClearedSeqNum); 23411247Sradhika.jagtap@ARM.com 23511247Sradhika.jagtap@ARM.com // Since this is the first probe activated in the pipeline, create 23611247Sradhika.jagtap@ARM.com // a new execution info object to track this instruction as it 23711247Sradhika.jagtap@ARM.com // progresses through the pipeline. 23811247Sradhika.jagtap@ARM.com InstExecInfo* exec_info_ptr = new InstExecInfo; 23911247Sradhika.jagtap@ARM.com tempStore[seq_num] = exec_info_ptr; 24011247Sradhika.jagtap@ARM.com 24111247Sradhika.jagtap@ARM.com // Loop through the source registers and look up the dependency map. If 24211247Sradhika.jagtap@ARM.com // the source register entry is found in the dependency map, add a 24311247Sradhika.jagtap@ARM.com // dependency on the last writer. 24411247Sradhika.jagtap@ARM.com int8_t max_regs = dyn_inst->numSrcRegs(); 24511247Sradhika.jagtap@ARM.com for (int src_idx = 0; src_idx < max_regs; src_idx++) { 24612255Sradhika.jagtap@arm.com 24712255Sradhika.jagtap@arm.com const RegId& src_reg = dyn_inst->srcRegIdx(src_idx); 24812255Sradhika.jagtap@arm.com if (!src_reg.isMiscReg() && 24912255Sradhika.jagtap@arm.com !src_reg.isZeroReg()) { 25012255Sradhika.jagtap@arm.com // Get the physical register index of the i'th source register. 25112255Sradhika.jagtap@arm.com PhysRegIdPtr phys_src_reg = dyn_inst->renamedSrcRegIdx(src_idx); 25212255Sradhika.jagtap@arm.com DPRINTFR(ElasticTrace, "[sn:%lli] Check map for src reg" 25312255Sradhika.jagtap@arm.com " %i (%s)\n", seq_num, 25412255Sradhika.jagtap@arm.com phys_src_reg->flatIndex(), phys_src_reg->className()); 25512255Sradhika.jagtap@arm.com auto itr_writer = physRegDepMap.find(phys_src_reg->flatIndex()); 25612255Sradhika.jagtap@arm.com if (itr_writer != physRegDepMap.end()) { 25712255Sradhika.jagtap@arm.com InstSeqNum last_writer = itr_writer->second; 25812255Sradhika.jagtap@arm.com // Additionally the dependency distance is kept less than the 25912255Sradhika.jagtap@arm.com // window size parameter to limit the memory allocation to 26012255Sradhika.jagtap@arm.com // nodes in the graph. If the window were tending to infinite 26112255Sradhika.jagtap@arm.com // we would have to load a large number of node objects during 26212255Sradhika.jagtap@arm.com // replay. 26312255Sradhika.jagtap@arm.com if (seq_num - last_writer < depWindowSize) { 26412255Sradhika.jagtap@arm.com // Record a physical register dependency. 26512255Sradhika.jagtap@arm.com exec_info_ptr->physRegDepSet.insert(last_writer); 26612255Sradhika.jagtap@arm.com } 26711247Sradhika.jagtap@ARM.com } 26812255Sradhika.jagtap@arm.com 26911247Sradhika.jagtap@ARM.com } 27012255Sradhika.jagtap@arm.com 27111247Sradhika.jagtap@ARM.com } 27211247Sradhika.jagtap@ARM.com 27311247Sradhika.jagtap@ARM.com // Loop through the destination registers of this instruction and update 27411247Sradhika.jagtap@ARM.com // the physical register dependency map for last writers to registers. 27511247Sradhika.jagtap@ARM.com max_regs = dyn_inst->numDestRegs(); 27611247Sradhika.jagtap@ARM.com for (int dest_idx = 0; dest_idx < max_regs; dest_idx++) { 27711247Sradhika.jagtap@ARM.com // For data dependency tracking the register must be an int, float or 27811247Sradhika.jagtap@ARM.com // CC register and not a Misc register. 27912106SRekai.GonzalezAlberquilla@arm.com const RegId& dest_reg = dyn_inst->destRegIdx(dest_idx); 28012106SRekai.GonzalezAlberquilla@arm.com if (!dest_reg.isMiscReg() && 28112104Snathanael.premillieu@arm.com !dest_reg.isZeroReg()) { 28212104Snathanael.premillieu@arm.com // Get the physical register index of the i'th destination 28312104Snathanael.premillieu@arm.com // register. 28412105Snathanael.premillieu@arm.com PhysRegIdPtr phys_dest_reg = dyn_inst->renamedDestRegIdx(dest_idx); 28512105Snathanael.premillieu@arm.com DPRINTFR(ElasticTrace, "[sn:%lli] Update map for dest reg" 28612255Sradhika.jagtap@arm.com " %i (%s)\n", seq_num, phys_dest_reg->flatIndex(), 28712106SRekai.GonzalezAlberquilla@arm.com dest_reg.className()); 28812106SRekai.GonzalezAlberquilla@arm.com physRegDepMap[phys_dest_reg->flatIndex()] = seq_num; 28911247Sradhika.jagtap@ARM.com } 29011247Sradhika.jagtap@ARM.com } 29111247Sradhika.jagtap@ARM.com maxPhysRegDepMapSize = std::max(physRegDepMap.size(), 29211247Sradhika.jagtap@ARM.com (std::size_t)maxPhysRegDepMapSize.value()); 29311247Sradhika.jagtap@ARM.com} 29411247Sradhika.jagtap@ARM.com 29511247Sradhika.jagtap@ARM.comvoid 29611247Sradhika.jagtap@ARM.comElasticTrace::removeRegDepMapEntry(const SeqNumRegPair &inst_reg_pair) 29711247Sradhika.jagtap@ARM.com{ 29811247Sradhika.jagtap@ARM.com DPRINTFR(ElasticTrace, "Remove Map entry for Reg %i\n", 29912105Snathanael.premillieu@arm.com inst_reg_pair.second); 30011247Sradhika.jagtap@ARM.com auto itr_regdep_map = physRegDepMap.find(inst_reg_pair.second); 30111247Sradhika.jagtap@ARM.com if (itr_regdep_map != physRegDepMap.end()) 30211247Sradhika.jagtap@ARM.com physRegDepMap.erase(itr_regdep_map); 30311247Sradhika.jagtap@ARM.com} 30411247Sradhika.jagtap@ARM.com 30511247Sradhika.jagtap@ARM.comvoid 30613429Srekai.gonzalezalberquilla@arm.comElasticTrace::addSquashedInst(const DynInstConstPtr& head_inst) 30711247Sradhika.jagtap@ARM.com{ 30811247Sradhika.jagtap@ARM.com // If the squashed instruction was squashed before being processed by 30911247Sradhika.jagtap@ARM.com // execute stage then it will not be in the temporary store. In this case 31011247Sradhika.jagtap@ARM.com // do nothing and return. 31111247Sradhika.jagtap@ARM.com auto itr_exec_info = tempStore.find(head_inst->seqNum); 31211247Sradhika.jagtap@ARM.com if (itr_exec_info == tempStore.end()) 31311247Sradhika.jagtap@ARM.com return; 31411247Sradhika.jagtap@ARM.com 31511247Sradhika.jagtap@ARM.com // If there is a squashed load for which a read request was 31611247Sradhika.jagtap@ARM.com // sent before it got squashed then add it to the trace. 31711247Sradhika.jagtap@ARM.com DPRINTFR(ElasticTrace, "Attempt to add squashed inst [sn:%lli]\n", 31811247Sradhika.jagtap@ARM.com head_inst->seqNum); 31911247Sradhika.jagtap@ARM.com // Get pointer to the execution info object corresponding to the inst. 32011247Sradhika.jagtap@ARM.com InstExecInfo* exec_info_ptr = itr_exec_info->second; 32111247Sradhika.jagtap@ARM.com if (head_inst->isLoad() && exec_info_ptr->executeTick != MaxTick && 32211247Sradhika.jagtap@ARM.com exec_info_ptr->toCommitTick != MaxTick && 32311247Sradhika.jagtap@ARM.com head_inst->hasRequest() && 32411247Sradhika.jagtap@ARM.com head_inst->getFault() == NoFault) { 32511247Sradhika.jagtap@ARM.com // Add record to depTrace with commit parameter as false. 32611247Sradhika.jagtap@ARM.com addDepTraceRecord(head_inst, exec_info_ptr, false); 32711247Sradhika.jagtap@ARM.com } 32811247Sradhika.jagtap@ARM.com // As the information contained is no longer needed, remove the execution 32911247Sradhika.jagtap@ARM.com // info object from the temporary store. 33011247Sradhika.jagtap@ARM.com clearTempStoreUntil(head_inst); 33111247Sradhika.jagtap@ARM.com} 33211247Sradhika.jagtap@ARM.com 33311247Sradhika.jagtap@ARM.comvoid 33413429Srekai.gonzalezalberquilla@arm.comElasticTrace::addCommittedInst(const DynInstConstPtr& head_inst) 33511247Sradhika.jagtap@ARM.com{ 33611247Sradhika.jagtap@ARM.com DPRINTFR(ElasticTrace, "Attempt to add committed inst [sn:%lli]\n", 33711247Sradhika.jagtap@ARM.com head_inst->seqNum); 33811247Sradhika.jagtap@ARM.com 33911247Sradhika.jagtap@ARM.com // Add the instruction to the depTrace. 34011247Sradhika.jagtap@ARM.com if (!head_inst->isNop()) { 34111247Sradhika.jagtap@ARM.com 34211247Sradhika.jagtap@ARM.com // If tracing has just been enabled then the instruction at this stage 34311247Sradhika.jagtap@ARM.com // of execution is far enough that we cannot gather info about its past 34411247Sradhika.jagtap@ARM.com // like the tick it started execution. Simply return until we see an 34511247Sradhika.jagtap@ARM.com // instruction that is found in the tempStore. 34611247Sradhika.jagtap@ARM.com auto itr_temp_store = tempStore.find(head_inst->seqNum); 34711247Sradhika.jagtap@ARM.com if (itr_temp_store == tempStore.end()) { 34811247Sradhika.jagtap@ARM.com DPRINTFR(ElasticTrace, "addCommittedInst: [sn:%lli] Not in temp " 34911247Sradhika.jagtap@ARM.com "store, skipping.\n", head_inst->seqNum); 35011247Sradhika.jagtap@ARM.com return; 35111247Sradhika.jagtap@ARM.com } 35211247Sradhika.jagtap@ARM.com 35311247Sradhika.jagtap@ARM.com // Get pointer to the execution info object corresponding to the inst. 35411247Sradhika.jagtap@ARM.com InstExecInfo* exec_info_ptr = itr_temp_store->second; 35511247Sradhika.jagtap@ARM.com assert(exec_info_ptr->executeTick != MaxTick); 35611247Sradhika.jagtap@ARM.com assert(exec_info_ptr->toCommitTick != MaxTick); 35711247Sradhika.jagtap@ARM.com 35811247Sradhika.jagtap@ARM.com // Check if the instruction had a fault, if it predicated false and 35911247Sradhika.jagtap@ARM.com // thus previous register values were restored or if it was a 36011247Sradhika.jagtap@ARM.com // load/store that did not have a request (e.g. when the size of the 36111247Sradhika.jagtap@ARM.com // request is zero). In all these cases the instruction is set as 36211247Sradhika.jagtap@ARM.com // executed and is picked up by the commit probe listener. But a 36311247Sradhika.jagtap@ARM.com // request is not issued and registers are not written. So practically, 36411247Sradhika.jagtap@ARM.com // skipping these should not hurt as execution would not stall on them. 36511247Sradhika.jagtap@ARM.com // Alternatively, these could be included merely as a compute node in 36611247Sradhika.jagtap@ARM.com // the graph. Removing these for now. If correlation accuracy needs to 36711247Sradhika.jagtap@ARM.com // be improved in future these can be turned into comp nodes at the 36811247Sradhika.jagtap@ARM.com // cost of bigger traces. 36911247Sradhika.jagtap@ARM.com if (head_inst->getFault() != NoFault) { 37011247Sradhika.jagtap@ARM.com DPRINTF(ElasticTrace, "%s [sn:%lli] has faulted so " 37111247Sradhika.jagtap@ARM.com "skip adding it to the trace\n", 37211247Sradhika.jagtap@ARM.com (head_inst->isMemRef() ? "Load/store" : "Comp inst."), 37311247Sradhika.jagtap@ARM.com head_inst->seqNum); 37411247Sradhika.jagtap@ARM.com } else if (head_inst->isMemRef() && !head_inst->hasRequest()) { 37511247Sradhika.jagtap@ARM.com DPRINTF(ElasticTrace, "Load/store [sn:%lli] has no request so " 37611247Sradhika.jagtap@ARM.com "skip adding it to the trace\n", head_inst->seqNum); 37711247Sradhika.jagtap@ARM.com } else if (!head_inst->readPredicate()) { 37811247Sradhika.jagtap@ARM.com DPRINTF(ElasticTrace, "%s [sn:%lli] is predicated false so " 37911247Sradhika.jagtap@ARM.com "skip adding it to the trace\n", 38011247Sradhika.jagtap@ARM.com (head_inst->isMemRef() ? "Load/store" : "Comp inst."), 38111247Sradhika.jagtap@ARM.com head_inst->seqNum); 38211247Sradhika.jagtap@ARM.com } else { 38311247Sradhika.jagtap@ARM.com // Add record to depTrace with commit parameter as true. 38411247Sradhika.jagtap@ARM.com addDepTraceRecord(head_inst, exec_info_ptr, true); 38511247Sradhika.jagtap@ARM.com } 38611247Sradhika.jagtap@ARM.com } 38711247Sradhika.jagtap@ARM.com // As the information contained is no longer needed, remove the execution 38811247Sradhika.jagtap@ARM.com // info object from the temporary store. 38911247Sradhika.jagtap@ARM.com clearTempStoreUntil(head_inst); 39011247Sradhika.jagtap@ARM.com} 39111247Sradhika.jagtap@ARM.com 39211247Sradhika.jagtap@ARM.comvoid 39313429Srekai.gonzalezalberquilla@arm.comElasticTrace::addDepTraceRecord(const DynInstConstPtr& head_inst, 39411247Sradhika.jagtap@ARM.com InstExecInfo* exec_info_ptr, bool commit) 39511247Sradhika.jagtap@ARM.com{ 39611247Sradhika.jagtap@ARM.com // Create a record to assign dynamic intruction related fields. 39711247Sradhika.jagtap@ARM.com TraceInfo* new_record = new TraceInfo; 39811247Sradhika.jagtap@ARM.com // Add to map for sequence number look up to retrieve the TraceInfo pointer 39911247Sradhika.jagtap@ARM.com traceInfoMap[head_inst->seqNum] = new_record; 40011247Sradhika.jagtap@ARM.com 40111247Sradhika.jagtap@ARM.com // Assign fields from the instruction 40211247Sradhika.jagtap@ARM.com new_record->instNum = head_inst->seqNum; 40311247Sradhika.jagtap@ARM.com new_record->commit = commit; 40411252Sradhika.jagtap@ARM.com new_record->type = head_inst->isLoad() ? Record::LOAD : 40511252Sradhika.jagtap@ARM.com (head_inst->isStore() ? Record::STORE : 40611252Sradhika.jagtap@ARM.com Record::COMP); 40711247Sradhika.jagtap@ARM.com 40811247Sradhika.jagtap@ARM.com // Assign fields for creating a request in case of a load/store 40911247Sradhika.jagtap@ARM.com new_record->reqFlags = head_inst->memReqFlags; 41011253Sradhika.jagtap@ARM.com new_record->virtAddr = head_inst->effAddr; 41111253Sradhika.jagtap@ARM.com new_record->asid = head_inst->asid; 41211253Sradhika.jagtap@ARM.com new_record->physAddr = head_inst->physEffAddrLow; 41311247Sradhika.jagtap@ARM.com // Currently the tracing does not support split requests. 41411247Sradhika.jagtap@ARM.com new_record->size = head_inst->effSize; 41511247Sradhika.jagtap@ARM.com new_record->pc = head_inst->instAddr(); 41611247Sradhika.jagtap@ARM.com 41711247Sradhika.jagtap@ARM.com // Assign the timing information stored in the execution info object 41811247Sradhika.jagtap@ARM.com new_record->executeTick = exec_info_ptr->executeTick; 41911247Sradhika.jagtap@ARM.com new_record->toCommitTick = exec_info_ptr->toCommitTick; 42011247Sradhika.jagtap@ARM.com new_record->commitTick = curTick(); 42111247Sradhika.jagtap@ARM.com 42211247Sradhika.jagtap@ARM.com // Assign initial values for number of dependents and computational delay 42311247Sradhika.jagtap@ARM.com new_record->numDepts = 0; 42411247Sradhika.jagtap@ARM.com new_record->compDelay = -1; 42511247Sradhika.jagtap@ARM.com 42611247Sradhika.jagtap@ARM.com // The physical register dependency set of the first instruction is 42711247Sradhika.jagtap@ARM.com // empty. Since there are no records in the depTrace at this point, the 42811247Sradhika.jagtap@ARM.com // case of adding an ROB dependency by using a reverse iterator is not 42911247Sradhika.jagtap@ARM.com // applicable. Thus, populate the fields of the record corresponding to the 43011247Sradhika.jagtap@ARM.com // first instruction and return. 43111247Sradhika.jagtap@ARM.com if (depTrace.empty()) { 43211247Sradhika.jagtap@ARM.com // Store the record in depTrace. 43311247Sradhika.jagtap@ARM.com depTrace.push_back(new_record); 43411247Sradhika.jagtap@ARM.com DPRINTF(ElasticTrace, "Added first inst record %lli to DepTrace.\n", 43511247Sradhika.jagtap@ARM.com new_record->instNum); 43611247Sradhika.jagtap@ARM.com return; 43711247Sradhika.jagtap@ARM.com } 43811247Sradhika.jagtap@ARM.com 43911247Sradhika.jagtap@ARM.com // Clear register dependencies for squashed loads as they may be dependent 44011247Sradhika.jagtap@ARM.com // on squashed instructions and we do not add those to the trace. 44111247Sradhika.jagtap@ARM.com if (head_inst->isLoad() && !commit) { 44211247Sradhika.jagtap@ARM.com (exec_info_ptr->physRegDepSet).clear(); 44311247Sradhika.jagtap@ARM.com } 44411247Sradhika.jagtap@ARM.com 44511247Sradhika.jagtap@ARM.com // Assign the register dependencies stored in the execution info object 44611247Sradhika.jagtap@ARM.com std::set<InstSeqNum>::const_iterator dep_set_it; 44711247Sradhika.jagtap@ARM.com for (dep_set_it = (exec_info_ptr->physRegDepSet).begin(); 44811247Sradhika.jagtap@ARM.com dep_set_it != (exec_info_ptr->physRegDepSet).end(); 44911247Sradhika.jagtap@ARM.com ++dep_set_it) { 45011247Sradhika.jagtap@ARM.com auto trace_info_itr = traceInfoMap.find(*dep_set_it); 45111247Sradhika.jagtap@ARM.com if (trace_info_itr != traceInfoMap.end()) { 45211247Sradhika.jagtap@ARM.com // The register dependency is valid. Assign it and calculate 45311247Sradhika.jagtap@ARM.com // computational delay 45411247Sradhika.jagtap@ARM.com new_record->physRegDepList.push_back(*dep_set_it); 45511247Sradhika.jagtap@ARM.com DPRINTF(ElasticTrace, "Inst %lli has register dependency on " 45611247Sradhika.jagtap@ARM.com "%lli\n", new_record->instNum, *dep_set_it); 45711247Sradhika.jagtap@ARM.com TraceInfo* reg_dep = trace_info_itr->second; 45811247Sradhika.jagtap@ARM.com reg_dep->numDepts++; 45911247Sradhika.jagtap@ARM.com compDelayPhysRegDep(reg_dep, new_record); 46011247Sradhika.jagtap@ARM.com ++numRegDep; 46111247Sradhika.jagtap@ARM.com } else { 46211247Sradhika.jagtap@ARM.com // The instruction that this has a register dependency on was 46311247Sradhika.jagtap@ARM.com // not added to the trace because of one of the following 46411247Sradhika.jagtap@ARM.com // 1. it was an instruction that had a fault 46511247Sradhika.jagtap@ARM.com // 2. it was an instruction that was predicated false and 46611247Sradhika.jagtap@ARM.com // previous register values were restored 46711247Sradhika.jagtap@ARM.com // 3. it was load/store that did not have a request (e.g. when 46811247Sradhika.jagtap@ARM.com // the size of the request is zero but this may not be a fault) 46911247Sradhika.jagtap@ARM.com // In all these cases the instruction is set as executed and is 47011247Sradhika.jagtap@ARM.com // picked up by the commit probe listener. But a request is not 47111247Sradhika.jagtap@ARM.com // issued and registers are not written to in these cases. 47211247Sradhika.jagtap@ARM.com DPRINTF(ElasticTrace, "Inst %lli has register dependency on " 47311247Sradhika.jagtap@ARM.com "%lli is skipped\n",new_record->instNum, *dep_set_it); 47411247Sradhika.jagtap@ARM.com } 47511247Sradhika.jagtap@ARM.com } 47611247Sradhika.jagtap@ARM.com 47711247Sradhika.jagtap@ARM.com // Check for and assign an ROB dependency in addition to register 47811247Sradhika.jagtap@ARM.com // dependency before adding the record to the trace. 47911247Sradhika.jagtap@ARM.com // As stores have to commit in order a store is dependent on the last 48011247Sradhika.jagtap@ARM.com // committed load/store. This is recorded in the ROB dependency. 48111247Sradhika.jagtap@ARM.com if (head_inst->isStore()) { 48211247Sradhika.jagtap@ARM.com // Look up store-after-store order dependency 48311247Sradhika.jagtap@ARM.com updateCommitOrderDep(new_record, false); 48411247Sradhika.jagtap@ARM.com // Look up store-after-load order dependency 48511247Sradhika.jagtap@ARM.com updateCommitOrderDep(new_record, true); 48611247Sradhika.jagtap@ARM.com } 48711247Sradhika.jagtap@ARM.com 48811247Sradhika.jagtap@ARM.com // In case a node is dependency-free or its dependency got discarded 48911247Sradhika.jagtap@ARM.com // because it was outside the window, it is marked ready in the ROB at the 49011247Sradhika.jagtap@ARM.com // time of issue. A request is sent as soon as possible. To model this, a 49111247Sradhika.jagtap@ARM.com // node is assigned an issue order dependency on a committed instruction 49211247Sradhika.jagtap@ARM.com // that completed earlier than it. This is done to avoid the problem of 49311247Sradhika.jagtap@ARM.com // determining the issue times of such dependency-free nodes during replay 49411247Sradhika.jagtap@ARM.com // which could lead to too much parallelism, thinking conservatively. 49511247Sradhika.jagtap@ARM.com if (new_record->robDepList.empty() && new_record->physRegDepList.empty()) { 49611247Sradhika.jagtap@ARM.com updateIssueOrderDep(new_record); 49711247Sradhika.jagtap@ARM.com } 49811247Sradhika.jagtap@ARM.com 49911247Sradhika.jagtap@ARM.com // Store the record in depTrace. 50011247Sradhika.jagtap@ARM.com depTrace.push_back(new_record); 50111247Sradhika.jagtap@ARM.com DPRINTF(ElasticTrace, "Added %s inst %lli to DepTrace.\n", 50211247Sradhika.jagtap@ARM.com (commit ? "committed" : "squashed"), new_record->instNum); 50311247Sradhika.jagtap@ARM.com 50411247Sradhika.jagtap@ARM.com // To process the number of records specified by depWindowSize in the 50511247Sradhika.jagtap@ARM.com // forward direction, the depTrace must have twice as many records 50611247Sradhika.jagtap@ARM.com // to check for dependencies. 50711247Sradhika.jagtap@ARM.com if (depTrace.size() == 2 * depWindowSize) { 50811247Sradhika.jagtap@ARM.com 50911247Sradhika.jagtap@ARM.com DPRINTF(ElasticTrace, "Writing out trace...\n"); 51011247Sradhika.jagtap@ARM.com 51111247Sradhika.jagtap@ARM.com // Write out the records which have been processed to the trace 51211247Sradhika.jagtap@ARM.com // and remove them from the depTrace. 51311247Sradhika.jagtap@ARM.com writeDepTrace(depWindowSize); 51411247Sradhika.jagtap@ARM.com 51511247Sradhika.jagtap@ARM.com // After the first window, writeDepTrace() must check for valid 51611247Sradhika.jagtap@ARM.com // compDelay. 51711247Sradhika.jagtap@ARM.com firstWin = false; 51811247Sradhika.jagtap@ARM.com } 51911247Sradhika.jagtap@ARM.com} 52011247Sradhika.jagtap@ARM.com 52111247Sradhika.jagtap@ARM.comvoid 52211247Sradhika.jagtap@ARM.comElasticTrace::updateCommitOrderDep(TraceInfo* new_record, 52311247Sradhika.jagtap@ARM.com bool find_load_not_store) 52411247Sradhika.jagtap@ARM.com{ 52511252Sradhika.jagtap@ARM.com assert(new_record->isStore()); 52611247Sradhika.jagtap@ARM.com // Iterate in reverse direction to search for the last committed 52711247Sradhika.jagtap@ARM.com // load/store that completed earlier than the new record 52811247Sradhika.jagtap@ARM.com depTraceRevItr from_itr(depTrace.end()); 52911247Sradhika.jagtap@ARM.com depTraceRevItr until_itr(depTrace.begin()); 53011247Sradhika.jagtap@ARM.com TraceInfo* past_record = *from_itr; 53111247Sradhika.jagtap@ARM.com uint32_t num_go_back = 0; 53211247Sradhika.jagtap@ARM.com 53311247Sradhika.jagtap@ARM.com // The execution time of this store is when it is sent, that is committed 53411247Sradhika.jagtap@ARM.com Tick execute_tick = curTick(); 53511247Sradhika.jagtap@ARM.com // Search for store-after-load or store-after-store order dependency 53611247Sradhika.jagtap@ARM.com while (num_go_back < depWindowSize && from_itr != until_itr) { 53711247Sradhika.jagtap@ARM.com if (find_load_not_store) { 53811247Sradhika.jagtap@ARM.com // Check if previous inst is a load completed earlier by comparing 53911247Sradhika.jagtap@ARM.com // with execute tick 54011247Sradhika.jagtap@ARM.com if (hasLoadCompleted(past_record, execute_tick)) { 54111247Sradhika.jagtap@ARM.com // Assign rob dependency and calculate the computational delay 54211247Sradhika.jagtap@ARM.com assignRobDep(past_record, new_record); 54311247Sradhika.jagtap@ARM.com ++numOrderDepStores; 54411247Sradhika.jagtap@ARM.com return; 54511247Sradhika.jagtap@ARM.com } 54611247Sradhika.jagtap@ARM.com } else { 54711247Sradhika.jagtap@ARM.com // Check if previous inst is a store sent earlier by comparing with 54811247Sradhika.jagtap@ARM.com // execute tick 54911247Sradhika.jagtap@ARM.com if (hasStoreCommitted(past_record, execute_tick)) { 55011247Sradhika.jagtap@ARM.com // Assign rob dependency and calculate the computational delay 55111247Sradhika.jagtap@ARM.com assignRobDep(past_record, new_record); 55211247Sradhika.jagtap@ARM.com ++numOrderDepStores; 55311247Sradhika.jagtap@ARM.com return; 55411247Sradhika.jagtap@ARM.com } 55511247Sradhika.jagtap@ARM.com } 55611247Sradhika.jagtap@ARM.com ++from_itr; 55711247Sradhika.jagtap@ARM.com past_record = *from_itr; 55811247Sradhika.jagtap@ARM.com ++num_go_back; 55911247Sradhika.jagtap@ARM.com } 56011247Sradhika.jagtap@ARM.com} 56111247Sradhika.jagtap@ARM.com 56211247Sradhika.jagtap@ARM.comvoid 56311247Sradhika.jagtap@ARM.comElasticTrace::updateIssueOrderDep(TraceInfo* new_record) 56411247Sradhika.jagtap@ARM.com{ 56511247Sradhika.jagtap@ARM.com // Interate in reverse direction to search for the last committed 56611247Sradhika.jagtap@ARM.com // record that completed earlier than the new record 56711247Sradhika.jagtap@ARM.com depTraceRevItr from_itr(depTrace.end()); 56811247Sradhika.jagtap@ARM.com depTraceRevItr until_itr(depTrace.begin()); 56911247Sradhika.jagtap@ARM.com TraceInfo* past_record = *from_itr; 57011247Sradhika.jagtap@ARM.com 57111247Sradhika.jagtap@ARM.com uint32_t num_go_back = 0; 57211247Sradhika.jagtap@ARM.com Tick execute_tick = 0; 57311247Sradhika.jagtap@ARM.com 57411252Sradhika.jagtap@ARM.com if (new_record->isLoad()) { 57511247Sradhika.jagtap@ARM.com // The execution time of a load is when a request is sent 57611247Sradhika.jagtap@ARM.com execute_tick = new_record->executeTick; 57711247Sradhika.jagtap@ARM.com ++numIssueOrderDepLoads; 57811252Sradhika.jagtap@ARM.com } else if (new_record->isStore()) { 57911247Sradhika.jagtap@ARM.com // The execution time of a store is when it is sent, i.e. committed 58011247Sradhika.jagtap@ARM.com execute_tick = curTick(); 58111247Sradhika.jagtap@ARM.com ++numIssueOrderDepStores; 58211247Sradhika.jagtap@ARM.com } else { 58311247Sradhika.jagtap@ARM.com // The execution time of a non load/store is when it completes 58411247Sradhika.jagtap@ARM.com execute_tick = new_record->toCommitTick; 58511247Sradhika.jagtap@ARM.com ++numIssueOrderDepOther; 58611247Sradhika.jagtap@ARM.com } 58711247Sradhika.jagtap@ARM.com 58811247Sradhika.jagtap@ARM.com // We search if this record has an issue order dependency on a past record. 58911247Sradhika.jagtap@ARM.com // Once we find it, we update both the new record and the record it depends 59011247Sradhika.jagtap@ARM.com // on and return. 59111247Sradhika.jagtap@ARM.com while (num_go_back < depWindowSize && from_itr != until_itr) { 59211247Sradhika.jagtap@ARM.com // Check if a previous inst is a load sent earlier, or a store sent 59311247Sradhika.jagtap@ARM.com // earlier, or a comp inst completed earlier by comparing with execute 59411247Sradhika.jagtap@ARM.com // tick 59511247Sradhika.jagtap@ARM.com if (hasLoadBeenSent(past_record, execute_tick) || 59611247Sradhika.jagtap@ARM.com hasStoreCommitted(past_record, execute_tick) || 59711247Sradhika.jagtap@ARM.com hasCompCompleted(past_record, execute_tick)) { 59811247Sradhika.jagtap@ARM.com // Assign rob dependency and calculate the computational delay 59911247Sradhika.jagtap@ARM.com assignRobDep(past_record, new_record); 60011247Sradhika.jagtap@ARM.com return; 60111247Sradhika.jagtap@ARM.com } 60211247Sradhika.jagtap@ARM.com ++from_itr; 60311247Sradhika.jagtap@ARM.com past_record = *from_itr; 60411247Sradhika.jagtap@ARM.com ++num_go_back; 60511247Sradhika.jagtap@ARM.com } 60611247Sradhika.jagtap@ARM.com} 60711247Sradhika.jagtap@ARM.com 60811247Sradhika.jagtap@ARM.comvoid 60911247Sradhika.jagtap@ARM.comElasticTrace::assignRobDep(TraceInfo* past_record, TraceInfo* new_record) { 61011247Sradhika.jagtap@ARM.com DPRINTF(ElasticTrace, "%s %lli has ROB dependency on %lli\n", 61111252Sradhika.jagtap@ARM.com new_record->typeToStr(), new_record->instNum, 61211252Sradhika.jagtap@ARM.com past_record->instNum); 61311247Sradhika.jagtap@ARM.com // Add dependency on past record 61411247Sradhika.jagtap@ARM.com new_record->robDepList.push_back(past_record->instNum); 61511247Sradhika.jagtap@ARM.com // Update new_record's compute delay with respect to the past record 61611247Sradhika.jagtap@ARM.com compDelayRob(past_record, new_record); 61711247Sradhika.jagtap@ARM.com // Increment number of dependents of the past record 61811247Sradhika.jagtap@ARM.com ++(past_record->numDepts); 61911247Sradhika.jagtap@ARM.com // Update stat to log max number of dependents 62011247Sradhika.jagtap@ARM.com maxNumDependents = std::max(past_record->numDepts, 62111247Sradhika.jagtap@ARM.com (uint32_t)maxNumDependents.value()); 62211247Sradhika.jagtap@ARM.com} 62311247Sradhika.jagtap@ARM.com 62411247Sradhika.jagtap@ARM.combool 62511247Sradhika.jagtap@ARM.comElasticTrace::hasStoreCommitted(TraceInfo* past_record, 62611247Sradhika.jagtap@ARM.com Tick execute_tick) const 62711247Sradhika.jagtap@ARM.com{ 62811252Sradhika.jagtap@ARM.com return (past_record->isStore() && past_record->commitTick <= execute_tick); 62911247Sradhika.jagtap@ARM.com} 63011247Sradhika.jagtap@ARM.com 63111247Sradhika.jagtap@ARM.combool 63211247Sradhika.jagtap@ARM.comElasticTrace::hasLoadCompleted(TraceInfo* past_record, 63311247Sradhika.jagtap@ARM.com Tick execute_tick) const 63411247Sradhika.jagtap@ARM.com{ 63511252Sradhika.jagtap@ARM.com return(past_record->isLoad() && past_record->commit && 63611247Sradhika.jagtap@ARM.com past_record->toCommitTick <= execute_tick); 63711247Sradhika.jagtap@ARM.com} 63811247Sradhika.jagtap@ARM.com 63911247Sradhika.jagtap@ARM.combool 64011247Sradhika.jagtap@ARM.comElasticTrace::hasLoadBeenSent(TraceInfo* past_record, 64111247Sradhika.jagtap@ARM.com Tick execute_tick) const 64211247Sradhika.jagtap@ARM.com{ 64311247Sradhika.jagtap@ARM.com // Check if previous inst is a load sent earlier than this 64411252Sradhika.jagtap@ARM.com return (past_record->isLoad() && past_record->commit && 64511247Sradhika.jagtap@ARM.com past_record->executeTick <= execute_tick); 64611247Sradhika.jagtap@ARM.com} 64711247Sradhika.jagtap@ARM.com 64811247Sradhika.jagtap@ARM.combool 64911247Sradhika.jagtap@ARM.comElasticTrace::hasCompCompleted(TraceInfo* past_record, 65011247Sradhika.jagtap@ARM.com Tick execute_tick) const 65111247Sradhika.jagtap@ARM.com{ 65211252Sradhika.jagtap@ARM.com return(past_record->isComp() && past_record->toCommitTick <= execute_tick); 65311247Sradhika.jagtap@ARM.com} 65411247Sradhika.jagtap@ARM.com 65511247Sradhika.jagtap@ARM.comvoid 65613429Srekai.gonzalezalberquilla@arm.comElasticTrace::clearTempStoreUntil(const DynInstConstPtr& head_inst) 65711247Sradhika.jagtap@ARM.com{ 65811247Sradhika.jagtap@ARM.com // Clear from temp store starting with the execution info object 65911247Sradhika.jagtap@ARM.com // corresponding the head_inst and continue clearing by decrementing the 66011247Sradhika.jagtap@ARM.com // sequence number until the last cleared sequence number. 66111247Sradhika.jagtap@ARM.com InstSeqNum temp_sn = (head_inst->seqNum); 66211247Sradhika.jagtap@ARM.com while (temp_sn > lastClearedSeqNum) { 66311247Sradhika.jagtap@ARM.com auto itr_exec_info = tempStore.find(temp_sn); 66411247Sradhika.jagtap@ARM.com if (itr_exec_info != tempStore.end()) { 66511247Sradhika.jagtap@ARM.com InstExecInfo* exec_info_ptr = itr_exec_info->second; 66611247Sradhika.jagtap@ARM.com // Free allocated memory for the info object 66711247Sradhika.jagtap@ARM.com delete exec_info_ptr; 66811247Sradhika.jagtap@ARM.com // Remove entry from temporary store 66911247Sradhika.jagtap@ARM.com tempStore.erase(itr_exec_info); 67011247Sradhika.jagtap@ARM.com } 67111247Sradhika.jagtap@ARM.com temp_sn--; 67211247Sradhika.jagtap@ARM.com } 67311247Sradhika.jagtap@ARM.com // Update the last cleared sequence number to that of the head_inst 67411247Sradhika.jagtap@ARM.com lastClearedSeqNum = head_inst->seqNum; 67511247Sradhika.jagtap@ARM.com} 67611247Sradhika.jagtap@ARM.com 67711247Sradhika.jagtap@ARM.comvoid 67811247Sradhika.jagtap@ARM.comElasticTrace::compDelayRob(TraceInfo* past_record, TraceInfo* new_record) 67911247Sradhika.jagtap@ARM.com{ 68011247Sradhika.jagtap@ARM.com // The computation delay is the delay between the completion tick of the 68111247Sradhika.jagtap@ARM.com // inst. pointed to by past_record and the execution tick of its dependent 68211247Sradhika.jagtap@ARM.com // inst. pointed to by new_record. 68311247Sradhika.jagtap@ARM.com int64_t comp_delay = -1; 68411247Sradhika.jagtap@ARM.com Tick execution_tick = 0, completion_tick = 0; 68511247Sradhika.jagtap@ARM.com 68611247Sradhika.jagtap@ARM.com DPRINTF(ElasticTrace, "Seq num %lli has ROB dependency on seq num %lli.\n", 68711247Sradhika.jagtap@ARM.com new_record->instNum, past_record->instNum); 68811247Sradhika.jagtap@ARM.com 68911247Sradhika.jagtap@ARM.com // Get the tick when the node is executed as per the modelling of 69011247Sradhika.jagtap@ARM.com // computation delay 69111247Sradhika.jagtap@ARM.com execution_tick = new_record->getExecuteTick(); 69211247Sradhika.jagtap@ARM.com 69311252Sradhika.jagtap@ARM.com if (past_record->isLoad()) { 69411252Sradhika.jagtap@ARM.com if (new_record->isStore()) { 69511247Sradhika.jagtap@ARM.com completion_tick = past_record->toCommitTick; 69611247Sradhika.jagtap@ARM.com } else { 69711247Sradhika.jagtap@ARM.com completion_tick = past_record->executeTick; 69811247Sradhika.jagtap@ARM.com } 69911252Sradhika.jagtap@ARM.com } else if (past_record->isStore()) { 70011247Sradhika.jagtap@ARM.com completion_tick = past_record->commitTick; 70111252Sradhika.jagtap@ARM.com } else if (past_record->isComp()){ 70211247Sradhika.jagtap@ARM.com completion_tick = past_record->toCommitTick; 70311247Sradhika.jagtap@ARM.com } 70411247Sradhika.jagtap@ARM.com assert(execution_tick >= completion_tick); 70511247Sradhika.jagtap@ARM.com comp_delay = execution_tick - completion_tick; 70611247Sradhika.jagtap@ARM.com 70711247Sradhika.jagtap@ARM.com DPRINTF(ElasticTrace, "Computational delay is %lli - %lli = %lli\n", 70811247Sradhika.jagtap@ARM.com execution_tick, completion_tick, comp_delay); 70911247Sradhika.jagtap@ARM.com 71011247Sradhika.jagtap@ARM.com // Assign the computational delay with respect to the dependency which 71111247Sradhika.jagtap@ARM.com // completes the latest. 71211247Sradhika.jagtap@ARM.com if (new_record->compDelay == -1) 71311247Sradhika.jagtap@ARM.com new_record->compDelay = comp_delay; 71411247Sradhika.jagtap@ARM.com else 71511247Sradhika.jagtap@ARM.com new_record->compDelay = std::min(comp_delay, new_record->compDelay); 71611247Sradhika.jagtap@ARM.com DPRINTF(ElasticTrace, "Final computational delay = %lli.\n", 71711247Sradhika.jagtap@ARM.com new_record->compDelay); 71811247Sradhika.jagtap@ARM.com} 71911247Sradhika.jagtap@ARM.com 72011247Sradhika.jagtap@ARM.comvoid 72111247Sradhika.jagtap@ARM.comElasticTrace::compDelayPhysRegDep(TraceInfo* past_record, 72211247Sradhika.jagtap@ARM.com TraceInfo* new_record) 72311247Sradhika.jagtap@ARM.com{ 72411247Sradhika.jagtap@ARM.com // The computation delay is the delay between the completion tick of the 72511247Sradhika.jagtap@ARM.com // inst. pointed to by past_record and the execution tick of its dependent 72611247Sradhika.jagtap@ARM.com // inst. pointed to by new_record. 72711247Sradhika.jagtap@ARM.com int64_t comp_delay = -1; 72811247Sradhika.jagtap@ARM.com Tick execution_tick = 0, completion_tick = 0; 72911247Sradhika.jagtap@ARM.com 73011247Sradhika.jagtap@ARM.com DPRINTF(ElasticTrace, "Seq. num %lli has register dependency on seq. num" 73111247Sradhika.jagtap@ARM.com " %lli.\n", new_record->instNum, past_record->instNum); 73211247Sradhika.jagtap@ARM.com 73311247Sradhika.jagtap@ARM.com // Get the tick when the node is executed as per the modelling of 73411247Sradhika.jagtap@ARM.com // computation delay 73511247Sradhika.jagtap@ARM.com execution_tick = new_record->getExecuteTick(); 73611247Sradhika.jagtap@ARM.com 73711247Sradhika.jagtap@ARM.com // When there is a physical register dependency on an instruction, the 73811247Sradhika.jagtap@ARM.com // completion tick of that instruction is when it wrote to the register, 73911247Sradhika.jagtap@ARM.com // that is toCommitTick. In case, of a store updating a destination 74011247Sradhika.jagtap@ARM.com // register, this is approximated to commitTick instead 74111252Sradhika.jagtap@ARM.com if (past_record->isStore()) { 74211247Sradhika.jagtap@ARM.com completion_tick = past_record->commitTick; 74311247Sradhika.jagtap@ARM.com } else { 74411247Sradhika.jagtap@ARM.com completion_tick = past_record->toCommitTick; 74511247Sradhika.jagtap@ARM.com } 74611247Sradhika.jagtap@ARM.com assert(execution_tick >= completion_tick); 74711247Sradhika.jagtap@ARM.com comp_delay = execution_tick - completion_tick; 74811247Sradhika.jagtap@ARM.com DPRINTF(ElasticTrace, "Computational delay is %lli - %lli = %lli\n", 74911247Sradhika.jagtap@ARM.com execution_tick, completion_tick, comp_delay); 75011247Sradhika.jagtap@ARM.com 75111247Sradhika.jagtap@ARM.com // Assign the computational delay with respect to the dependency which 75211247Sradhika.jagtap@ARM.com // completes the latest. 75311247Sradhika.jagtap@ARM.com if (new_record->compDelay == -1) 75411247Sradhika.jagtap@ARM.com new_record->compDelay = comp_delay; 75511247Sradhika.jagtap@ARM.com else 75611247Sradhika.jagtap@ARM.com new_record->compDelay = std::min(comp_delay, new_record->compDelay); 75711247Sradhika.jagtap@ARM.com DPRINTF(ElasticTrace, "Final computational delay = %lli.\n", 75811247Sradhika.jagtap@ARM.com new_record->compDelay); 75911247Sradhika.jagtap@ARM.com} 76011247Sradhika.jagtap@ARM.com 76111247Sradhika.jagtap@ARM.comTick 76211247Sradhika.jagtap@ARM.comElasticTrace::TraceInfo::getExecuteTick() const 76311247Sradhika.jagtap@ARM.com{ 76411252Sradhika.jagtap@ARM.com if (isLoad()) { 76511247Sradhika.jagtap@ARM.com // Execution tick for a load instruction is when the request was sent, 76611247Sradhika.jagtap@ARM.com // that is executeTick. 76711247Sradhika.jagtap@ARM.com return executeTick; 76811252Sradhika.jagtap@ARM.com } else if (isStore()) { 76911247Sradhika.jagtap@ARM.com // Execution tick for a store instruction is when the request was sent, 77011247Sradhika.jagtap@ARM.com // that is commitTick. 77111247Sradhika.jagtap@ARM.com return commitTick; 77211247Sradhika.jagtap@ARM.com } else { 77311247Sradhika.jagtap@ARM.com // Execution tick for a non load/store instruction is when the register 77411247Sradhika.jagtap@ARM.com // value was written to, that is commitTick. 77511247Sradhika.jagtap@ARM.com return toCommitTick; 77611247Sradhika.jagtap@ARM.com } 77711247Sradhika.jagtap@ARM.com} 77811247Sradhika.jagtap@ARM.com 77911247Sradhika.jagtap@ARM.comvoid 78011247Sradhika.jagtap@ARM.comElasticTrace::writeDepTrace(uint32_t num_to_write) 78111247Sradhika.jagtap@ARM.com{ 78211247Sradhika.jagtap@ARM.com // Write the trace with fields as follows: 78311247Sradhika.jagtap@ARM.com // Instruction sequence number 78411247Sradhika.jagtap@ARM.com // If instruction was a load 78511247Sradhika.jagtap@ARM.com // If instruction was a store 78611247Sradhika.jagtap@ARM.com // If instruction has addr 78711247Sradhika.jagtap@ARM.com // If instruction has size 78811247Sradhika.jagtap@ARM.com // If instruction has flags 78911247Sradhika.jagtap@ARM.com // List of order dependencies - optional, repeated 79011247Sradhika.jagtap@ARM.com // Computational delay with respect to last completed dependency 79111247Sradhika.jagtap@ARM.com // List of physical register RAW dependencies - optional, repeated 79211247Sradhika.jagtap@ARM.com // Weight of a node equal to no. of filtered nodes before it - optional 79311247Sradhika.jagtap@ARM.com uint16_t num_filtered_nodes = 0; 79411247Sradhika.jagtap@ARM.com depTraceItr dep_trace_itr(depTrace.begin()); 79511247Sradhika.jagtap@ARM.com depTraceItr dep_trace_itr_start = dep_trace_itr; 79611247Sradhika.jagtap@ARM.com while (num_to_write > 0) { 79711247Sradhika.jagtap@ARM.com TraceInfo* temp_ptr = *dep_trace_itr; 79811252Sradhika.jagtap@ARM.com assert(temp_ptr->type != Record::INVALID); 79911252Sradhika.jagtap@ARM.com // If no node dependends on a comp node then there is no reason to 80011252Sradhika.jagtap@ARM.com // track the comp node in the dependency graph. We filter out such 80111247Sradhika.jagtap@ARM.com // nodes but count them and add a weight field to the subsequent node 80211247Sradhika.jagtap@ARM.com // that we do include in the trace. 80311252Sradhika.jagtap@ARM.com if (!temp_ptr->isComp() || temp_ptr->numDepts != 0) { 80411247Sradhika.jagtap@ARM.com DPRINTFR(ElasticTrace, "Instruction with seq. num %lli " 80511247Sradhika.jagtap@ARM.com "is as follows:\n", temp_ptr->instNum); 80611252Sradhika.jagtap@ARM.com if (temp_ptr->isLoad() || temp_ptr->isStore()) { 80711252Sradhika.jagtap@ARM.com DPRINTFR(ElasticTrace, "\tis a %s\n", temp_ptr->typeToStr()); 80811253Sradhika.jagtap@ARM.com DPRINTFR(ElasticTrace, "\thas a request with phys addr %i, " 80911253Sradhika.jagtap@ARM.com "size %i, flags %i\n", temp_ptr->physAddr, 81011253Sradhika.jagtap@ARM.com temp_ptr->size, temp_ptr->reqFlags); 81111247Sradhika.jagtap@ARM.com } else { 81211252Sradhika.jagtap@ARM.com DPRINTFR(ElasticTrace, "\tis a %s\n", temp_ptr->typeToStr()); 81311247Sradhika.jagtap@ARM.com } 81411247Sradhika.jagtap@ARM.com if (firstWin && temp_ptr->compDelay == -1) { 81511252Sradhika.jagtap@ARM.com if (temp_ptr->isLoad()) { 81611247Sradhika.jagtap@ARM.com temp_ptr->compDelay = temp_ptr->executeTick; 81711252Sradhika.jagtap@ARM.com } else if (temp_ptr->isStore()) { 81811247Sradhika.jagtap@ARM.com temp_ptr->compDelay = temp_ptr->commitTick; 81911247Sradhika.jagtap@ARM.com } else { 82011247Sradhika.jagtap@ARM.com temp_ptr->compDelay = temp_ptr->toCommitTick; 82111247Sradhika.jagtap@ARM.com } 82211247Sradhika.jagtap@ARM.com } 82311247Sradhika.jagtap@ARM.com assert(temp_ptr->compDelay != -1); 82411247Sradhika.jagtap@ARM.com DPRINTFR(ElasticTrace, "\thas computational delay %lli\n", 82511247Sradhika.jagtap@ARM.com temp_ptr->compDelay); 82611247Sradhika.jagtap@ARM.com 82711247Sradhika.jagtap@ARM.com // Create a protobuf message for the dependency record 82811247Sradhika.jagtap@ARM.com ProtoMessage::InstDepRecord dep_pkt; 82911247Sradhika.jagtap@ARM.com dep_pkt.set_seq_num(temp_ptr->instNum); 83011252Sradhika.jagtap@ARM.com dep_pkt.set_type(temp_ptr->type); 83111247Sradhika.jagtap@ARM.com dep_pkt.set_pc(temp_ptr->pc); 83211252Sradhika.jagtap@ARM.com if (temp_ptr->isLoad() || temp_ptr->isStore()) { 83311247Sradhika.jagtap@ARM.com dep_pkt.set_flags(temp_ptr->reqFlags); 83411253Sradhika.jagtap@ARM.com dep_pkt.set_p_addr(temp_ptr->physAddr); 83511253Sradhika.jagtap@ARM.com // If tracing of virtual addresses is enabled, set the optional 83611253Sradhika.jagtap@ARM.com // field for it 83711253Sradhika.jagtap@ARM.com if (traceVirtAddr) { 83811253Sradhika.jagtap@ARM.com dep_pkt.set_v_addr(temp_ptr->virtAddr); 83911253Sradhika.jagtap@ARM.com dep_pkt.set_asid(temp_ptr->asid); 84011253Sradhika.jagtap@ARM.com } 84111247Sradhika.jagtap@ARM.com dep_pkt.set_size(temp_ptr->size); 84211247Sradhika.jagtap@ARM.com } 84311247Sradhika.jagtap@ARM.com dep_pkt.set_comp_delay(temp_ptr->compDelay); 84411247Sradhika.jagtap@ARM.com if (temp_ptr->robDepList.empty()) { 84511247Sradhika.jagtap@ARM.com DPRINTFR(ElasticTrace, "\thas no order (rob) dependencies\n"); 84611247Sradhika.jagtap@ARM.com } 84711247Sradhika.jagtap@ARM.com while (!temp_ptr->robDepList.empty()) { 84811247Sradhika.jagtap@ARM.com DPRINTFR(ElasticTrace, "\thas order (rob) dependency on %lli\n", 84911247Sradhika.jagtap@ARM.com temp_ptr->robDepList.front()); 85011247Sradhika.jagtap@ARM.com dep_pkt.add_rob_dep(temp_ptr->robDepList.front()); 85111247Sradhika.jagtap@ARM.com temp_ptr->robDepList.pop_front(); 85211247Sradhika.jagtap@ARM.com } 85311247Sradhika.jagtap@ARM.com if (temp_ptr->physRegDepList.empty()) { 85411247Sradhika.jagtap@ARM.com DPRINTFR(ElasticTrace, "\thas no register dependencies\n"); 85511247Sradhika.jagtap@ARM.com } 85611247Sradhika.jagtap@ARM.com while (!temp_ptr->physRegDepList.empty()) { 85711247Sradhika.jagtap@ARM.com DPRINTFR(ElasticTrace, "\thas register dependency on %lli\n", 85811247Sradhika.jagtap@ARM.com temp_ptr->physRegDepList.front()); 85911247Sradhika.jagtap@ARM.com dep_pkt.add_reg_dep(temp_ptr->physRegDepList.front()); 86011247Sradhika.jagtap@ARM.com temp_ptr->physRegDepList.pop_front(); 86111247Sradhika.jagtap@ARM.com } 86211247Sradhika.jagtap@ARM.com if (num_filtered_nodes != 0) { 86311247Sradhika.jagtap@ARM.com // Set the weight of this node as the no. of filtered nodes 86411247Sradhika.jagtap@ARM.com // between this node and the last node that we wrote to output 86511247Sradhika.jagtap@ARM.com // stream. The weight will be used during replay to model ROB 86611247Sradhika.jagtap@ARM.com // occupancy of filtered nodes. 86711247Sradhika.jagtap@ARM.com dep_pkt.set_weight(num_filtered_nodes); 86811247Sradhika.jagtap@ARM.com num_filtered_nodes = 0; 86911247Sradhika.jagtap@ARM.com } 87011247Sradhika.jagtap@ARM.com // Write the message to the protobuf output stream 87111247Sradhika.jagtap@ARM.com dataTraceStream->write(dep_pkt); 87211247Sradhika.jagtap@ARM.com } else { 87311247Sradhika.jagtap@ARM.com // Don't write the node to the trace but note that we have filtered 87411247Sradhika.jagtap@ARM.com // out a node. 87511247Sradhika.jagtap@ARM.com ++numFilteredNodes; 87611247Sradhika.jagtap@ARM.com ++num_filtered_nodes; 87711247Sradhika.jagtap@ARM.com } 87811247Sradhika.jagtap@ARM.com dep_trace_itr++; 87911247Sradhika.jagtap@ARM.com traceInfoMap.erase(temp_ptr->instNum); 88011247Sradhika.jagtap@ARM.com delete temp_ptr; 88111247Sradhika.jagtap@ARM.com num_to_write--; 88211247Sradhika.jagtap@ARM.com } 88311247Sradhika.jagtap@ARM.com depTrace.erase(dep_trace_itr_start, dep_trace_itr); 88411247Sradhika.jagtap@ARM.com} 88511247Sradhika.jagtap@ARM.com 88611247Sradhika.jagtap@ARM.comvoid 88711247Sradhika.jagtap@ARM.comElasticTrace::regStats() { 88811523Sdavid.guillen@arm.com ProbeListenerObject::regStats(); 88911523Sdavid.guillen@arm.com 89011247Sradhika.jagtap@ARM.com using namespace Stats; 89111247Sradhika.jagtap@ARM.com numRegDep 89211247Sradhika.jagtap@ARM.com .name(name() + ".numRegDep") 89311247Sradhika.jagtap@ARM.com .desc("Number of register dependencies recorded during tracing") 89411247Sradhika.jagtap@ARM.com ; 89511247Sradhika.jagtap@ARM.com 89611247Sradhika.jagtap@ARM.com numOrderDepStores 89711247Sradhika.jagtap@ARM.com .name(name() + ".numOrderDepStores") 89811247Sradhika.jagtap@ARM.com .desc("Number of commit order (rob) dependencies for a store recorded" 89911247Sradhika.jagtap@ARM.com " on a past load/store during tracing") 90011247Sradhika.jagtap@ARM.com ; 90111247Sradhika.jagtap@ARM.com 90211247Sradhika.jagtap@ARM.com numIssueOrderDepLoads 90311247Sradhika.jagtap@ARM.com .name(name() + ".numIssueOrderDepLoads") 90411247Sradhika.jagtap@ARM.com .desc("Number of loads that got assigned issue order dependency" 90511247Sradhika.jagtap@ARM.com " because they were dependency-free") 90611247Sradhika.jagtap@ARM.com ; 90711247Sradhika.jagtap@ARM.com 90811247Sradhika.jagtap@ARM.com numIssueOrderDepStores 90911247Sradhika.jagtap@ARM.com .name(name() + ".numIssueOrderDepStores") 91011247Sradhika.jagtap@ARM.com .desc("Number of stores that got assigned issue order dependency" 91111247Sradhika.jagtap@ARM.com " because they were dependency-free") 91211247Sradhika.jagtap@ARM.com ; 91311247Sradhika.jagtap@ARM.com 91411247Sradhika.jagtap@ARM.com numIssueOrderDepOther 91511247Sradhika.jagtap@ARM.com .name(name() + ".numIssueOrderDepOther") 91611247Sradhika.jagtap@ARM.com .desc("Number of non load/store insts that got assigned issue order" 91711247Sradhika.jagtap@ARM.com " dependency because they were dependency-free") 91811247Sradhika.jagtap@ARM.com ; 91911247Sradhika.jagtap@ARM.com 92011247Sradhika.jagtap@ARM.com numFilteredNodes 92111247Sradhika.jagtap@ARM.com .name(name() + ".numFilteredNodes") 92211247Sradhika.jagtap@ARM.com .desc("No. of nodes filtered out before writing the output trace") 92311247Sradhika.jagtap@ARM.com ; 92411247Sradhika.jagtap@ARM.com 92511247Sradhika.jagtap@ARM.com maxNumDependents 92611247Sradhika.jagtap@ARM.com .name(name() + ".maxNumDependents") 92711247Sradhika.jagtap@ARM.com .desc("Maximum number or dependents on any instruction") 92811247Sradhika.jagtap@ARM.com ; 92911247Sradhika.jagtap@ARM.com 93011247Sradhika.jagtap@ARM.com maxTempStoreSize 93111247Sradhika.jagtap@ARM.com .name(name() + ".maxTempStoreSize") 93211247Sradhika.jagtap@ARM.com .desc("Maximum size of the temporary store during the run") 93311247Sradhika.jagtap@ARM.com ; 93411247Sradhika.jagtap@ARM.com 93511247Sradhika.jagtap@ARM.com maxPhysRegDepMapSize 93611247Sradhika.jagtap@ARM.com .name(name() + ".maxPhysRegDepMapSize") 93711247Sradhika.jagtap@ARM.com .desc("Maximum size of register dependency map") 93811247Sradhika.jagtap@ARM.com ; 93911247Sradhika.jagtap@ARM.com} 94011247Sradhika.jagtap@ARM.com 94111252Sradhika.jagtap@ARM.comconst std::string& 94211252Sradhika.jagtap@ARM.comElasticTrace::TraceInfo::typeToStr() const 94311252Sradhika.jagtap@ARM.com{ 94411252Sradhika.jagtap@ARM.com return Record::RecordType_Name(type); 94511252Sradhika.jagtap@ARM.com} 94611252Sradhika.jagtap@ARM.com 94711247Sradhika.jagtap@ARM.comconst std::string 94811247Sradhika.jagtap@ARM.comElasticTrace::name() const 94911247Sradhika.jagtap@ARM.com{ 95011247Sradhika.jagtap@ARM.com return ProbeListenerObject::name(); 95111247Sradhika.jagtap@ARM.com} 95211247Sradhika.jagtap@ARM.com 95311247Sradhika.jagtap@ARM.comvoid 95411247Sradhika.jagtap@ARM.comElasticTrace::flushTraces() 95511247Sradhika.jagtap@ARM.com{ 95611247Sradhika.jagtap@ARM.com // Write to trace all records in the depTrace. 95711247Sradhika.jagtap@ARM.com writeDepTrace(depTrace.size()); 95811247Sradhika.jagtap@ARM.com // Delete the stream objects 95911247Sradhika.jagtap@ARM.com delete dataTraceStream; 96011247Sradhika.jagtap@ARM.com delete instTraceStream; 96111247Sradhika.jagtap@ARM.com} 96211247Sradhika.jagtap@ARM.com 96311247Sradhika.jagtap@ARM.comElasticTrace* 96411247Sradhika.jagtap@ARM.comElasticTraceParams::create() 96511247Sradhika.jagtap@ARM.com{ 96611247Sradhika.jagtap@ARM.com return new ElasticTrace(this); 96711247Sradhika.jagtap@ARM.com} 968