@@ -315,7 +315,25 @@ std::unique_ptr<GenericCombiner> OffsetCombiner::clone() const {
315
315
316
316
std::optional<std::pair<std::vector<SUnit *>, std::vector<SUnit *>>>
317
317
OffsetCombiner::getInstructionsToMove (const AIE::DataDependenceHelper &DAG) {
318
- return {{/* MoveUp*/ {}, /* MoveDown*/ {}}};
318
+ auto *PtrAdd = getPtrInc ();
319
+ if (!getImm (*PtrAdd, *MRI)) {
320
+ // / Offset is not an immediate and the OffsetCombiner is not eligible for
321
+ // / reordering.
322
+ // Since the Offset already dominates the MemoryInstruction (where the
323
+ // insertion happens), no checks have to be performed.
324
+ return {{/* MoveUp=*/ {}, /* MoveDown=*/ {}}};
325
+ }
326
+
327
+ auto *SUnitPtrAdd = DAG.getSUnit (PtrAdd);
328
+ if (!SUnitPtrAdd) {
329
+ // / PtrAdd is an Immediate but it is outside of the MBB, so it already
330
+ // / dominates the MemoryInstruction. No checks have to be performed.
331
+ return {{/* MoveUp=*/ {}, /* MoveDown=*/ {}}};
332
+ }
333
+
334
+ // / Immediate Offset can be a reordering Candidate. Therefore, track Immediate
335
+ // / Offset, so it can be moved in case of a reordering.
336
+ return {{/* MoveUp=*/ {SUnitPtrAdd}, /* MoveDown=*/ {}}};
319
337
}
320
338
321
339
void OffsetCombiner::adjustGain (const MachineDominatorTree &MDT) {
@@ -335,7 +353,7 @@ void OffsetCombiner::adjustGain(const MachineDominatorTree &MDT) {
335
353
Gain.setPtrMod (0 );
336
354
}
337
355
338
- std::optional<APInt> ImmOffset = getImm (*PtrAdd, *MRI);
356
+ ImmOffset = getImm (*PtrAdd, *MRI);
339
357
if (!ImmOffset)
340
358
return ;
341
359
@@ -363,6 +381,58 @@ std::optional<unsigned> OffsetCombiner::getOpCode(MachineInstr *PtrInc,
363
381
return TII->getOffsetMemOpcode (MemI->getOpcode ());
364
382
}
365
383
384
+ bool OffsetCombiner::canReorder () const { return ImmOffset.has_value (); }
385
+
386
+ bool OffsetCombiner::isReorderCandidate (
387
+ const GenericCombiner *PostIncCombiner) const {
388
+ auto GetInputPtr = [&](const MachineInstr *PtrMod) {
389
+ auto InputPtrIdx = PtrModSupport.getInputPtrIdx (*PtrMod);
390
+ assert (InputPtrIdx);
391
+ return PtrMod->getOperand (*InputPtrIdx);
392
+ };
393
+
394
+ const PointerModifierCombiner *PtrModCombiner =
395
+ static_cast <const PointerModifierCombiner *>(PostIncCombiner);
396
+ if (!PtrModCombiner->isPostInc ())
397
+ return false ;
398
+
399
+ // only allow loads to be reordered
400
+ if (getMemI ()->mayStore () || PtrModCombiner->getMemI ()->mayStore ())
401
+ return false ;
402
+
403
+ // Same MBB check
404
+ auto *PtrAdd = getPtrInc ();
405
+ auto *PostIncPtrMod = PtrModCombiner->getPtrInc ();
406
+ if (PtrAdd->getParent () != PostIncPtrMod->getParent ())
407
+ return false ;
408
+
409
+ // Same Input Ptr Check
410
+ auto InputPtr = GetInputPtr (PtrAdd);
411
+ auto PostIncInputPtr = GetInputPtr (PostIncPtrMod);
412
+ if (!InputPtr.isIdenticalTo (PostIncInputPtr))
413
+ return false ;
414
+
415
+ // Check if Store Instruction of Offset dominates PostInc
416
+ auto *MemI = getMemI ();
417
+ if (MemI->mayStore ()) {
418
+ auto Source = MemI->getOperand (0 );
419
+ assert (Source.isReg ());
420
+ auto *DefSource = MRI->getUniqueVRegDef (Source.getReg ());
421
+ if (!DefSource)
422
+ return false ;
423
+ auto *DefSUnit = DAG->getSUnit (DefSource);
424
+ if (DefSUnit &&
425
+ DefSUnit->NodeNum > PostIncCombiner->InsertionPointNodeNum ) {
426
+ // Source of Offset-Store would be after the new InsertionPoint and thus
427
+ // generate invalid mir
428
+ return false ;
429
+ }
430
+ }
431
+
432
+ // OffsetCombiner occurs after PostIncCombiner
433
+ return InsertionPointNodeNum > PostIncCombiner->InsertionPointNodeNum ;
434
+ }
435
+
366
436
// -------------------------- PostIncCombiner --------------------------------//
367
437
368
438
bool PostIncCombiner::isCombineCandidate (MachineInstr &MemI,
0 commit comments