@@ -108,6 +108,15 @@ FuncUnitWrapper &FuncUnitWrapper::operator|=(const FuncUnitWrapper &Other) {
108
108
return *this ;
109
109
}
110
110
111
+ FuncUnitWrapper &FuncUnitWrapper::operator ^=(const FuncUnitWrapper &Other) {
112
+ // XOR operation with the same FuncUnitWrapper will release resources.
113
+ Required ^= Other.Required ;
114
+ Reserved ^= Other.Reserved ;
115
+ Slots ^= Other.Slots ;
116
+ MemoryBanks ^= Other.MemoryBanks ;
117
+ return *this ;
118
+ }
119
+
111
120
bool FuncUnitWrapper::conflict (const FuncUnitWrapper &Other) const {
112
121
if ((Required & Other.Required ) != 0 || (Slots & Other.Slots ) != 0 ||
113
122
(MemoryBanks & Other.MemoryBanks ) != 0 ||
@@ -591,6 +600,18 @@ void AIEHazardRecognizer::emitInScoreboard(
591
600
TII->getMemoryCycles (SchedClass), DeltaCycles, FUDepthLimit);
592
601
}
593
602
603
+ void AIEHazardRecognizer::releaseFromScoreboard (
604
+ ResourceScoreboard<FuncUnitWrapper> &TheScoreboard, const MCInstrDesc &Desc,
605
+ MemoryBankBits MemoryBanks,
606
+ iterator_range<const MachineOperand *> MIOperands,
607
+ const MachineRegisterInfo &MRI, int DeltaCycles) const {
608
+ const unsigned SchedClass = TII->getSchedClass (Desc, MIOperands, MRI);
609
+ const SlotBits SlotSet =
610
+ getSlotSet (Desc, *TII->getFormatInterface (), IgnoreUnknownSlotSets);
611
+ releaseResources (TheScoreboard, ItinData, SchedClass, SlotSet, MemoryBanks,
612
+ TII->getMemoryCycles (SchedClass), DeltaCycles, FUDepthLimit);
613
+ }
614
+
594
615
void AIEHazardRecognizer::enterResources (
595
616
ResourceScoreboard<FuncUnitWrapper> &Scoreboard,
596
617
const InstrItineraryData *ItinData, unsigned SchedClass, SlotBits SlotSet,
@@ -632,6 +653,47 @@ void AIEHazardRecognizer::enterResources(
632
653
});
633
654
}
634
655
656
+ void AIEHazardRecognizer::releaseResources (
657
+ ResourceScoreboard<FuncUnitWrapper> &Scoreboard,
658
+ const InstrItineraryData *ItinData, unsigned SchedClass, SlotBits SlotSet,
659
+ MemoryBankBits MemoryBanks, SmallVector<int , 2 > MemoryAccessCycles,
660
+ int DeltaCycles, std::optional<int > FUDepthLimit) {
661
+ assert (Scoreboard.isValidDelta (DeltaCycles));
662
+
663
+ // Remove slot usage
664
+ FuncUnitWrapper EmissionCycle (/* Req=*/ 0 , /* Res=*/ 0 , SlotSet);
665
+ Scoreboard[DeltaCycles] ^= EmissionCycle;
666
+
667
+ // Remove memory bank usage
668
+ if (!MemoryAccessCycles.empty ()) {
669
+ FuncUnitWrapper MemoryBankAccessCycle (/* Req=*/ 0 , /* Res=*/ 0 , /* SlotSet=*/ 0 ,
670
+ MemoryBanks);
671
+ for (int Cycles : MemoryAccessCycles) {
672
+ Scoreboard[DeltaCycles + Cycles - 1 ] ^= MemoryBankAccessCycle;
673
+ }
674
+ }
675
+
676
+ int Cycle = DeltaCycles;
677
+ Scoreboard[Cycle].IssueCount --;
678
+ for (const InstrStage &IS : ItinData->getStages (SchedClass)) {
679
+ if (FUDepthLimit && (Cycle - DeltaCycles) >= *FUDepthLimit) {
680
+ break ;
681
+ }
682
+ const FuncUnitWrapper ResourceToRelease (IS);
683
+ for (unsigned int C = 0 ; C < IS.getCycles (); ++C) {
684
+ Scoreboard[Cycle + C] ^= ResourceToRelease;
685
+ }
686
+
687
+ // Advance the cycle to the next stage.
688
+ Cycle += IS.getNextCycles ();
689
+ }
690
+
691
+ LLVM_DEBUG ({
692
+ dbgs () << " Scoreboard after release resources:\n " ;
693
+ Scoreboard.dump ();
694
+ });
695
+ }
696
+
635
697
unsigned AIEHazardRecognizer::getPipelineDepth () const { return PipelineDepth; }
636
698
637
699
unsigned AIEHazardRecognizer::getMaxLatency () const { return MaxLatency; }
0 commit comments