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->commit = commit; |
388 new_record->type = head_inst->isLoad() ? Record::LOAD : 389 (head_inst->isStore() ? Record::STORE : 390 Record::COMP); |
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{ |
507 assert(new_record->isStore()); |
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 |
556 if (new_record->isLoad()) { |
557 // The execution time of a load is when a request is sent 558 execute_tick = new_record->executeTick; 559 ++numIssueOrderDepLoads; |
560 } else if (new_record->isStore()) { |
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", |
593 new_record->typeToStr(), new_record->instNum, 594 past_record->instNum); |
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{ |
610 return (past_record->isStore() && past_record->commitTick <= execute_tick); |
611} 612 613bool 614ElasticTrace::hasLoadCompleted(TraceInfo* past_record, 615 Tick execute_tick) const 616{ |
617 return(past_record->isLoad() && past_record->commit && |
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 |
626 return (past_record->isLoad() && past_record->commit && |
627 past_record->executeTick <= execute_tick); 628} 629 630bool 631ElasticTrace::hasCompCompleted(TraceInfo* past_record, 632 Tick execute_tick) const 633{ |
634 return(past_record->isComp() && past_record->toCommitTick <= execute_tick); |
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 |
675 if (past_record->isLoad()) { 676 if (new_record->isStore()) { |
677 completion_tick = past_record->toCommitTick; 678 } else { 679 completion_tick = past_record->executeTick; 680 } |
681 } else if (past_record->isStore()) { |
682 completion_tick = past_record->commitTick; |
683 } else if (past_record->isComp()){ |
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 |
723 if (past_record->isStore()) { |
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{ |
746 if (isLoad()) { |
747 // Execution tick for a load instruction is when the request was sent, 748 // that is executeTick. 749 return executeTick; |
750 } else if (isStore()) { |
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; |
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 |
783 // nodes but count them and add a weight field to the subsequent node 784 // that we do include in the trace. |
785 if (!temp_ptr->isComp() || temp_ptr->numDepts != 0) { |
786 DPRINTFR(ElasticTrace, "Instruction with seq. num %lli " 787 "is as follows:\n", temp_ptr->instNum); |
788 if (temp_ptr->isLoad() || temp_ptr->isStore()) { 789 DPRINTFR(ElasticTrace, "\tis a %s\n", temp_ptr->typeToStr()); |
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 { |
794 DPRINTFR(ElasticTrace, "\tis a %s\n", temp_ptr->typeToStr()); |
795 } 796 if (firstWin && temp_ptr->compDelay == -1) { |
797 if (temp_ptr->isLoad()) { |
798 temp_ptr->compDelay = temp_ptr->executeTick; |
799 } else if (temp_ptr->isStore()) { |
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); |
812 dep_pkt.set_type(temp_ptr->type); |
813 dep_pkt.set_pc(temp_ptr->pc); |
814 if (temp_ptr->isLoad() || temp_ptr->isStore()) { |
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 |
921const std::string 922ElasticTrace::name() const 923{ 924 return ProbeListenerObject::name(); 925} 926 927void 928ElasticTrace::flushTraces() --- 13 unchanged lines hidden --- |