From 66d2e8e6498a4b8321a47c2da74e74c51b77dabd Mon Sep 17 00:00:00 2001 From: Krishnam Tibrewala Date: Mon, 28 Oct 2024 11:09:20 -0700 Subject: [PATCH] [AIEX] NFC : Refactor hazard recognizer to track type of conflict --- llvm/lib/Target/AIE/AIEHazardRecognizer.cpp | 68 +++++++++++++++++---- llvm/lib/Target/AIE/AIEHazardRecognizer.h | 39 +++++++++++- 2 files changed, 91 insertions(+), 16 deletions(-) diff --git a/llvm/lib/Target/AIE/AIEHazardRecognizer.cpp b/llvm/lib/Target/AIE/AIEHazardRecognizer.cpp index 0b535ef7354a..8e2ad67d76cf 100644 --- a/llvm/lib/Target/AIE/AIEHazardRecognizer.cpp +++ b/llvm/lib/Target/AIE/AIEHazardRecognizer.cpp @@ -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 &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 &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); @@ -461,18 +477,42 @@ bool AIEHazardRecognizer::checkConflict( MemoryBanks, TII->getMemoryCycles(SchedClass), DeltaCycles, std::nullopt); } -bool AIEHazardRecognizer::checkConflict( +ConflictTypeBits AIEHazardRecognizer::checkConflict( const ResourceScoreboard &Scoreboard, const InstrItineraryData *ItinData, unsigned SchedClass, SlotBits SlotSet, MemoryBankBits MemoryBanks, SmallVector MemoryAccessCycles, int DeltaCycles, std::optional 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 &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 &MemoryAccessCycles, + const ResourceScoreboard &Scoreboard, int DeltaCycles, + unsigned MemoryBanks) { // Verify memory bank hazards if (!MemoryAccessCycles.empty()) { FuncUnitWrapper MemoryBankAccessCycle(/*Req=*/0, /*Res=*/0, /*SlotSet=*/0, @@ -488,15 +528,22 @@ 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 &Scoreboard, + const std::optional &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); @@ -504,18 +551,13 @@ bool AIEHazardRecognizer::checkConflict( 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; } diff --git a/llvm/lib/Target/AIE/AIEHazardRecognizer.h b/llvm/lib/Target/AIE/AIEHazardRecognizer.h index 2e712e7c5ae8..eff912d610bd 100644 --- a/llvm/lib/Target/AIE/AIEHazardRecognizer.h +++ b/llvm/lib/Target/AIE/AIEHazardRecognizer.h @@ -29,6 +29,7 @@ namespace llvm { class MachineInstr; +using ConflictTypeBits = uint64_t; void applyFormatOrdering(AIE::MachineBundle &Bundle, const VLIWFormat &Format, MachineInstr *BundleRoot, @@ -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. @@ -189,19 +197,44 @@ class AIEHazardRecognizer : public ScheduleHazardRecognizer { const MCInstrDesc &Desc, MemoryBankBits MemoryBanks, iterator_range MIOperands, const MachineRegisterInfo &MRI, int DeltaCycles) const; - bool checkConflict(const ResourceScoreboard &Scoreboard, - MachineInstr &MI, int DeltaCycles) const; + + ConflictTypeBits checkConflict(MachineInstr &MI, int DeltaCycles) const; + ConflictTypeBits + checkConflict(const ResourceScoreboard &Scoreboard, + MachineInstr &MI, int DeltaCycles) const; + + ConflictTypeBits + checkConflict(const ResourceScoreboard &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 &Scoreboard, const InstrItineraryData *ItinData, unsigned SchedClass, SlotBits SlotSet, MemoryBankBits MemoryBanks, SmallVector MemoryAccessCycles, int DeltaCycles, std::optional FUDepthLimit); + static bool + checkFormatConflict(const ResourceScoreboard &Scoreboard, + int DeltaCycles, unsigned SlotSet); + + static bool + checkMemoryBankConflict(const SmallVector &MemoryAccessCycles, + const ResourceScoreboard &Scoreboard, + int DeltaCycles, unsigned MemoryBanks); + + static bool + checkFUConflict(const InstrItineraryData *ItinData, unsigned SchedClass, + int DeltaCycles, + const ResourceScoreboard &Scoreboard, + const std::optional &FUDepthLimit); + static void enterResources(ResourceScoreboard &Scoreboard, const InstrItineraryData *ItinData, unsigned SchedClass, SlotBits SlotSet,