elastic_trace.cc (11247:76f75db08e09) elastic_trace.cc (11252:18bb597fc40c)
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

--- 370 unchanged lines hidden (view full) ---

379{
380 // Create a record to assign dynamic intruction related fields.
381 TraceInfo* new_record = new TraceInfo;
382 // Add to map for sequence number look up to retrieve the TraceInfo pointer
383 traceInfoMap[head_inst->seqNum] = new_record;
384
385 // Assign fields from the instruction
386 new_record->instNum = head_inst->seqNum;
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

--- 370 unchanged lines hidden (view full) ---

379{
380 // Create a record to assign dynamic intruction related fields.
381 TraceInfo* new_record = new TraceInfo;
382 // Add to map for sequence number look up to retrieve the TraceInfo pointer
383 traceInfoMap[head_inst->seqNum] = new_record;
384
385 // Assign fields from the instruction
386 new_record->instNum = head_inst->seqNum;
387 new_record->load = head_inst->isLoad();
388 new_record->store = head_inst->isStore();
389 new_record->commit = commit;
387 new_record->commit = commit;
388 new_record->type = head_inst->isLoad() ? Record::LOAD :
389 (head_inst->isStore() ? Record::STORE :
390 Record::COMP);
390
391 // Assign fields for creating a request in case of a load/store
392 new_record->reqFlags = head_inst->memReqFlags;
393 new_record->addr = head_inst->physEffAddrLow;
394 // Currently the tracing does not support split requests.
395 new_record->size = head_inst->effSize;
396 new_record->pc = head_inst->instAddr();
397

--- 100 unchanged lines hidden (view full) ---

498 firstWin = false;
499 }
500}
501
502void
503ElasticTrace::updateCommitOrderDep(TraceInfo* new_record,
504 bool find_load_not_store)
505{
391
392 // Assign fields for creating a request in case of a load/store
393 new_record->reqFlags = head_inst->memReqFlags;
394 new_record->addr = head_inst->physEffAddrLow;
395 // Currently the tracing does not support split requests.
396 new_record->size = head_inst->effSize;
397 new_record->pc = head_inst->instAddr();
398

--- 100 unchanged lines hidden (view full) ---

499 firstWin = false;
500 }
501}
502
503void
504ElasticTrace::updateCommitOrderDep(TraceInfo* new_record,
505 bool find_load_not_store)
506{
506 assert(new_record->store);
507 assert(new_record->isStore());
507 // Iterate in reverse direction to search for the last committed
508 // load/store that completed earlier than the new record
509 depTraceRevItr from_itr(depTrace.end());
510 depTraceRevItr until_itr(depTrace.begin());
511 TraceInfo* past_record = *from_itr;
512 uint32_t num_go_back = 0;
513
514 // The execution time of this store is when it is sent, that is committed

--- 32 unchanged lines hidden (view full) ---

547 // record that completed earlier than the new record
548 depTraceRevItr from_itr(depTrace.end());
549 depTraceRevItr until_itr(depTrace.begin());
550 TraceInfo* past_record = *from_itr;
551
552 uint32_t num_go_back = 0;
553 Tick execute_tick = 0;
554
508 // Iterate in reverse direction to search for the last committed
509 // load/store that completed earlier than the new record
510 depTraceRevItr from_itr(depTrace.end());
511 depTraceRevItr until_itr(depTrace.begin());
512 TraceInfo* past_record = *from_itr;
513 uint32_t num_go_back = 0;
514
515 // The execution time of this store is when it is sent, that is committed

--- 32 unchanged lines hidden (view full) ---

548 // record that completed earlier than the new record
549 depTraceRevItr from_itr(depTrace.end());
550 depTraceRevItr until_itr(depTrace.begin());
551 TraceInfo* past_record = *from_itr;
552
553 uint32_t num_go_back = 0;
554 Tick execute_tick = 0;
555
555 if (new_record->load) {
556 if (new_record->isLoad()) {
556 // The execution time of a load is when a request is sent
557 execute_tick = new_record->executeTick;
558 ++numIssueOrderDepLoads;
557 // The execution time of a load is when a request is sent
558 execute_tick = new_record->executeTick;
559 ++numIssueOrderDepLoads;
559 } else if (new_record->store) {
560 } else if (new_record->isStore()) {
560 // The execution time of a store is when it is sent, i.e. committed
561 execute_tick = curTick();
562 ++numIssueOrderDepStores;
563 } else {
564 // The execution time of a non load/store is when it completes
565 execute_tick = new_record->toCommitTick;
566 ++numIssueOrderDepOther;
567 }

--- 16 unchanged lines hidden (view full) ---

584 past_record = *from_itr;
585 ++num_go_back;
586 }
587}
588
589void
590ElasticTrace::assignRobDep(TraceInfo* past_record, TraceInfo* new_record) {
591 DPRINTF(ElasticTrace, "%s %lli has ROB dependency on %lli\n",
561 // The execution time of a store is when it is sent, i.e. committed
562 execute_tick = curTick();
563 ++numIssueOrderDepStores;
564 } else {
565 // The execution time of a non load/store is when it completes
566 execute_tick = new_record->toCommitTick;
567 ++numIssueOrderDepOther;
568 }

--- 16 unchanged lines hidden (view full) ---

585 past_record = *from_itr;
586 ++num_go_back;
587 }
588}
589
590void
591ElasticTrace::assignRobDep(TraceInfo* past_record, TraceInfo* new_record) {
592 DPRINTF(ElasticTrace, "%s %lli has ROB dependency on %lli\n",
592 new_record->load ? "Load" : (new_record->store ? "Store" :
593 "Non load/store"),
594 new_record->instNum, past_record->instNum);
595
593 new_record->typeToStr(), new_record->instNum,
594 past_record->instNum);
596 // Add dependency on past record
597 new_record->robDepList.push_back(past_record->instNum);
598 // Update new_record's compute delay with respect to the past record
599 compDelayRob(past_record, new_record);
600 // Increment number of dependents of the past record
601 ++(past_record->numDepts);
602 // Update stat to log max number of dependents
603 maxNumDependents = std::max(past_record->numDepts,
604 (uint32_t)maxNumDependents.value());
605}
606
607bool
608ElasticTrace::hasStoreCommitted(TraceInfo* past_record,
609 Tick execute_tick) const
610{
595 // Add dependency on past record
596 new_record->robDepList.push_back(past_record->instNum);
597 // Update new_record's compute delay with respect to the past record
598 compDelayRob(past_record, new_record);
599 // Increment number of dependents of the past record
600 ++(past_record->numDepts);
601 // Update stat to log max number of dependents
602 maxNumDependents = std::max(past_record->numDepts,
603 (uint32_t)maxNumDependents.value());
604}
605
606bool
607ElasticTrace::hasStoreCommitted(TraceInfo* past_record,
608 Tick execute_tick) const
609{
611 return (past_record->store && past_record->commitTick <= execute_tick);
610 return (past_record->isStore() && past_record->commitTick <= execute_tick);
612}
613
614bool
615ElasticTrace::hasLoadCompleted(TraceInfo* past_record,
616 Tick execute_tick) const
617{
611}
612
613bool
614ElasticTrace::hasLoadCompleted(TraceInfo* past_record,
615 Tick execute_tick) const
616{
618 return(past_record->load && past_record->commit &&
617 return(past_record->isLoad() && past_record->commit &&
619 past_record->toCommitTick <= execute_tick);
620}
621
622bool
623ElasticTrace::hasLoadBeenSent(TraceInfo* past_record,
624 Tick execute_tick) const
625{
626 // Check if previous inst is a load sent earlier than this
618 past_record->toCommitTick <= execute_tick);
619}
620
621bool
622ElasticTrace::hasLoadBeenSent(TraceInfo* past_record,
623 Tick execute_tick) const
624{
625 // Check if previous inst is a load sent earlier than this
627 return (past_record->load && past_record->commit &&
626 return (past_record->isLoad() && past_record->commit &&
628 past_record->executeTick <= execute_tick);
629}
630
631bool
632ElasticTrace::hasCompCompleted(TraceInfo* past_record,
633 Tick execute_tick) const
634{
627 past_record->executeTick <= execute_tick);
628}
629
630bool
631ElasticTrace::hasCompCompleted(TraceInfo* past_record,
632 Tick execute_tick) const
633{
635 return(!past_record->store && !past_record->load &&
636 past_record->toCommitTick <= execute_tick);
634 return(past_record->isComp() && past_record->toCommitTick <= execute_tick);
637}
638
639void
640ElasticTrace::clearTempStoreUntil(const DynInstPtr head_inst)
641{
642 // Clear from temp store starting with the execution info object
643 // corresponding the head_inst and continue clearing by decrementing the
644 // sequence number until the last cleared sequence number.

--- 24 unchanged lines hidden (view full) ---

669
670 DPRINTF(ElasticTrace, "Seq num %lli has ROB dependency on seq num %lli.\n",
671 new_record->instNum, past_record->instNum);
672
673 // Get the tick when the node is executed as per the modelling of
674 // computation delay
675 execution_tick = new_record->getExecuteTick();
676
635}
636
637void
638ElasticTrace::clearTempStoreUntil(const DynInstPtr head_inst)
639{
640 // Clear from temp store starting with the execution info object
641 // corresponding the head_inst and continue clearing by decrementing the
642 // sequence number until the last cleared sequence number.

--- 24 unchanged lines hidden (view full) ---

667
668 DPRINTF(ElasticTrace, "Seq num %lli has ROB dependency on seq num %lli.\n",
669 new_record->instNum, past_record->instNum);
670
671 // Get the tick when the node is executed as per the modelling of
672 // computation delay
673 execution_tick = new_record->getExecuteTick();
674
677 if (past_record->load) {
678 if (new_record->store) {
675 if (past_record->isLoad()) {
676 if (new_record->isStore()) {
679 completion_tick = past_record->toCommitTick;
680 } else {
681 completion_tick = past_record->executeTick;
682 }
677 completion_tick = past_record->toCommitTick;
678 } else {
679 completion_tick = past_record->executeTick;
680 }
683 } else if (past_record->store) {
681 } else if (past_record->isStore()) {
684 completion_tick = past_record->commitTick;
682 completion_tick = past_record->commitTick;
685 } else {
683 } else if (past_record->isComp()){
686 completion_tick = past_record->toCommitTick;
687 }
688 assert(execution_tick >= completion_tick);
689 comp_delay = execution_tick - completion_tick;
690
691 DPRINTF(ElasticTrace, "Computational delay is %lli - %lli = %lli\n",
692 execution_tick, completion_tick, comp_delay);
693

--- 23 unchanged lines hidden (view full) ---

717 // Get the tick when the node is executed as per the modelling of
718 // computation delay
719 execution_tick = new_record->getExecuteTick();
720
721 // When there is a physical register dependency on an instruction, the
722 // completion tick of that instruction is when it wrote to the register,
723 // that is toCommitTick. In case, of a store updating a destination
724 // register, this is approximated to commitTick instead
684 completion_tick = past_record->toCommitTick;
685 }
686 assert(execution_tick >= completion_tick);
687 comp_delay = execution_tick - completion_tick;
688
689 DPRINTF(ElasticTrace, "Computational delay is %lli - %lli = %lli\n",
690 execution_tick, completion_tick, comp_delay);
691

--- 23 unchanged lines hidden (view full) ---

715 // Get the tick when the node is executed as per the modelling of
716 // computation delay
717 execution_tick = new_record->getExecuteTick();
718
719 // When there is a physical register dependency on an instruction, the
720 // completion tick of that instruction is when it wrote to the register,
721 // that is toCommitTick. In case, of a store updating a destination
722 // register, this is approximated to commitTick instead
725 if (past_record->store) {
723 if (past_record->isStore()) {
726 completion_tick = past_record->commitTick;
727 } else {
728 completion_tick = past_record->toCommitTick;
729 }
730 assert(execution_tick >= completion_tick);
731 comp_delay = execution_tick - completion_tick;
732 DPRINTF(ElasticTrace, "Computational delay is %lli - %lli = %lli\n",
733 execution_tick, completion_tick, comp_delay);

--- 6 unchanged lines hidden (view full) ---

740 new_record->compDelay = std::min(comp_delay, new_record->compDelay);
741 DPRINTF(ElasticTrace, "Final computational delay = %lli.\n",
742 new_record->compDelay);
743}
744
745Tick
746ElasticTrace::TraceInfo::getExecuteTick() const
747{
724 completion_tick = past_record->commitTick;
725 } else {
726 completion_tick = past_record->toCommitTick;
727 }
728 assert(execution_tick >= completion_tick);
729 comp_delay = execution_tick - completion_tick;
730 DPRINTF(ElasticTrace, "Computational delay is %lli - %lli = %lli\n",
731 execution_tick, completion_tick, comp_delay);

--- 6 unchanged lines hidden (view full) ---

738 new_record->compDelay = std::min(comp_delay, new_record->compDelay);
739 DPRINTF(ElasticTrace, "Final computational delay = %lli.\n",
740 new_record->compDelay);
741}
742
743Tick
744ElasticTrace::TraceInfo::getExecuteTick() const
745{
748 if (load) {
746 if (isLoad()) {
749 // Execution tick for a load instruction is when the request was sent,
750 // that is executeTick.
751 return executeTick;
747 // Execution tick for a load instruction is when the request was sent,
748 // that is executeTick.
749 return executeTick;
752 } else if (store) {
750 } else if (isStore()) {
753 // Execution tick for a store instruction is when the request was sent,
754 // that is commitTick.
755 return commitTick;
756 } else {
757 // Execution tick for a non load/store instruction is when the register
758 // value was written to, that is commitTick.
759 return toCommitTick;
760 }

--- 13 unchanged lines hidden (view full) ---

774 // Computational delay with respect to last completed dependency
775 // List of physical register RAW dependencies - optional, repeated
776 // Weight of a node equal to no. of filtered nodes before it - optional
777 uint16_t num_filtered_nodes = 0;
778 depTraceItr dep_trace_itr(depTrace.begin());
779 depTraceItr dep_trace_itr_start = dep_trace_itr;
780 while (num_to_write > 0) {
781 TraceInfo* temp_ptr = *dep_trace_itr;
751 // Execution tick for a store instruction is when the request was sent,
752 // that is commitTick.
753 return commitTick;
754 } else {
755 // Execution tick for a non load/store instruction is when the register
756 // value was written to, that is commitTick.
757 return toCommitTick;
758 }

--- 13 unchanged lines hidden (view full) ---

772 // Computational delay with respect to last completed dependency
773 // List of physical register RAW dependencies - optional, repeated
774 // Weight of a node equal to no. of filtered nodes before it - optional
775 uint16_t num_filtered_nodes = 0;
776 depTraceItr dep_trace_itr(depTrace.begin());
777 depTraceItr dep_trace_itr_start = dep_trace_itr;
778 while (num_to_write > 0) {
779 TraceInfo* temp_ptr = *dep_trace_itr;
782 // If no node dependends on a non load/store node then there is
783 // no reason to track it in the dependency graph. We filter out such
780 assert(temp_ptr->type != Record::INVALID);
781 // If no node dependends on a comp node then there is no reason to
782 // track the comp node in the dependency graph. We filter out such
784 // nodes but count them and add a weight field to the subsequent node
785 // that we do include in the trace.
783 // nodes but count them and add a weight field to the subsequent node
784 // that we do include in the trace.
786 if (temp_ptr->numDepts != 0 || temp_ptr->load || temp_ptr->store) {
787
785 if (!temp_ptr->isComp() || temp_ptr->numDepts != 0) {
788 DPRINTFR(ElasticTrace, "Instruction with seq. num %lli "
789 "is as follows:\n", temp_ptr->instNum);
786 DPRINTFR(ElasticTrace, "Instruction with seq. num %lli "
787 "is as follows:\n", temp_ptr->instNum);
790 if (temp_ptr->load || temp_ptr->store) {
791 DPRINTFR(ElasticTrace, "\tis a %s\n",
792 (temp_ptr->load ? "Load" : "Store"));
788 if (temp_ptr->isLoad() || temp_ptr->isStore()) {
789 DPRINTFR(ElasticTrace, "\tis a %s\n", temp_ptr->typeToStr());
793 DPRINTFR(ElasticTrace, "\thas a request with addr %i, size %i,"
794 " flags %i\n", temp_ptr->addr, temp_ptr->size,
795 temp_ptr->reqFlags);
796 } else {
790 DPRINTFR(ElasticTrace, "\thas a request with addr %i, size %i,"
791 " flags %i\n", temp_ptr->addr, temp_ptr->size,
792 temp_ptr->reqFlags);
793 } else {
797 DPRINTFR(ElasticTrace, "\tis not a load or store\n");
794 DPRINTFR(ElasticTrace, "\tis a %s\n", temp_ptr->typeToStr());
798 }
799 if (firstWin && temp_ptr->compDelay == -1) {
795 }
796 if (firstWin && temp_ptr->compDelay == -1) {
800 if (temp_ptr->load) {
797 if (temp_ptr->isLoad()) {
801 temp_ptr->compDelay = temp_ptr->executeTick;
798 temp_ptr->compDelay = temp_ptr->executeTick;
802 } else if (temp_ptr->store) {
799 } else if (temp_ptr->isStore()) {
803 temp_ptr->compDelay = temp_ptr->commitTick;
804 } else {
805 temp_ptr->compDelay = temp_ptr->toCommitTick;
806 }
807 }
808 assert(temp_ptr->compDelay != -1);
809 DPRINTFR(ElasticTrace, "\thas computational delay %lli\n",
810 temp_ptr->compDelay);
811
812 // Create a protobuf message for the dependency record
813 ProtoMessage::InstDepRecord dep_pkt;
814 dep_pkt.set_seq_num(temp_ptr->instNum);
800 temp_ptr->compDelay = temp_ptr->commitTick;
801 } else {
802 temp_ptr->compDelay = temp_ptr->toCommitTick;
803 }
804 }
805 assert(temp_ptr->compDelay != -1);
806 DPRINTFR(ElasticTrace, "\thas computational delay %lli\n",
807 temp_ptr->compDelay);
808
809 // Create a protobuf message for the dependency record
810 ProtoMessage::InstDepRecord dep_pkt;
811 dep_pkt.set_seq_num(temp_ptr->instNum);
815 dep_pkt.set_load(temp_ptr->load);
816 dep_pkt.set_store(temp_ptr->store);
812 dep_pkt.set_type(temp_ptr->type);
817 dep_pkt.set_pc(temp_ptr->pc);
813 dep_pkt.set_pc(temp_ptr->pc);
818 if (temp_ptr->load || temp_ptr->store) {
814 if (temp_ptr->isLoad() || temp_ptr->isStore()) {
819 dep_pkt.set_flags(temp_ptr->reqFlags);
820 dep_pkt.set_addr(temp_ptr->addr);
821 dep_pkt.set_size(temp_ptr->size);
822 }
823 dep_pkt.set_comp_delay(temp_ptr->compDelay);
824 if (temp_ptr->robDepList.empty()) {
825 DPRINTFR(ElasticTrace, "\thas no order (rob) dependencies\n");
826 }

--- 84 unchanged lines hidden (view full) ---

911 ;
912
913 maxPhysRegDepMapSize
914 .name(name() + ".maxPhysRegDepMapSize")
915 .desc("Maximum size of register dependency map")
916 ;
917}
918
815 dep_pkt.set_flags(temp_ptr->reqFlags);
816 dep_pkt.set_addr(temp_ptr->addr);
817 dep_pkt.set_size(temp_ptr->size);
818 }
819 dep_pkt.set_comp_delay(temp_ptr->compDelay);
820 if (temp_ptr->robDepList.empty()) {
821 DPRINTFR(ElasticTrace, "\thas no order (rob) dependencies\n");
822 }

--- 84 unchanged lines hidden (view full) ---

907 ;
908
909 maxPhysRegDepMapSize
910 .name(name() + ".maxPhysRegDepMapSize")
911 .desc("Maximum size of register dependency map")
912 ;
913}
914
915const std::string&
916ElasticTrace::TraceInfo::typeToStr() const
917{
918 return Record::RecordType_Name(type);
919}
920
919const std::string
920ElasticTrace::name() const
921{
922 return ProbeListenerObject::name();
923}
924
925void
926ElasticTrace::flushTraces()

--- 13 unchanged lines hidden ---
921const std::string
922ElasticTrace::name() const
923{
924 return ProbeListenerObject::name();
925}
926
927void
928ElasticTrace::flushTraces()

--- 13 unchanged lines hidden ---