@@ -508,6 +508,10 @@ IssueQue::wakeUpDependents(const DynInstPtr& inst, bool speculative)
508508void
509509IssueQue::addIfReady (const DynInstPtr& inst)
510510{
511+ if (inst->isIssued ()) {
512+ return ;
513+ }
514+
511515 if (inst->readyToIssue ()) {
512516 if (inst->readyTick == -1 ) {
513517 inst->readyTick = curTick ();
@@ -1258,6 +1262,32 @@ Scheduler::specWakeUpDependents(const DynInstPtr& inst, IssueQue* from_issue_que
12581262 }
12591263}
12601264
1265+ void
1266+ Scheduler::specWakeUpFromVP (const DynInstPtr& inst)
1267+ {
1268+ DPRINTF (Schedule, " [sn:%llu] VP speculative wakeup dependents\n " , inst->seqNum );
1269+ // Wake consumers already in IQ via speculative wakeup (preserves subDepGraph)
1270+ for (auto to : issueQues) {
1271+ to->wakeUpDependents (inst, true ); // speculative=true -> depgraph preserved
1272+ }
1273+ // Set earlyScoreboard + bypassScoreboard (but NOT scoreboard) so that
1274+ // future consumers entering IQ via insert() will:
1275+ // - see scoreboard[src]=false -> enter the else branch
1276+ // - see earlyScoreboard[src]=true -> markSrcRegReady AND added to subDepGraph
1277+ // This ensures loadCancel DFS can find them.
1278+ for (int i = 0 ; i < inst->numDestRegs (); i++) {
1279+ PhysRegIdPtr dst = inst->renamedDestIdx (i);
1280+ if (dst->isFixedMapping ()) [[unlikely]] {
1281+ continue ;
1282+ }
1283+ earlyScoreboard[dst->flatIndex ()] = true ;
1284+ bypassScoreboard[dst->flatIndex ()] = true ;
1285+ // NOTE: intentionally NOT setting scoreboard[dst] = true
1286+ // so consumers go through the earlyScoreboard path in insert()
1287+ // which adds them to subDepGraph
1288+ }
1289+ }
1290+
12611291void
12621292Scheduler::specWakeUpFromLoadPipe (const DynInstPtr& inst)
12631293{
@@ -1360,7 +1390,7 @@ Scheduler::useRfWrPort(const DynInstPtr& inst, const PhysRegIdPtr& regid, int ty
13601390 t_lat = lat;
13611391}
13621392
1363- void
1393+ bool
13641394Scheduler::loadCancel (const DynInstPtr& inst)
13651395{
13661396 DPRINTF (Schedule, " [sn:%llu] %s cache miss, cancel consumers\n " , inst->seqNum ,
@@ -1369,10 +1399,12 @@ Scheduler::loadCancel(const DynInstPtr& inst)
13691399 inst->issueQue ->iqstats ->loadmiss ++;
13701400 }
13711401
1372- // speculative value prediction load should not be cancel
1373- // because the dependency issue has been resolved
1374- if (inst->vpResult .speculative ) {
1375- return ;
1402+ bool needSquashFallback = false ;
1403+
1404+ // For VP load: if prediction is correct (no misprediction), skip cancel.
1405+ // If VP misprediction detected, allow DFS to cancel dependent consumers.
1406+ if (inst->vpResult .speculative && !inst->vpMisprediction ) {
1407+ return false ;
13761408 }
13771409
13781410 dfs.push (inst);
@@ -1398,6 +1430,18 @@ Scheduler::loadCancel(const DynInstPtr& inst)
13981430 if (depInst->readySrcIdx (srcIdx)) {
13991431 DPRINTF (Schedule, " cancel [sn:%llu], clear src p%d ready\n " , depInst->seqNum ,
14001432 depInst->renamedSrcIdx (srcIdx)->flatIndex ());
1433+ if (depInst->isIssued ()) {
1434+ if (inst->vpMisprediction ) {
1435+ // VP misprediction: consumer may already be in-flight.
1436+ // Mark canceled and propagate to its dependents.
1437+ depInst->setCancel ();
1438+ depInst->clearSrcRegReady (srcIdx);
1439+ dfs.push (depInst);
1440+ needSquashFallback = true ;
1441+ }
1442+ continue ;
1443+ }
1444+
14011445 depInst->issueQue ->cancel (depInst);
14021446 depInst->clearSrcRegReady (srcIdx);
14031447 dfs.push (depInst);
@@ -1418,6 +1462,8 @@ Scheduler::loadCancel(const DynInstPtr& inst)
14181462 }
14191463 }
14201464 }
1465+
1466+ return needSquashFallback;
14211467}
14221468
14231469void
@@ -1456,14 +1502,14 @@ Scheduler::bypassWriteback(const DynInstPtr& inst)
14561502 }
14571503 if (inst->canLVP ()) {
14581504 RegVal actualValue = cpu->getReg (inst->extRenamedDestIdx (0 ));
1459- // RegVal actualValue_2 = inst->getResult().as<RegVal>();
1460- // assert(actualValue == actualValue_2);
14611505 inst->actualValue = actualValue;
1462- if (inst->vpResult .speculative && inst->fault == NoFault) {
1463- if (actualValue != inst->vpResult .value ) {
1464- // check error
1465- inst->vpMisprediction = true ;
1466- }
1506+ inst->vpMisprediction = false ;
1507+ if (inst->vpResult .speculative && inst->fault == NoFault &&
1508+ actualValue != inst->vpResult .value ) {
1509+ DPRINTF (Schedule, " actual value: 0x%lx, predicted value: 0x%lx pc %lx\n " , actualValue,
1510+ inst->vpResult .value , inst->pcState ().instAddr ());
1511+ inst->vpMisprediction = true ;
1512+ inst->vpResult .speculative = false ;
14671513 }
14681514 }
14691515}
0 commit comments