[llvm] a3d58bb - Detemplate llvm::EmitGEPOffset and move it into a cpp file. NFC.

Benjamin Kramer via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 29 07:25:24 PST 2022


Author: Benjamin Kramer
Date: 2022-12-29T16:24:21+01:00
New Revision: a3d58bbaff92686434473f3f00cc153d0840ca91

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

LOG: Detemplate llvm::EmitGEPOffset and move it into a cpp file. NFC.

Added: 
    llvm/lib/Analysis/Local.cpp

Modified: 
    llvm/include/llvm/Analysis/Utils/Local.h
    llvm/lib/Analysis/CMakeLists.txt
    llvm/lib/Analysis/MemoryBuiltins.cpp
    llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
    llvm/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Analysis/Utils/Local.h b/llvm/include/llvm/Analysis/Utils/Local.h
index 031938c6f9c72..e1dbfd3e5f37c 100644
--- a/llvm/include/llvm/Analysis/Utils/Local.h
+++ b/llvm/include/llvm/Analysis/Utils/Local.h
@@ -14,90 +14,21 @@
 #ifndef LLVM_ANALYSIS_UTILS_LOCAL_H
 #define LLVM_ANALYSIS_UTILS_LOCAL_H
 
-#include "llvm/ADT/StringRef.h"
-#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/GetElementPtrTypeIterator.h"
-
 namespace llvm {
 
+class DataLayout;
+class IRBuilderBase;
+class User;
+class Value;
+
 /// Given a getelementptr instruction/constantexpr, emit the code necessary to
 /// compute the offset from the base pointer (without adding in the base
 /// pointer). Return the result as a signed integer of intptr size.
 /// When NoAssumptions is true, no assumptions about index computation not
 /// overflowing is made.
-template <typename IRBuilderTy>
-Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &DL, User *GEP,
-                     bool NoAssumptions = false) {
-  GEPOperator *GEPOp = cast<GEPOperator>(GEP);
-  Type *IntIdxTy = DL.getIndexType(GEP->getType());
-  Value *Result = nullptr;
-
-  // If the GEP is inbounds, we know that none of the addressing operations will
-  // overflow in a signed sense.
-  bool isInBounds = GEPOp->isInBounds() && !NoAssumptions;
-
-  // Build a mask for high order bits.
-  unsigned IntPtrWidth = IntIdxTy->getScalarType()->getIntegerBitWidth();
-  uint64_t PtrSizeMask =
-      std::numeric_limits<uint64_t>::max() >> (64 - IntPtrWidth);
-
-  gep_type_iterator GTI = gep_type_begin(GEP);
-  for (User::op_iterator i = GEP->op_begin() + 1, e = GEP->op_end(); i != e;
-       ++i, ++GTI) {
-    Value *Op = *i;
-    uint64_t Size = DL.getTypeAllocSize(GTI.getIndexedType()) & PtrSizeMask;
-    Value *Offset;
-    if (Constant *OpC = dyn_cast<Constant>(Op)) {
-      if (OpC->isZeroValue())
-        continue;
-
-      // Handle a struct index, which adds its field offset to the pointer.
-      if (StructType *STy = GTI.getStructTypeOrNull()) {
-        uint64_t OpValue = OpC->getUniqueInteger().getZExtValue();
-        Size = DL.getStructLayout(STy)->getElementOffset(OpValue);
-        if (!Size)
-          continue;
-
-        Offset = ConstantInt::get(IntIdxTy, Size);
-      } else {
-        // Splat the constant if needed.
-        if (IntIdxTy->isVectorTy() && !OpC->getType()->isVectorTy())
-          OpC = ConstantVector::getSplat(
-              cast<VectorType>(IntIdxTy)->getElementCount(), OpC);
-
-        Constant *Scale = ConstantInt::get(IntIdxTy, Size);
-        Constant *OC =
-            ConstantExpr::getIntegerCast(OpC, IntIdxTy, true /*SExt*/);
-        Offset =
-            ConstantExpr::getMul(OC, Scale, false /*NUW*/, isInBounds /*NSW*/);
-      }
-    } else {
-      // Splat the index if needed.
-      if (IntIdxTy->isVectorTy() && !Op->getType()->isVectorTy())
-        Op = Builder->CreateVectorSplat(
-            cast<FixedVectorType>(IntIdxTy)->getNumElements(), Op);
-
-      // Convert to correct type.
-      if (Op->getType() != IntIdxTy)
-        Op = Builder->CreateIntCast(Op, IntIdxTy, true, Op->getName().str()+".c");
-      if (Size != 1) {
-        // We'll let instcombine(mul) convert this to a shl if possible.
-        Op = Builder->CreateMul(Op, ConstantInt::get(IntIdxTy, Size),
-                                GEP->getName().str() + ".idx", false /*NUW*/,
-                                isInBounds /*NSW*/);
-      }
-      Offset = Op;
-    }
-
-    if (Result)
-      Result = Builder->CreateAdd(Result, Offset, GEP->getName().str()+".offs",
-                                  false /*NUW*/, isInBounds /*NSW*/);
-    else
-      Result = Offset;
-  }
-  return Result ? Result : Constant::getNullValue(IntIdxTy);
-}
+Value *emitGEPOffset(IRBuilderBase *Builder, const DataLayout &DL, User *GEP,
+                     bool NoAssumptions = false);
 
