inst_queue_impl.hh (12833:4566a9331697) | inst_queue_impl.hh (13429:a1e199fd8122) |
---|---|
1/* 2 * Copyright (c) 2011-2014 ARM Limited 3 * Copyright (c) 2013 Advanced Micro Devices, Inc. 4 * All rights reserved. 5 * 6 * The license below extends only to copyright in the software and shall 7 * not be construed as granting a license to any other intellectual 8 * property including but not limited to intellectual property relating --- 46 unchanged lines hidden (view full) --- 55#include "params/DerivO3CPU.hh" 56#include "sim/core.hh" 57 58// clang complains about std::set being overloaded with Packet::set if 59// we open up the entire namespace std 60using std::list; 61 62template <class Impl> | 1/* 2 * Copyright (c) 2011-2014 ARM Limited 3 * Copyright (c) 2013 Advanced Micro Devices, Inc. 4 * All rights reserved. 5 * 6 * The license below extends only to copyright in the software and shall 7 * not be construed as granting a license to any other intellectual 8 * property including but not limited to intellectual property relating --- 46 unchanged lines hidden (view full) --- 55#include "params/DerivO3CPU.hh" 56#include "sim/core.hh" 57 58// clang complains about std::set being overloaded with Packet::set if 59// we open up the entire namespace std 60using std::list; 61 62template <class Impl> |
63InstructionQueue | 63InstructionQueue<Impl>::FUCompletion::FUCompletion(const DynInstPtr &_inst, |
64 int fu_idx, InstructionQueue<Impl> *iq_ptr) 65 : Event(Stat_Event_Pri, AutoDelete), 66 inst(_inst), fuIdx(fu_idx), iqPtr(iq_ptr), freeFU(false) 67{ 68} 69 70template <class Impl> 71void --- 508 unchanged lines hidden (view full) --- 580 } 581 } 582 583 return false; 584} 585 586template <class Impl> 587void | 64 int fu_idx, InstructionQueue<Impl> *iq_ptr) 65 : Event(Stat_Event_Pri, AutoDelete), 66 inst(_inst), fuIdx(fu_idx), iqPtr(iq_ptr), freeFU(false) 67{ 68} 69 70template <class Impl> 71void --- 508 unchanged lines hidden (view full) --- 580 } 581 } 582 583 return false; 584} 585 586template <class Impl> 587void |
588InstructionQueue | 588InstructionQueue<Impl>::insert(const DynInstPtr &new_inst) |
589{ 590 if (new_inst->isFloating()) { 591 fpInstQueueWrites++; 592 } else if (new_inst->isVector()) { 593 vecInstQueueWrites++; 594 } else { 595 intInstQueueWrites++; 596 } --- 29 unchanged lines hidden (view full) --- 626 627 count[new_inst->threadNumber]++; 628 629 assert(freeEntries == (numEntries - countInsts())); 630} 631 632template <class Impl> 633void | 589{ 590 if (new_inst->isFloating()) { 591 fpInstQueueWrites++; 592 } else if (new_inst->isVector()) { 593 vecInstQueueWrites++; 594 } else { 595 intInstQueueWrites++; 596 } --- 29 unchanged lines hidden (view full) --- 626 627 count[new_inst->threadNumber]++; 628 629 assert(freeEntries == (numEntries - countInsts())); 630} 631 632template <class Impl> 633void |
634InstructionQueue | 634InstructionQueue<Impl>::insertNonSpec(const DynInstPtr &new_inst) |
635{ 636 // @todo: Clean up this code; can do it by setting inst as unable 637 // to issue, then calling normal insert on the inst. 638 if (new_inst->isFloating()) { 639 fpInstQueueWrites++; 640 } else if (new_inst->isVector()) { 641 vecInstQueueWrites++; 642 } else { --- 30 unchanged lines hidden (view full) --- 673 674 count[new_inst->threadNumber]++; 675 676 assert(freeEntries == (numEntries - countInsts())); 677} 678 679template <class Impl> 680void | 635{ 636 // @todo: Clean up this code; can do it by setting inst as unable 637 // to issue, then calling normal insert on the inst. 638 if (new_inst->isFloating()) { 639 fpInstQueueWrites++; 640 } else if (new_inst->isVector()) { 641 vecInstQueueWrites++; 642 } else { --- 30 unchanged lines hidden (view full) --- 673 674 count[new_inst->threadNumber]++; 675 676 assert(freeEntries == (numEntries - countInsts())); 677} 678 679template <class Impl> 680void |
681InstructionQueue | 681InstructionQueue<Impl>::insertBarrier(const DynInstPtr &barr_inst) |
682{ 683 memDepUnit[barr_inst->threadNumber].insertBarrier(barr_inst); 684 685 insertNonSpec(barr_inst); 686} 687 688template <class Impl> 689typename Impl::DynInstPtr 690InstructionQueue<Impl>::getInstToExecute() 691{ 692 assert(!instsToExecute.empty()); | 682{ 683 memDepUnit[barr_inst->threadNumber].insertBarrier(barr_inst); 684 685 insertNonSpec(barr_inst); 686} 687 688template <class Impl> 689typename Impl::DynInstPtr 690InstructionQueue<Impl>::getInstToExecute() 691{ 692 assert(!instsToExecute.empty()); |
693 DynInstPtr inst = instsToExecute.front(); | 693 DynInstPtr inst = std::move(instsToExecute.front()); |
694 instsToExecute.pop_front(); 695 if (inst->isFloating()) { 696 fpInstQueueReads++; 697 } else if (inst->isVector()) { 698 vecInstQueueReads++; 699 } else { 700 intInstQueueReads++; 701 } --- 50 unchanged lines hidden (view full) --- 752 ++next_it; 753 } 754 755 readyIt[op_class] = listOrder.insert(next_it, queue_entry); 756} 757 758template <class Impl> 759void | 694 instsToExecute.pop_front(); 695 if (inst->isFloating()) { 696 fpInstQueueReads++; 697 } else if (inst->isVector()) { 698 vecInstQueueReads++; 699 } else { 700 intInstQueueReads++; 701 } --- 50 unchanged lines hidden (view full) --- 752 ++next_it; 753 } 754 755 readyIt[op_class] = listOrder.insert(next_it, queue_entry); 756} 757 758template <class Impl> 759void |
760InstructionQueue | 760InstructionQueue<Impl>::processFUCompletion(const DynInstPtr &inst, int fu_idx) |
761{ 762 DPRINTF(IQ, "Processing FU completion [sn:%lli]\n", inst->seqNum); 763 assert(!cpu->switchedOut()); 764 // The CPU could have been sleeping until this op completed (*extremely* 765 // long latency op). Wake it if it was. This may be overkill. 766 --wbOutstanding; 767 iewStage->wakeCPU(); 768 --- 15 unchanged lines hidden (view full) --- 784InstructionQueue<Impl>::scheduleReadyInsts() 785{ 786 DPRINTF(IQ, "Attempting to schedule ready instructions from " 787 "the IQ.\n"); 788 789 IssueStruct *i2e_info = issueToExecuteQueue->access(0); 790 791 DynInstPtr mem_inst; | 761{ 762 DPRINTF(IQ, "Processing FU completion [sn:%lli]\n", inst->seqNum); 763 assert(!cpu->switchedOut()); 764 // The CPU could have been sleeping until this op completed (*extremely* 765 // long latency op). Wake it if it was. This may be overkill. 766 --wbOutstanding; 767 iewStage->wakeCPU(); 768 --- 15 unchanged lines hidden (view full) --- 784InstructionQueue<Impl>::scheduleReadyInsts() 785{ 786 DPRINTF(IQ, "Attempting to schedule ready instructions from " 787 "the IQ.\n"); 788 789 IssueStruct *i2e_info = issueToExecuteQueue->access(0); 790 791 DynInstPtr mem_inst; |
792 while (mem_inst = getDeferredMemInstToExecute()) { | 792 while (mem_inst = std::move(getDeferredMemInstToExecute())) { |
793 addReadyMemInst(mem_inst); 794 } 795 796 // See if any cache blocked instructions are able to be executed | 793 addReadyMemInst(mem_inst); 794 } 795 796 // See if any cache blocked instructions are able to be executed |
797 while (mem_inst = getBlockedMemInstToExecute()) { | 797 while (mem_inst = std::move(getBlockedMemInstToExecute())) { |
798 addReadyMemInst(mem_inst); 799 } 800 801 // Have iterator to head of the list 802 // While I haven't exceeded bandwidth or reached the end of the list, 803 // Try to get a FU that can do what this op needs. 804 // If successful, change the oldestInst to the new top of the list, put 805 // the queue in the proper place in the list. --- 184 unchanged lines hidden (view full) --- 990 instList[tid].pop_front(); 991 } 992 993 assert(freeEntries == (numEntries - countInsts())); 994} 995 996template <class Impl> 997int | 798 addReadyMemInst(mem_inst); 799 } 800 801 // Have iterator to head of the list 802 // While I haven't exceeded bandwidth or reached the end of the list, 803 // Try to get a FU that can do what this op needs. 804 // If successful, change the oldestInst to the new top of the list, put 805 // the queue in the proper place in the list. --- 184 unchanged lines hidden (view full) --- 990 instList[tid].pop_front(); 991 } 992 993 assert(freeEntries == (numEntries - countInsts())); 994} 995 996template <class Impl> 997int |
998InstructionQueue | 998InstructionQueue<Impl>::wakeDependents(const DynInstPtr &completed_inst) |
999{ 1000 int dependents = 0; 1001 1002 // The instruction queue here takes care of both floating and int ops 1003 if (completed_inst->isFloating()) { 1004 fpInstQueueWakeupAccesses++; 1005 } else if (completed_inst->isVector()) { 1006 vecInstQueueWakeupAccesses++; --- 67 unchanged lines hidden (view full) --- 1074 // Mark the scoreboard as having that register ready. 1075 regScoreboard[dest_reg->flatIndex()] = true; 1076 } 1077 return dependents; 1078} 1079 1080template <class Impl> 1081void | 999{ 1000 int dependents = 0; 1001 1002 // The instruction queue here takes care of both floating and int ops 1003 if (completed_inst->isFloating()) { 1004 fpInstQueueWakeupAccesses++; 1005 } else if (completed_inst->isVector()) { 1006 vecInstQueueWakeupAccesses++; --- 67 unchanged lines hidden (view full) --- 1074 // Mark the scoreboard as having that register ready. 1075 regScoreboard[dest_reg->flatIndex()] = true; 1076 } 1077 return dependents; 1078} 1079 1080template <class Impl> 1081void |
1082InstructionQueue | 1082InstructionQueue<Impl>::addReadyMemInst(const DynInstPtr &ready_inst) |
1083{ 1084 OpClass op_class = ready_inst->opClass(); 1085 1086 readyInsts[op_class].push(ready_inst); 1087 1088 // Will need to reorder the list if either a queue is not on the list, 1089 // or it has an older instruction than last time. 1090 if (!queueOnList[op_class]) { --- 6 unchanged lines hidden (view full) --- 1097 1098 DPRINTF(IQ, "Instruction is ready to issue, putting it onto " 1099 "the ready list, PC %s opclass:%i [sn:%lli].\n", 1100 ready_inst->pcState(), op_class, ready_inst->seqNum); 1101} 1102 1103template <class Impl> 1104void | 1083{ 1084 OpClass op_class = ready_inst->opClass(); 1085 1086 readyInsts[op_class].push(ready_inst); 1087 1088 // Will need to reorder the list if either a queue is not on the list, 1089 // or it has an older instruction than last time. 1090 if (!queueOnList[op_class]) { --- 6 unchanged lines hidden (view full) --- 1097 1098 DPRINTF(IQ, "Instruction is ready to issue, putting it onto " 1099 "the ready list, PC %s opclass:%i [sn:%lli].\n", 1100 ready_inst->pcState(), op_class, ready_inst->seqNum); 1101} 1102 1103template <class Impl> 1104void |
1105InstructionQueue | 1105InstructionQueue<Impl>::rescheduleMemInst(const DynInstPtr &resched_inst) |
1106{ 1107 DPRINTF(IQ, "Rescheduling mem inst [sn:%lli]\n", resched_inst->seqNum); 1108 1109 // Reset DTB translation state 1110 resched_inst->translationStarted(false); 1111 resched_inst->translationCompleted(false); 1112 1113 resched_inst->clearCanIssue(); 1114 memDepUnit[resched_inst->threadNumber].reschedule(resched_inst); 1115} 1116 1117template <class Impl> 1118void | 1106{ 1107 DPRINTF(IQ, "Rescheduling mem inst [sn:%lli]\n", resched_inst->seqNum); 1108 1109 // Reset DTB translation state 1110 resched_inst->translationStarted(false); 1111 resched_inst->translationCompleted(false); 1112 1113 resched_inst->clearCanIssue(); 1114 memDepUnit[resched_inst->threadNumber].reschedule(resched_inst); 1115} 1116 1117template <class Impl> 1118void |
1119InstructionQueue | 1119InstructionQueue<Impl>::replayMemInst(const DynInstPtr &replay_inst) |
1120{ 1121 memDepUnit[replay_inst->threadNumber].replay(); 1122} 1123 1124template <class Impl> 1125void | 1120{ 1121 memDepUnit[replay_inst->threadNumber].replay(); 1122} 1123 1124template <class Impl> 1125void |
1126InstructionQueue | 1126InstructionQueue<Impl>::completeMemInst(const DynInstPtr &completed_inst) |
1127{ 1128 ThreadID tid = completed_inst->threadNumber; 1129 1130 DPRINTF(IQ, "Completing mem instruction PC: %s [sn:%lli]\n", 1131 completed_inst->pcState(), completed_inst->seqNum); 1132 1133 ++freeEntries; 1134 1135 completed_inst->memOpDone(true); 1136 1137 memDepUnit[tid].completed(completed_inst); 1138 count[tid]--; 1139} 1140 1141template <class Impl> 1142void | 1127{ 1128 ThreadID tid = completed_inst->threadNumber; 1129 1130 DPRINTF(IQ, "Completing mem instruction PC: %s [sn:%lli]\n", 1131 completed_inst->pcState(), completed_inst->seqNum); 1132 1133 ++freeEntries; 1134 1135 completed_inst->memOpDone(true); 1136 1137 memDepUnit[tid].completed(completed_inst); 1138 count[tid]--; 1139} 1140 1141template <class Impl> 1142void |
1143InstructionQueue | 1143InstructionQueue<Impl>::deferMemInst(const DynInstPtr &deferred_inst) |
1144{ 1145 deferredMemInsts.push_back(deferred_inst); 1146} 1147 1148template <class Impl> 1149void | 1144{ 1145 deferredMemInsts.push_back(deferred_inst); 1146} 1147 1148template <class Impl> 1149void |
1150InstructionQueue | 1150InstructionQueue<Impl>::blockMemInst(const DynInstPtr &blocked_inst) |
1151{ 1152 blocked_inst->translationStarted(false); 1153 blocked_inst->translationCompleted(false); 1154 1155 blocked_inst->clearIssued(); 1156 blocked_inst->clearCanIssue(); 1157 blockedMemInsts.push_back(blocked_inst); 1158} --- 9 unchanged lines hidden (view full) --- 1168 1169template <class Impl> 1170typename Impl::DynInstPtr 1171InstructionQueue<Impl>::getDeferredMemInstToExecute() 1172{ 1173 for (ListIt it = deferredMemInsts.begin(); it != deferredMemInsts.end(); 1174 ++it) { 1175 if ((*it)->translationCompleted() || (*it)->isSquashed()) { | 1151{ 1152 blocked_inst->translationStarted(false); 1153 blocked_inst->translationCompleted(false); 1154 1155 blocked_inst->clearIssued(); 1156 blocked_inst->clearCanIssue(); 1157 blockedMemInsts.push_back(blocked_inst); 1158} --- 9 unchanged lines hidden (view full) --- 1168 1169template <class Impl> 1170typename Impl::DynInstPtr 1171InstructionQueue<Impl>::getDeferredMemInstToExecute() 1172{ 1173 for (ListIt it = deferredMemInsts.begin(); it != deferredMemInsts.end(); 1174 ++it) { 1175 if ((*it)->translationCompleted() || (*it)->isSquashed()) { |
1176 DynInstPtr mem_inst = *it; | 1176 DynInstPtr mem_inst = std::move(*it); |
1177 deferredMemInsts.erase(it); 1178 return mem_inst; 1179 } 1180 } 1181 return nullptr; 1182} 1183 1184template <class Impl> 1185typename Impl::DynInstPtr 1186InstructionQueue<Impl>::getBlockedMemInstToExecute() 1187{ 1188 if (retryMemInsts.empty()) { 1189 return nullptr; 1190 } else { | 1177 deferredMemInsts.erase(it); 1178 return mem_inst; 1179 } 1180 } 1181 return nullptr; 1182} 1183 1184template <class Impl> 1185typename Impl::DynInstPtr 1186InstructionQueue<Impl>::getBlockedMemInstToExecute() 1187{ 1188 if (retryMemInsts.empty()) { 1189 return nullptr; 1190 } else { |
1191 DynInstPtr mem_inst = retryMemInsts.front(); | 1191 DynInstPtr mem_inst = std::move(retryMemInsts.front()); |
1192 retryMemInsts.pop_front(); 1193 return mem_inst; 1194 } 1195} 1196 1197template <class Impl> 1198void | 1192 retryMemInsts.pop_front(); 1193 return mem_inst; 1194 } 1195} 1196 1197template <class Impl> 1198void |
1199InstructionQueue 1200 DynInstPtr &faulting_load) | 1199InstructionQueue<Impl>::violation(const DynInstPtr &store, 1200 const DynInstPtr &faulting_load) |
1201{ 1202 intInstQueueWrites++; 1203 memDepUnit[store->threadNumber].violation(store, faulting_load); 1204} 1205 1206template <class Impl> 1207void 1208InstructionQueue<Impl>::squash(ThreadID tid) --- 150 unchanged lines hidden (view full) --- 1359 } 1360 instList[tid].erase(squash_it--); 1361 ++iqSquashedInstsExamined; 1362 } 1363} 1364 1365template <class Impl> 1366bool | 1201{ 1202 intInstQueueWrites++; 1203 memDepUnit[store->threadNumber].violation(store, faulting_load); 1204} 1205 1206template <class Impl> 1207void 1208InstructionQueue<Impl>::squash(ThreadID tid) --- 150 unchanged lines hidden (view full) --- 1359 } 1360 instList[tid].erase(squash_it--); 1361 ++iqSquashedInstsExamined; 1362 } 1363} 1364 1365template <class Impl> 1366bool |
1367InstructionQueue | 1367InstructionQueue<Impl>::addToDependents(const DynInstPtr &new_inst) |
1368{ 1369 // Loop through the instruction's source registers, adding 1370 // them to the dependency list if they are not ready. 1371 int8_t total_src_regs = new_inst->numSrcRegs(); 1372 bool return_val = false; 1373 1374 for (int src_reg_idx = 0; 1375 src_reg_idx < total_src_regs; --- 31 unchanged lines hidden (view full) --- 1407 } 1408 } 1409 1410 return return_val; 1411} 1412 1413template <class Impl> 1414void | 1368{ 1369 // Loop through the instruction's source registers, adding 1370 // them to the dependency list if they are not ready. 1371 int8_t total_src_regs = new_inst->numSrcRegs(); 1372 bool return_val = false; 1373 1374 for (int src_reg_idx = 0; 1375 src_reg_idx < total_src_regs; --- 31 unchanged lines hidden (view full) --- 1407 } 1408 } 1409 1410 return return_val; 1411} 1412 1413template <class Impl> 1414void |
1415InstructionQueue | 1415InstructionQueue<Impl>::addToProducers(const DynInstPtr &new_inst) |
1416{ 1417 // Nothing really needs to be marked when an instruction becomes 1418 // the producer of a register's value, but for convenience a ptr 1419 // to the producing instruction will be placed in the head node of 1420 // the dependency links. 1421 int8_t total_dest_regs = new_inst->numDestRegs(); 1422 1423 for (int dest_reg_idx = 0; --- 19 unchanged lines hidden (view full) --- 1443 1444 // Mark the scoreboard to say it's not yet ready. 1445 regScoreboard[dest_reg->flatIndex()] = false; 1446 } 1447} 1448 1449template <class Impl> 1450void | 1416{ 1417 // Nothing really needs to be marked when an instruction becomes 1418 // the producer of a register's value, but for convenience a ptr 1419 // to the producing instruction will be placed in the head node of 1420 // the dependency links. 1421 int8_t total_dest_regs = new_inst->numDestRegs(); 1422 1423 for (int dest_reg_idx = 0; --- 19 unchanged lines hidden (view full) --- 1443 1444 // Mark the scoreboard to say it's not yet ready. 1445 regScoreboard[dest_reg->flatIndex()] = false; 1446 } 1447} 1448 1449template <class Impl> 1450void |
1451InstructionQueue | 1451InstructionQueue<Impl>::addIfReady(const DynInstPtr &inst) |
1452{ 1453 // If the instruction now has all of its source registers 1454 // available, then add it to the list of ready instructions. 1455 if (inst->readyToIssue()) { 1456 1457 //Add the instruction to the proper ready list. 1458 if (inst->isMemRef()) { 1459 --- 194 unchanged lines hidden --- | 1452{ 1453 // If the instruction now has all of its source registers 1454 // available, then add it to the list of ready instructions. 1455 if (inst->readyToIssue()) { 1456 1457 //Add the instruction to the proper ready list. 1458 if (inst->isMemRef()) { 1459 --- 194 unchanged lines hidden --- |