@@ -161,30 +161,36 @@ bool Scheduler::tryScheduleUntil(ArrayRef<Instruction *> Instrs) {
161161Scheduler::BndlSchedState
162162Scheduler::getBndlSchedState (ArrayRef<Instruction *> Instrs) const {
163163 assert (!Instrs.empty () && " Expected non-empty bundle" );
164- bool PartiallyScheduled = false ;
165- bool FullyScheduled = true ;
166- for (auto *I : Instrs) {
164+ auto *N0 = DAG.getNode (Instrs[0 ]);
165+ auto *SB0 = N0 != nullptr ? N0->getSchedBundle () : nullptr ;
166+ bool AllUnscheduled = SB0 == nullptr ;
167+ bool FullyScheduled = SB0 != nullptr && !SB0->isSingleton ();
168+ for (auto *I : drop_begin (Instrs)) {
167169 auto *N = DAG.getNode (I);
168- if (N != nullptr && N->scheduled ())
169- PartiallyScheduled = true ;
170- else
171- FullyScheduled = false ;
172- }
173- if (FullyScheduled) {
174- // If not all instrs in the bundle are in the same SchedBundle then this
175- // should be considered as partially-scheduled, because we will need to
176- // re-schedule.
177- SchedBundle *SB = DAG.getNode (Instrs[0 ])->getSchedBundle ();
178- assert (SB != nullptr && " FullyScheduled assumes that there is an SB!" );
179- if (any_of (drop_begin (Instrs), [this , SB](sandboxir::Value *SBV) {
180- return DAG.getNode (cast<sandboxir::Instruction>(SBV))
181- ->getSchedBundle () != SB;
182- }))
170+ auto *SB = N != nullptr ? N->getSchedBundle () : nullptr ;
171+ if (SB != nullptr ) {
172+ // We found a scheduled instr, so there is now way all are unscheduled.
173+ AllUnscheduled = false ;
174+ if (SB->isSingleton ()) {
175+ // We found an instruction in a temporarily scheduled singleton. There
176+ // is no way that all instructions are scheduled in the same bundle.
177+ FullyScheduled = false ;
178+ }
179+ }
180+
181+ if (SB != SB0) {
182+ // Either one of SB, SB0 is null, or they are in different bundles, so
183+ // Instrs are definitely not in the same vector bundle.
183184 FullyScheduled = false ;
185+ // One of SB, SB0 are in a vector bundle and they differ.
186+ if ((SB != nullptr && !SB->isSingleton ()) ||
187+ (SB0 != nullptr && !SB0->isSingleton ()))
188+ return BndlSchedState::AlreadyScheduled;
189+ }
184190 }
185- return FullyScheduled ? BndlSchedState::FullyScheduled
186- : PartiallyScheduled ? BndlSchedState::PartiallyOrDifferentlyScheduled
187- : BndlSchedState::NoneScheduled ;
191+ return AllUnscheduled ? BndlSchedState::NoneScheduled
192+ : FullyScheduled ? BndlSchedState::FullyScheduled
193+ : BndlSchedState::TemporarilyScheduled ;
188194}
189195
190196void Scheduler::trimSchedule (ArrayRef<Instruction *> Instrs) {
@@ -203,13 +209,14 @@ void Scheduler::trimSchedule(ArrayRef<Instruction *> Instrs) {
203209 //
204210 Instruction *TopI = &*ScheduleTopItOpt.value ();
205211 Instruction *LowestI = VecUtils::getLowest (Instrs);
206- // Destroy the schedule bundles from LowestI all the way to the top.
212+ // Destroy the singleton schedule bundles from LowestI all the way to the top.
207213 for (auto *I = LowestI, *E = TopI->getPrevNode (); I != E;
208214 I = I->getPrevNode ()) {
209215 auto *N = DAG.getNode (I);
210216 if (N == nullptr )
211217 continue ;
212- if (auto *SB = N->getSchedBundle ())
218+ auto *SB = N->getSchedBundle ();
219+ if (SB->isSingleton ())
213220 eraseBundle (SB);
214221 }
215222 // The DAG Nodes contain state like the number of UnscheduledSuccs and the
@@ -259,7 +266,12 @@ bool Scheduler::trySchedule(ArrayRef<Instruction *> Instrs) {
259266 case BndlSchedState::FullyScheduled:
260267 // Nothing to do.
261268 return true ;
262- case BndlSchedState::PartiallyOrDifferentlyScheduled:
269+ case BndlSchedState::AlreadyScheduled:
270+ // Instructions are part of a different vector schedule, so we can't
271+ // schedule \p Instrs in the same bundle (without destroying the existing
272+ // schedule).
273+ return false ;
274+ case BndlSchedState::TemporarilyScheduled:
263275 // If one or more instrs are already scheduled we need to destroy the
264276 // top-most part of the schedule that includes the instrs in the bundle and
265277 // re-schedule.
0 commit comments