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

Generated on Wed Sep 30 2020 14:02:09 for gem5 by doxygen 1.8.17