[llvm] [InferAlignment] Misc. refactoring (NFC) (PR #112699)

via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 17 05:28:46 PDT 2024


https://github.com/ParkHanbum created https://github.com/llvm/llvm-project/pull/112699

This patch do some misc refactoring in InferAlignment. 
-. Removes code duplication in tryToImproveAlign by unifying load and
store instruction handling with getLoadStore helper functions.
-. Removed the code to get the alignment via KnownBits as it was 
redundant with the implementation of `getOrEnforceKnownAlignment`.
-. Adds `needEnforceAlignment` that use ValueToBasePtr cache to
avoid redundant calculations for previously processed pointers in
tryToImproveAlign.


>From 70feb1842ebd1e0a4c79ea707824d7ee437668a6 Mon Sep 17 00:00:00 2001
From: hanbeom <kese111 at gmail.com>
Date: Thu, 17 Oct 2024 19:10:25 +0900
Subject: [PATCH 1/3] Unify Load/Store handling in tryToImproveAlign

---
 llvm/include/llvm/IR/Instructions.h           | 10 +++++++++
 llvm/lib/Transforms/Scalar/InferAlignment.cpp | 21 +++++++------------
 2 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/llvm/include/llvm/IR/Instructions.h b/llvm/include/llvm/IR/Instructions.h
index e89739a5552662..3772c57ef83b04 100644
--- a/llvm/include/llvm/IR/Instructions.h
+++ b/llvm/include/llvm/IR/Instructions.h
@@ -4952,6 +4952,16 @@ inline Align getLoadStoreAlignment(const Value *I) {
   return cast<StoreInst>(I)->getAlign();
 }
 
+/// A helper function that set the alignment of load or store instruction.
+inline void setLoadStoreAlignment(Value *I, Align NewAlign) {
+  assert((isa<LoadInst>(I) || isa<StoreInst>(I)) &&
+         "Expected Load or Store instruction");
+  if (auto *LI = dyn_cast<LoadInst>(I))
+    LI->setAlignment(NewAlign);
+  else
+    cast<StoreInst>(I)->setAlignment(NewAlign);
+}
+
 /// A helper function that returns the address space of the pointer operand of
 /// load or store instruction.
 inline unsigned getLoadStoreAddressSpace(const Value *I) {
diff --git a/llvm/lib/Transforms/Scalar/InferAlignment.cpp b/llvm/lib/Transforms/Scalar/InferAlignment.cpp
index 6e0c206bd19805..21d373790ac53d 100644
--- a/llvm/lib/Transforms/Scalar/InferAlignment.cpp
+++ b/llvm/lib/Transforms/Scalar/InferAlignment.cpp
@@ -25,21 +25,14 @@ using namespace llvm;
 static bool tryToImproveAlign(
     const DataLayout &DL, Instruction *I,
     function_ref<Align(Value *PtrOp, Align OldAlign, Align PrefAlign)> Fn) {
-  if (auto *LI = dyn_cast<LoadInst>(I)) {
-    Value *PtrOp = LI->getPointerOperand();
-    Align OldAlign = LI->getAlign();
-    Align NewAlign = Fn(PtrOp, OldAlign, DL.getPrefTypeAlign(LI->getType()));
-    if (NewAlign > OldAlign) {
-      LI->setAlignment(NewAlign);
-      return true;
-    }
-  } else if (auto *SI = dyn_cast<StoreInst>(I)) {
-    Value *PtrOp = SI->getPointerOperand();
-    Value *ValOp = SI->getValueOperand();
-    Align OldAlign = SI->getAlign();
-    Align NewAlign = Fn(PtrOp, OldAlign, DL.getPrefTypeAlign(ValOp->getType()));
+
+  if (auto *PtrOp = getLoadStorePointerOperand(I)) {
+    Align OldAlign = getLoadStoreAlignment(I);
+    Align PrefAlign = DL.getPrefTypeAlign(getLoadStoreType(I));
+
+    Align NewAlign = Fn(PtrOp, OldAlign, PrefAlign);
     if (NewAlign > OldAlign) {
-      SI->setAlignment(NewAlign);
+      setLoadStoreAlignment(I, NewAlign);
       return true;
     }
   }

>From de865353e301982efb2b53af4fb2ff742badbb99 Mon Sep 17 00:00:00 2001
From: hanbeom <kese111 at gmail.com>
Date: Thu, 17 Oct 2024 20:27:57 +0900
Subject: [PATCH 2/3] Remove redundant alignment calculation

---
 llvm/lib/Transforms/Scalar/InferAlignment.cpp | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Transforms/Scalar/InferAlignment.cpp b/llvm/lib/Transforms/Scalar/InferAlignment.cpp
index 21d373790ac53d..1a35cacef22466 100644
--- a/llvm/lib/Transforms/Scalar/InferAlignment.cpp
+++ b/llvm/lib/Transforms/Scalar/InferAlignment.cpp
@@ -63,10 +63,8 @@ bool inferAlignment(Function &F, AssumptionCache &AC, DominatorTree &DT) {
     for (Instruction &I : BB) {
       Changed |= tryToImproveAlign(
           DL, &I, [&](Value *PtrOp, Align OldAlign, Align PrefAlign) {
-            KnownBits Known = computeKnownBits(PtrOp, DL, 0, &AC, &I, &DT);
-            unsigned TrailZ = std::min(Known.countMinTrailingZeros(),
-                                       +Value::MaxAlignmentExponent);
-            return Align(1ull << std::min(Known.getBitWidth() - 1, TrailZ));
+            return getOrEnforceKnownAlignment(PtrOp, MaybeAlign(), DL, &I, &AC,
+                                              &DT);
           });
     }
   }

>From aa7d584ea907484a726a1282971124ca885c328c Mon Sep 17 00:00:00 2001
From: hanbeom <kese111 at gmail.com>
Date: Thu, 17 Oct 2024 20:28:50 +0900
Subject: [PATCH 3/3] Add caching to reduce finding its base

---
 llvm/lib/Transforms/Scalar/InferAlignment.cpp | 36 +++++++++++++++++--
 1 file changed, 33 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Transforms/Scalar/InferAlignment.cpp b/llvm/lib/Transforms/Scalar/InferAlignment.cpp
index 1a35cacef22466..ac8e6ae943c9f6 100644
--- a/llvm/lib/Transforms/Scalar/InferAlignment.cpp
+++ b/llvm/lib/Transforms/Scalar/InferAlignment.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Transforms/Scalar/InferAlignment.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/Analysis/AssumptionCache.h"
 #include "llvm/Analysis/ValueTracking.h"
 #include "llvm/IR/Instructions.h"
@@ -22,6 +23,8 @@
 
 using namespace llvm;
 
+DenseMap<Value *, Value *> ValueToBasePtr;
+
 static bool tryToImproveAlign(
     const DataLayout &DL, Instruction *I,
     function_ref<Align(Value *PtrOp, Align OldAlign, Align PrefAlign)> Fn) {
@@ -36,10 +39,31 @@ static bool tryToImproveAlign(
       return true;
     }
   }
+
   // TODO: Also handle memory intrinsics.
   return false;
 }
 
+static bool needEnforceAlignment(Value *PtrOp, Instruction *I, Align PrefAlign,
+                                 const DataLayout &DL) {
+  auto it = ValueToBasePtr.find(PtrOp);
+  if (it != ValueToBasePtr.end()) {
+    Value *V = it->second;
+    Align CurrentAlign;
+    if (auto Alloca = dyn_cast<AllocaInst>(V))
+      CurrentAlign = Alloca->getAlign();
+    if (auto GO = dyn_cast<GlobalObject>(V))
+      CurrentAlign = GO->getPointerAlignment(DL);
+
+    if (PrefAlign <= CurrentAlign) {
+      setLoadStoreAlignment(I, CurrentAlign);
+      return false;
+    }
+  }
+
+  return true;
+}
+
 bool inferAlignment(Function &F, AssumptionCache &AC, DominatorTree &DT) {
   const DataLayout &DL = F.getDataLayout();
   bool Changed = false;
@@ -50,9 +74,15 @@ bool inferAlignment(Function &F, AssumptionCache &AC, DominatorTree &DT) {
     for (Instruction &I : BB) {
       Changed |= tryToImproveAlign(
           DL, &I, [&](Value *PtrOp, Align OldAlign, Align PrefAlign) {
-            if (PrefAlign > OldAlign)
-              return std::max(OldAlign,
-                              tryEnforceAlignment(PtrOp, PrefAlign, DL));
+            if (needEnforceAlignment(PtrOp, &I, PrefAlign, DL) &&
+                PrefAlign > OldAlign) {
+              Align NewAlign = tryEnforceAlignment(PtrOp, PrefAlign, DL);
+              if (NewAlign > OldAlign) {
+                ValueToBasePtr[PtrOp] = PtrOp->stripPointerCasts();
+                return NewAlign;
+              }
+            }
+
             return OldAlign;
           });
     }



More information about the llvm-commits mailing list