diff --git a/llvm/lib/Target/AIE/AIEHazardRecognizer.cpp b/llvm/lib/Target/AIE/AIEHazardRecognizer.cpp index 23ccbf519938..a17aa7ca1f6c 100644 --- a/llvm/lib/Target/AIE/AIEHazardRecognizer.cpp +++ b/llvm/lib/Target/AIE/AIEHazardRecognizer.cpp @@ -104,6 +104,15 @@ FuncUnitWrapper &FuncUnitWrapper::operator|=(const FuncUnitWrapper &Other) { return *this; } +FuncUnitWrapper &FuncUnitWrapper::operator^=(const FuncUnitWrapper &Other) { + // XOR operation with the same FuncUnitWrapper will release resources. + Required ^= Other.Required; + Reserved ^= Other.Reserved; + Slots ^= Other.Slots; + MemoryBanks ^= Other.MemoryBanks; + return *this; +} + bool FuncUnitWrapper::conflict(const FuncUnitWrapper &Other) const { if ((Required & Other.Required) != 0 || (Slots & Other.Slots) != 0 || (MemoryBanks & Other.MemoryBanks) != 0 || @@ -598,6 +607,18 @@ void AIEHazardRecognizer::emitInScoreboard( TII->getMemoryCycles(SchedClass), DeltaCycles, FUDepthLimit); } +void AIEHazardRecognizer::releaseFromScoreboard( + ResourceScoreboard &TheScoreboard, const MCInstrDesc &Desc, + MemoryBankBits MemoryBanks, + iterator_range MIOperands, + const MachineRegisterInfo &MRI, int DeltaCycles) const { + const unsigned SchedClass = TII->getSchedClass(Desc, MIOperands, MRI); + const SlotBits SlotSet = + getSlotSet(Desc, *TII->getFormatInterface(), IgnoreUnknownSlotSets); + releaseResources(TheScoreboard, ItinData, SchedClass, SlotSet, MemoryBanks, + TII->getMemoryCycles(SchedClass), DeltaCycles, FUDepthLimit); +} + void AIEHazardRecognizer::enterResources( ResourceScoreboard &Scoreboard, const InstrItineraryData *ItinData, unsigned SchedClass, SlotBits SlotSet, @@ -639,6 +660,47 @@ void AIEHazardRecognizer::enterResources( }); } +void AIEHazardRecognizer::releaseResources( + ResourceScoreboard &Scoreboard, + const InstrItineraryData *ItinData, unsigned SchedClass, SlotBits SlotSet, + MemoryBankBits MemoryBanks, SmallVector MemoryAccessCycles, + int DeltaCycles, std::optional FUDepthLimit) { + assert(Scoreboard.isValidDelta(DeltaCycles)); + + // Remove slot usage + FuncUnitWrapper EmissionCycle(/*Req=*/0, /*Res=*/0, SlotSet); + Scoreboard[DeltaCycles] ^= EmissionCycle; + + // Remove memory bank usage + if (!MemoryAccessCycles.empty()) { + FuncUnitWrapper MemoryBankAccessCycle(/*Req=*/0, /*Res=*/0, /*SlotSet=*/0, + MemoryBanks); + for (auto Cycles : MemoryAccessCycles) { + Scoreboard[DeltaCycles + Cycles - 1] ^= MemoryBankAccessCycle; + } + } + + int Cycle = DeltaCycles; + Scoreboard[Cycle].IssueCount--; + for (const InstrStage &IS : ItinData->getStages(SchedClass)) { + if (FUDepthLimit && (Cycle - DeltaCycles) >= *FUDepthLimit) { + break; + } + const FuncUnitWrapper ThisCycle(IS); + for (unsigned int C = 0; C < IS.getCycles(); ++C) { + Scoreboard[Cycle + C] ^= ThisCycle; + } + + // Advance the cycle to the next stage. + Cycle += IS.getNextCycles(); + } + + LLVM_DEBUG({ + dbgs() << "Scoreboard after release resources:\n"; + Scoreboard.dump(); + }); +} + unsigned AIEHazardRecognizer::getPipelineDepth() const { return PipelineDepth; } unsigned AIEHazardRecognizer::getMaxLatency() const { return MaxLatency; } diff --git a/llvm/lib/Target/AIE/AIEHazardRecognizer.h b/llvm/lib/Target/AIE/AIEHazardRecognizer.h index a001a4ac1b13..20f879f9dbee 100644 --- a/llvm/lib/Target/AIE/AIEHazardRecognizer.h +++ b/llvm/lib/Target/AIE/AIEHazardRecognizer.h @@ -85,6 +85,7 @@ class FuncUnitWrapper { void dump() const; FuncUnitWrapper &operator|=(const FuncUnitWrapper &Other); + FuncUnitWrapper &operator^=(const FuncUnitWrapper &Other); bool conflict(const FuncUnitWrapper &Other) const; }; @@ -152,6 +153,13 @@ class AIEHazardRecognizer : public ScheduleHazardRecognizer { iterator_range MIOperands, const MachineRegisterInfo &MRI, int DeltaCycles); + void releaseFromScoreboard(ResourceScoreboard &Scoreboard, + const MCInstrDesc &Desc, + MemoryBankBits MemoryBanks, + iterator_range MIOperands, + const MachineRegisterInfo &MRI, + int DeltaCycles) const; + /// Block all scoreboard resources at DeltaCycles void blockCycleInScoreboard(int DeltaCycle); @@ -233,6 +241,14 @@ class AIEHazardRecognizer : public ScheduleHazardRecognizer { SmallVector MemoryAccessCycles, int DeltaCycles, std::optional FUDepthLimit); + static void releaseResources(ResourceScoreboard &Scoreboard, + const InstrItineraryData *ItinData, + unsigned SchedClass, SlotBits SlotSet, + MemoryBankBits MemoryBanks, + SmallVector MemoryAccessCycles, + int DeltaCycles, + std::optional FUDepthLimit); + private: ResourceScoreboard Scoreboard; const AIEBaseInstrInfo *TII;