16b1207267f01877ff9b351786c902cb2ecd354c0Andrew Trick//===----- ScoreboardHazardRecognizer.cpp - Scheduler Support -------------===// 2d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin// 3d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin// The LLVM Compiler Infrastructure 4d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin// 5d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin// This file is distributed under the University of Illinois Open Source 6d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin// License. See LICENSE.TXT for details. 7d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin// 8d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin//===----------------------------------------------------------------------===// 9d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin// 106b1207267f01877ff9b351786c902cb2ecd354c0Andrew Trick// This file implements the ScoreboardHazardRecognizer class, which 116b1207267f01877ff9b351786c902cb2ecd354c0Andrew Trick// encapsultes hazard-avoidance heuristics for scheduling, based on the 126b1207267f01877ff9b351786c902cb2ecd354c0Andrew Trick// scheduling itineraries specified for the target. 13d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin// 14d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin//===----------------------------------------------------------------------===// 15d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin 166b1207267f01877ff9b351786c902cb2ecd354c0Andrew Trick#include "llvm/CodeGen/ScoreboardHazardRecognizer.h" 17774bc882fdb3bbb0558075360c6e5bc510a0bdadEvan Cheng#include "llvm/CodeGen/ScheduleDAG.h" 18ab8be96fd30ca9396e6b84fdddf1ac6208984cadEvan Cheng#include "llvm/MC/MCInstrItineraries.h" 19d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin#include "llvm/Support/Debug.h" 20d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin#include "llvm/Support/ErrorHandling.h" 213a5f0d444cf21e2b90d5eb965bb677c7ce098546David Goodwin#include "llvm/Support/raw_ostream.h" 22c8bfd1d78ff9a307d1d4cb57cce4549b538e60f4Andrew Trick#include "llvm/Target/TargetInstrInfo.h" 23d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin 24fb98a43b311dec66188b3669a0da017829833617Bill Wendlingusing namespace llvm; 25d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin 26dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE ::llvm::ScoreboardHazardRecognizer::DebugType 27dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 282da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick#ifndef NDEBUG 292da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trickconst char *ScoreboardHazardRecognizer::DebugType = ""; 302da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick#endif 312da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick 326b1207267f01877ff9b351786c902cb2ecd354c0Andrew TrickScoreboardHazardRecognizer:: 332da8bc8a5f7705ac131184cd247f48500da0d74eAndrew TrickScoreboardHazardRecognizer(const InstrItineraryData *II, 342da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick const ScheduleDAG *SchedDAG, 352da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick const char *ParentDebugType) : 362da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick ScheduleHazardRecognizer(), ItinData(II), DAG(SchedDAG), IssueWidth(0), 372da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick IssueCount(0) { 382da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick 392da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick#ifndef NDEBUG 402da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick DebugType = ParentDebugType; 412da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick#endif 422da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick 43d327d3ddddaf23fe920a01bf6304f6a8f4986e89Andrew Trick // Determine the maximum depth of any itinerary. This determines the depth of 44d327d3ddddaf23fe920a01bf6304f6a8f4986e89Andrew Trick // the scoreboard. We always make the scoreboard at least 1 cycle deep to 45d327d3ddddaf23fe920a01bf6304f6a8f4986e89Andrew Trick // avoid dealing with the boundary condition. 461298948c5c36e6e88cbde0abe73f7f37c3a038a6Anton Korobeynikov unsigned ScoreboardDepth = 1; 473ef1c8759a20167457eb7fd82ebcaffe7ccaa1d1Evan Cheng if (ItinData && !ItinData->isEmpty()) { 48d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin for (unsigned idx = 0; ; ++idx) { 493ef1c8759a20167457eb7fd82ebcaffe7ccaa1d1Evan Cheng if (ItinData->isEndMarker(idx)) 50d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin break; 51d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin 523ef1c8759a20167457eb7fd82ebcaffe7ccaa1d1Evan Cheng const InstrStage *IS = ItinData->beginStage(idx); 533ef1c8759a20167457eb7fd82ebcaffe7ccaa1d1Evan Cheng const InstrStage *E = ItinData->endStage(idx); 542da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick unsigned CurCycle = 0; 55d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin unsigned ItinDepth = 0; 562da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick for (; IS != E; ++IS) { 572da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick unsigned StageDepth = CurCycle + IS->getCycles(); 582da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick if (ItinDepth < StageDepth) ItinDepth = StageDepth; 592da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick CurCycle += IS->getNextCycles(); 602da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick } 61d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin 626b1207267f01877ff9b351786c902cb2ecd354c0Andrew Trick // Find the next power-of-2 >= ItinDepth 636b1207267f01877ff9b351786c902cb2ecd354c0Andrew Trick while (ItinDepth > ScoreboardDepth) { 646b1207267f01877ff9b351786c902cb2ecd354c0Andrew Trick ScoreboardDepth *= 2; 65d327d3ddddaf23fe920a01bf6304f6a8f4986e89Andrew Trick // Don't set MaxLookAhead until we find at least one nonzero stage. 66d327d3ddddaf23fe920a01bf6304f6a8f4986e89Andrew Trick // This way, an itinerary with no stages has MaxLookAhead==0, which 67d327d3ddddaf23fe920a01bf6304f6a8f4986e89Andrew Trick // completely bypasses the scoreboard hazard logic. 68d327d3ddddaf23fe920a01bf6304f6a8f4986e89Andrew Trick MaxLookAhead = ScoreboardDepth; 696b1207267f01877ff9b351786c902cb2ecd354c0Andrew Trick } 70d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin } 71d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin } 72d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin 7396085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov ReservedScoreboard.reset(ScoreboardDepth); 7496085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov RequiredScoreboard.reset(ScoreboardDepth); 75d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin 762661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick // If MaxLookAhead is not set above, then we are not enabled. 77fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick if (!isEnabled()) 78d327d3ddddaf23fe920a01bf6304f6a8f4986e89Andrew Trick DEBUG(dbgs() << "Disabled scoreboard hazard recognizer\n"); 79fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick else { 802661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick // A nonempty itinerary must have a SchedModel. 812661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick IssueWidth = ItinData->SchedModel->IssueWidth; 82d327d3ddddaf23fe920a01bf6304f6a8f4986e89Andrew Trick DEBUG(dbgs() << "Using scoreboard hazard recognizer: Depth = " 83d327d3ddddaf23fe920a01bf6304f6a8f4986e89Andrew Trick << ScoreboardDepth << '\n'); 84fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick } 85d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin} 86d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin 876b1207267f01877ff9b351786c902cb2ecd354c0Andrew Trickvoid ScoreboardHazardRecognizer::Reset() { 882da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick IssueCount = 0; 8996085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov RequiredScoreboard.reset(); 9096085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov ReservedScoreboard.reset(); 91d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin} 92d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin 93b720be6a50f4e1b3280d2b029ee38dda14577525Manman Ren#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 946b1207267f01877ff9b351786c902cb2ecd354c0Andrew Trickvoid ScoreboardHazardRecognizer::Scoreboard::dump() const { 9573242dd692c0226073c367c2fe573287a3d63fc1David Greene dbgs() << "Scoreboard:\n"; 961298948c5c36e6e88cbde0abe73f7f37c3a038a6Anton Korobeynikov 971298948c5c36e6e88cbde0abe73f7f37c3a038a6Anton Korobeynikov unsigned last = Depth - 1; 981298948c5c36e6e88cbde0abe73f7f37c3a038a6Anton Korobeynikov while ((last > 0) && ((*this)[last] == 0)) 99d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin last--; 100d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin 101d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin for (unsigned i = 0; i <= last; i++) { 102b460a3382961c5be9952a75d46228f624edbd39fHal Finkel unsigned FUs = (*this)[i]; 10373242dd692c0226073c367c2fe573287a3d63fc1David Greene dbgs() << "\t"; 104b460a3382961c5be9952a75d46228f624edbd39fHal Finkel for (int j = 31; j >= 0; j--) 105b460a3382961c5be9952a75d46228f624edbd39fHal Finkel dbgs() << ((FUs & (1 << j)) ? '1' : '0'); 10673242dd692c0226073c367c2fe573287a3d63fc1David Greene dbgs() << '\n'; 107d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin } 108d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin} 10977e300e8f0b8db8eec448cae9c87d7c5bfad9757Manman Ren#endif 110d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin 1112da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trickbool ScoreboardHazardRecognizer::atIssueLimit() const { 1122da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick if (IssueWidth == 0) 1132da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick return false; 1142da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick 1152da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick return IssueCount == IssueWidth; 1162da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick} 1172da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick 11846df4eb46e784036cf895db271fe29e1cf2a975aEvan ChengScheduleHazardRecognizer::HazardType 1192da8bc8a5f7705ac131184cd247f48500da0d74eAndrew TrickScoreboardHazardRecognizer::getHazardType(SUnit *SU, int Stalls) { 1203ef1c8759a20167457eb7fd82ebcaffe7ccaa1d1Evan Cheng if (!ItinData || ItinData->isEmpty()) 121047ae2f2ad2161d37996c26a5e5ac2b79f09eee5David Goodwin return NoHazard; 122047ae2f2ad2161d37996c26a5e5ac2b79f09eee5David Goodwin 1232da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick // Note that stalls will be negative for bottom-up scheduling. 1242da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick int cycle = Stalls; 125047ae2f2ad2161d37996c26a5e5ac2b79f09eee5David Goodwin 126047ae2f2ad2161d37996c26a5e5ac2b79f09eee5David Goodwin // Use the itinerary for the underlying instruction to check for 127047ae2f2ad2161d37996c26a5e5ac2b79f09eee5David Goodwin // free FU's in the scoreboard at the appropriate future cycles. 1282da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick 129e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng const MCInstrDesc *MCID = DAG->getInstrDesc(SU); 130dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!MCID) { 1312da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick // Don't check hazards for non-machineinstr Nodes. 1322da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick return NoHazard; 1332da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick } 134e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng unsigned idx = MCID->getSchedClass(); 1353ef1c8759a20167457eb7fd82ebcaffe7ccaa1d1Evan Cheng for (const InstrStage *IS = ItinData->beginStage(idx), 1363ef1c8759a20167457eb7fd82ebcaffe7ccaa1d1Evan Cheng *E = ItinData->endStage(idx); IS != E; ++IS) { 137047ae2f2ad2161d37996c26a5e5ac2b79f09eee5David Goodwin // We must find one of the stage's units free for every cycle the 138047ae2f2ad2161d37996c26a5e5ac2b79f09eee5David Goodwin // stage is occupied. FIXME it would be more accurate to find the 139047ae2f2ad2161d37996c26a5e5ac2b79f09eee5David Goodwin // same unit free in all the cycles. 140047ae2f2ad2161d37996c26a5e5ac2b79f09eee5David Goodwin for (unsigned int i = 0; i < IS->getCycles(); ++i) { 1412da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick int StageCycle = cycle + (int)i; 1422da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick if (StageCycle < 0) 1432da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick continue; 1442da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick 1452da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick if (StageCycle >= (int)RequiredScoreboard.getDepth()) { 1462da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick assert((StageCycle - Stalls) < (int)RequiredScoreboard.getDepth() && 1472da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick "Scoreboard depth exceeded!"); 1482da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick // This stage was stalled beyond pipeline depth, so cannot conflict. 1492da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick break; 1502da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick } 1511298948c5c36e6e88cbde0abe73f7f37c3a038a6Anton Korobeynikov 152b460a3382961c5be9952a75d46228f624edbd39fHal Finkel unsigned freeUnits = IS->getUnits(); 15396085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov switch (IS->getReservationKind()) { 15496085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov case InstrStage::Required: 15596085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov // Required FUs conflict with both reserved and required ones 1562da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick freeUnits &= ~ReservedScoreboard[StageCycle]; 15796085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov // FALLTHROUGH 15896085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov case InstrStage::Reserved: 15996085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov // Reserved FUs can conflict only with required ones. 1602da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick freeUnits &= ~RequiredScoreboard[StageCycle]; 16196085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov break; 16296085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov } 16396085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov 164047ae2f2ad2161d37996c26a5e5ac2b79f09eee5David Goodwin if (!freeUnits) { 1659632f77f8dde9d2c9c9cb9d022b846a82c918cbdBenjamin Kramer DEBUG(dbgs() << "*** Hazard in cycle +" << StageCycle << ", "); 16673242dd692c0226073c367c2fe573287a3d63fc1David Greene DEBUG(dbgs() << "SU(" << SU->NodeNum << "): "); 1672da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick DEBUG(DAG->dumpNode(SU)); 168047ae2f2ad2161d37996c26a5e5ac2b79f09eee5David Goodwin return Hazard; 169047ae2f2ad2161d37996c26a5e5ac2b79f09eee5David Goodwin } 170d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin } 1711298948c5c36e6e88cbde0abe73f7f37c3a038a6Anton Korobeynikov 172047ae2f2ad2161d37996c26a5e5ac2b79f09eee5David Goodwin // Advance the cycle to the next stage. 173047ae2f2ad2161d37996c26a5e5ac2b79f09eee5David Goodwin cycle += IS->getNextCycles(); 174d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin } 175d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin 176d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin return NoHazard; 177d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin} 1781298948c5c36e6e88cbde0abe73f7f37c3a038a6Anton Korobeynikov 1796b1207267f01877ff9b351786c902cb2ecd354c0Andrew Trickvoid ScoreboardHazardRecognizer::EmitInstruction(SUnit *SU) { 1803ef1c8759a20167457eb7fd82ebcaffe7ccaa1d1Evan Cheng if (!ItinData || ItinData->isEmpty()) 181047ae2f2ad2161d37996c26a5e5ac2b79f09eee5David Goodwin return; 182047ae2f2ad2161d37996c26a5e5ac2b79f09eee5David Goodwin 183047ae2f2ad2161d37996c26a5e5ac2b79f09eee5David Goodwin // Use the itinerary for the underlying instruction to reserve FU's 184047ae2f2ad2161d37996c26a5e5ac2b79f09eee5David Goodwin // in the scoreboard at the appropriate future cycles. 185e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng const MCInstrDesc *MCID = DAG->getInstrDesc(SU); 186e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng assert(MCID && "The scheduler must filter non-machineinstrs"); 187e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng if (DAG->TII->isZeroCost(MCID->Opcode)) 188c8bfd1d78ff9a307d1d4cb57cce4549b538e60f4Andrew Trick return; 189c8bfd1d78ff9a307d1d4cb57cce4549b538e60f4Andrew Trick 190c8bfd1d78ff9a307d1d4cb57cce4549b538e60f4Andrew Trick ++IssueCount; 191c8bfd1d78ff9a307d1d4cb57cce4549b538e60f4Andrew Trick 192c8bfd1d78ff9a307d1d4cb57cce4549b538e60f4Andrew Trick unsigned cycle = 0; 193c8bfd1d78ff9a307d1d4cb57cce4549b538e60f4Andrew Trick 194e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng unsigned idx = MCID->getSchedClass(); 1953ef1c8759a20167457eb7fd82ebcaffe7ccaa1d1Evan Cheng for (const InstrStage *IS = ItinData->beginStage(idx), 1963ef1c8759a20167457eb7fd82ebcaffe7ccaa1d1Evan Cheng *E = ItinData->endStage(idx); IS != E; ++IS) { 197047ae2f2ad2161d37996c26a5e5ac2b79f09eee5David Goodwin // We must reserve one of the stage's units for every cycle the 198047ae2f2ad2161d37996c26a5e5ac2b79f09eee5David Goodwin // stage is occupied. FIXME it would be more accurate to reserve 199047ae2f2ad2161d37996c26a5e5ac2b79f09eee5David Goodwin // the same unit free in all the cycles. 200047ae2f2ad2161d37996c26a5e5ac2b79f09eee5David Goodwin for (unsigned int i = 0; i < IS->getCycles(); ++i) { 20196085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov assert(((cycle + i) < RequiredScoreboard.getDepth()) && 202047ae2f2ad2161d37996c26a5e5ac2b79f09eee5David Goodwin "Scoreboard depth exceeded!"); 2031298948c5c36e6e88cbde0abe73f7f37c3a038a6Anton Korobeynikov 204b460a3382961c5be9952a75d46228f624edbd39fHal Finkel unsigned freeUnits = IS->getUnits(); 20596085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov switch (IS->getReservationKind()) { 20696085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov case InstrStage::Required: 20796085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov // Required FUs conflict with both reserved and required ones 20896085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov freeUnits &= ~ReservedScoreboard[cycle + i]; 20996085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov // FALLTHROUGH 21096085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov case InstrStage::Reserved: 21196085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov // Reserved FUs can conflict only with required ones. 21296085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov freeUnits &= ~RequiredScoreboard[cycle + i]; 21396085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov break; 21496085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov } 2151298948c5c36e6e88cbde0abe73f7f37c3a038a6Anton Korobeynikov 216047ae2f2ad2161d37996c26a5e5ac2b79f09eee5David Goodwin // reduce to a single unit 217b460a3382961c5be9952a75d46228f624edbd39fHal Finkel unsigned freeUnit = 0; 218047ae2f2ad2161d37996c26a5e5ac2b79f09eee5David Goodwin do { 219047ae2f2ad2161d37996c26a5e5ac2b79f09eee5David Goodwin freeUnit = freeUnits; 220047ae2f2ad2161d37996c26a5e5ac2b79f09eee5David Goodwin freeUnits = freeUnit & (freeUnit - 1); 221047ae2f2ad2161d37996c26a5e5ac2b79f09eee5David Goodwin } while (freeUnits); 2221298948c5c36e6e88cbde0abe73f7f37c3a038a6Anton Korobeynikov 22396085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov if (IS->getReservationKind() == InstrStage::Required) 22496085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov RequiredScoreboard[cycle + i] |= freeUnit; 22596085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov else 22696085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov ReservedScoreboard[cycle + i] |= freeUnit; 227d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin } 2281298948c5c36e6e88cbde0abe73f7f37c3a038a6Anton Korobeynikov 229047ae2f2ad2161d37996c26a5e5ac2b79f09eee5David Goodwin // Advance the cycle to the next stage. 230047ae2f2ad2161d37996c26a5e5ac2b79f09eee5David Goodwin cycle += IS->getNextCycles(); 231d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin } 2321298948c5c36e6e88cbde0abe73f7f37c3a038a6Anton Korobeynikov 23396085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov DEBUG(ReservedScoreboard.dump()); 23496085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov DEBUG(RequiredScoreboard.dump()); 235d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin} 2361298948c5c36e6e88cbde0abe73f7f37c3a038a6Anton Korobeynikov 2376b1207267f01877ff9b351786c902cb2ecd354c0Andrew Trickvoid ScoreboardHazardRecognizer::AdvanceCycle() { 2382da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick IssueCount = 0; 23996085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov ReservedScoreboard[0] = 0; ReservedScoreboard.advance(); 24096085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov RequiredScoreboard[0] = 0; RequiredScoreboard.advance(); 241d94a4e5d8de1145be200ff7223f98b0928462b94David Goodwin} 2426b1207267f01877ff9b351786c902cb2ecd354c0Andrew Trick 2436b1207267f01877ff9b351786c902cb2ecd354c0Andrew Trickvoid ScoreboardHazardRecognizer::RecedeCycle() { 2442da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick IssueCount = 0; 2456b1207267f01877ff9b351786c902cb2ecd354c0Andrew Trick ReservedScoreboard[ReservedScoreboard.getDepth()-1] = 0; 2466b1207267f01877ff9b351786c902cb2ecd354c0Andrew Trick ReservedScoreboard.recede(); 2476b1207267f01877ff9b351786c902cb2ecd354c0Andrew Trick RequiredScoreboard[RequiredScoreboard.getDepth()-1] = 0; 2486b1207267f01877ff9b351786c902cb2ecd354c0Andrew Trick RequiredScoreboard.recede(); 2496b1207267f01877ff9b351786c902cb2ecd354c0Andrew Trick} 250