From: Alina Sbirlea Date: Wed, 2 Oct 2019 18:42:33 +0000 (+0000) Subject: [MemorySSA] Update Phi creation when inserting a Def. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c1679d6c229dca9bf7b6a7e98256ee39967339df;p=llvm [MemorySSA] Update Phi creation when inserting a Def. MemoryPhis should be added in the IDF of the blocks newly gaining Defs. This includes the blocks that gained a Phi and the block gaining a Def, if the block did not have one before. Resolves PR43427. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@373505 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/MemorySSAUpdater.cpp b/lib/Analysis/MemorySSAUpdater.cpp index 6018968c199..d103c3a8b83 100644 --- a/lib/Analysis/MemorySSAUpdater.cpp +++ b/lib/Analysis/MemorySSAUpdater.cpp @@ -347,51 +347,54 @@ void MemorySSAUpdater::insertDef(MemoryDef *MD, bool RenameUses) { // If this is the first def in the block and this insert is in an arbitrary // place, compute IDF and place phis. + SmallPtrSet DefiningBlocks; + + // If this is the last Def in the block, also compute IDF based on MD, since + // this may a new Def added, and we may need additional Phis. auto Iter = MD->getDefsIterator(); ++Iter; auto IterEnd = MSSA->getBlockDefs(MD->getBlock())->end(); - if (Iter == IterEnd) { - SmallPtrSet DefiningBlocks; + if (Iter == IterEnd) DefiningBlocks.insert(MD->getBlock()); - for (const auto &VH : InsertedPHIs) - if (const auto *RealPHI = cast_or_null(VH)) - DefiningBlocks.insert(RealPHI->getBlock()); - ForwardIDFCalculator IDFs(*MSSA->DT); - SmallVector IDFBlocks; - IDFs.setDefiningBlocks(DefiningBlocks); - IDFs.calculate(IDFBlocks); - SmallVector, 4> NewInsertedPHIs; - for (auto *BBIDF : IDFBlocks) { - auto *MPhi = MSSA->getMemoryAccess(BBIDF); - if (!MPhi) { - MPhi = MSSA->createMemoryPhi(BBIDF); - NewInsertedPHIs.push_back(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. Once they are complete, all these Phis are added to the - // FixupList, and removed from NonOptPhis inside fixupDefs(). Existing - // Phis in IDF may need fixing as well, and potentially be trivial - // before this insertion, hence add all IDF Phis. See PR43044. - NonOptPhis.insert(MPhi); + + for (const auto &VH : InsertedPHIs) + if (const auto *RealPHI = cast_or_null(VH)) + DefiningBlocks.insert(RealPHI->getBlock()); + ForwardIDFCalculator IDFs(*MSSA->DT); + SmallVector IDFBlocks; + IDFs.setDefiningBlocks(DefiningBlocks); + IDFs.calculate(IDFBlocks); + SmallVector, 4> NewInsertedPHIs; + for (auto *BBIDF : IDFBlocks) { + auto *MPhi = MSSA->getMemoryAccess(BBIDF); + if (!MPhi) { + MPhi = MSSA->createMemoryPhi(BBIDF); + NewInsertedPHIs.push_back(MPhi); } - for (auto &MPhi : NewInsertedPHIs) { - auto *BBIDF = MPhi->getBlock(); - for (auto *Pred : predecessors(BBIDF)) { - DenseMap> CachedPreviousDef; - MPhi->addIncoming(getPreviousDefFromEnd(Pred, CachedPreviousDef), - Pred); - } + // Add the phis created into the IDF blocks to NonOptPhis, so they are not + // optimized out as trivial by the call to getPreviousDefFromEnd below. + // Once they are complete, all these Phis are added to the FixupList, and + // removed from NonOptPhis inside fixupDefs(). Existing Phis in IDF may + // need fixing as well, and potentially be trivial before this insertion, + // hence add all IDF Phis. See PR43044. + NonOptPhis.insert(MPhi); + } + for (auto &MPhi : NewInsertedPHIs) { + auto *BBIDF = MPhi->getBlock(); + for (auto *Pred : predecessors(BBIDF)) { + DenseMap> CachedPreviousDef; + MPhi->addIncoming(getPreviousDefFromEnd(Pred, CachedPreviousDef), Pred); } + } - // Re-take the index where we're adding the new phis, because the above - // call to getPreviousDefFromEnd, may have inserted into InsertedPHIs. - NewPhiIndex = InsertedPHIs.size(); - for (auto &MPhi : NewInsertedPHIs) { - InsertedPHIs.push_back(&*MPhi); - FixupList.push_back(&*MPhi); - } + // Re-take the index where we're adding the new phis, because the above call + // to getPreviousDefFromEnd, may have inserted into InsertedPHIs. + NewPhiIndex = InsertedPHIs.size(); + for (auto &MPhi : NewInsertedPHIs) { + InsertedPHIs.push_back(&*MPhi); + FixupList.push_back(&*MPhi); } + FixupList.push_back(MD); } diff --git a/test/Analysis/MemorySSA/pr43427.ll b/test/Analysis/MemorySSA/pr43427.ll new file mode 100644 index 00000000000..f7088782217 --- /dev/null +++ b/test/Analysis/MemorySSA/pr43427.ll @@ -0,0 +1,42 @@ +; RUN: opt -disable-output -licm -print-memoryssa -enable-mssa-loop-dependency=true < %s 2>&1 | FileCheck %s + +; CHECK-LABEL: @f() +; CHECK: 8 = MemoryPhi( +; CHECK: 7 = MemoryPhi( +; CHECK: 9 = MemoryPhi( +define void @f() { +entry: + %e = alloca i16, align 1 + br label %lbl1 + +lbl1: ; preds = %if.else, %cleanup, %entry + store i16 undef, i16* %e, align 1 + call void @g() + br i1 undef, label %for.end, label %if.else + +for.end: ; preds = %lbl1 + br i1 undef, label %lbl3, label %lbl2 + +lbl2: ; preds = %lbl3, %for.end + br label %lbl3 + +lbl3: ; preds = %lbl2, %for.end + br i1 undef, label %lbl2, label %cleanup + +cleanup: ; preds = %lbl3 + %cleanup.dest = load i32, i32* undef, align 1 + %switch = icmp ult i32 %cleanup.dest, 1 + br i1 %switch, label %cleanup.cont, label %lbl1 + +cleanup.cont: ; preds = %cleanup + call void @llvm.lifetime.end.p0i8(i64 1, i8* null) + ret void + +if.else: ; preds = %lbl1 + br label %lbl1 +} + +declare void @g() + +; Function Attrs: argmemonly nounwind willreturn +declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture)