gem5  v21.1.0.2
elastic_trace.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 - 2015 ARM Limited
3  * All rights reserved
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions are
16  * met: redistributions of source code must retain the above copyright
17  * notice, this list of conditions and the following disclaimer;
18  * redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution;
21  * neither the name of the copyright holders nor the names of its
22  * contributors may be used to endorse or promote products derived from
23  * this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  */
37 
39 
40 #include "base/callback.hh"
41 #include "base/output.hh"
42 #include "base/trace.hh"
43 #include "cpu/o3/dyn_inst.hh"
44 #include "cpu/reg_class.hh"
45 #include "debug/ElasticTrace.hh"
46 #include "mem/packet.hh"
47 
48 namespace gem5
49 {
50 
51 namespace o3
52 {
53 
54 ElasticTrace::ElasticTrace(const ElasticTraceParams &params)
55  : ProbeListenerObject(params),
56  regEtraceListenersEvent([this]{ regEtraceListeners(); }, name()),
57  firstWin(true),
58  lastClearedSeqNum(0),
59  depWindowSize(params.depWindowSize),
60  dataTraceStream(nullptr),
61  instTraceStream(nullptr),
62  startTraceInst(params.startTraceInst),
63  allProbesReg(false),
64  traceVirtAddr(params.traceVirtAddr),
65  stats(this)
66 {
67  cpu = dynamic_cast<CPU *>(params.manager);
68  const BaseISA::RegClasses &regClasses =
69  cpu->getContext(0)->getIsaPtr()->regClasses();
70  zeroReg = regClasses.at(IntRegClass).zeroReg();
71 
72  fatal_if(!cpu, "Manager of %s is not of type O3CPU and thus does not "\
73  "support dependency tracing.\n", name());
74 
75  fatal_if(depWindowSize == 0, "depWindowSize parameter must be non-zero. "\
76  "Recommended size is 3x ROB size in the O3CPU.\n");
77 
78  fatal_if(cpu->numThreads > 1, "numThreads = %i, %s supports tracing for"\
79  "single-threaded workload only", cpu->numThreads, name());
80  // Initialize the protobuf output stream
81  fatal_if(params.instFetchTraceFile == "", "Assign instruction fetch "\
82  "trace file path to instFetchTraceFile");
83  fatal_if(params.dataDepTraceFile == "", "Assign data dependency "\
84  "trace file path to dataDepTraceFile");
85  std::string filename = simout.resolve(name() + "." +
86  params.instFetchTraceFile);
87  instTraceStream = new ProtoOutputStream(filename);
88  filename = simout.resolve(name() + "." + params.dataDepTraceFile);
89  dataTraceStream = new ProtoOutputStream(filename);
90  // Create a protobuf message for the header and write it to the stream
91  ProtoMessage::PacketHeader inst_pkt_header;
92  inst_pkt_header.set_obj_id(name());
93  inst_pkt_header.set_tick_freq(sim_clock::Frequency);
94  instTraceStream->write(inst_pkt_header);
95  // Create a protobuf message for the header and write it to
96  // the stream
97  ProtoMessage::InstDepRecordHeader data_rec_header;
98  data_rec_header.set_obj_id(name());
99  data_rec_header.set_tick_freq(sim_clock::Frequency);
100  data_rec_header.set_window_size(depWindowSize);
101  dataTraceStream->write(data_rec_header);
102  // Register a callback to flush trace records and close the output streams.
103  registerExitCallback([this]() { flushTraces(); });
104 }
105 
106 void
108 {
109  inform("@%llu: regProbeListeners() called, startTraceInst = %llu",
111  if (startTraceInst == 0) {
112  // If we want to start tracing from the start of the simulation,
113  // register all elastic trace probes now.
115  } else {
116  // Schedule an event to register all elastic trace probes when
117  // specified no. of instructions are committed.
120  }
121 }
122 
123 void
125 {
126  assert(!allProbesReg);
127  inform("@%llu: No. of instructions committed = %llu, registering elastic"
128  " probe listeners", curTick(), cpu->numSimulatedInsts());
129  // Create new listeners: provide method to be called upon a notify() for
130  // each probe point.
132  "FetchRequest", &ElasticTrace::fetchReqTrace));
134  DynInstConstPtr>(this, "Execute",
137  DynInstConstPtr>(this, "ToCommit",
140  DynInstConstPtr>(this, "Rename",
143  "SquashInRename", &ElasticTrace::removeRegDepMapEntry));
145  DynInstConstPtr>(this, "Squash",
148  DynInstConstPtr>(this, "Commit",
150  allProbesReg = true;
151 }
152 
153 void
155 {
156 
157  DPRINTFR(ElasticTrace, "Fetch Req %i,(%lli,%lli,%lli),%i,%i,%lli\n",
158  (MemCmd::ReadReq),
159  req->getPC(), req->getVaddr(), req->getPaddr(),
160  req->getFlags(), req->getSize(), curTick());
161 
162  // Create a protobuf message including the request fields necessary to
163  // recreate the request in the TraceCPU.
164  ProtoMessage::Packet inst_fetch_pkt;
165  inst_fetch_pkt.set_tick(curTick());
166  inst_fetch_pkt.set_cmd(MemCmd::ReadReq);
167  inst_fetch_pkt.set_pc(req->getPC());
168  inst_fetch_pkt.set_flags(req->getFlags());
169  inst_fetch_pkt.set_addr(req->getPaddr());
170  inst_fetch_pkt.set_size(req->getSize());
171  // Write the message to the stream.
172  instTraceStream->write(inst_fetch_pkt);
173 }
174 
175 void
177 {
178 
179  // In a corner case, a retired instruction is propagated backward to the
180  // IEW instruction queue to handle some side-channel information. But we
181  // must not process an instruction again. So we test the sequence number
182  // against the lastClearedSeqNum and skip adding the instruction for such
183  // corner cases.
184  if (dyn_inst->seqNum <= lastClearedSeqNum) {
185  DPRINTFR(ElasticTrace, "[sn:%lli] Ignoring in execute as instruction \
186  has already retired (mostly squashed)", dyn_inst->seqNum);
187  // Do nothing as program has proceeded and this inst has been
188  // propagated backwards to handle something.
189  return;
190  }
191 
192  DPRINTFR(ElasticTrace, "[sn:%lli] Execute Tick = %i\n", dyn_inst->seqNum,
193  curTick());
194  // Either the execution info object will already exist if this
195  // instruction had a register dependency recorded in the rename probe
196  // listener before entering execute stage or it will not exist and will
197  // need to be created here.
198  InstExecInfo* exec_info_ptr;
199  auto itr_exec_info = tempStore.find(dyn_inst->seqNum);
200  if (itr_exec_info != tempStore.end()) {
201  exec_info_ptr = itr_exec_info->second;
202  } else {
203  exec_info_ptr = new InstExecInfo;
204  tempStore[dyn_inst->seqNum] = exec_info_ptr;
205  }
206 
207  exec_info_ptr->executeTick = curTick();
208  stats.maxTempStoreSize = std::max(tempStore.size(),
209  (std::size_t)stats.maxTempStoreSize.value());
210 }
211 
212 void
214 {
215  // If tracing has just been enabled then the instruction at this stage of
216  // execution is far enough that we cannot gather info about its past like
217  // the tick it started execution. Simply return until we see an instruction
218  // that is found in the tempStore.
219  auto itr_exec_info = tempStore.find(dyn_inst->seqNum);
220  if (itr_exec_info == tempStore.end()) {
221  DPRINTFR(ElasticTrace, "recordToCommTick: [sn:%lli] Not in temp store,"
222  " skipping.\n", dyn_inst->seqNum);
223  return;
224  }
225 
226  DPRINTFR(ElasticTrace, "[sn:%lli] To Commit Tick = %i\n", dyn_inst->seqNum,
227  curTick());
228  InstExecInfo* exec_info_ptr = itr_exec_info->second;
229  exec_info_ptr->toCommitTick = curTick();
230 
231 }
232 
233 void
235 {
236  // Get the sequence number of the instruction
237  InstSeqNum seq_num = dyn_inst->seqNum;
238 
239  assert(dyn_inst->seqNum > lastClearedSeqNum);
240 
241  // Since this is the first probe activated in the pipeline, create
242  // a new execution info object to track this instruction as it
243  // progresses through the pipeline.
244  InstExecInfo* exec_info_ptr = new InstExecInfo;
245  tempStore[seq_num] = exec_info_ptr;
246 
247  // Loop through the source registers and look up the dependency map. If
248  // the source register entry is found in the dependency map, add a
249  // dependency on the last writer.
250  int8_t max_regs = dyn_inst->numSrcRegs();
251  for (int src_idx = 0; src_idx < max_regs; src_idx++) {
252 
253  const RegId& src_reg = dyn_inst->srcRegIdx(src_idx);
254  if (!src_reg.is(MiscRegClass) &&
255  !(src_reg.is(IntRegClass) && src_reg.index() == zeroReg)) {
256  // Get the physical register index of the i'th source register.
257  PhysRegIdPtr phys_src_reg = dyn_inst->regs.renamedSrcIdx(src_idx);
258  DPRINTFR(ElasticTrace, "[sn:%lli] Check map for src reg"
259  " %i (%s)\n", seq_num,
260  phys_src_reg->flatIndex(), phys_src_reg->className());
261  auto itr_writer = physRegDepMap.find(phys_src_reg->flatIndex());
262  if (itr_writer != physRegDepMap.end()) {
263  InstSeqNum last_writer = itr_writer->second;
264  // Additionally the dependency distance is kept less than the
265  // window size parameter to limit the memory allocation to
266  // nodes in the graph. If the window were tending to infinite
267  // we would have to load a large number of node objects during
268  // replay.
269  if (seq_num - last_writer < depWindowSize) {
270  // Record a physical register dependency.
271  exec_info_ptr->physRegDepSet.insert(last_writer);
272  }
273  }
274 
275  }
276 
277  }
278 
279  // Loop through the destination registers of this instruction and update
280  // the physical register dependency map for last writers to registers.
281  max_regs = dyn_inst->numDestRegs();
282  for (int dest_idx = 0; dest_idx < max_regs; dest_idx++) {
283  // For data dependency tracking the register must be an int, float or
284  // CC register and not a Misc register.
285  const RegId& dest_reg = dyn_inst->destRegIdx(dest_idx);
286  if (!dest_reg.is(MiscRegClass) &&
287  !(dest_reg.is(IntRegClass) && dest_reg.index() == zeroReg)) {
288  // Get the physical register index of the i'th destination
289  // register.
290  PhysRegIdPtr phys_dest_reg =
291  dyn_inst->regs.renamedDestIdx(dest_idx);
292  DPRINTFR(ElasticTrace, "[sn:%lli] Update map for dest reg"
293  " %i (%s)\n", seq_num, phys_dest_reg->flatIndex(),
294  dest_reg.className());
295  physRegDepMap[phys_dest_reg->flatIndex()] = seq_num;
296  }
297  }
298  stats.maxPhysRegDepMapSize = std::max(physRegDepMap.size(),
299  (std::size_t)stats.maxPhysRegDepMapSize.value());
300 }
301 
302 void
304 {
305  DPRINTFR(ElasticTrace, "Remove Map entry for Reg %i\n",
306  inst_reg_pair.second);
307  auto itr_regdep_map = physRegDepMap.find(inst_reg_pair.second);
308  if (itr_regdep_map != physRegDepMap.end())
309  physRegDepMap.erase(itr_regdep_map);
310 }
311 
312 void
314 {
315  // If the squashed instruction was squashed before being processed by
316  // execute stage then it will not be in the temporary store. In this case
317  // do nothing and return.
318  auto itr_exec_info = tempStore.find(head_inst->seqNum);
319  if (itr_exec_info == tempStore.end())
320  return;
321 
322  // If there is a squashed load for which a read request was
323  // sent before it got squashed then add it to the trace.
324  DPRINTFR(ElasticTrace, "Attempt to add squashed inst [sn:%lli]\n",
325  head_inst->seqNum);
326  // Get pointer to the execution info object corresponding to the inst.
327  InstExecInfo* exec_info_ptr = itr_exec_info->second;
328  if (head_inst->isLoad() && exec_info_ptr->executeTick != MaxTick &&
329  exec_info_ptr->toCommitTick != MaxTick &&
330  head_inst->hasRequest() &&
331  head_inst->getFault() == NoFault) {
332  // Add record to depTrace with commit parameter as false.
333  addDepTraceRecord(head_inst, exec_info_ptr, false);
334  }
335  // As the information contained is no longer needed, remove the execution
336  // info object from the temporary store.
337  clearTempStoreUntil(head_inst);
338 }
339 
340 void
342 {
343  DPRINTFR(ElasticTrace, "Attempt to add committed inst [sn:%lli]\n",
344  head_inst->seqNum);
345 
346  // Add the instruction to the depTrace.
347  if (!head_inst->isNop()) {
348 
349  // If tracing has just been enabled then the instruction at this stage
350  // of execution is far enough that we cannot gather info about its past
351  // like the tick it started execution. Simply return until we see an
352  // instruction that is found in the tempStore.
353  auto itr_temp_store = tempStore.find(head_inst->seqNum);
354  if (itr_temp_store == tempStore.end()) {
355  DPRINTFR(ElasticTrace, "addCommittedInst: [sn:%lli] Not in temp "
356  "store, skipping.\n", head_inst->seqNum);
357  return;
358  }
359 
360  // Get pointer to the execution info object corresponding to the inst.
361  InstExecInfo* exec_info_ptr = itr_temp_store->second;
362  assert(exec_info_ptr->executeTick != MaxTick);
363  assert(exec_info_ptr->toCommitTick != MaxTick);
364 
365  // Check if the instruction had a fault, if it predicated false and
366  // thus previous register values were restored or if it was a
367  // load/store that did not have a request (e.g. when the size of the
368  // request is zero). In all these cases the instruction is set as
369  // executed and is picked up by the commit probe listener. But a
370  // request is not issued and registers are not written. So practically,
371  // skipping these should not hurt as execution would not stall on them.
372  // Alternatively, these could be included merely as a compute node in
373  // the graph. Removing these for now. If correlation accuracy needs to
374  // be improved in future these can be turned into comp nodes at the
375  // cost of bigger traces.
376  if (head_inst->getFault() != NoFault) {
377  DPRINTF(ElasticTrace, "%s [sn:%lli] has faulted so "
378  "skip adding it to the trace\n",
379  (head_inst->isMemRef() ? "Load/store" : "Comp inst."),
380  head_inst->seqNum);
381  } else if (head_inst->isMemRef() && !head_inst->hasRequest()) {
382  DPRINTF(ElasticTrace, "Load/store [sn:%lli] has no request so "
383  "skip adding it to the trace\n", head_inst->seqNum);
384  } else if (!head_inst->readPredicate()) {
385  DPRINTF(ElasticTrace, "%s [sn:%lli] is predicated false so "
386  "skip adding it to the trace\n",
387  (head_inst->isMemRef() ? "Load/store" : "Comp inst."),
388  head_inst->seqNum);
389  } else {
390  // Add record to depTrace with commit parameter as true.
391  addDepTraceRecord(head_inst, exec_info_ptr, true);
392  }
393  }
394  // As the information contained is no longer needed, remove the execution
395  // info object from the temporary store.
396  clearTempStoreUntil(head_inst);
397 }
398 
399 void
401  InstExecInfo* exec_info_ptr, bool commit)
402 {
403  // Create a record to assign dynamic intruction related fields.
404  TraceInfo* new_record = new TraceInfo;
405  // Add to map for sequence number look up to retrieve the TraceInfo pointer
406  traceInfoMap[head_inst->seqNum] = new_record;
407 
408  // Assign fields from the instruction
409  new_record->instNum = head_inst->seqNum;
410  new_record->commit = commit;
411  new_record->type = head_inst->isLoad() ? Record::LOAD :
412  (head_inst->isStore() ? Record::STORE :
413  Record::COMP);
414 
415  // Assign fields for creating a request in case of a load/store
416  new_record->reqFlags = head_inst->memReqFlags;
417  new_record->virtAddr = head_inst->effAddr;
418  new_record->physAddr = head_inst->physEffAddr;
419  // Currently the tracing does not support split requests.
420  new_record->size = head_inst->effSize;
421  new_record->pc = head_inst->instAddr();
422 
423  // Assign the timing information stored in the execution info object
424  new_record->executeTick = exec_info_ptr->executeTick;
425  new_record->toCommitTick = exec_info_ptr->toCommitTick;
426  new_record->commitTick = curTick();
427 
428  // Assign initial values for number of dependents and computational delay
429  new_record->numDepts = 0;
430  new_record->compDelay = -1;
431 
432  // The physical register dependency set of the first instruction is
433  // empty. Since there are no records in the depTrace at this point, the
434  // case of adding an ROB dependency by using a reverse iterator is not
435  // applicable. Thus, populate the fields of the record corresponding to the
436  // first instruction and return.
437  if (depTrace.empty()) {
438  // Store the record in depTrace.
439  depTrace.push_back(new_record);
440  DPRINTF(ElasticTrace, "Added first inst record %lli to DepTrace.\n",
441  new_record->instNum);
442  return;
443  }
444 
445  // Clear register dependencies for squashed loads as they may be dependent
446  // on squashed instructions and we do not add those to the trace.
447  if (head_inst->isLoad() && !commit) {
448  (exec_info_ptr->physRegDepSet).clear();
449  }
450 
451  // Assign the register dependencies stored in the execution info object
452  std::set<InstSeqNum>::const_iterator dep_set_it;
453  for (dep_set_it = (exec_info_ptr->physRegDepSet).begin();
454  dep_set_it != (exec_info_ptr->physRegDepSet).end();
455  ++dep_set_it) {
456  auto trace_info_itr = traceInfoMap.find(*dep_set_it);
457  if (trace_info_itr != traceInfoMap.end()) {
458  // The register dependency is valid. Assign it and calculate
459  // computational delay
460  new_record->physRegDepList.push_back(*dep_set_it);
461  DPRINTF(ElasticTrace, "Inst %lli has register dependency on "
462  "%lli\n", new_record->instNum, *dep_set_it);
463  TraceInfo* reg_dep = trace_info_itr->second;
464  reg_dep->numDepts++;
465  compDelayPhysRegDep(reg_dep, new_record);
466  ++stats.numRegDep;
467  } else {
468  // The instruction that this has a register dependency on was
469  // not added to the trace because of one of the following
470  // 1. it was an instruction that had a fault
471  // 2. it was an instruction that was predicated false and
472  // previous register values were restored
473  // 3. it was load/store that did not have a request (e.g. when
474  // the size of the request is zero but this may not be a fault)
475  // In all these cases the instruction is set as executed and is
476  // picked up by the commit probe listener. But a request is not
477  // issued and registers are not written to in these cases.
478  DPRINTF(ElasticTrace, "Inst %lli has register dependency on "
479  "%lli is skipped\n",new_record->instNum, *dep_set_it);
480  }
481  }
482 
483  // Check for and assign an ROB dependency in addition to register
484  // dependency before adding the record to the trace.
485  // As stores have to commit in order a store is dependent on the last
486  // committed load/store. This is recorded in the ROB dependency.
487  if (head_inst->isStore()) {
488  // Look up store-after-store order dependency
489  updateCommitOrderDep(new_record, false);
490  // Look up store-after-load order dependency
491  updateCommitOrderDep(new_record, true);
492  }
493 
494  // In case a node is dependency-free or its dependency got discarded
495  // because it was outside the window, it is marked ready in the ROB at the
496  // time of issue. A request is sent as soon as possible. To model this, a
497  // node is assigned an issue order dependency on a committed instruction
498  // that completed earlier than it. This is done to avoid the problem of
499  // determining the issue times of such dependency-free nodes during replay
500  // which could lead to too much parallelism, thinking conservatively.
501  if (new_record->robDepList.empty() && new_record->physRegDepList.empty()) {
502  updateIssueOrderDep(new_record);
503  }
504 
505  // Store the record in depTrace.
506  depTrace.push_back(new_record);
507  DPRINTF(ElasticTrace, "Added %s inst %lli to DepTrace.\n",
508  (commit ? "committed" : "squashed"), new_record->instNum);
509 
510  // To process the number of records specified by depWindowSize in the
511  // forward direction, the depTrace must have twice as many records
512  // to check for dependencies.
513  if (depTrace.size() == 2 * depWindowSize) {
514 
515  DPRINTF(ElasticTrace, "Writing out trace...\n");
516 
517  // Write out the records which have been processed to the trace
518  // and remove them from the depTrace.
520 
521  // After the first window, writeDepTrace() must check for valid
522  // compDelay.
523  firstWin = false;
524  }
525 }
526 
527 void
529  bool find_load_not_store)
530 {
531  assert(new_record->isStore());
532  // Iterate in reverse direction to search for the last committed
533  // load/store that completed earlier than the new record
534  depTraceRevItr from_itr(depTrace.end());
535  depTraceRevItr until_itr(depTrace.begin());
536  TraceInfo* past_record = *from_itr;
537  uint32_t num_go_back = 0;
538 
539  // The execution time of this store is when it is sent, that is committed
540  Tick execute_tick = curTick();
541  // Search for store-after-load or store-after-store order dependency
542  while (num_go_back < depWindowSize && from_itr != until_itr) {
543  if (find_load_not_store) {
544  // Check if previous inst is a load completed earlier by comparing
545  // with execute tick
546  if (hasLoadCompleted(past_record, execute_tick)) {
547  // Assign rob dependency and calculate the computational delay
548  assignRobDep(past_record, new_record);
549  ++stats.numRegDep;
550  return;
551  }
552  } else {
553  // Check if previous inst is a store sent earlier by comparing with
554  // execute tick
555  if (hasStoreCommitted(past_record, execute_tick)) {
556  // Assign rob dependency and calculate the computational delay
557  assignRobDep(past_record, new_record);
558  ++stats.numRegDep;
559  return;
560  }
561  }
562  ++from_itr;
563  past_record = *from_itr;
564  ++num_go_back;
565  }
566 }
567 
568 void
570 {
571  // Interate in reverse direction to search for the last committed
572  // record that completed earlier than the new record
573  depTraceRevItr from_itr(depTrace.end());
574  depTraceRevItr until_itr(depTrace.begin());
575  TraceInfo* past_record = *from_itr;
576 
577  uint32_t num_go_back = 0;
578  Tick execute_tick = 0;
579 
580  if (new_record->isLoad()) {
581  // The execution time of a load is when a request is sent
582  execute_tick = new_record->executeTick;
584  } else if (new_record->isStore()) {
585  // The execution time of a store is when it is sent, i.e. committed
586  execute_tick = curTick();
588  } else {
589  // The execution time of a non load/store is when it completes
590  execute_tick = new_record->toCommitTick;
592  }
593 
594  // We search if this record has an issue order dependency on a past record.
595  // Once we find it, we update both the new record and the record it depends
596  // on and return.
597  while (num_go_back < depWindowSize && from_itr != until_itr) {
598  // Check if a previous inst is a load sent earlier, or a store sent
599  // earlier, or a comp inst completed earlier by comparing with execute
600  // tick
601  if (hasLoadBeenSent(past_record, execute_tick) ||
602  hasStoreCommitted(past_record, execute_tick) ||
603  hasCompCompleted(past_record, execute_tick)) {
604  // Assign rob dependency and calculate the computational delay
605  assignRobDep(past_record, new_record);
606  return;
607  }
608  ++from_itr;
609  past_record = *from_itr;
610  ++num_go_back;
611  }
612 }
613 
614 void
615 ElasticTrace::assignRobDep(TraceInfo* past_record, TraceInfo* new_record) {
616  DPRINTF(ElasticTrace, "%s %lli has ROB dependency on %lli\n",
617  new_record->typeToStr(), new_record->instNum,
618  past_record->instNum);
619  // Add dependency on past record
620  new_record->robDepList.push_back(past_record->instNum);
621  // Update new_record's compute delay with respect to the past record
622  compDelayRob(past_record, new_record);
623  // Increment number of dependents of the past record
624  ++(past_record->numDepts);
625  // Update stat to log max number of dependents
626  stats.maxNumDependents = std::max(past_record->numDepts,
627  (uint32_t)stats.maxNumDependents.value());
628 }
629 
630 bool
632  Tick execute_tick) const
633 {
634  return (past_record->isStore() && past_record->commitTick <= execute_tick);
635 }
636 
637 bool
639  Tick execute_tick) const
640 {
641  return(past_record->isLoad() && past_record->commit &&
642  past_record->toCommitTick <= execute_tick);
643 }
644 
645 bool
647  Tick execute_tick) const
648 {
649  // Check if previous inst is a load sent earlier than this
650  return (past_record->isLoad() && past_record->commit &&
651  past_record->executeTick <= execute_tick);
652 }
653 
654 bool
656  Tick execute_tick) const
657 {
658  return(past_record->isComp() && past_record->toCommitTick <= execute_tick);
659 }
660 
661 void
663 {
664  // Clear from temp store starting with the execution info object
665  // corresponding the head_inst and continue clearing by decrementing the
666  // sequence number until the last cleared sequence number.
667  InstSeqNum temp_sn = (head_inst->seqNum);
668  while (temp_sn > lastClearedSeqNum) {
669  auto itr_exec_info = tempStore.find(temp_sn);
670  if (itr_exec_info != tempStore.end()) {
671  InstExecInfo* exec_info_ptr = itr_exec_info->second;
672  // Free allocated memory for the info object
673  delete exec_info_ptr;
674  // Remove entry from temporary store
675  tempStore.erase(itr_exec_info);
676  }
677  temp_sn--;
678  }
679  // Update the last cleared sequence number to that of the head_inst
680  lastClearedSeqNum = head_inst->seqNum;
681 }
682 
683 void
685 {
686  // The computation delay is the delay between the completion tick of the
687  // inst. pointed to by past_record and the execution tick of its dependent
688  // inst. pointed to by new_record.
689  int64_t comp_delay = -1;
690  Tick execution_tick = 0, completion_tick = 0;
691 
692  DPRINTF(ElasticTrace, "Seq num %lli has ROB dependency on seq num %lli.\n",
693  new_record->instNum, past_record->instNum);
694 
695  // Get the tick when the node is executed as per the modelling of
696  // computation delay
697  execution_tick = new_record->getExecuteTick();
698 
699  if (past_record->isLoad()) {
700  if (new_record->isStore()) {
701  completion_tick = past_record->toCommitTick;
702  } else {
703  completion_tick = past_record->executeTick;
704  }
705  } else if (past_record->isStore()) {
706  completion_tick = past_record->commitTick;
707  } else if (past_record->isComp()){
708  completion_tick = past_record->toCommitTick;
709  }
710  assert(execution_tick >= completion_tick);
711  comp_delay = execution_tick - completion_tick;
712 
713  DPRINTF(ElasticTrace, "Computational delay is %lli - %lli = %lli\n",
714  execution_tick, completion_tick, comp_delay);
715 
716  // Assign the computational delay with respect to the dependency which
717  // completes the latest.
718  if (new_record->compDelay == -1)
719  new_record->compDelay = comp_delay;
720  else
721  new_record->compDelay = std::min(comp_delay, new_record->compDelay);
722  DPRINTF(ElasticTrace, "Final computational delay = %lli.\n",
723  new_record->compDelay);
724 }
725 
726 void
728  TraceInfo* new_record)
729 {
730  // The computation delay is the delay between the completion tick of the
731  // inst. pointed to by past_record and the execution tick of its dependent
732  // inst. pointed to by new_record.
733  int64_t comp_delay = -1;
734  Tick execution_tick = 0, completion_tick = 0;
735 
736  DPRINTF(ElasticTrace, "Seq. num %lli has register dependency on seq. num"
737  " %lli.\n", new_record->instNum, past_record->instNum);
738 
739  // Get the tick when the node is executed as per the modelling of
740  // computation delay
741  execution_tick = new_record->getExecuteTick();
742 
743  // When there is a physical register dependency on an instruction, the
744  // completion tick of that instruction is when it wrote to the register,
745  // that is toCommitTick. In case, of a store updating a destination
746  // register, this is approximated to commitTick instead
747  if (past_record->isStore()) {
748  completion_tick = past_record->commitTick;
749  } else {
750  completion_tick = past_record->toCommitTick;
751  }
752  assert(execution_tick >= completion_tick);
753  comp_delay = execution_tick - completion_tick;
754  DPRINTF(ElasticTrace, "Computational delay is %lli - %lli = %lli\n",
755  execution_tick, completion_tick, comp_delay);
756 
757  // Assign the computational delay with respect to the dependency which
758  // completes the latest.
759  if (new_record->compDelay == -1)
760  new_record->compDelay = comp_delay;
761  else
762  new_record->compDelay = std::min(comp_delay, new_record->compDelay);
763  DPRINTF(ElasticTrace, "Final computational delay = %lli.\n",
764  new_record->compDelay);
765 }
766 
767 Tick
769 {
770  if (isLoad()) {
771  // Execution tick for a load instruction is when the request was sent,
772  // that is executeTick.
773  return executeTick;
774  } else if (isStore()) {
775  // Execution tick for a store instruction is when the request was sent,
776  // that is commitTick.
777  return commitTick;
778  } else {
779  // Execution tick for a non load/store instruction is when the register
780  // value was written to, that is commitTick.
781  return toCommitTick;
782  }
783 }
784 
785 void
786 ElasticTrace::writeDepTrace(uint32_t num_to_write)
787 {
788  // Write the trace with fields as follows:
789  // Instruction sequence number
790  // If instruction was a load
791  // If instruction was a store
792  // If instruction has addr
793  // If instruction has size
794  // If instruction has flags
795  // List of order dependencies - optional, repeated
796  // Computational delay with respect to last completed dependency
797  // List of physical register RAW dependencies - optional, repeated
798  // Weight of a node equal to no. of filtered nodes before it - optional
799  uint16_t num_filtered_nodes = 0;
800  depTraceItr dep_trace_itr(depTrace.begin());
801  depTraceItr dep_trace_itr_start = dep_trace_itr;
802  while (num_to_write > 0) {
803  TraceInfo* temp_ptr = *dep_trace_itr;
804  assert(temp_ptr->type != Record::INVALID);
805  // If no node dependends on a comp node then there is no reason to
806  // track the comp node in the dependency graph. We filter out such
807  // nodes but count them and add a weight field to the subsequent node
808  // that we do include in the trace.
809  if (!temp_ptr->isComp() || temp_ptr->numDepts != 0) {
810  DPRINTFR(ElasticTrace, "Instruction with seq. num %lli "
811  "is as follows:\n", temp_ptr->instNum);
812  if (temp_ptr->isLoad() || temp_ptr->isStore()) {
813  DPRINTFR(ElasticTrace, "\tis a %s\n", temp_ptr->typeToStr());
814  DPRINTFR(ElasticTrace, "\thas a request with phys addr %i, "
815  "size %i, flags %i\n", temp_ptr->physAddr,
816  temp_ptr->size, temp_ptr->reqFlags);
817  } else {
818  DPRINTFR(ElasticTrace, "\tis a %s\n", temp_ptr->typeToStr());
819  }
820  if (firstWin && temp_ptr->compDelay == -1) {
821  if (temp_ptr->isLoad()) {
822  temp_ptr->compDelay = temp_ptr->executeTick;
823  } else if (temp_ptr->isStore()) {
824  temp_ptr->compDelay = temp_ptr->commitTick;
825  } else {
826  temp_ptr->compDelay = temp_ptr->toCommitTick;
827  }
828  }
829  assert(temp_ptr->compDelay != -1);
830  DPRINTFR(ElasticTrace, "\thas computational delay %lli\n",
831  temp_ptr->compDelay);
832 
833  // Create a protobuf message for the dependency record
834  ProtoMessage::InstDepRecord dep_pkt;
835  dep_pkt.set_seq_num(temp_ptr->instNum);
836  dep_pkt.set_type(temp_ptr->type);
837  dep_pkt.set_pc(temp_ptr->pc);
838  if (temp_ptr->isLoad() || temp_ptr->isStore()) {
839  dep_pkt.set_flags(temp_ptr->reqFlags);
840  dep_pkt.set_p_addr(temp_ptr->physAddr);
841  // If tracing of virtual addresses is enabled, set the optional
842  // field for it
843  if (traceVirtAddr)
844  dep_pkt.set_v_addr(temp_ptr->virtAddr);
845  dep_pkt.set_size(temp_ptr->size);
846  }
847  dep_pkt.set_comp_delay(temp_ptr->compDelay);
848  if (temp_ptr->robDepList.empty()) {
849  DPRINTFR(ElasticTrace, "\thas no order (rob) dependencies\n");
850  }
851  while (!temp_ptr->robDepList.empty()) {
852  DPRINTFR(ElasticTrace, "\thas order (rob) dependency on %lli\n",
853  temp_ptr->robDepList.front());
854  dep_pkt.add_rob_dep(temp_ptr->robDepList.front());
855  temp_ptr->robDepList.pop_front();
856  }
857  if (temp_ptr->physRegDepList.empty()) {
858  DPRINTFR(ElasticTrace, "\thas no register dependencies\n");
859  }
860  while (!temp_ptr->physRegDepList.empty()) {
861  DPRINTFR(ElasticTrace, "\thas register dependency on %lli\n",
862  temp_ptr->physRegDepList.front());
863  dep_pkt.add_reg_dep(temp_ptr->physRegDepList.front());
864  temp_ptr->physRegDepList.pop_front();
865  }
866  if (num_filtered_nodes != 0) {
867  // Set the weight of this node as the no. of filtered nodes
868  // between this node and the last node that we wrote to output
869  // stream. The weight will be used during replay to model ROB
870  // occupancy of filtered nodes.
871  dep_pkt.set_weight(num_filtered_nodes);
872  num_filtered_nodes = 0;
873  }
874  // Write the message to the protobuf output stream
875  dataTraceStream->write(dep_pkt);
876  } else {
877  // Don't write the node to the trace but note that we have filtered
878  // out a node.
880  ++num_filtered_nodes;
881  }
882  dep_trace_itr++;
883  traceInfoMap.erase(temp_ptr->instNum);
884  delete temp_ptr;
885  num_to_write--;
886  }
887  depTrace.erase(dep_trace_itr_start, dep_trace_itr);
888 }
889 
891  : statistics::Group(parent),
892  ADD_STAT(numRegDep, statistics::units::Count::get(),
893  "Number of register dependencies recorded during tracing"),
894  ADD_STAT(numOrderDepStores, statistics::units::Count::get(),
895  "Number of commit order (rob) dependencies for a store "
896  "recorded on a past load/store during tracing"),
897  ADD_STAT(numIssueOrderDepLoads, statistics::units::Count::get(),
898  "Number of loads that got assigned issue order dependency "
899  "because they were dependency-free"),
900  ADD_STAT(numIssueOrderDepStores, statistics::units::Count::get(),
901  "Number of stores that got assigned issue order dependency "
902  "because they were dependency-free"),
903  ADD_STAT(numIssueOrderDepOther, statistics::units::Count::get(),
904  "Number of non load/store insts that got assigned issue order "
905  "dependency because they were dependency-free"),
906  ADD_STAT(numFilteredNodes, statistics::units::Count::get(),
907  "No. of nodes filtered out before writing the output trace"),
908  ADD_STAT(maxNumDependents, statistics::units::Count::get(),
909  "Maximum number or dependents on any instruction"),
910  ADD_STAT(maxTempStoreSize, statistics::units::Count::get(),
911  "Maximum size of the temporary store during the run"),
912  ADD_STAT(maxPhysRegDepMapSize, statistics::units::Count::get(),
913  "Maximum size of register dependency map")
914 {
915 }
916 
917 const std::string&
919 {
920  return Record::RecordType_Name(type);
921 }
922 
923 void
925 {
926  // Write to trace all records in the depTrace.
927  writeDepTrace(depTrace.size());
928  // Delete the stream objects
929  delete dataTraceStream;
930  delete instTraceStream;
931 }
932 
933 } // namespace o3
934 } // namespace gem5
gem5::curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:46
gem5::o3::ElasticTrace::allProbesReg
bool allProbesReg
Whther the elastic trace listener has been registered for all probes.
Definition: elastic_trace.hh:368
ProtoOutputStream::write
void write(const google::protobuf::Message &msg)
Write a message to the stream, preprending it with the message size.
Definition: protoio.cc:82
gem5::o3::ElasticTrace::TraceInfo::numDepts
uint32_t numDepts
Definition: elastic_trace.hh:286
gem5::o3::ElasticTrace::TraceInfo::pc
Addr pc
Definition: elastic_trace.hh:288
gem5::o3::ElasticTrace::InstExecInfo
Definition: elastic_trace.hh:199
gem5::o3::ElasticTrace::TraceInfo::physRegDepList
std::list< InstSeqNum > physRegDepList
Definition: elastic_trace.hh:279
gem5::NoFault
constexpr decltype(nullptr) NoFault
Definition: types.hh:260
gem5::o3::ElasticTrace::TraceInfo::executeTick
Tick executeTick
Definition: elastic_trace.hh:269
gem5::o3::ElasticTrace::ElasticTraceStats::ElasticTraceStats
ElasticTraceStats(statistics::Group *parent)
Definition: elastic_trace.cc:890
DPRINTFR
#define DPRINTFR(x,...)
Definition: trace.hh:200
gem5::o3::ElasticTrace
The elastic trace is a type of probe listener and listens to probe points in multiple stages of the O...
Definition: elastic_trace.hh:93
gem5::o3::ElasticTrace::TraceInfo::toCommitTick
Tick toCommitTick
Definition: elastic_trace.hh:271
gem5::o3::ElasticTrace::updateIssueOrderDep
void updateIssueOrderDep(TraceInfo *new_record)
Reverse iterate through the graph, search for an issue order dependency for a new node and update the...
Definition: elastic_trace.cc:569
gem5::o3::ElasticTrace::cpu
CPU * cpu
Pointer to the O3CPU that is this listener's parent a.k.a.
Definition: elastic_trace.hh:374
gem5::o3::ElasticTrace::fetchReqTrace
void fetchReqTrace(const RequestPtr &req)
Take the fields of the request class object that are relevant to create an instruction fetch request.
Definition: elastic_trace.cc:154
gem5::o3::ElasticTrace::recordExecTick
void recordExecTick(const DynInstConstPtr &dyn_inst)
Populate the execute timestamp field in an InstExecInfo object for an instruction in flight.
Definition: elastic_trace.cc:176
gem5::o3::ElasticTrace::recordToCommTick
void recordToCommTick(const DynInstConstPtr &dyn_inst)
Populate the timestamp field in an InstExecInfo object for an instruction in flight when it is execut...
Definition: elastic_trace.cc:213
gem5::o3::ElasticTrace::firstWin
bool firstWin
Used for checking the first window for processing and writing of dependency trace.
Definition: elastic_trace.hh:191
gem5::ProbeListenerObject::listeners
std::vector< ProbeListener * > listeners
Definition: probe.hh:111
gem5::o3::ElasticTrace::regProbeListeners
void regProbeListeners()
Register the probe listeners that is the methods called on a probe point notify() call.
Definition: elastic_trace.cc:107
gem5::o3::ElasticTrace::ElasticTrace
ElasticTrace(const ElasticTraceParams &params)
Constructor.
Definition: elastic_trace.cc:54
gem5::o3::ElasticTrace::addCommittedInst
void addCommittedInst(const DynInstConstPtr &head_inst)
Add an instruction that is at the head of the ROB and is committed.
Definition: elastic_trace.cc:341
gem5::simout
OutputDirectory simout
Definition: output.cc:62
gem5::sim_clock::Frequency
Tick Frequency
The simulated frequency of curTick(). (In ticks per second)
Definition: core.cc:48
gem5::o3::ElasticTrace::ElasticTraceStats::numFilteredNodes
statistics::Scalar numFilteredNodes
Number of filtered nodes.
Definition: elastic_trace.hh:545
gem5::MiscRegClass
@ MiscRegClass
Control (misc) register.
Definition: reg_class.hh:65
gem5::MaxTick
const Tick MaxTick
Definition: types.hh:60
std::vector< RegClassInfo >
dyn_inst.hh
gem5::ProbeListenerObject
This class is a minimal wrapper around SimObject.
Definition: probe.hh:107
gem5::ProbeListenerArg
ProbeListenerArg generates a listener for the class of Arg and the class type T which is the class co...
Definition: probe.hh:228
gem5::o3::ElasticTrace::zeroReg
RegIndex zeroReg
Definition: elastic_trace.hh:193
gem5::o3::ElasticTrace::hasLoadBeenSent
bool hasLoadBeenSent(TraceInfo *past_record, Tick execute_tick) const
Check if past record is a load sent earlier than the execute tick.
Definition: elastic_trace.cc:646
gem5::RegId::index
RegIndex index() const
Index accessors.
Definition: reg_class.hh:154
output.hh
gem5::o3::ElasticTrace::ElasticTraceStats::numIssueOrderDepStores
statistics::Scalar numIssueOrderDepStores
Number of store insts that got assigned an issue order dependency because they were dependency-free.
Definition: elastic_trace.hh:536
gem5::RefCountingPtr
If you want a reference counting pointer to a mutable object, create it like this:
Definition: refcnt.hh:126
gem5::o3::ElasticTrace::regEtraceListenersEvent
EventFunctionWrapper regEtraceListenersEvent
Event to trigger registering this listener for all probe points.
Definition: elastic_trace.hh:183
packet.hh
gem5::o3::ElasticTrace::InstExecInfo::executeTick
Tick executeTick
Timestamp when instruction was first processed by execute stage.
Definition: elastic_trace.hh:206
gem5::RegId::is
bool is(RegClass reg_class) const
Definition: reg_class.hh:150
elastic_trace.hh
gem5::o3::ElasticTrace::flushTraces
void flushTraces()
Process any outstanding trace records, flush them out to the protobuf output streams and delete the s...
Definition: elastic_trace.cc:924
gem5::o3::ElasticTrace::TraceInfo::typeToStr
const std::string & typeToStr() const
Return string specifying the type of the node.
Definition: elastic_trace.cc:918
gem5::o3::ElasticTrace::hasStoreCommitted
bool hasStoreCommitted(TraceInfo *past_record, Tick execute_tick) const
Check if past record is a store sent earlier than the execute tick.
Definition: elastic_trace.cc:631
gem5::PhysRegId::flatIndex
const RegIndex & flatIndex() const
Flat index accessor.
Definition: reg_class.hh:263
gem5::o3::ElasticTrace::addDepTraceRecord
void addDepTraceRecord(const DynInstConstPtr &head_inst, InstExecInfo *exec_info_ptr, bool commit)
Add a record to the dependency trace depTrace which is a sequential container.
Definition: elastic_trace.cc:400
gem5::o3::ElasticTrace::TraceInfo::robDepList
std::list< InstSeqNum > robDepList
Definition: elastic_trace.hh:277
gem5::o3::CPU
O3CPU class, has each of the stages (fetch through commit) within it, as well as all of the time buff...
Definition: cpu.hh:95
gem5::o3::ElasticTrace::TraceInfo::isComp
bool isComp() const
Is the record a fetch triggering an Icache request.
Definition: elastic_trace.hh:306
gem5::o3::ElasticTrace::physRegDepMap
std::unordered_map< RegIndex, InstSeqNum > physRegDepMap
Map for recording the producer of a physical register to check Read After Write dependencies.
Definition: elastic_trace.hh:246
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:186
ADD_STAT
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:75
gem5::o3::ElasticTrace::TraceInfo::compDelay
int64_t compDelay
Computational delay after the last dependent inst.
Definition: elastic_trace.hh:284
gem5::o3::ElasticTrace::clearTempStoreUntil
void clearTempStoreUntil(const DynInstConstPtr &head_inst)
Clear entries in the temporary store of execution info objects to free allocated memory until the pre...
Definition: elastic_trace.cc:662
gem5::o3::ElasticTrace::lastClearedSeqNum
InstSeqNum lastClearedSeqNum
The last cleared instruction sequence number used to free up the memory allocated in the temporary st...
Definition: elastic_trace.hh:239
gem5::probing::Packet
ProbePointArg< PacketInfo > Packet
Packet probe point.
Definition: mem.hh:109
gem5::Tick
uint64_t Tick
Tick count type.
Definition: types.hh:58
gem5::X86ISA::type
type
Definition: misc.hh:733
gem5::RequestPtr
std::shared_ptr< Request > RequestPtr
Definition: request.hh:92
gem5::OutputDirectory::resolve
std::string resolve(const std::string &name) const
Returns relative file names prepended with name of this directory.
Definition: output.cc:204
gem5::MemCmd::ReadReq
@ ReadReq
Definition: packet.hh:86
gem5::o3::ElasticTrace::ElasticTraceStats::maxTempStoreSize
statistics::Scalar maxTempStoreSize
Maximum size of the temporary store mostly useful as a check that it is not growing.
Definition: elastic_trace.hh:554
gem5::o3::ElasticTrace::TraceInfo::size
unsigned size
Definition: elastic_trace.hh:296
gem5::o3::ElasticTrace::ElasticTraceStats::numIssueOrderDepOther
statistics::Scalar numIssueOrderDepOther
Number of non load/store insts that got assigned an issue order dependency because they were dependen...
Definition: elastic_trace.hh:542
gem5::o3::ElasticTrace::compDelayPhysRegDep
void compDelayPhysRegDep(TraceInfo *past_record, TraceInfo *new_record)
Calculate the computational delay between an instruction and a subsequent instruction that has a Phys...
Definition: elastic_trace.cc:727
gem5::o3::ElasticTrace::dataTraceStream
ProtoOutputStream * dataTraceStream
Protobuf output stream for data dependency trace.
Definition: elastic_trace.hh:354
gem5::o3::ElasticTrace::writeDepTrace
void writeDepTrace(uint32_t num_to_write)
Write out given number of records to the trace starting with the first record in depTrace and iterati...
Definition: elastic_trace.cc:786
gem5::o3::ElasticTrace::traceInfoMap
std::unordered_map< InstSeqNum, TraceInfo * > traceInfoMap
Map where the instruction sequence number is mapped to the pointer to the TraceInfo object.
Definition: elastic_trace.hh:337
gem5::o3::ElasticTrace::TraceInfo::commitTick
Tick commitTick
Definition: elastic_trace.hh:273
gem5::BaseCPU::numSimulatedInsts
static Counter numSimulatedInsts()
Definition: base.hh:570
gem5::o3::ElasticTrace::hasLoadCompleted
bool hasLoadCompleted(TraceInfo *past_record, Tick execute_tick) const
Check if past record is a load that completed earlier than the execute tick.
Definition: elastic_trace.cc:638
gem5::o3::ElasticTrace::InstExecInfo::toCommitTick
Tick toCommitTick
Timestamp when instruction execution is completed in execute stage and instruction is marked as ready...
Definition: elastic_trace.hh:211
gem5::o3::ElasticTrace::startTraceInst
const InstSeqNum startTraceInst
Number of instructions after which to enable tracing.
Definition: elastic_trace.hh:360
gem5::RegId::className
const char * className() const
Return a const char* with the register class name.
Definition: reg_class.hh:182
gem5::o3::ElasticTrace::TraceInfo::type
RecordType type
The type of trace record for the instruction node.
Definition: elastic_trace.hh:267
std::pair
STL pair class.
Definition: stl.hh:58
gem5::BaseCPU::getContext
virtual ThreadContext * getContext(int tn)
Given a thread num get tho thread context for it.
Definition: base.hh:290
gem5::o3::ElasticTrace::depWindowSize
uint32_t depWindowSize
The maximum distance for a dependency and is set by a top level level parameter.
Definition: elastic_trace.hh:351
gem5::o3::ElasticTrace::addSquashedInst
void addSquashedInst(const DynInstConstPtr &head_inst)
Add an instruction that is at the head of the ROB and is squashed only if it is a load and a request ...
Definition: elastic_trace.cc:313
name
const std::string & name()
Definition: trace.cc:49
gem5::o3::ElasticTrace::TraceInfo::physAddr
Addr physAddr
Definition: elastic_trace.hh:292
gem5::o3::ElasticTrace::removeRegDepMapEntry
void removeRegDepMapEntry(const SeqNumRegPair &inst_reg_pair)
When an instruction gets squashed the destination register mapped to it is freed up in the rename sta...
Definition: elastic_trace.cc:303
gem5::ThreadContext::scheduleInstCountEvent
virtual void scheduleInstCountEvent(Event *event, Tick count)=0
gem5::o3::ElasticTrace::InstExecInfo::physRegDepSet
std::set< InstSeqNum > physRegDepSet
Set of instruction sequence numbers that this instruction depends on due to Read After Write data dep...
Definition: elastic_trace.hh:216
gem5::o3::ElasticTrace::TraceInfo
Definition: elastic_trace.hh:258
inform
#define inform(...)
Definition: logging.hh:246
gem5::PhysRegId::className
const char * className() const
Return a const char* with the register class name.
Definition: reg_class.hh:182
gem5::o3::ElasticTrace::TraceInfo::instNum
InstSeqNum instNum
Definition: elastic_trace.hh:265
gem5::o3::ElasticTrace::TraceInfo::reqFlags
Request::FlagsType reqFlags
Definition: elastic_trace.hh:290
gem5::o3::ElasticTrace::depTraceRevItr
std::reverse_iterator< depTraceItr > depTraceRevItr
Typedef of the reverse iterator to the instruction dependency trace.
Definition: elastic_trace.hh:343
reg_class.hh
gem5::statistics::Group
Statistics container.
Definition: group.hh:93
gem5::InstSeqNum
uint64_t InstSeqNum
Definition: inst_seq.hh:40
gem5::PhysRegId
Physical register ID.
Definition: reg_class.hh:198
gem5::o3::ElasticTrace::compDelayRob
void compDelayRob(TraceInfo *past_record, TraceInfo *new_record)
Calculate the computational delay between an instruction and a subsequent instruction that has an ROB...
Definition: elastic_trace.cc:684
gem5::o3::ElasticTrace::TraceInfo::virtAddr
Addr virtAddr
Definition: elastic_trace.hh:294
gem5::o3::ElasticTrace::stats
gem5::o3::ElasticTrace::ElasticTraceStats stats
trace.hh
gem5::o3::ElasticTrace::ElasticTraceStats::maxPhysRegDepMapSize
statistics::Scalar maxPhysRegDepMapSize
Maximum size of the map that holds the last writer to a physical register.
Definition: elastic_trace.hh:560
gem5::o3::ElasticTrace::traceVirtAddr
const bool traceVirtAddr
Whether to trace virtual addresses for memory requests.
Definition: elastic_trace.hh:371
gem5::registerExitCallback
void registerExitCallback(const std::function< void()> &callback)
Register an exit callback.
Definition: core.cc:146
gem5::o3::ElasticTrace::ElasticTraceStats::numIssueOrderDepLoads
statistics::Scalar numIssueOrderDepLoads
Number of load insts that got assigned an issue order dependency because they were dependency-free.
Definition: elastic_trace.hh:530
fatal_if
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:225
gem5::IntRegClass
@ IntRegClass
Integer register.
Definition: reg_class.hh:57
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: decoder.cc:40
gem5::o3::ElasticTrace::TraceInfo::isLoad
bool isLoad() const
Is the record a load.
Definition: elastic_trace.hh:302
gem5::o3::ElasticTrace::ElasticTraceStats::numRegDep
statistics::Scalar numRegDep
Number of register dependencies recorded during tracing.
Definition: elastic_trace.hh:518
gem5::o3::ElasticTrace::hasCompCompleted
bool hasCompCompleted(TraceInfo *past_record, Tick execute_tick) const
Check if past record is a comp node that completed earlier than the execute tick.
Definition: elastic_trace.cc:655
gem5::o3::ElasticTrace::updateRegDep
void updateRegDep(const DynInstConstPtr &dyn_inst)
Record a Read After Write physical register dependency if there has been a write to the source regist...
Definition: elastic_trace.cc:234
ProtoOutputStream
A ProtoOutputStream wraps a coded stream, potentially with compression, based on looking at the file ...
Definition: protoio.hh:90
gem5::o3::ElasticTrace::assignRobDep
void assignRobDep(TraceInfo *past_record, TraceInfo *new_record)
The new_record has an order dependency on a past_record, thus update the new record's Rob dependency ...
Definition: elastic_trace.cc:615
gem5::o3::ElasticTrace::TraceInfo::commit
bool commit
Definition: elastic_trace.hh:275
gem5::o3::ElasticTrace::updateCommitOrderDep
void updateCommitOrderDep(TraceInfo *new_record, bool find_load_not_store)
Reverse iterate through the graph, search for a store-after-store or store-after-load dependency and ...
Definition: elastic_trace.cc:528
gem5::o3::ElasticTrace::regEtraceListeners
void regEtraceListeners()
Register all listeners.
Definition: elastic_trace.cc:124
gem5::o3::ElasticTrace::depTrace
std::vector< TraceInfo * > depTrace
The instruction dependency trace containing TraceInfo objects.
Definition: elastic_trace.hh:331
gem5::o3::ElasticTrace::ElasticTraceStats::maxNumDependents
statistics::Scalar maxNumDependents
Maximum number of dependents on any instruction.
Definition: elastic_trace.hh:548
gem5::o3::ElasticTrace::instTraceStream
ProtoOutputStream * instTraceStream
Protobuf output stream for instruction fetch trace.
Definition: elastic_trace.hh:357
gem5::o3::ElasticTrace::tempStore
std::unordered_map< InstSeqNum, InstExecInfo * > tempStore
Temporary store of InstExecInfo objects.
Definition: elastic_trace.hh:233
gem5::o3::ElasticTrace::depTraceItr
std::vector< TraceInfo * >::iterator depTraceItr
Typedef of iterator to the instruction dependency trace.
Definition: elastic_trace.hh:340
callback.hh
gem5::o3::ElasticTrace::TraceInfo::isStore
bool isStore() const
Is the record a store.
Definition: elastic_trace.hh:304
gem5::RegId
Register ID: describe an architectural register with its class and index.
Definition: reg_class.hh:88
gem5::o3::ElasticTrace::TraceInfo::getExecuteTick
Tick getExecuteTick() const
Get the execute tick of the instruction.
Definition: elastic_trace.cc:768
gem5::statistics::ScalarBase::value
Counter value() const
Return the current value of this stat as its base type.
Definition: statistics.hh:619

Generated on Tue Sep 21 2021 12:25:05 for gem5 by doxygen 1.8.17