Skip to content

Commit

Permalink
[AIEX] NFC : Refactor hazard recognizer to track type of conflict
Browse files Browse the repository at this point in the history
  • Loading branch information
krishnamtibrewala committed Oct 31, 2024
1 parent 4c793d4 commit 66d2e8e
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 16 deletions.
68 changes: 55 additions & 13 deletions llvm/lib/Target/AIE/AIEHazardRecognizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -448,10 +448,26 @@ ScheduleHazardRecognizer::HazardType AIEHazardRecognizer::getHazardType(
FUDepthLimit));
}

bool AIEHazardRecognizer::checkConflict(
ConflictTypeBits AIEHazardRecognizer::checkConflict(MachineInstr &MI,
int DeltaCycles) const {
return checkConflict(Scoreboard, MI, DeltaCycles);
}

ConflictTypeBits AIEHazardRecognizer::checkConflict(
const ResourceScoreboard<FuncUnitWrapper> &Scoreboard, MachineInstr &MI,
int DeltaCycles) const {
const MCInstrDesc &Desc = MI.getDesc();
return checkConflict(Scoreboard, MI, MI.getDesc(), DeltaCycles);
}

ConflictTypeBits AIEHazardRecognizer::checkConflict(MachineInstr &MI,
const MCInstrDesc &Desc,
int DeltaCycles) {
return checkConflict(Scoreboard, MI, Desc, DeltaCycles);
}

ConflictTypeBits AIEHazardRecognizer::checkConflict(
const ResourceScoreboard<FuncUnitWrapper> &Scoreboard, MachineInstr &MI,
const MCInstrDesc &Desc, int DeltaCycles) const {
const unsigned SchedClass =
TII->getSchedClass(Desc, MI.operands(), MI.getMF()->getRegInfo());
const MemoryBankBits MemoryBanks = getMemoryBanks(&MI);
Expand All @@ -461,18 +477,42 @@ bool AIEHazardRecognizer::checkConflict(
MemoryBanks, TII->getMemoryCycles(SchedClass), DeltaCycles, std::nullopt);
}

bool AIEHazardRecognizer::checkConflict(
ConflictTypeBits AIEHazardRecognizer::checkConflict(
const ResourceScoreboard<FuncUnitWrapper> &Scoreboard,
const InstrItineraryData *ItinData, unsigned SchedClass, SlotBits SlotSet,
MemoryBankBits MemoryBanks, SmallVector<int, 2> MemoryAccessCycles,
int DeltaCycles, std::optional<int> FUDepthLimit) {
assert(Scoreboard.isValidDelta(DeltaCycles));
ConflictTypeBits Conflict = ConflictType::NoConflict;

if (checkFormatConflict(Scoreboard, DeltaCycles, SlotSet))
Conflict |= ConflictType::Format;

if (checkMemoryBankConflict(MemoryAccessCycles, Scoreboard, DeltaCycles,
MemoryBanks))
Conflict |= ConflictType::MemoryBank;

if (checkFUConflict(ItinData, SchedClass, DeltaCycles, Scoreboard,
FUDepthLimit))
Conflict |= ConflictType::FU;

return Conflict;
}

// Return true if there is a conflict due to format.
bool AIEHazardRecognizer::checkFormatConflict(
const ResourceScoreboard<FuncUnitWrapper> &Scoreboard, int DeltaCycles,
unsigned SlotSet) {
// Verify format hazards
FuncUnitWrapper EmissionCycle(/*Req=*/0, /*Res=*/0, SlotSet);
if (EmissionCycle.conflict(Scoreboard[DeltaCycles]))
return true;
return EmissionCycle.conflict(Scoreboard[DeltaCycles]);
}

// Return true if there is a conflict due to memory banks.
bool AIEHazardRecognizer::checkMemoryBankConflict(
const SmallVector<int, 2> &MemoryAccessCycles,
const ResourceScoreboard<FuncUnitWrapper> &Scoreboard, int DeltaCycles,
unsigned MemoryBanks) {
// Verify memory bank hazards
if (!MemoryAccessCycles.empty()) {
FuncUnitWrapper MemoryBankAccessCycle(/*Req=*/0, /*Res=*/0, /*SlotSet=*/0,
Expand All @@ -488,34 +528,36 @@ bool AIEHazardRecognizer::checkConflict(
}
}
}
return false;
}

// Return true if there is a conflict in the functional units.
bool AIEHazardRecognizer::checkFUConflict(
const InstrItineraryData *ItinData, unsigned SchedClass, int DeltaCycles,
const ResourceScoreboard<FuncUnitWrapper> &Scoreboard,
const std::optional<int> &FUDepthLimit) {

// Note that Delta will be negative for bottom-up scheduling.
// Cycle is 'our' cycle at which each stage of the itinerary starts.
// It gets updated by the increment from the InstrStage.
int Cycle = DeltaCycles;
for (const InstrStage &IS : ItinData->getStages(SchedClass)) {
if (FUDepthLimit && (Cycle - DeltaCycles) >= *FUDepthLimit) {
if (FUDepthLimit && (Cycle - DeltaCycles) >= *FUDepthLimit)
break;
}
// Check availability of this stage's resources for the specified number
// of cycles
const FuncUnitWrapper ThisCycle(IS);
for (unsigned int C = 0; C < IS.getCycles(); ++C) {
int StageCycle = Cycle + (int)C;
assert(StageCycle < Scoreboard.getDepth());

if (ThisCycle.conflict(Scoreboard[StageCycle])) {
LLVM_DEBUG(dbgs() << "*** Hazard in cycle=" << StageCycle
<< " EC=" << StageCycle - DeltaCycles << ":\n";
ThisCycle.dump(); dbgs() << "\n");
if (ThisCycle.conflict(Scoreboard[StageCycle]))
return true;
}
}

// Advance the cycle to the next stage.
Cycle += IS.getNextCycles();
}

return false;
}

Expand Down
39 changes: 36 additions & 3 deletions llvm/lib/Target/AIE/AIEHazardRecognizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
namespace llvm {

class MachineInstr;
using ConflictTypeBits = uint64_t;

void applyFormatOrdering(AIE::MachineBundle &Bundle, const VLIWFormat &Format,
MachineInstr *BundleRoot,
Expand Down Expand Up @@ -99,6 +100,13 @@ class AIEHazardRecognizer : public ScheduleHazardRecognizer {
void computeMaxLatency();

public:
enum ConflictType {
NoConflict = 0b000,
Format = 0b001,
MemoryBank = 0b010,
FU = 0b100,
};

/// ScoreboardDepth can be used to speficy a fixed depth without querying the
/// scheduling model. This is mostly used for testing, for other cases we
/// should trust the instruction itineraries.
Expand Down Expand Up @@ -189,19 +197,44 @@ class AIEHazardRecognizer : public ScheduleHazardRecognizer {
const MCInstrDesc &Desc, MemoryBankBits MemoryBanks,
iterator_range<const MachineOperand *> MIOperands,
const MachineRegisterInfo &MRI, int DeltaCycles) const;
bool checkConflict(const ResourceScoreboard<FuncUnitWrapper> &Scoreboard,
MachineInstr &MI, int DeltaCycles) const;

ConflictTypeBits checkConflict(MachineInstr &MI, int DeltaCycles) const;
ConflictTypeBits
checkConflict(const ResourceScoreboard<FuncUnitWrapper> &Scoreboard,
MachineInstr &MI, int DeltaCycles) const;

ConflictTypeBits
checkConflict(const ResourceScoreboard<FuncUnitWrapper> &Scoreboard,
MachineInstr &MI, const MCInstrDesc &Desc,
int DeltaCycles) const;
ConflictTypeBits checkConflict(MachineInstr &MI, const MCInstrDesc &Desc,
int DeltaCycles);

protected:
ScheduleHazardRecognizer::HazardType getHazardType(const MCInstrDesc &Desc,
int DeltaCycles);
static bool
static ConflictTypeBits
checkConflict(const ResourceScoreboard<FuncUnitWrapper> &Scoreboard,
const InstrItineraryData *ItinData, unsigned SchedClass,
SlotBits SlotSet, MemoryBankBits MemoryBanks,
SmallVector<int, 2> MemoryAccessCycles, int DeltaCycles,
std::optional<int> FUDepthLimit);

static bool
checkFormatConflict(const ResourceScoreboard<FuncUnitWrapper> &Scoreboard,
int DeltaCycles, unsigned SlotSet);

static bool
checkMemoryBankConflict(const SmallVector<int, 2> &MemoryAccessCycles,
const ResourceScoreboard<FuncUnitWrapper> &Scoreboard,
int DeltaCycles, unsigned MemoryBanks);

static bool
checkFUConflict(const InstrItineraryData *ItinData, unsigned SchedClass,
int DeltaCycles,
const ResourceScoreboard<FuncUnitWrapper> &Scoreboard,
const std::optional<int> &FUDepthLimit);

static void enterResources(ResourceScoreboard<FuncUnitWrapper> &Scoreboard,
const InstrItineraryData *ItinData,
unsigned SchedClass, SlotBits SlotSet,
Expand Down

0 comments on commit 66d2e8e

Please sign in to comment.