commit_impl.hh (13652:45d94ac03a27) commit_impl.hh (13831:4fba790d88be)
1/*
2 * Copyright 2014 Google, Inc.
3 * Copyright (c) 2010-2014, 2017 ARM Limited
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

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

639 commitStatus[tid] = ROBSquashing;
640 cpu->activityThisCycle();
641}
642
643template <class Impl>
644void
645DefaultCommit<Impl>::squashAfter(ThreadID tid, const DynInstPtr &head_inst)
646{
1/*
2 * Copyright 2014 Google, Inc.
3 * Copyright (c) 2010-2014, 2017 ARM Limited
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

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

639 commitStatus[tid] = ROBSquashing;
640 cpu->activityThisCycle();
641}
642
643template <class Impl>
644void
645DefaultCommit<Impl>::squashAfter(ThreadID tid, const DynInstPtr &head_inst)
646{
647 DPRINTF(Commit, "Executing squash after for [tid:%i] inst [sn:%lli]\n",
647 DPRINTF(Commit, "Executing squash after for [tid:%i] inst [sn:%llu]\n",
648 tid, head_inst->seqNum);
649
650 assert(!squashAfterInst[tid] || squashAfterInst[tid] == head_inst);
651 commitStatus[tid] = SquashAfterPending;
652 squashAfterInst[tid] = head_inst;
653}
654
655template <class Impl>

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

674 // this cycle.
675 committedStores[tid] = false;
676
677 if (commitStatus[tid] == ROBSquashing) {
678
679 if (rob->isDoneSquashing(tid)) {
680 commitStatus[tid] = Running;
681 } else {
648 tid, head_inst->seqNum);
649
650 assert(!squashAfterInst[tid] || squashAfterInst[tid] == head_inst);
651 commitStatus[tid] = SquashAfterPending;
652 squashAfterInst[tid] = head_inst;
653}
654
655template <class Impl>

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

674 // this cycle.
675 committedStores[tid] = false;
676
677 if (commitStatus[tid] == ROBSquashing) {
678
679 if (rob->isDoneSquashing(tid)) {
680 commitStatus[tid] = Running;
681 } else {
682 DPRINTF(Commit,"[tid:%u]: Still Squashing, cannot commit any"
682 DPRINTF(Commit,"[tid:%i] Still Squashing, cannot commit any"
683 " insts this cycle.\n", tid);
684 rob->doSquash(tid);
685 toIEW->commitInfo[tid].robSquashing = true;
686 wroteToTimeBuffer = true;
687 }
688 }
689 }
690

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

699
700 if (!rob->isEmpty(tid) && rob->readHeadInst(tid)->readyToCommit()) {
701 // The ROB has more instructions it can commit. Its next status
702 // will be active.
703 _nextStatus = Active;
704
705 const DynInstPtr &inst M5_VAR_USED = rob->readHeadInst(tid);
706
683 " insts this cycle.\n", tid);
684 rob->doSquash(tid);
685 toIEW->commitInfo[tid].robSquashing = true;
686 wroteToTimeBuffer = true;
687 }
688 }
689 }
690

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

699
700 if (!rob->isEmpty(tid) && rob->readHeadInst(tid)->readyToCommit()) {
701 // The ROB has more instructions it can commit. Its next status
702 // will be active.
703 _nextStatus = Active;
704
705 const DynInstPtr &inst M5_VAR_USED = rob->readHeadInst(tid);
706
707 DPRINTF(Commit,"[tid:%i]: Instruction [sn:%lli] PC %s is head of"
707 DPRINTF(Commit,"[tid:%i] Instruction [sn:%llu] PC %s is head of"
708 " ROB and ready to commit\n",
709 tid, inst->seqNum, inst->pcState());
710
711 } else if (!rob->isEmpty(tid)) {
712 const DynInstPtr &inst = rob->readHeadInst(tid);
713
714 ppCommitStall->notify(inst);
715
708 " ROB and ready to commit\n",
709 tid, inst->seqNum, inst->pcState());
710
711 } else if (!rob->isEmpty(tid)) {
712 const DynInstPtr &inst = rob->readHeadInst(tid);
713
714 ppCommitStall->notify(inst);
715
716 DPRINTF(Commit,"[tid:%i]: Can't commit, Instruction [sn:%lli] PC "
716 DPRINTF(Commit,"[tid:%i] Can't commit, Instruction [sn:%llu] PC "
717 "%s is head of ROB and not ready\n",
718 tid, inst->seqNum, inst->pcState());
719 }
720
717 "%s is head of ROB and not ready\n",
718 tid, inst->seqNum, inst->pcState());
719 }
720
721 DPRINTF(Commit, "[tid:%i]: ROB has %d insts & %d free entries.\n",
721 DPRINTF(Commit, "[tid:%i] ROB has %d insts & %d free entries.\n",
722 tid, rob->countInsts(tid), rob->numFreeEntries(tid));
723 }
724
725
726 if (wroteToTimeBuffer) {
727 DPRINTF(Activity, "Activity This Cycle.\n");
728 cpu->activityThisCycle();
729 }

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

857 // instruction in the ROB. This prevents squashes from younger
858 // instructions overriding squashes from older instructions.
859 if (fromIEW->squash[tid] &&
860 commitStatus[tid] != TrapPending &&
861 fromIEW->squashedSeqNum[tid] <= youngestSeqNum[tid]) {
862
863 if (fromIEW->mispredictInst[tid]) {
864 DPRINTF(Commit,
722 tid, rob->countInsts(tid), rob->numFreeEntries(tid));
723 }
724
725
726 if (wroteToTimeBuffer) {
727 DPRINTF(Activity, "Activity This Cycle.\n");
728 cpu->activityThisCycle();
729 }

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

857 // instruction in the ROB. This prevents squashes from younger
858 // instructions overriding squashes from older instructions.
859 if (fromIEW->squash[tid] &&
860 commitStatus[tid] != TrapPending &&
861 fromIEW->squashedSeqNum[tid] <= youngestSeqNum[tid]) {
862
863 if (fromIEW->mispredictInst[tid]) {
864 DPRINTF(Commit,
865 "[tid:%i]: Squashing due to branch mispred PC:%#x [sn:%i]\n",
865 "[tid:%i] Squashing due to branch mispred "
866 "PC:%#x [sn:%llu]\n",
866 tid,
867 fromIEW->mispredictInst[tid]->instAddr(),
868 fromIEW->squashedSeqNum[tid]);
869 } else {
870 DPRINTF(Commit,
867 tid,
868 fromIEW->mispredictInst[tid]->instAddr(),
869 fromIEW->squashedSeqNum[tid]);
870 } else {
871 DPRINTF(Commit,
871 "[tid:%i]: Squashing due to order violation [sn:%i]\n",
872 "[tid:%i] Squashing due to order violation [sn:%llu]\n",
872 tid, fromIEW->squashedSeqNum[tid]);
873 }
874
873 tid, fromIEW->squashedSeqNum[tid]);
874 }
875
875 DPRINTF(Commit, "[tid:%i]: Redirecting to PC %#x\n",
876 DPRINTF(Commit, "[tid:%i] Redirecting to PC %#x\n",
876 tid,
877 fromIEW->pc[tid].nextInstAddr());
878
879 commitStatus[tid] = ROBSquashing;
880
881 // If we want to include the squashing instruction in the squash,
882 // then use one older sequence number.
883 InstSeqNum squashed_inst = fromIEW->squashedSeqNum[tid];

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

1005 break;
1006
1007 head_inst = rob->readHeadInst(commit_thread);
1008
1009 ThreadID tid = head_inst->threadNumber;
1010
1011 assert(tid == commit_thread);
1012
877 tid,
878 fromIEW->pc[tid].nextInstAddr());
879
880 commitStatus[tid] = ROBSquashing;
881
882 // If we want to include the squashing instruction in the squash,
883 // then use one older sequence number.
884 InstSeqNum squashed_inst = fromIEW->squashedSeqNum[tid];

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

1006 break;
1007
1008 head_inst = rob->readHeadInst(commit_thread);
1009
1010 ThreadID tid = head_inst->threadNumber;
1011
1012 assert(tid == commit_thread);
1013
1013 DPRINTF(Commit, "Trying to commit head instruction, [sn:%i] [tid:%i]\n",
1014 head_inst->seqNum, tid);
1014 DPRINTF(Commit,
1015 "Trying to commit head instruction, [tid:%i] [sn:%llu]\n",
1016 tid, head_inst->seqNum);
1015
1016 // If the head instruction is squashed, it is ready to retire
1017 // (be removed from the ROB) at any time.
1018 if (head_inst->isSquashed()) {
1019
1020 DPRINTF(Commit, "Retiring squashed instruction from "
1021 "ROB.\n");
1022

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

1127 // case squash now to make sure the interrupt is handled.
1128 //
1129 // If we don't do this, we might end up in a live lock situation
1130 if (!interrupt && avoidQuiesceLiveLock &&
1131 onInstBoundary && cpu->checkInterrupts(cpu->tcBase(0)))
1132 squashAfter(tid, head_inst);
1133 } else {
1134 DPRINTF(Commit, "Unable to commit head instruction PC:%s "
1017
1018 // If the head instruction is squashed, it is ready to retire
1019 // (be removed from the ROB) at any time.
1020 if (head_inst->isSquashed()) {
1021
1022 DPRINTF(Commit, "Retiring squashed instruction from "
1023 "ROB.\n");
1024

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

1129 // case squash now to make sure the interrupt is handled.
1130 //
1131 // If we don't do this, we might end up in a live lock situation
1132 if (!interrupt && avoidQuiesceLiveLock &&
1133 onInstBoundary && cpu->checkInterrupts(cpu->tcBase(0)))
1134 squashAfter(tid, head_inst);
1135 } else {
1136 DPRINTF(Commit, "Unable to commit head instruction PC:%s "
1135 "[tid:%i] [sn:%i].\n",
1137 "[tid:%i] [sn:%llu].\n",
1136 head_inst->pcState(), tid ,head_inst->seqNum);
1137 break;
1138 }
1139 }
1140 }
1141
1142 DPRINTF(CommitRate, "%i\n", num_committed);
1143 numCommittedDist.sample(num_committed);

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

1164
1165 // Make sure we are only trying to commit un-executed instructions we
1166 // think are possible.
1167 assert(head_inst->isNonSpeculative() || head_inst->isStoreConditional()
1168 || head_inst->isMemBarrier() || head_inst->isWriteBarrier()
1169 || head_inst->isAtomic()
1170 || (head_inst->isLoad() && head_inst->strictlyOrdered()));
1171
1138 head_inst->pcState(), tid ,head_inst->seqNum);
1139 break;
1140 }
1141 }
1142 }
1143
1144 DPRINTF(CommitRate, "%i\n", num_committed);
1145 numCommittedDist.sample(num_committed);

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

1166
1167 // Make sure we are only trying to commit un-executed instructions we
1168 // think are possible.
1169 assert(head_inst->isNonSpeculative() || head_inst->isStoreConditional()
1170 || head_inst->isMemBarrier() || head_inst->isWriteBarrier()
1171 || head_inst->isAtomic()
1172 || (head_inst->isLoad() && head_inst->strictlyOrdered()));
1173
1172 DPRINTF(Commit, "Encountered a barrier or non-speculative "
1173 "instruction [sn:%lli] at the head of the ROB, PC %s.\n",
1174 head_inst->seqNum, head_inst->pcState());
1174 DPRINTF(Commit,
1175 "Encountered a barrier or non-speculative "
1176 "instruction [tid:%i] [sn:%llu] "
1177 "at the head of the ROB, PC %s.\n",
1178 tid, head_inst->seqNum, head_inst->pcState());
1175
1176 if (inst_num > 0 || iewStage->hasStoresToWB(tid)) {
1179
1180 if (inst_num > 0 || iewStage->hasStoresToWB(tid)) {
1177 DPRINTF(Commit, "Waiting for all stores to writeback.\n");
1181 DPRINTF(Commit,
1182 "[tid:%i] [sn:%llu] "
1183 "Waiting for all stores to writeback.\n",
1184 tid, head_inst->seqNum);
1178 return false;
1179 }
1180
1181 toIEW->commitInfo[tid].nonSpecSeqNum = head_inst->seqNum;
1182
1183 // Change the instruction so it won't try to commit again until
1184 // it is executed.
1185 head_inst->clearCanCommit();
1186
1187 if (head_inst->isLoad() && head_inst->strictlyOrdered()) {
1185 return false;
1186 }
1187
1188 toIEW->commitInfo[tid].nonSpecSeqNum = head_inst->seqNum;
1189
1190 // Change the instruction so it won't try to commit again until
1191 // it is executed.
1192 head_inst->clearCanCommit();
1193
1194 if (head_inst->isLoad() && head_inst->strictlyOrdered()) {
1188 DPRINTF(Commit, "[sn:%lli]: Strictly ordered load, PC %s.\n",
1189 head_inst->seqNum, head_inst->pcState());
1195 DPRINTF(Commit, "[tid:%i] [sn:%llu] "
1196 "Strictly ordered load, PC %s.\n",
1197 tid, head_inst->seqNum, head_inst->pcState());
1190 toIEW->commitInfo[tid].strictlyOrdered = true;
1191 toIEW->commitInfo[tid].strictlyOrderedLoad = head_inst;
1192 } else {
1193 ++commitNonSpecStalls;
1194 }
1195
1196 return false;
1197 }

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

1205 Fault inst_fault = head_inst->getFault();
1206
1207 // Stores mark themselves as completed.
1208 if (!head_inst->isStore() && inst_fault == NoFault) {
1209 head_inst->setCompleted();
1210 }
1211
1212 if (inst_fault != NoFault) {
1198 toIEW->commitInfo[tid].strictlyOrdered = true;
1199 toIEW->commitInfo[tid].strictlyOrderedLoad = head_inst;
1200 } else {
1201 ++commitNonSpecStalls;
1202 }
1203
1204 return false;
1205 }

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

1213 Fault inst_fault = head_inst->getFault();
1214
1215 // Stores mark themselves as completed.
1216 if (!head_inst->isStore() && inst_fault == NoFault) {
1217 head_inst->setCompleted();
1218 }
1219
1220 if (inst_fault != NoFault) {
1213 DPRINTF(Commit, "Inst [sn:%lli] PC %s has a fault\n",
1214 head_inst->seqNum, head_inst->pcState());
1221 DPRINTF(Commit, "Inst [tid:%i] [sn:%llu] PC %s has a fault\n",
1222 tid, head_inst->seqNum, head_inst->pcState());
1215
1216 if (iewStage->hasStoresToWB(tid) || inst_num > 0) {
1223
1224 if (iewStage->hasStoresToWB(tid) || inst_num > 0) {
1217 DPRINTF(Commit, "Stores outstanding, fault must wait.\n");
1225 DPRINTF(Commit,
1226 "[tid:%i] [sn:%llu] "
1227 "Stores outstanding, fault must wait.\n",
1228 tid, head_inst->seqNum);
1218 return false;
1219 }
1220
1221 head_inst->setCompleted();
1222
1223 // If instruction has faulted, let the checker execute it and
1224 // check if it sees the same fault and control flow.
1225 if (cpu->checker) {

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

1244 StaticInst::nullStaticInstPtr :
1245 head_inst->staticInst);
1246
1247 // Exit state update mode to avoid accidental updating.
1248 thread[tid]->noSquashFromTC = false;
1249
1250 commitStatus[tid] = TrapPending;
1251
1229 return false;
1230 }
1231
1232 head_inst->setCompleted();
1233
1234 // If instruction has faulted, let the checker execute it and
1235 // check if it sees the same fault and control flow.
1236 if (cpu->checker) {

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

1255 StaticInst::nullStaticInstPtr :
1256 head_inst->staticInst);
1257
1258 // Exit state update mode to avoid accidental updating.
1259 thread[tid]->noSquashFromTC = false;
1260
1261 commitStatus[tid] = TrapPending;
1262
1252 DPRINTF(Commit, "Committing instruction with fault [sn:%lli]\n",
1253 head_inst->seqNum);
1263 DPRINTF(Commit,
1264 "[tid:%i] [sn:%llu] Committing instruction with fault\n",
1265 tid, head_inst->seqNum);
1254 if (head_inst->traceData) {
1255 if (DTRACE(ExecFaulting)) {
1256 head_inst->traceData->setFetchSeq(head_inst->seqNum);
1257 head_inst->traceData->setCPSeq(thread[tid]->numOp);
1258 head_inst->traceData->dump();
1259 }
1260 delete head_inst->traceData;
1261 head_inst->traceData = NULL;

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

1279 }
1280 if (CPA::available()) {
1281 if (head_inst->isControl()) {
1282 ThreadContext *tc = thread[tid]->getTC();
1283 CPA::cpa()->swAutoBegin(tc, head_inst->nextInstAddr());
1284 }
1285 }
1286 }
1266 if (head_inst->traceData) {
1267 if (DTRACE(ExecFaulting)) {
1268 head_inst->traceData->setFetchSeq(head_inst->seqNum);
1269 head_inst->traceData->setCPSeq(thread[tid]->numOp);
1270 head_inst->traceData->dump();
1271 }
1272 delete head_inst->traceData;
1273 head_inst->traceData = NULL;

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

1291 }
1292 if (CPA::available()) {
1293 if (head_inst->isControl()) {
1294 ThreadContext *tc = thread[tid]->getTC();
1295 CPA::cpa()->swAutoBegin(tc, head_inst->nextInstAddr());
1296 }
1297 }
1298 }
1287 DPRINTF(Commit, "Committing instruction with [sn:%lli] PC %s\n",
1288 head_inst->seqNum, head_inst->pcState());
1299 DPRINTF(Commit,
1300 "[tid:%i] [sn:%llu] Committing instruction with PC %s\n",
1301 tid, head_inst->seqNum, head_inst->pcState());
1289 if (head_inst->traceData) {
1290 head_inst->traceData->setFetchSeq(head_inst->seqNum);
1291 head_inst->traceData->setCPSeq(thread[tid]->numOp);
1292 head_inst->traceData->dump();
1293 delete head_inst->traceData;
1294 head_inst->traceData = NULL;
1295 }
1296 if (head_inst->isReturn()) {
1302 if (head_inst->traceData) {
1303 head_inst->traceData->setFetchSeq(head_inst->seqNum);
1304 head_inst->traceData->setCPSeq(thread[tid]->numOp);
1305 head_inst->traceData->dump();
1306 delete head_inst->traceData;
1307 head_inst->traceData = NULL;
1308 }
1309 if (head_inst->isReturn()) {
1297 DPRINTF(Commit,"Return Instruction Committed [sn:%lli] PC %s \n",
1298 head_inst->seqNum, head_inst->pcState());
1310 DPRINTF(Commit,
1311 "[tid:%i] [sn:%llu] Return Instruction Committed PC %s \n",
1312 tid, head_inst->seqNum, head_inst->pcState());
1299 }
1300
1301 // Update the commit rename map
1302 for (int i = 0; i < head_inst->numDestRegs(); i++) {
1303 renameMap[tid]->setEntry(head_inst->flattenedDestRegIdx(i),
1304 head_inst->renamedDestRegIdx(i));
1305 }
1306

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

1334 const DynInstPtr &inst = fromRename->insts[inst_num];
1335 ThreadID tid = inst->threadNumber;
1336
1337 if (!inst->isSquashed() &&
1338 commitStatus[tid] != ROBSquashing &&
1339 commitStatus[tid] != TrapPending) {
1340 changedROBNumEntries[tid] = true;
1341
1313 }
1314
1315 // Update the commit rename map
1316 for (int i = 0; i < head_inst->numDestRegs(); i++) {
1317 renameMap[tid]->setEntry(head_inst->flattenedDestRegIdx(i),
1318 head_inst->renamedDestRegIdx(i));
1319 }
1320

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

1348 const DynInstPtr &inst = fromRename->insts[inst_num];
1349 ThreadID tid = inst->threadNumber;
1350
1351 if (!inst->isSquashed() &&
1352 commitStatus[tid] != ROBSquashing &&
1353 commitStatus[tid] != TrapPending) {
1354 changedROBNumEntries[tid] = true;
1355
1342 DPRINTF(Commit, "Inserting PC %s [sn:%i] [tid:%i] into ROB.\n",
1343 inst->pcState(), inst->seqNum, tid);
1356 DPRINTF(Commit, "[tid:%i] [sn:%llu] Inserting PC %s into ROB.\n",
1357 inst->seqNum, tid, inst->pcState());
1344
1345 rob->insertInst(inst);
1346
1347 assert(rob->getThreadEntries(tid) <= rob->getMaxEntries(tid));
1348
1349 youngestSeqNum[tid] = inst->seqNum;
1350 } else {
1358
1359 rob->insertInst(inst);
1360
1361 assert(rob->getThreadEntries(tid) <= rob->getMaxEntries(tid));
1362
1363 youngestSeqNum[tid] = inst->seqNum;
1364 } else {
1351 DPRINTF(Commit, "Instruction PC %s [sn:%i] [tid:%i] was "
1352 "squashed, skipping.\n",
1353 inst->pcState(), inst->seqNum, tid);
1365 DPRINTF(Commit, "[tid:%i] [sn:%llu] "
1366 "Instruction PC %s was squashed, skipping.\n",
1367 inst->seqNum, tid, inst->pcState());
1354 }
1355 }
1356}
1357
1358template <class Impl>
1359void
1360DefaultCommit<Impl>::markCompletedInsts()
1361{
1362 // Grab completed insts out of the IEW instruction queue, and mark
1363 // instructions completed within the ROB.
1364 for (int inst_num = 0; inst_num < fromIEW->size; ++inst_num) {
1365 assert(fromIEW->insts[inst_num]);
1366 if (!fromIEW->insts[inst_num]->isSquashed()) {
1368 }
1369 }
1370}
1371
1372template <class Impl>
1373void
1374DefaultCommit<Impl>::markCompletedInsts()
1375{
1376 // Grab completed insts out of the IEW instruction queue, and mark
1377 // instructions completed within the ROB.
1378 for (int inst_num = 0; inst_num < fromIEW->size; ++inst_num) {
1379 assert(fromIEW->insts[inst_num]);
1380 if (!fromIEW->insts[inst_num]->isSquashed()) {
1367 DPRINTF(Commit, "[tid:%i]: Marking PC %s, [sn:%lli] ready "
1381 DPRINTF(Commit, "[tid:%i] Marking PC %s, [sn:%llu] ready "
1368 "within ROB.\n",
1369 fromIEW->insts[inst_num]->threadNumber,
1370 fromIEW->insts[inst_num]->pcState(),
1371 fromIEW->insts[inst_num]->seqNum);
1372
1373 // Mark the instruction as ready to commit.
1374 fromIEW->insts[inst_num]->setCanCommit();
1375 }

--- 170 unchanged lines hidden ---
1382 "within ROB.\n",
1383 fromIEW->insts[inst_num]->threadNumber,
1384 fromIEW->insts[inst_num]->pcState(),
1385 fromIEW->insts[inst_num]->seqNum);
1386
1387 // Mark the instruction as ready to commit.
1388 fromIEW->insts[inst_num]->setCanCommit();
1389 }

--- 170 unchanged lines hidden ---