X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FExactHazardRecognizer.cpp;h=af5f2892c2f07f2f1a56321e96688b4037688308;hb=95c57ea1825fedc10dc2a311b0d97105f6e61148;hp=266c74c9995ed542180b3a3d1e2cf1126e058d41;hpb=73242dd692c0226073c367c2fe573287a3d63fc1;p=oota-llvm.git diff --git a/lib/CodeGen/ExactHazardRecognizer.cpp b/lib/CodeGen/ExactHazardRecognizer.cpp index 266c74c9995..af5f2892c2f 100644 --- a/lib/CodeGen/ExactHazardRecognizer.cpp +++ b/lib/CodeGen/ExactHazardRecognizer.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This implements a a hazard recognizer using the instructions itineraries +// This implements a hazard recognizer using the instructions itineraries // defined for the current target. // //===----------------------------------------------------------------------===// @@ -29,7 +29,7 @@ ExactHazardRecognizer(const InstrItineraryData &LItinData) : // Determine the maximum depth of any itinerary. This determines the // depth of the scoreboard. We always make the scoreboard at least 1 // cycle deep to avoid dealing with the boundary condition. - ScoreboardDepth = 1; + unsigned ScoreboardDepth = 1; if (!ItinData.isEmpty()) { for (unsigned idx = 0; ; ++idx) { if (ItinData.isEndMarker(idx)) @@ -45,35 +45,27 @@ ExactHazardRecognizer(const InstrItineraryData &LItinData) : } } - Scoreboard = new unsigned[ScoreboardDepth]; - ScoreboardHead = 0; + ReservedScoreboard.reset(ScoreboardDepth); + RequiredScoreboard.reset(ScoreboardDepth); DEBUG(dbgs() << "Using exact hazard recognizer: ScoreboardDepth = " << ScoreboardDepth << '\n'); } -ExactHazardRecognizer::~ExactHazardRecognizer() { - delete [] Scoreboard; -} - void ExactHazardRecognizer::Reset() { - memset(Scoreboard, 0, ScoreboardDepth * sizeof(unsigned)); - ScoreboardHead = 0; + RequiredScoreboard.reset(); + ReservedScoreboard.reset(); } -unsigned ExactHazardRecognizer::getFutureIndex(unsigned offset) { - return (ScoreboardHead + offset) % ScoreboardDepth; -} - -void ExactHazardRecognizer::dumpScoreboard() { +void ExactHazardRecognizer::ScoreBoard::dump() const { dbgs() << "Scoreboard:\n"; - - unsigned last = ScoreboardDepth - 1; - while ((last > 0) && (Scoreboard[getFutureIndex(last)] == 0)) + + unsigned last = Depth - 1; + while ((last > 0) && ((*this)[last] == 0)) last--; for (unsigned i = 0; i <= last; i++) { - unsigned FUs = Scoreboard[getFutureIndex(i)]; + unsigned FUs = (*this)[i]; dbgs() << "\t"; for (int j = 31; j >= 0; j--) dbgs() << ((FUs & (1 << j)) ? '1' : '0'); @@ -96,11 +88,23 @@ ExactHazardRecognizer::HazardType ExactHazardRecognizer::getHazardType(SUnit *SU // stage is occupied. FIXME it would be more accurate to find the // same unit free in all the cycles. for (unsigned int i = 0; i < IS->getCycles(); ++i) { - assert(((cycle + i) < ScoreboardDepth) && + assert(((cycle + i) < RequiredScoreboard.getDepth()) && "Scoreboard depth exceeded!"); - - unsigned index = getFutureIndex(cycle + i); - unsigned freeUnits = IS->getUnits() & ~Scoreboard[index]; + + unsigned freeUnits = IS->getUnits(); + switch (IS->getReservationKind()) { + default: + assert(0 && "Invalid FU reservation"); + case InstrStage::Required: + // Required FUs conflict with both reserved and required ones + freeUnits &= ~ReservedScoreboard[cycle + i]; + // FALLTHROUGH + case InstrStage::Reserved: + // Reserved FUs can conflict only with required ones. + freeUnits &= ~RequiredScoreboard[cycle + i]; + break; + } + if (!freeUnits) { DEBUG(dbgs() << "*** Hazard in cycle " << (cycle + i) << ", "); DEBUG(dbgs() << "SU(" << SU->NodeNum << "): "); @@ -108,14 +112,14 @@ ExactHazardRecognizer::HazardType ExactHazardRecognizer::getHazardType(SUnit *SU return Hazard; } } - + // Advance the cycle to the next stage. cycle += IS->getNextCycles(); } return NoHazard; } - + void ExactHazardRecognizer::EmitInstruction(SUnit *SU) { if (ItinData.isEmpty()) return; @@ -125,37 +129,52 @@ void ExactHazardRecognizer::EmitInstruction(SUnit *SU) { // Use the itinerary for the underlying instruction to reserve FU's // in the scoreboard at the appropriate future cycles. unsigned idx = SU->getInstr()->getDesc().getSchedClass(); - for (const InstrStage *IS = ItinData.beginStage(idx), + for (const InstrStage *IS = ItinData.beginStage(idx), *E = ItinData.endStage(idx); IS != E; ++IS) { // We must reserve one of the stage's units for every cycle the // stage is occupied. FIXME it would be more accurate to reserve // the same unit free in all the cycles. for (unsigned int i = 0; i < IS->getCycles(); ++i) { - assert(((cycle + i) < ScoreboardDepth) && + assert(((cycle + i) < RequiredScoreboard.getDepth()) && "Scoreboard depth exceeded!"); - - unsigned index = getFutureIndex(cycle + i); - unsigned freeUnits = IS->getUnits() & ~Scoreboard[index]; - + + unsigned freeUnits = IS->getUnits(); + switch (IS->getReservationKind()) { + default: + assert(0 && "Invalid FU reservation"); + case InstrStage::Required: + // Required FUs conflict with both reserved and required ones + freeUnits &= ~ReservedScoreboard[cycle + i]; + // FALLTHROUGH + case InstrStage::Reserved: + // Reserved FUs can conflict only with required ones. + freeUnits &= ~RequiredScoreboard[cycle + i]; + break; + } + // reduce to a single unit unsigned freeUnit = 0; do { freeUnit = freeUnits; freeUnits = freeUnit & (freeUnit - 1); } while (freeUnits); - + assert(freeUnit && "No function unit available!"); - Scoreboard[index] |= freeUnit; + if (IS->getReservationKind() == InstrStage::Required) + RequiredScoreboard[cycle + i] |= freeUnit; + else + ReservedScoreboard[cycle + i] |= freeUnit; } - + // Advance the cycle to the next stage. cycle += IS->getNextCycles(); } - - DEBUG(dumpScoreboard()); + + DEBUG(ReservedScoreboard.dump()); + DEBUG(RequiredScoreboard.dump()); } - + void ExactHazardRecognizer::AdvanceCycle() { - Scoreboard[ScoreboardHead] = 0; - ScoreboardHead = getFutureIndex(1); + ReservedScoreboard[0] = 0; ReservedScoreboard.advance(); + RequiredScoreboard[0] = 0; RequiredScoreboard.advance(); }