mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-01 12:24:24 +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:
@ -29,7 +29,7 @@ ExactHazardRecognizer(const InstrItineraryData &LItinData) :
|
|||||||
// Determine the maximum depth of any itinerary. This determines the
|
// Determine the maximum depth of any itinerary. This determines the
|
||||||
// depth of the scoreboard. We always make the scoreboard at least 1
|
// depth of the scoreboard. We always make the scoreboard at least 1
|
||||||
// cycle deep to avoid dealing with the boundary condition.
|
// cycle deep to avoid dealing with the boundary condition.
|
||||||
ScoreboardDepth = 1;
|
unsigned ScoreboardDepth = 1;
|
||||||
if (!ItinData.isEmpty()) {
|
if (!ItinData.isEmpty()) {
|
||||||
for (unsigned idx = 0; ; ++idx) {
|
for (unsigned idx = 0; ; ++idx) {
|
||||||
if (ItinData.isEndMarker(idx))
|
if (ItinData.isEndMarker(idx))
|
||||||
@ -45,35 +45,25 @@ ExactHazardRecognizer(const InstrItineraryData &LItinData) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Scoreboard = new unsigned[ScoreboardDepth];
|
Scoreboard.reset(ScoreboardDepth);
|
||||||
ScoreboardHead = 0;
|
|
||||||
|
|
||||||
DEBUG(dbgs() << "Using exact hazard recognizer: ScoreboardDepth = "
|
DEBUG(dbgs() << "Using exact hazard recognizer: ScoreboardDepth = "
|
||||||
<< ScoreboardDepth << '\n');
|
<< ScoreboardDepth << '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
ExactHazardRecognizer::~ExactHazardRecognizer() {
|
|
||||||
delete [] Scoreboard;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExactHazardRecognizer::Reset() {
|
void ExactHazardRecognizer::Reset() {
|
||||||
memset(Scoreboard, 0, ScoreboardDepth * sizeof(unsigned));
|
Scoreboard.reset();
|
||||||
ScoreboardHead = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned ExactHazardRecognizer::getFutureIndex(unsigned offset) {
|
void ExactHazardRecognizer::ScoreBoard::dump() const {
|
||||||
return (ScoreboardHead + offset) % ScoreboardDepth;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExactHazardRecognizer::dumpScoreboard() {
|
|
||||||
dbgs() << "Scoreboard:\n";
|
dbgs() << "Scoreboard:\n";
|
||||||
|
|
||||||
unsigned last = ScoreboardDepth - 1;
|
unsigned last = Depth - 1;
|
||||||
while ((last > 0) && (Scoreboard[getFutureIndex(last)] == 0))
|
while ((last > 0) && ((*this)[last] == 0))
|
||||||
last--;
|
last--;
|
||||||
|
|
||||||
for (unsigned i = 0; i <= last; i++) {
|
for (unsigned i = 0; i <= last; i++) {
|
||||||
unsigned FUs = Scoreboard[getFutureIndex(i)];
|
unsigned FUs = (*this)[i];
|
||||||
dbgs() << "\t";
|
dbgs() << "\t";
|
||||||
for (int j = 31; j >= 0; j--)
|
for (int j = 31; j >= 0; j--)
|
||||||
dbgs() << ((FUs & (1 << j)) ? '1' : '0');
|
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
|
// stage is occupied. FIXME it would be more accurate to find the
|
||||||
// same unit free in all the cycles.
|
// same unit free in all the cycles.
|
||||||
for (unsigned int i = 0; i < IS->getCycles(); ++i) {
|
for (unsigned int i = 0; i < IS->getCycles(); ++i) {
|
||||||
assert(((cycle + i) < ScoreboardDepth) &&
|
assert(((cycle + i) < Scoreboard.getDepth()) &&
|
||||||
"Scoreboard depth exceeded!");
|
"Scoreboard depth exceeded!");
|
||||||
|
|
||||||
unsigned index = getFutureIndex(cycle + i);
|
unsigned freeUnits = IS->getUnits() & ~Scoreboard[cycle + i];
|
||||||
unsigned freeUnits = IS->getUnits() & ~Scoreboard[index];
|
|
||||||
if (!freeUnits) {
|
if (!freeUnits) {
|
||||||
DEBUG(dbgs() << "*** Hazard in cycle " << (cycle + i) << ", ");
|
DEBUG(dbgs() << "*** Hazard in cycle " << (cycle + i) << ", ");
|
||||||
DEBUG(dbgs() << "SU(" << SU->NodeNum << "): ");
|
DEBUG(dbgs() << "SU(" << SU->NodeNum << "): ");
|
||||||
@ -108,14 +97,14 @@ ExactHazardRecognizer::HazardType ExactHazardRecognizer::getHazardType(SUnit *SU
|
|||||||
return Hazard;
|
return Hazard;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Advance the cycle to the next stage.
|
// Advance the cycle to the next stage.
|
||||||
cycle += IS->getNextCycles();
|
cycle += IS->getNextCycles();
|
||||||
}
|
}
|
||||||
|
|
||||||
return NoHazard;
|
return NoHazard;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExactHazardRecognizer::EmitInstruction(SUnit *SU) {
|
void ExactHazardRecognizer::EmitInstruction(SUnit *SU) {
|
||||||
if (ItinData.isEmpty())
|
if (ItinData.isEmpty())
|
||||||
return;
|
return;
|
||||||
@ -131,31 +120,30 @@ void ExactHazardRecognizer::EmitInstruction(SUnit *SU) {
|
|||||||
// stage is occupied. FIXME it would be more accurate to reserve
|
// stage is occupied. FIXME it would be more accurate to reserve
|
||||||
// the same unit free in all the cycles.
|
// the same unit free in all the cycles.
|
||||||
for (unsigned int i = 0; i < IS->getCycles(); ++i) {
|
for (unsigned int i = 0; i < IS->getCycles(); ++i) {
|
||||||
assert(((cycle + i) < ScoreboardDepth) &&
|
assert(((cycle + i) < Scoreboard.getDepth()) &&
|
||||||
"Scoreboard depth exceeded!");
|
"Scoreboard depth exceeded!");
|
||||||
|
|
||||||
unsigned index = getFutureIndex(cycle + i);
|
unsigned freeUnits = IS->getUnits() & ~Scoreboard[cycle + i];
|
||||||
unsigned freeUnits = IS->getUnits() & ~Scoreboard[index];
|
|
||||||
|
|
||||||
// reduce to a single unit
|
// reduce to a single unit
|
||||||
unsigned freeUnit = 0;
|
unsigned freeUnit = 0;
|
||||||
do {
|
do {
|
||||||
freeUnit = freeUnits;
|
freeUnit = freeUnits;
|
||||||
freeUnits = freeUnit & (freeUnit - 1);
|
freeUnits = freeUnit & (freeUnit - 1);
|
||||||
} while (freeUnits);
|
} while (freeUnits);
|
||||||
|
|
||||||
assert(freeUnit && "No function unit available!");
|
assert(freeUnit && "No function unit available!");
|
||||||
Scoreboard[index] |= freeUnit;
|
Scoreboard[cycle + i] |= freeUnit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Advance the cycle to the next stage.
|
// Advance the cycle to the next stage.
|
||||||
cycle += IS->getNextCycles();
|
cycle += IS->getNextCycles();
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(dumpScoreboard());
|
DEBUG(Scoreboard.dump());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExactHazardRecognizer::AdvanceCycle() {
|
void ExactHazardRecognizer::AdvanceCycle() {
|
||||||
Scoreboard[ScoreboardHead] = 0;
|
Scoreboard[0] = 0;
|
||||||
ScoreboardHead = getFutureIndex(1);
|
Scoreboard.advance();
|
||||||
}
|
}
|
||||||
|
@ -22,35 +22,59 @@
|
|||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
class ExactHazardRecognizer : public ScheduleHazardRecognizer {
|
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.
|
// Itinerary data for the target.
|
||||||
const InstrItineraryData &ItinData;
|
const InstrItineraryData &ItinData;
|
||||||
|
|
||||||
// Scoreboard to track function unit usage. Scoreboard[0] is a
|
ScoreBoard Scoreboard;
|
||||||
// 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();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ExactHazardRecognizer(const InstrItineraryData &ItinData);
|
ExactHazardRecognizer(const InstrItineraryData &ItinData);
|
||||||
~ExactHazardRecognizer();
|
|
||||||
|
|
||||||
virtual HazardType getHazardType(SUnit *SU);
|
virtual HazardType getHazardType(SUnit *SU);
|
||||||
virtual void Reset();
|
virtual void Reset();
|
||||||
virtual void EmitInstruction(SUnit *SU);
|
virtual void EmitInstruction(SUnit *SU);
|
||||||
|
Reference in New Issue
Block a user