-}
+} // namespace llvm
 
 #endif // LLVM_ANALYSIS_UTILS_LOCAL_H

diff  --git a/llvm/lib/Analysis/CMakeLists.txt b/llvm/lib/Analysis/CMakeLists.txt
index 7d015727de6df..93303719ccfb3 100644
--- a/llvm/lib/Analysis/CMakeLists.txt
+++ b/llvm/lib/Analysis/CMakeLists.txt
@@ -91,6 +91,7 @@ add_llvm_component_library(LLVMAnalysis
   LegacyDivergenceAnalysis.cpp
   Lint.cpp
   Loads.cpp
+  Local.cpp
   LoopAccessAnalysis.cpp
   LoopAnalysisManager.cpp
   LoopCacheAnalysis.cpp

diff  --git a/llvm/lib/Analysis/Local.cpp b/llvm/lib/Analysis/Local.cpp
new file mode 100644
index 0000000000000..5d558de516d35
--- /dev/null
+++ b/llvm/lib/Analysis/Local.cpp
@@ -0,0 +1,92 @@
+//===- Local.cpp - Functions to perform local transformations -------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This family of functions perform various local transformations to the
+// program.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/Utils/Local.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/GetElementPtrTypeIterator.h"
+#include "llvm/IR/IRBuilder.h"
+
+using namespace llvm;
+
+Value *llvm::emitGEPOffset(IRBuilderBase *Builder, const DataLayout &DL,
+                           User *GEP, bool NoAssumptions) {
+  GEPOperator *GEPOp = cast<GEPOperator>(GEP);
+  Type *IntIdxTy = DL.getIndexType(GEP->getType());
+  Value *Result = nullptr;
+
+  // If the GEP is inbounds, we know that none of the addressing operations will
+  // overflow in a signed sense.
+  bool isInBounds = GEPOp->isInBounds() && !NoAssumptions;
+
+  // Build a mask for high order bits.
+  unsigned IntPtrWidth = IntIdxTy->getScalarType()->getIntegerBitWidth();
+  uint64_t PtrSizeMask =
+      std::numeric_limits<uint64_t>::max() >> (64 - IntPtrWidth);
+
+  gep_type_iterator GTI = gep_type_begin(GEP);
+  for (User::op_iterator i = GEP->op_begin() + 1, e = GEP->op_end(); i != e;
+       ++i, ++GTI) {
+    Value *Op = *i;
+    uint64_t Size = DL.getTypeAllocSize(GTI.getIndexedType()) & PtrSizeMask;
+    Value *Offset;
+    if (Constant *OpC = dyn_cast<Constant>(Op)) {
+      if (OpC->isZeroValue())
+        continue;
+
+      // Handle a struct index, which adds its field offset to the pointer.
+      if (StructType *STy = GTI.getStructTypeOrNull()) {
+        uint64_t OpValue = OpC->getUniqueInteger().getZExtValue();
+        Size = DL.getStructLayout(STy)->getElementOffset(OpValue);
+        if (!Size)
+          continue;
+
+        Offset = ConstantInt::get(IntIdxTy, Size);
+      } else {
+        // Splat the constant if needed.
+        if (IntIdxTy->isVectorTy() && !OpC->getType()->isVectorTy())
+          OpC = ConstantVector::getSplat(
+              cast<VectorType>(IntIdxTy)->getElementCount(), OpC);
+
+        Constant *Scale = ConstantInt::get(IntIdxTy, Size);
+        Constant *OC =
+            ConstantExpr::getIntegerCast(OpC, IntIdxTy, true /*SExt*/);
+        Offset =
+            ConstantExpr::getMul(OC, Scale, false /*NUW*/, isInBounds /*NSW*/);
+      }
+    } else {
+      // Splat the index if needed.
+      if (IntIdxTy->isVectorTy() && !Op->getType()->isVectorTy())
+        Op = Builder->CreateVectorSplat(
+            cast<FixedVectorType>(IntIdxTy)->getNumElements(), Op);
+
+      // Convert to correct type.
+      if (Op->getType() != IntIdxTy)
+        Op = Builder->CreateIntCast(Op, IntIdxTy, true, Op->getName() + ".c");
+      if (Size != 1) {
+        // We'll let instcombine(mul) convert this to a shl if possible.
+        Op = Builder->CreateMul(Op, ConstantInt::get(IntIdxTy, Size),
+                                GEP->getName() + ".idx", false /*NUW*/,
+                                isInBounds /*NSW*/);
+      }
+      Offset = Op;
+    }
+
+    if (Result)
+      Result = Builder->CreateAdd(Result, Offset, GEP->getName() + ".offs",
+                                  false /*NUW*/, isInBounds /*NSW*/);
+    else
+      Result = Offset;
+  }
+  return Result ? Result : Constant::getNullValue(IntIdxTy);
+}

diff  --git a/llvm/lib/Analysis/MemoryBuiltins.cpp b/llvm/lib/Analysis/MemoryBuiltins.cpp
index 27005e547182f..aa74867200eb5 100644
--- a/llvm/lib/Analysis/MemoryBuiltins.cpp
+++ b/llvm/lib/Analysis/MemoryBuiltins.cpp
@@ -1150,7 +1150,7 @@ ObjectSizeOffsetEvaluator::visitGEPOperator(GEPOperator &GEP) {
   if (!bothKnown(PtrData))
     return unknown();
 
-  Value *Offset = EmitGEPOffset(&Builder, DL, &GEP, /*NoAssumptions=*/true);
+  Value *Offset = emitGEPOffset(&Builder, DL, &GEP, /*NoAssumptions=*/true);
   Offset = Builder.CreateAdd(PtrData.second, Offset);
   return std::make_pair(PtrData.first, Offset);
 }

diff  --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 56e76e087bf1a..7731f852e06be 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -204,7 +204,7 @@ std::optional<Value *> InstCombiner::targetSimplifyDemandedVectorEltsIntrinsic(
 }
 
 Value *InstCombinerImpl::EmitGEPOffset(User *GEP) {
-  return llvm::EmitGEPOffset(&Builder, DL, GEP);
+  return llvm::emitGEPOffset(&Builder, DL, GEP);
 }
 
 /// Legal integers and common types are considered desirable. This is used to

diff  --git a/llvm/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn
index 259a9cb10cd94..b7e8623d7c543 100644
--- a/llvm/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn
@@ -75,6 +75,7 @@ static_library("Analysis") {
     "LegacyDivergenceAnalysis.cpp",
     "Lint.cpp",
     "Loads.cpp",
+    "Local.cpp",
     "LoopAccessAnalysis.cpp",
     "LoopAnalysisManager.cpp",
     "LoopCacheAnalysis.cpp",


        


More information about the llvm-commits mailing list