From: Benjamin Kramer Date: Thu, 29 Dec 2022 15:05:33 +0000 (+0100) Subject: Detemplate llvm::EmitGEPOffset and move it into a cpp file. NFC. X-Git-Tag: upstream/17.0.6~22488 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a3d58bbaff92686434473f3f00cc153d0840ca91;p=platform%2Fupstream%2Fllvm.git Detemplate llvm::EmitGEPOffset and move it into a cpp file. NFC. --- diff --git a/llvm/include/llvm/Analysis/Utils/Local.h b/llvm/include/llvm/Analysis/Utils/Local.h index 031938c..e1dbfd3 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 -Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &DL, User *GEP, - bool NoAssumptions = false) { - GEPOperator *GEPOp = cast(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::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(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(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(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 7d01572..9330371 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 0000000..5d558de --- /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(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::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(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(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(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 27005e5..aa74867 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 56e76e0..7731f85 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -204,7 +204,7 @@ std::optional 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 259a9cb..b7e8623 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",