[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