@@ -325,29 +325,31 @@ void DependencyGraph::createNewNodes(const Interval<Instruction> &NewInterval) {
325
325
setDefUseUnscheduledSuccs (NewInterval);
326
326
}
327
327
328
- MemDGNode *DependencyGraph::getMemDGNodeBefore (DGNode *N,
329
- bool IncludingN ) const {
328
+ MemDGNode *DependencyGraph::getMemDGNodeBefore (DGNode *N, bool IncludingN,
329
+ MemDGNode *SkipN ) const {
330
330
auto *I = N->getInstruction ();
331
331
for (auto *PrevI = IncludingN ? I : I->getPrevNode (); PrevI != nullptr ;
332
332
PrevI = PrevI->getPrevNode ()) {
333
333
auto *PrevN = getNodeOrNull (PrevI);
334
334
if (PrevN == nullptr )
335
335
return nullptr ;
336
- if (auto *PrevMemN = dyn_cast<MemDGNode>(PrevN))
336
+ auto *PrevMemN = dyn_cast<MemDGNode>(PrevN);
337
+ if (PrevMemN != nullptr && PrevMemN != SkipN)
337
338
return PrevMemN;
338
339
}
339
340
return nullptr ;
340
341
}
341
342
342
- MemDGNode *DependencyGraph::getMemDGNodeAfter (DGNode *N,
343
- bool IncludingN ) const {
343
+ MemDGNode *DependencyGraph::getMemDGNodeAfter (DGNode *N, bool IncludingN,
344
+ MemDGNode *SkipN ) const {
344
345
auto *I = N->getInstruction ();
345
346
for (auto *NextI = IncludingN ? I : I->getNextNode (); NextI != nullptr ;
346
347
NextI = NextI->getNextNode ()) {
347
348
auto *NextN = getNodeOrNull (NextI);
348
349
if (NextN == nullptr )
349
350
return nullptr ;
350
- if (auto *NextMemN = dyn_cast<MemDGNode>(NextN))
351
+ auto *NextMemN = dyn_cast<MemDGNode>(NextN);
352
+ if (NextMemN != nullptr && NextMemN != SkipN)
351
353
return NextMemN;
352
354
}
353
355
return nullptr ;
@@ -377,6 +379,20 @@ void DependencyGraph::notifyMoveInstr(Instruction *I, const BBIterator &To) {
377
379
!(To == BB->end () && std::next (I->getIterator ()) == BB->end ()) &&
378
380
" Should not have been called if destination is same as origin." );
379
381
382
+ // TODO: We can only handle fully internal movements within DAGInterval or at
383
+ // the borders, i.e., right before the top or right after the bottom.
384
+ assert (To.getNodeParent () == I->getParent () &&
385
+ " TODO: We don't support movement across BBs!" );
386
+ assert (
387
+ (To == std::next (DAGInterval.bottom ()->getIterator ()) ||
388
+ (To != BB->end () && std::next (To) == DAGInterval.top ()->getIterator ()) ||
389
+ (To != BB->end () && DAGInterval.contains (&*To))) &&
390
+ " TODO: To should be either within the DAGInterval or right "
391
+ " before/after it." );
392
+
393
+ // Make a copy of the DAGInterval before we update it.
394
+ auto OrigDAGInterval = DAGInterval;
395
+
380
396
// Maintain the DAGInterval.
381
397
DAGInterval.notifyMoveInstr (I, To);
382
398
@@ -389,23 +405,37 @@ void DependencyGraph::notifyMoveInstr(Instruction *I, const BBIterator &To) {
389
405
MemDGNode *MemN = dyn_cast<MemDGNode>(N);
390
406
if (MemN == nullptr )
391
407
return ;
392
- // First detach it from the existing chain.
408
+
409
+ // First safely detach it from the existing chain.
393
410
MemN->detachFromChain ();
411
+
394
412
// Now insert it back into the chain at the new location.
395
- if (To != BB->end ()) {
396
- DGNode *ToN = getNodeOrNull (&*To);
397
- if (ToN != nullptr ) {
398
- MemN->setPrevNode (getMemDGNodeBefore (ToN, /* IncludingN=*/ false ));
399
- MemN->setNextNode (getMemDGNodeAfter (ToN, /* IncludingN=*/ true ));
400
- }
413
+ //
414
+ // We won't always have a DGNode to insert before it. If `To` is BB->end() or
415
+ // if it points to an instr after DAGInterval.bottom() then we will have to
416
+ // find a node to insert *after*.
417
+ //
418
+ // BB: BB:
419
+ // I1 I1 ^
420
+ // I2 I2 | DAGInteval [I1 to I3]
421
+ // I3 I3 V
422
+ // I4 I4 <- `To` == right after DAGInterval
423
+ // <- `To` == BB->end()
424
+ //
425
+ if (To == BB->end () ||
426
+ To == std::next (OrigDAGInterval.bottom ()->getIterator ())) {
427
+ // If we don't have a node to insert before, find a node to insert after and
428
+ // update the chain.
429
+ DGNode *InsertAfterN = getNode (&*std::prev (To));
430
+ MemN->setPrevNode (
431
+ getMemDGNodeBefore (InsertAfterN, /* IncludingN=*/ true , /* SkipN=*/ MemN));
401
432
} else {
402
- // MemN becomes the last instruction in the BB.
403
- auto *TermN = getNodeOrNull (BB->getTerminator ());
404
- if (TermN != nullptr ) {
405
- MemN->setPrevNode (getMemDGNodeBefore (TermN, /* IncludingN=*/ false ));
406
- } else {
407
- // The terminator is outside the DAG interval so do nothing.
408
- }
433
+ // We have a node to insert before, so update the chain.
434
+ DGNode *BeforeToN = getNode (&*To);
435
+ MemN->setPrevNode (
436
+ getMemDGNodeBefore (BeforeToN, /* IncludingN=*/ false , /* SkipN=*/ MemN));
437
+ MemN->setNextNode (
438
+ getMemDGNodeAfter (BeforeToN, /* IncludingN=*/ true , /* SkipN=*/ MemN));
409
439
}
410
440
}
411
441
0 commit comments