[llvm] 6bf590d - [InstCombine] Pull out a helper function to simplify upcoming patch [NFC]

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 11 13:05:39 PST 2022


Author: Philip Reames
Date: 2022-01-11T13:05:25-08:00
New Revision: 6bf590d6e86d8a2b938042d28ef6d4cbb309e0e6

URL: https://github.com/llvm/llvm-project/commit/6bf590d6e86d8a2b938042d28ef6d4cbb309e0e6
DIFF: https://github.com/llvm/llvm-project/commit/6bf590d6e86d8a2b938042d28ef6d4cbb309e0e6.diff

LOG: [InstCombine] Pull out a helper function to simplify upcoming patch [NFC]

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index ecdc4b5b5b4a..f6e261953272 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -3721,6 +3721,50 @@ Instruction *InstCombinerImpl::visitFreeze(FreezeInst &I) {
   return nullptr;
 }
 
+/// Check for case where the call writes to an otherwise dead alloca.  This
+/// shows up for unused out-params in idiomatic C/C++ code.   Note that this
+/// helper *only* analyzes the write; doesn't check any other legality aspect.
+static bool SoleWriteToDeadLocal(Instruction *I, TargetLibraryInfo &TLI) {
+  auto *CB = dyn_cast<CallBase>(I);
+  if (!CB)
+    // TODO: handle e.g. store to alloca here - only worth doing if we extend
+    // to allow reload along used path as described below.  Otherwise, this
+    // is simply a store to a dead allocation which will be removed.
+    return false;
+  Optional<MemoryLocation> Dest = MemoryLocation::getForDest(CB, TLI);
+  if (!Dest)
+    return false;
+  auto *AI = dyn_cast<AllocaInst>(getUnderlyingObject(Dest->Ptr));
+  if (!AI)
+    // TODO: allow malloc?
+    return false;
+  // TODO: allow memory access dominated by move point?  Note that since AI
+  // could have a reference to itself captured by the call, we would need to
+  // account for cycles in doing so.
+  SmallVector<const User *> AllocaUsers;
+  SmallPtrSet<const User *, 4> Visited;
+  auto pushUsers = [&](const Instruction &I) {
+    for (const User *U : I.users()) {
+      if (Visited.insert(U).second)
+        AllocaUsers.push_back(U);
+    }
+  };
+  pushUsers(*AI);
+  while (!AllocaUsers.empty()) {
+    auto *UserI = cast<Instruction>(AllocaUsers.pop_back_val());
+    if (isa<BitCastInst>(UserI) || isa<GetElementPtrInst>(UserI) ||
+        isa<AddrSpaceCastInst>(UserI)) {
+      pushUsers(*UserI);
+      continue;
+    }
+    if (UserI == CB)
+      continue;
+    // TODO: support lifetime.start/end here
+    return false;
+  }
+  return true;
+}
+
 /// Try to move the specified instruction from its current block into the
 /// beginning of DestBlock, which can only happen if it's safe to move the
 /// instruction past all of the instructions between it and the end of its
@@ -3755,45 +3799,8 @@ static bool TryToSinkInstruction(Instruction *I, BasicBlock *DestBlock,
   // Unless we can prove that the memory write isn't visibile except on the
   // path we're sinking to, we must bail.
   if (I->mayWriteToMemory()) {
-    // Check for case where the call writes to an otherwise dead alloca.  This
-    // shows up for unused out-params in idiomatic C/C++ code.
-    auto *CB = dyn_cast<CallBase>(I);
-    if (!CB)
-      // TODO: handle e.g. store to alloca here - only worth doing if we extend
-      // to allow reload along used path as described below.  Otherwise, this
-      // is simply a store to a dead allocation which will be removed.
-      return false;
-    Optional<MemoryLocation> Dest = MemoryLocation::getForDest(CB, TLI);
-    if (!Dest)
+    if (!SoleWriteToDeadLocal(I, TLI))
       return false;
-    auto *AI = dyn_cast<AllocaInst>(getUnderlyingObject(Dest->Ptr));
-    if (!AI)
-      // TODO: allow malloc?
-      return false;
-    // TODO: allow memory access dominated by move point?  Note that since AI
-    // could have a reference to itself captured by the call, we would need to
-    // account for cycles in doing so.
-    SmallVector<const User *> AllocaUsers;
-    SmallPtrSet<const User *, 4> Visited;
-    auto pushUsers = [&](const Instruction &I) {
-      for (const User *U : I.users()) {
-        if (Visited.insert(U).second)
-          AllocaUsers.push_back(U);
-      }
-    };
-    pushUsers(*AI);
-    while (!AllocaUsers.empty()) {
-      auto *UserI = cast<Instruction>(AllocaUsers.pop_back_val());
-      if (isa<BitCastInst>(UserI) || isa<GetElementPtrInst>(UserI) ||
-          isa<AddrSpaceCastInst>(UserI)) {
-        pushUsers(*UserI);
-        continue;
-      }
-      if (UserI == CB)
-        continue;
-      // TODO: support lifetime.start/end here
-      return false;
-    }
   }
 
   // We can only sink load instructions if there is nothing between the load and


        


More information about the llvm-commits mailing list