diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2021-06-13 19:31:46 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2021-06-13 19:37:19 +0000 |
commit | e8d8bef961a50d4dc22501cde4fb9fb0be1b2532 (patch) | |
tree | 94f04805f47bb7c59ae29690d8952b6074fff602 /contrib/llvm-project/llvm/lib/Analysis/MemorySSAUpdater.cpp | |
parent | bb130ff39747b94592cb26d71b7cb097b9a4ea6b (diff) | |
parent | b60736ec1405bb0a8dd40989f67ef4c93da068ab (diff) |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Analysis/MemorySSAUpdater.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Analysis/MemorySSAUpdater.cpp | 102 |
1 files changed, 65 insertions, 37 deletions
diff --git a/contrib/llvm-project/llvm/lib/Analysis/MemorySSAUpdater.cpp b/contrib/llvm-project/llvm/lib/Analysis/MemorySSAUpdater.cpp index 85af091772e7..99fa58b8872a 100644 --- a/contrib/llvm-project/llvm/lib/Analysis/MemorySSAUpdater.cpp +++ b/contrib/llvm-project/llvm/lib/Analysis/MemorySSAUpdater.cpp @@ -319,8 +319,7 @@ void MemorySSAUpdater::insertDef(MemoryDef *MD, bool RenameUses) { bool DefBeforeSameBlock = false; if (DefBefore->getBlock() == MD->getBlock() && !(isa<MemoryPhi>(DefBefore) && - std::find(InsertedPHIs.begin(), InsertedPHIs.end(), DefBefore) != - InsertedPHIs.end())) + llvm::is_contained(InsertedPHIs, DefBefore))) DefBeforeSameBlock = true; // There is a def before us, which means we can replace any store/phi uses @@ -343,6 +342,8 @@ void MemorySSAUpdater::insertDef(MemoryDef *MD, bool RenameUses) { SmallVector<WeakVH, 8> FixupList(InsertedPHIs.begin(), InsertedPHIs.end()); + SmallSet<WeakVH, 8> ExistingPhis; + // Remember the index where we may insert new phis. unsigned NewPhiIndex = InsertedPHIs.size(); if (!DefBeforeSameBlock) { @@ -383,6 +384,8 @@ void MemorySSAUpdater::insertDef(MemoryDef *MD, bool RenameUses) { if (!MPhi) { MPhi = MSSA->createMemoryPhi(BBIDF); NewInsertedPHIs.push_back(MPhi); + } else { + ExistingPhis.insert(MPhi); } // Add the phis created into the IDF blocks to NonOptPhis, so they are not // optimized out as trivial by the call to getPreviousDefFromEnd below. @@ -428,10 +431,11 @@ void MemorySSAUpdater::insertDef(MemoryDef *MD, bool RenameUses) { if (NewPhiSize) tryRemoveTrivialPhis(ArrayRef<WeakVH>(&InsertedPHIs[NewPhiIndex], NewPhiSize)); - // Now that all fixups are done, rename all uses if we are asked. - if (RenameUses) { + // Now that all fixups are done, rename all uses if we are asked. Skip + // renaming for defs in unreachable blocks. + BasicBlock *StartBlock = MD->getBlock(); + if (RenameUses && MSSA->getDomTree().getNode(StartBlock)) { SmallPtrSet<BasicBlock *, 16> Visited; - BasicBlock *StartBlock = MD->getBlock(); // We are guaranteed there is a def in the block, because we just got it // handed to us in this function. MemoryAccess *FirstDef = &*MSSA->getWritableBlockDefs(StartBlock)->begin(); @@ -448,6 +452,13 @@ void MemorySSAUpdater::insertDef(MemoryDef *MD, bool RenameUses) { if (Phi) MSSA->renamePass(Phi->getBlock(), nullptr, Visited); } + // Existing Phi blocks may need renaming too, if an access was previously + // optimized and the inserted Defs "covers" the Optimized value. + for (auto &MP : ExistingPhis) { + MemoryPhi *Phi = dyn_cast_or_null<MemoryPhi>(MP); + if (Phi) + MSSA->renamePass(Phi->getBlock(), nullptr, Visited); + } } } @@ -544,6 +555,20 @@ void MemorySSAUpdater::removeDuplicatePhiEdgesBetween(const BasicBlock *From, } } +/// If all arguments of a MemoryPHI are defined by the same incoming +/// argument, return that argument. +static MemoryAccess *onlySingleValue(MemoryPhi *MP) { + MemoryAccess *MA = nullptr; + + for (auto &Arg : MP->operands()) { + if (!MA) + MA = cast<MemoryAccess>(Arg); + else if (MA != Arg) + return nullptr; + } + return MA; +} + static MemoryAccess *getNewDefiningAccessForClone(MemoryAccess *MA, const ValueToValueMapTy &VMap, PhiToDefMap &MPhiMap, @@ -700,6 +725,10 @@ void MemorySSAUpdater::updateForClonedLoop(const LoopBlocksRPO &LoopBlocks, NewPhi->addIncoming(IncPhi, IncBB); } } + if (auto *SingleAccess = onlySingleValue(NewPhi)) { + MPhiMap[Phi] = SingleAccess; + removeMemoryAccess(NewPhi); + } }; auto ProcessBlock = [&](BasicBlock *BB) { @@ -782,27 +811,42 @@ void MemorySSAUpdater::updateExitBlocksForClonedLoop( } void MemorySSAUpdater::applyUpdates(ArrayRef<CFGUpdate> Updates, - DominatorTree &DT) { + DominatorTree &DT, bool UpdateDT) { SmallVector<CFGUpdate, 4> DeleteUpdates; + SmallVector<CFGUpdate, 4> RevDeleteUpdates; SmallVector<CFGUpdate, 4> InsertUpdates; for (auto &Update : Updates) { if (Update.getKind() == DT.Insert) InsertUpdates.push_back({DT.Insert, Update.getFrom(), Update.getTo()}); - else + else { DeleteUpdates.push_back({DT.Delete, Update.getFrom(), Update.getTo()}); + RevDeleteUpdates.push_back({DT.Insert, Update.getFrom(), Update.getTo()}); + } } if (!DeleteUpdates.empty()) { - // Update for inserted edges: use newDT and snapshot CFG as if deletes had - // not occurred. - // FIXME: This creates a new DT, so it's more expensive to do mix - // delete/inserts vs just inserts. We can do an incremental update on the DT - // to revert deletes, than re-delete the edges. Teaching DT to do this, is - // part of a pending cleanup. - DominatorTree NewDT(DT, DeleteUpdates); - GraphDiff<BasicBlock *> GD(DeleteUpdates, /*ReverseApplyUpdates=*/true); - applyInsertUpdates(InsertUpdates, NewDT, &GD); + if (!UpdateDT) { + SmallVector<CFGUpdate, 0> Empty; + // Deletes are reversed applied, because this CFGView is pretending the + // deletes did not happen yet, hence the edges still exist. + DT.applyUpdates(Empty, RevDeleteUpdates); + } else { + // Apply all updates, with the RevDeleteUpdates as PostCFGView. + DT.applyUpdates(Updates, RevDeleteUpdates); + } + + // Note: the MSSA update below doesn't distinguish between a GD with + // (RevDelete,false) and (Delete, true), but this matters for the DT + // updates above; for "children" purposes they are equivalent; but the + // updates themselves convey the desired update, used inside DT only. + GraphDiff<BasicBlock *> GD(RevDeleteUpdates); + applyInsertUpdates(InsertUpdates, DT, &GD); + // Update DT to redelete edges; this matches the real CFG so we can perform + // the standard update without a postview of the CFG. + DT.applyUpdates(DeleteUpdates); } else { + if (UpdateDT) + DT.applyUpdates(Updates); GraphDiff<BasicBlock *> GD; applyInsertUpdates(InsertUpdates, DT, &GD); } @@ -832,8 +876,8 @@ void MemorySSAUpdater::applyInsertUpdates(ArrayRef<CFGUpdate> Updates, // Check number of predecessors, we only care if there's more than one. unsigned Count = 0; BasicBlock *Pred = nullptr; - for (auto &Pair : children<GraphDiffInvBBPair>({GD, BB})) { - Pred = Pair.second; + for (auto *Pi : GD->template getChildren</*InverseEdge=*/true>(BB)) { + Pred = Pi; Count++; if (Count == 2) break; @@ -926,8 +970,7 @@ void MemorySSAUpdater::applyInsertUpdates(ArrayRef<CFGUpdate> Updates, auto *BB = BBPredPair.first; const auto &AddedBlockSet = BBPredPair.second.Added; auto &PrevBlockSet = BBPredPair.second.Prev; - for (auto &Pair : children<GraphDiffInvBBPair>({GD, BB})) { - BasicBlock *Pi = Pair.second; + for (auto *Pi : GD->template getChildren</*InverseEdge=*/true>(BB)) { if (!AddedBlockSet.count(Pi)) PrevBlockSet.insert(Pi); EdgeCountMap[{Pi, BB}]++; @@ -1078,10 +1121,8 @@ void MemorySSAUpdater::applyInsertUpdates(ArrayRef<CFGUpdate> Updates, for (unsigned I = 0, E = IDFPhi->getNumIncomingValues(); I < E; ++I) IDFPhi->setIncomingValue(I, GetLastDef(IDFPhi->getIncomingBlock(I))); } else { - for (auto &Pair : children<GraphDiffInvBBPair>({GD, BBIDF})) { - BasicBlock *Pi = Pair.second; + for (auto *Pi : GD->template getChildren</*InverseEdge=*/true>(BBIDF)) IDFPhi->addIncoming(GetLastDef(Pi), Pi); - } } } } @@ -1227,20 +1268,6 @@ void MemorySSAUpdater::moveAllAfterMergeBlocks(BasicBlock *From, BasicBlock *To, MPhi->setIncomingBlock(MPhi->getBasicBlockIndex(From), To); } -/// If all arguments of a MemoryPHI are defined by the same incoming -/// argument, return that argument. -static MemoryAccess *onlySingleValue(MemoryPhi *MP) { - MemoryAccess *MA = nullptr; - - for (auto &Arg : MP->operands()) { - if (!MA) - MA = cast<MemoryAccess>(Arg); - else if (MA != Arg) - return nullptr; - } - return MA; -} - void MemorySSAUpdater::wireOldPredecessorsToNewImmediatePredecessor( BasicBlock *Old, BasicBlock *New, ArrayRef<BasicBlock *> Preds, bool IdenticalEdgesWereMerged) { @@ -1314,6 +1341,7 @@ void MemorySSAUpdater::removeMemoryAccess(MemoryAccess *MA, bool OptimizePhis) { // Note: We assume MemorySSA is not used in metadata since it's not really // part of the IR. + assert(NewDefTarget != MA && "Going into an infinite loop"); while (!MA->use_empty()) { Use &U = *MA->use_begin(); if (auto *MUD = dyn_cast<MemoryUseOrDef>(U.getUser())) |