@@ -80,6 +80,11 @@ static cl::opt<bool>
8080 InterBlockAlignment (" aie-interblock-alignment" , cl::init(true ),
8181 cl::desc(" Allow for alignment of successor blocks" ));
8282
83+ namespace {
84+ // A sentinel value to represent an unknown SUnit.
85+ const constexpr unsigned UnknownSUNum = ~0 ;
86+ } // namespace
87+
8388static AIEHazardRecognizer *getAIEHazardRecognizer (const SchedBoundary &Zone) {
8489 return static_cast <AIEHazardRecognizer *>(Zone.HazardRec );
8590}
@@ -771,6 +776,7 @@ void AIEPreRASchedStrategy::enterRegion(MachineBasicBlock *BB,
771776 CurMBB = BB;
772777 RegionBegin = Begin;
773778 RegionEnd = End;
779+ SUDelayerMap.resize (std::distance (Begin, End), UnknownSUNum);
774780}
775781
776782void AIEPreRASchedStrategy::leaveRegion (const SUnit &ExitSU) {
@@ -795,6 +801,7 @@ void AIEPreRASchedStrategy::leaveRegion(const SUnit &ExitSU) {
795801 CurMBB = nullptr ;
796802 RegionBegin = nullptr ;
797803 RegionEnd = nullptr ;
804+ SUDelayerMap.clear ();
798805}
799806
800807PressureDiff estimatePressureDiff (const SUnit &SU,
@@ -883,8 +890,34 @@ bool AIEPreRASchedStrategy::isAvailableNode(SUnit &SU, SchedBoundary &Zone,
883890
884891 // The node will likely cause a spill, only consider it schedule-able if
885892 // there is no pending node that can reduce the register pressure.
886- return findPressureReducer (WorstPC.getPSet (), Zone.Pending .elements (),
887- BotRPT) == nullptr ;
893+ if (const SUnit *PendingPressureReducer = findPressureReducer (
894+ WorstPC.getPSet (), Zone.Pending .elements (), BotRPT);
895+ PendingPressureReducer && canBeDelayed (SU, *PendingPressureReducer)) {
896+ LLVM_DEBUG (dbgs () << " ** Delaying SU(" << SU.NodeNum << " ): Waiting for SU("
897+ << PendingPressureReducer->NodeNum << " )\n " );
898+
899+ // Keep track of PendingPressureReducer to avoid cycles of SUs
900+ // delaying each other.
901+ SUDelayerMap[SU.NodeNum ] = PendingPressureReducer->NodeNum ;
902+ return false ;
903+ }
904+
905+ // Can't prove a pending SU will help reduce reg pressure, keep as available.
906+ return true ;
907+ }
908+
909+ bool AIEPreRASchedStrategy::canBeDelayed (const SUnit &DelayedSU,
910+ const SUnit &Delayer) const {
911+ std::function<bool (unsigned )> Impl = [&](unsigned SUNum) {
912+ if (SUNum == UnknownSUNum)
913+ return true ;
914+ if (SUNum == DelayedSU.NodeNum )
915+ return false ;
916+ return Impl (SUDelayerMap[SUNum]);
917+ };
918+ // If SU is delayed by another instruction that is eventually waiting on SU
919+ // itself, do not keep delaying SU otherwise this creates an infinite loop.
920+ return Impl (Delayer.NodeNum );
888921}
889922
890923bool AIEPreRASchedStrategy::tryCandidate (SchedCandidate &Cand,
0 commit comments