[llvm] [SCCP] Determine early whether GlobalVariable is Constant or not (PR #107245)

via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 4 22:30:28 PDT 2024


https://github.com/ParkHanbum updated https://github.com/llvm/llvm-project/pull/107245

>From d12672a6c09916c086d6d40f966d21c769a44ac9 Mon Sep 17 00:00:00 2001
From: hanbeom <kese111 at gmail.com>
Date: Wed, 4 Sep 2024 19:33:42 +0900
Subject: [PATCH] [SCCP] Determine early whether GlobalVariable is Constant or
 not

Previously, we determine if 1.`LoadInst` could be replaced with
`Constant`, and 2. if the instruction can be removed by used the
`wouldInstructionBeTriviallyDead` function. if it can then we
replace it with `Constant`. However, in special case, we do not set
`GlobalVariable` to `Constant` even if it is a constant, and
`wouldInstructionBeTriviallyDead` returns false.

Because of this, we created a `canRemoveInstruction` function to
determine if an instruction is removable, returning true if and
only if `LoadInst` can be replaced with  `Constant`.

This patch eliminates the `canRemoveInstruction` function by removing
the `LoadInst` that uses it if GlobalVariable is a constant.
---
 llvm/lib/Transforms/IPO/SCCP.cpp         |  7 +++++--
 llvm/lib/Transforms/Utils/SCCPSolver.cpp | 18 +++---------------
 2 files changed, 8 insertions(+), 17 deletions(-)

diff --git a/llvm/lib/Transforms/IPO/SCCP.cpp b/llvm/lib/Transforms/IPO/SCCP.cpp
index 94ae511b2e4a1e..ceae22d3cc9421 100644
--- a/llvm/lib/Transforms/IPO/SCCP.cpp
+++ b/llvm/lib/Transforms/IPO/SCCP.cpp
@@ -357,8 +357,11 @@ static bool runIPSCCP(
     LLVM_DEBUG(dbgs() << "Found that GV '" << GV->getName()
                       << "' is constant!\n");
     while (!GV->use_empty()) {
-      StoreInst *SI = cast<StoreInst>(GV->user_back());
-      SI->eraseFromParent();
+      auto User = GV->user_back();
+      // We can remove LoadInst at here, because we already replace user of this
+      // to constant.
+      if (isa<StoreInst>(User) || isa<LoadInst>(User))
+        cast<Instruction>(User)->eraseFromParent();
     }
 
     // Try to create a debug constant expression for the global variable
diff --git a/llvm/lib/Transforms/Utils/SCCPSolver.cpp b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
index c944859cc69b89..04b63636f6232c 100644
--- a/llvm/lib/Transforms/Utils/SCCPSolver.cpp
+++ b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
@@ -53,18 +53,6 @@ bool SCCPSolver::isOverdefined(const ValueLatticeElement &LV) {
   return !LV.isUnknownOrUndef() && !SCCPSolver::isConstant(LV);
 }
 
-static bool canRemoveInstruction(Instruction *I) {
-  if (wouldInstructionBeTriviallyDead(I))
-    return true;
-
-  // Some instructions can be handled but are rejected above. Catch
-  // those cases by falling through to here.
-  // TODO: Mark globals as being constant earlier, so
-  // TODO: wouldInstructionBeTriviallyDead() knows that atomic loads
-  // TODO: are safe to remove.
-  return isa<LoadInst>(I);
-}
-
 bool SCCPSolver::tryToReplaceWithConstant(Value *V) {
   Constant *Const = getConstantOrNull(V);
   if (!Const)
@@ -74,8 +62,7 @@ bool SCCPSolver::tryToReplaceWithConstant(Value *V) {
   // Calls with "clang.arc.attachedcall" implicitly use the return value and
   // those uses cannot be updated with a constant.
   CallBase *CB = dyn_cast<CallBase>(V);
-  if (CB && ((CB->isMustTailCall() &&
-              !canRemoveInstruction(CB)) ||
+  if (CB && ((CB->isMustTailCall() && !wouldInstructionBeTriviallyDead(CB)) ||
              CB->getOperandBundle(LLVMContext::OB_clang_arc_attachedcall))) {
     Function *F = CB->getCalledFunction();
 
@@ -92,6 +79,7 @@ bool SCCPSolver::tryToReplaceWithConstant(Value *V) {
 
   // Replaces all of the uses of a variable with uses of the constant.
   V->replaceAllUsesWith(Const);
+
   return true;
 }
 
@@ -243,7 +231,7 @@ bool SCCPSolver::simplifyInstsInBlock(BasicBlock &BB,
     if (Inst.getType()->isVoidTy())
       continue;
     if (tryToReplaceWithConstant(&Inst)) {
-      if (canRemoveInstruction(&Inst))
+      if (wouldInstructionBeTriviallyDead(&Inst))
         Inst.eraseFromParent();
 
       MadeChanges = true;



More information about the llvm-commits mailing list