[Reduce] Function reduction: replace all users of function with undef
authorRoman Lebedev <lebedev.ri@gmail.com>
Mon, 27 Jul 2020 10:30:39 +0000 (13:30 +0300)
committerRoman Lebedev <lebedev.ri@gmail.com>
Mon, 27 Jul 2020 12:39:02 +0000 (15:39 +0300)
There may be other users of a function other than CallInsts,
but what's more important, we can't actually replace function pointer
with undef, because for constants, that would not preserve the type
and RAUW would assert.

In particular, that affects blockaddress, however it proves to be
prohibitively complex to come up with a good test involving blockaddress:
we'd need to both ensure that the function body survives until
this pass, and is not interesting in this pass.

llvm/tools/llvm-reduce/deltas/ReduceFunctions.cpp

index b29df88..4dd7b98 100644 (file)
@@ -32,22 +32,21 @@ static void extractFunctionsFromModule(const std::vector<Chunk> &ChunksToKeep,
     if (O.shouldKeep())
       FuncsToKeep.insert(&F);
 
-  // Delete out-of-chunk functions, and replace their calls with undef
+  // Delete out-of-chunk functions, and replace their users with undef
   std::vector<Function *> FuncsToRemove;
-  SetVector<CallInst *> CallsToRemove;
+  SetVector<Instruction *> InstrsToRemove;
   for (auto &F : *Program)
     if (!FuncsToKeep.count(&F)) {
-      for (auto U : F.users())
-        if (auto *Call = dyn_cast<CallInst>(U)) {
-          Call->replaceAllUsesWith(UndefValue::get(Call->getType()));
-          CallsToRemove.insert(Call);
-        }
-      F.replaceAllUsesWith(UndefValue::get(F.getType()));
+      for (auto U : F.users()) {
+        U->replaceAllUsesWith(UndefValue::get(U->getType()));
+        if (auto *I = dyn_cast<Instruction>(U))
+          InstrsToRemove.insert(I);
+      }
       FuncsToRemove.push_back(&F);
     }
 
-  for (auto *C : CallsToRemove)
-    C->eraseFromParent();
+  for (auto *I : InstrsToRemove)
+    I->eraseFromParent();
 
   for (auto *F : FuncsToRemove)
     F->eraseFromParent();