mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-03-01 01:30:36 +00:00
Factor out scoreboard into separate class. This way we might have several different score boards.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@100644 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2eeeff8371
commit
1298948c5c
@ -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,25 @@ ExactHazardRecognizer(const InstrItineraryData &LItinData) :
|
||||
}
|
||||
}
|
||||
|
||||
Scoreboard = new unsigned[ScoreboardDepth];
|
||||
ScoreboardHead = 0;
|
||||
Scoreboard.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;
|
||||
Scoreboard.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 +86,10 @@ 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) < Scoreboard.getDepth()) &&
|
||||
"Scoreboard depth exceeded!");
|
||||
|
||||
unsigned index = getFutureIndex(cycle + i);
|
||||
unsigned freeUnits = IS->getUnits() & ~Scoreboard[index];
|
||||
|
||||
unsigned freeUnits = IS->getUnits() & ~Scoreboard[cycle + i];
|
||||
if (!freeUnits) {
|
||||
DEBUG(dbgs() << "*** Hazard in cycle " << (cycle + i) << ", ");
|
||||
DEBUG(dbgs() << "SU(" << SU->NodeNum << "): ");
|
||||
@ -108,14 +97,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;
|
||||
@ -131,31 +120,30 @@ void ExactHazardRecognizer::EmitInstruction(SUnit *SU) {
|
||||
// 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) < Scoreboard.getDepth()) &&
|
||||
"Scoreboard depth exceeded!");
|
||||
|
||||
unsigned index = getFutureIndex(cycle + i);
|
||||
unsigned freeUnits = IS->getUnits() & ~Scoreboard[index];
|
||||
|
||||
|
||||
unsigned freeUnits = IS->getUnits() & ~Scoreboard[cycle + i];
|
||||
|
||||
// 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;
|
||||
Scoreboard[cycle + i] |= freeUnit;
|
||||
}
|
||||
|
||||
|
||||
// Advance the cycle to the next stage.
|
||||
cycle += IS->getNextCycles();
|
||||
}
|
||||
|
||||
DEBUG(dumpScoreboard());
|
||||
|
||||
DEBUG(Scoreboard.dump());
|
||||
}
|
||||
|
||||
|
||||
void ExactHazardRecognizer::AdvanceCycle() {
|
||||
Scoreboard[ScoreboardHead] = 0;
|
||||
ScoreboardHead = getFutureIndex(1);
|
||||
Scoreboard[0] = 0;
|
||||
Scoreboard.advance();
|
||||
}
|
||||
|
@ -22,35 +22,59 @@
|
||||
|
||||
namespace llvm {
|
||||
class ExactHazardRecognizer : public ScheduleHazardRecognizer {
|
||||
// ScoreBoard to track function unit usage. ScoreBoard[0] is a
|
||||
// mask of the FUs in use in the cycle currently being
|
||||
// schedule. ScoreBoard[1] is a mask for the next cycle. The
|
||||
// ScoreBoard is used as a circular buffer with the current cycle
|
||||
// indicated by Head.
|
||||
class ScoreBoard {
|
||||
unsigned *Data;
|
||||
|
||||
// The maximum number of cycles monitored by the Scoreboard. This
|
||||
// value is determined based on the target itineraries to ensure
|
||||
// that all hazards can be tracked.
|
||||
size_t Depth;
|
||||
// Indices into the Scoreboard that represent the current cycle.
|
||||
size_t Head;
|
||||
public:
|
||||
ScoreBoard():Data(NULL), Depth(0), Head(0) { }
|
||||
~ScoreBoard() {
|
||||
delete[] Data;
|
||||
}
|
||||
|
||||
size_t getDepth() const { return Depth; }
|
||||
unsigned& operator[](size_t idx) const {
|
||||
assert(Depth && "ScoreBoard was not initialized properly!");
|
||||
|
||||
return Data[(Head + idx) % Depth];
|
||||
}
|
||||
|
||||
void reset(size_t d = 1) {
|
||||
if (Data == NULL) {
|
||||
Depth = d;
|
||||
Data = new unsigned[Depth];
|
||||
}
|
||||
|
||||
memset(Data, 0, Depth * sizeof(Data[0]));
|
||||
Head = 0;
|
||||
}
|
||||
|
||||
void advance() {
|
||||
Head = (Head + 1) % Depth;
|
||||
}
|
||||
|
||||
// Print the scoreboard.
|
||||
void dump() const;
|
||||
};
|
||||
|
||||
// Itinerary data for the target.
|
||||
const InstrItineraryData &ItinData;
|
||||
|
||||
// Scoreboard to track function unit usage. Scoreboard[0] is a
|
||||
// mask of the FUs in use in the cycle currently being
|
||||
// schedule. Scoreboard[1] is a mask for the next cycle. The
|
||||
// Scoreboard is used as a circular buffer with the current cycle
|
||||
// indicated by ScoreboardHead.
|
||||
unsigned *Scoreboard;
|
||||
|
||||
// The maximum number of cycles monitored by the Scoreboard. This
|
||||
// value is determined based on the target itineraries to ensure
|
||||
// that all hazards can be tracked.
|
||||
unsigned ScoreboardDepth;
|
||||
|
||||
// Indices into the Scoreboard that represent the current cycle.
|
||||
unsigned ScoreboardHead;
|
||||
|
||||
// Return the scoreboard index to use for 'offset' cycles in the
|
||||
// future. 'offset' of 0 returns ScoreboardHead.
|
||||
unsigned getFutureIndex(unsigned offset);
|
||||
|
||||
// Print the scoreboard.
|
||||
void dumpScoreboard();
|
||||
ScoreBoard Scoreboard;
|
||||
|
||||
public:
|
||||
ExactHazardRecognizer(const InstrItineraryData &ItinData);
|
||||
~ExactHazardRecognizer();
|
||||
|
||||
|
||||
virtual HazardType getHazardType(SUnit *SU);
|
||||
virtual void Reset();
|
||||
virtual void EmitInstruction(SUnit *SU);
|
||||
|
Loading…
x
Reference in New Issue
Block a user