Index: include/llvm/Analysis/MemorySSAUpdater.h =================================================================== --- include/llvm/Analysis/MemorySSAUpdater.h +++ include/llvm/Analysis/MemorySSAUpdater.h @@ -120,6 +120,14 @@ /// |------| |------| void moveAllAfterMergeBlocks(BasicBlock *From, BasicBlock *To, Instruction *Start); + /// BasicBlock Old had New, an empty BasicBlock, added directly before it, + /// and the predecessors in Preds that used to point to Old, now point to + /// New. If New is the only predecessor, move Old's Phi, if present, to New. + /// Otherwise, add a new Phi in New with appropriate incoming values, and + /// update the incoming values in Old's Phi node too, if present. + void wireOldPredecessorsToNewImmediatePredecessor(BasicBlock *Old, + BasicBlock *New, + ArrayRefPreds); // The below are utility functions. Other than creation of accesses to pass // to insertDef, and removeAccess to remove accesses, you should generally Index: lib/Analysis/MemorySSAUpdater.cpp =================================================================== --- lib/Analysis/MemorySSAUpdater.cpp +++ lib/Analysis/MemorySSAUpdater.cpp @@ -494,6 +494,32 @@ return MA; } +void MemorySSAUpdater::wireOldPredecessorsToNewImmediatePredecessor(BasicBlock *Old, + BasicBlock *New, + ArrayRefPreds) { + assert(MSSA->getWritableBlockAccesses(New) == nullptr && + "Access list should be null for a new block."); + MemoryPhi *Phi = MSSA->getMemoryAccess(Old); + if (!Phi) + return; + if (pred_size(Old) == 1 && pred_size(New) == Preds.size()) + MSSA->moveTo(Phi, New, MemorySSA::Beginning); + else { + assert (Preds.size() > 0 && + "Must be moving at least one predecessor to the new immediate predecessor."); + MemoryPhi *NewPhi = MSSA->createMemoryPhi(New); + for (auto *Pred : Preds) { + int Idx = Phi->getBasicBlockIndex(Pred); + assert (Idx >=0 && "Predecessor must have an incoming value in Phi."); + NewPhi->addIncoming(Phi->getIncomingValue(Idx), Pred); + Phi->unorderedDeleteIncoming(Idx); + } + Phi->addIncoming(NewPhi, New); + if (onlySingleValue(NewPhi)) + removeMemoryAccess(NewPhi); + } +} + void MemorySSAUpdater::removeMemoryAccess(MemoryAccess *MA) { assert(!MSSA->isLiveOnEntryDef(MA) && "Trying to remove the live on entry def");