aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/clang16/lib/CodeGen/CGBuilder.h
diff options
context:
space:
mode:
authorthegeorg <thegeorg@yandex-team.com>2024-03-13 13:58:24 +0300
committerthegeorg <thegeorg@yandex-team.com>2024-03-13 14:11:53 +0300
commit11a895b7e15d1c5a1f52706396b82e3f9db953cb (patch)
treefabc6d883b0f946151f61ae7865cee9f529a1fdd /contrib/libs/clang16/lib/CodeGen/CGBuilder.h
parent9685917341315774aad5733b1793b1e533a88bbb (diff)
downloadydb-11a895b7e15d1c5a1f52706396b82e3f9db953cb.tar.gz
Export clang-format16 via ydblib project
6e6be3a95868fde888d801b7590af4044049563f
Diffstat (limited to 'contrib/libs/clang16/lib/CodeGen/CGBuilder.h')
-rw-r--r--contrib/libs/clang16/lib/CodeGen/CGBuilder.h379
1 files changed, 379 insertions, 0 deletions
diff --git a/contrib/libs/clang16/lib/CodeGen/CGBuilder.h b/contrib/libs/clang16/lib/CodeGen/CGBuilder.h
new file mode 100644
index 0000000000..2fcfea64ed
--- /dev/null
+++ b/contrib/libs/clang16/lib/CodeGen/CGBuilder.h
@@ -0,0 +1,379 @@
+//===-- CGBuilder.h - Choose IRBuilder implementation ----------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_CODEGEN_CGBUILDER_H
+#define LLVM_CLANG_LIB_CODEGEN_CGBUILDER_H
+
+#include "Address.h"
+#include "CodeGenTypeCache.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Type.h"
+
+namespace clang {
+namespace CodeGen {
+
+class CodeGenFunction;
+
+/// This is an IRBuilder insertion helper that forwards to
+/// CodeGenFunction::InsertHelper, which adds necessary metadata to
+/// instructions.
+class CGBuilderInserter final : public llvm::IRBuilderDefaultInserter {
+public:
+ CGBuilderInserter() = default;
+ explicit CGBuilderInserter(CodeGenFunction *CGF) : CGF(CGF) {}
+
+ /// This forwards to CodeGenFunction::InsertHelper.
+ void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name,
+ llvm::BasicBlock *BB,
+ llvm::BasicBlock::iterator InsertPt) const override;
+
+private:
+ CodeGenFunction *CGF = nullptr;
+};
+
+typedef CGBuilderInserter CGBuilderInserterTy;
+
+typedef llvm::IRBuilder<llvm::ConstantFolder, CGBuilderInserterTy>
+ CGBuilderBaseTy;
+
+class CGBuilderTy : public CGBuilderBaseTy {
+ /// Storing a reference to the type cache here makes it a lot easier
+ /// to build natural-feeling, target-specific IR.
+ const CodeGenTypeCache &TypeCache;
+
+public:
+ CGBuilderTy(const CodeGenTypeCache &TypeCache, llvm::LLVMContext &C)
+ : CGBuilderBaseTy(C), TypeCache(TypeCache) {}
+ CGBuilderTy(const CodeGenTypeCache &TypeCache, llvm::LLVMContext &C,
+ const llvm::ConstantFolder &F,
+ const CGBuilderInserterTy &Inserter)
+ : CGBuilderBaseTy(C, F, Inserter), TypeCache(TypeCache) {}
+ CGBuilderTy(const CodeGenTypeCache &TypeCache, llvm::Instruction *I)
+ : CGBuilderBaseTy(I), TypeCache(TypeCache) {}
+ CGBuilderTy(const CodeGenTypeCache &TypeCache, llvm::BasicBlock *BB)
+ : CGBuilderBaseTy(BB), TypeCache(TypeCache) {}
+
+ llvm::ConstantInt *getSize(CharUnits N) {
+ return llvm::ConstantInt::get(TypeCache.SizeTy, N.getQuantity());
+ }
+ llvm::ConstantInt *getSize(uint64_t N) {
+ return llvm::ConstantInt::get(TypeCache.SizeTy, N);
+ }
+
+ // Note that we intentionally hide the CreateLoad APIs that don't
+ // take an alignment.
+ llvm::LoadInst *CreateLoad(Address Addr, const llvm::Twine &Name = "") {
+ return CreateAlignedLoad(Addr.getElementType(), Addr.getPointer(),
+ Addr.getAlignment().getAsAlign(), Name);
+ }
+ llvm::LoadInst *CreateLoad(Address Addr, const char *Name) {
+ // This overload is required to prevent string literals from
+ // ending up in the IsVolatile overload.
+ return CreateAlignedLoad(Addr.getElementType(), Addr.getPointer(),
+ Addr.getAlignment().getAsAlign(), Name);
+ }
+ llvm::LoadInst *CreateLoad(Address Addr, bool IsVolatile,
+ const llvm::Twine &Name = "") {
+ return CreateAlignedLoad(Addr.getElementType(), Addr.getPointer(),
+ Addr.getAlignment().getAsAlign(), IsVolatile,
+ Name);
+ }
+
+ using CGBuilderBaseTy::CreateAlignedLoad;
+ llvm::LoadInst *CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr,
+ CharUnits Align,
+ const llvm::Twine &Name = "") {
+ assert(llvm::cast<llvm::PointerType>(Addr->getType())
+ ->isOpaqueOrPointeeTypeMatches(Ty));
+ return CreateAlignedLoad(Ty, Addr, Align.getAsAlign(), Name);
+ }
+
+ // Note that we intentionally hide the CreateStore APIs that don't
+ // take an alignment.
+ llvm::StoreInst *CreateStore(llvm::Value *Val, Address Addr,
+ bool IsVolatile = false) {
+ return CreateAlignedStore(Val, Addr.getPointer(),
+ Addr.getAlignment().getAsAlign(), IsVolatile);
+ }
+
+ using CGBuilderBaseTy::CreateAlignedStore;
+ llvm::StoreInst *CreateAlignedStore(llvm::Value *Val, llvm::Value *Addr,
+ CharUnits Align,
+ bool IsVolatile = false) {
+ return CreateAlignedStore(Val, Addr, Align.getAsAlign(), IsVolatile);
+ }
+
+ // FIXME: these "default-aligned" APIs should be removed,
+ // but I don't feel like fixing all the builtin code right now.
+ llvm::StoreInst *CreateDefaultAlignedStore(llvm::Value *Val,
+ llvm::Value *Addr,
+ bool IsVolatile = false) {
+ return CGBuilderBaseTy::CreateStore(Val, Addr, IsVolatile);
+ }
+
+ /// Emit a load from an i1 flag variable.
+ llvm::LoadInst *CreateFlagLoad(llvm::Value *Addr,
+ const llvm::Twine &Name = "") {
+ assert(llvm::cast<llvm::PointerType>(Addr->getType())
+ ->isOpaqueOrPointeeTypeMatches(getInt1Ty()));
+ return CreateAlignedLoad(getInt1Ty(), Addr, CharUnits::One(), Name);
+ }
+
+ /// Emit a store to an i1 flag variable.
+ llvm::StoreInst *CreateFlagStore(bool Value, llvm::Value *Addr) {
+ assert(llvm::cast<llvm::PointerType>(Addr->getType())
+ ->isOpaqueOrPointeeTypeMatches(getInt1Ty()));
+ return CreateAlignedStore(getInt1(Value), Addr, CharUnits::One());
+ }
+
+ // Temporarily use old signature; clang will be updated to an Address overload
+ // in a subsequent patch.
+ llvm::AtomicCmpXchgInst *
+ CreateAtomicCmpXchg(llvm::Value *Ptr, llvm::Value *Cmp, llvm::Value *New,
+ llvm::AtomicOrdering SuccessOrdering,
+ llvm::AtomicOrdering FailureOrdering,
+ llvm::SyncScope::ID SSID = llvm::SyncScope::System) {
+ return CGBuilderBaseTy::CreateAtomicCmpXchg(
+ Ptr, Cmp, New, llvm::MaybeAlign(), SuccessOrdering, FailureOrdering,
+ SSID);
+ }
+
+ // Temporarily use old signature; clang will be updated to an Address overload
+ // in a subsequent patch.
+ llvm::AtomicRMWInst *
+ CreateAtomicRMW(llvm::AtomicRMWInst::BinOp Op, llvm::Value *Ptr,
+ llvm::Value *Val, llvm::AtomicOrdering Ordering,
+ llvm::SyncScope::ID SSID = llvm::SyncScope::System) {
+ return CGBuilderBaseTy::CreateAtomicRMW(Op, Ptr, Val, llvm::MaybeAlign(),
+ Ordering, SSID);
+ }
+
+ using CGBuilderBaseTy::CreateAddrSpaceCast;
+ Address CreateAddrSpaceCast(Address Addr, llvm::Type *Ty,
+ const llvm::Twine &Name = "") {
+ assert(cast<llvm::PointerType>(Ty)->isOpaqueOrPointeeTypeMatches(
+ Addr.getElementType()) &&
+ "Should not change the element type");
+ return Addr.withPointer(CreateAddrSpaceCast(Addr.getPointer(), Ty, Name));
+ }
+
+ /// Cast the element type of the given address to a different type,
+ /// preserving information like the alignment and address space.
+ Address CreateElementBitCast(Address Addr, llvm::Type *Ty,
+ const llvm::Twine &Name = "") {
+ auto *PtrTy = Ty->getPointerTo(Addr.getAddressSpace());
+ return Address(CreateBitCast(Addr.getPointer(), PtrTy, Name), Ty,
+ Addr.getAlignment());
+ }
+
+ using CGBuilderBaseTy::CreatePointerBitCastOrAddrSpaceCast;
+ Address CreatePointerBitCastOrAddrSpaceCast(Address Addr, llvm::Type *Ty,
+ llvm::Type *ElementTy,
+ const llvm::Twine &Name = "") {
+ llvm::Value *Ptr =
+ CreatePointerBitCastOrAddrSpaceCast(Addr.getPointer(), Ty, Name);
+ return Address(Ptr, ElementTy, Addr.getAlignment());
+ }
+
+ /// Given
+ /// %addr = {T1, T2...}* ...
+ /// produce
+ /// %name = getelementptr inbounds %addr, i32 0, i32 index
+ ///
+ /// This API assumes that drilling into a struct like this is always an
+ /// inbounds operation.
+ using CGBuilderBaseTy::CreateStructGEP;
+ Address CreateStructGEP(Address Addr, unsigned Index,
+ const llvm::Twine &Name = "") {
+ llvm::StructType *ElTy = cast<llvm::StructType>(Addr.getElementType());
+ const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
+ const llvm::StructLayout *Layout = DL.getStructLayout(ElTy);
+ auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index));
+
+ return Address(
+ CreateStructGEP(Addr.getElementType(), Addr.getPointer(), Index, Name),
+ ElTy->getElementType(Index),
+ Addr.getAlignment().alignmentAtOffset(Offset));
+ }
+
+ /// Given
+ /// %addr = [n x T]* ...
+ /// produce
+ /// %name = getelementptr inbounds %addr, i64 0, i64 index
+ /// where i64 is actually the target word size.
+ ///
+ /// This API assumes that drilling into an array like this is always
+ /// an inbounds operation.
+ Address CreateConstArrayGEP(Address Addr, uint64_t Index,
+ const llvm::Twine &Name = "") {
+ llvm::ArrayType *ElTy = cast<llvm::ArrayType>(Addr.getElementType());
+ const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
+ CharUnits EltSize =
+ CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy->getElementType()));
+
+ return Address(
+ CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(),
+ {getSize(CharUnits::Zero()), getSize(Index)}, Name),
+ ElTy->getElementType(),
+ Addr.getAlignment().alignmentAtOffset(Index * EltSize));
+ }
+
+ /// Given
+ /// %addr = T* ...
+ /// produce
+ /// %name = getelementptr inbounds %addr, i64 index
+ /// where i64 is actually the target word size.
+ Address CreateConstInBoundsGEP(Address Addr, uint64_t Index,
+ const llvm::Twine &Name = "") {
+ llvm::Type *ElTy = Addr.getElementType();
+ const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
+ CharUnits EltSize = CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy));
+
+ return Address(CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(),
+ getSize(Index), Name),
+ ElTy,
+ Addr.getAlignment().alignmentAtOffset(Index * EltSize));
+ }
+
+ /// Given
+ /// %addr = T* ...
+ /// produce
+ /// %name = getelementptr inbounds %addr, i64 index
+ /// where i64 is actually the target word size.
+ Address CreateConstGEP(Address Addr, uint64_t Index,
+ const llvm::Twine &Name = "") {
+ const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
+ CharUnits EltSize =
+ CharUnits::fromQuantity(DL.getTypeAllocSize(Addr.getElementType()));
+
+ return Address(CreateGEP(Addr.getElementType(), Addr.getPointer(),
+ getSize(Index), Name),
+ Addr.getElementType(),
+ Addr.getAlignment().alignmentAtOffset(Index * EltSize));
+ }
+
+ /// Create GEP with single dynamic index. The address alignment is reduced
+ /// according to the element size.
+ using CGBuilderBaseTy::CreateGEP;
+ Address CreateGEP(Address Addr, llvm::Value *Index,
+ const llvm::Twine &Name = "") {
+ const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
+ CharUnits EltSize =
+ CharUnits::fromQuantity(DL.getTypeAllocSize(Addr.getElementType()));
+
+ return Address(
+ CreateGEP(Addr.getElementType(), Addr.getPointer(), Index, Name),
+ Addr.getElementType(),
+ Addr.getAlignment().alignmentOfArrayElement(EltSize));
+ }
+
+ /// Given a pointer to i8, adjust it by a given constant offset.
+ Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset,
+ const llvm::Twine &Name = "") {
+ assert(Addr.getElementType() == TypeCache.Int8Ty);
+ return Address(CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(),
+ getSize(Offset), Name),
+ Addr.getElementType(),
+ Addr.getAlignment().alignmentAtOffset(Offset));
+ }
+ Address CreateConstByteGEP(Address Addr, CharUnits Offset,
+ const llvm::Twine &Name = "") {
+ assert(Addr.getElementType() == TypeCache.Int8Ty);
+ return Address(CreateGEP(Addr.getElementType(), Addr.getPointer(),
+ getSize(Offset), Name),
+ Addr.getElementType(),
+ Addr.getAlignment().alignmentAtOffset(Offset));
+ }
+
+ using CGBuilderBaseTy::CreateConstInBoundsGEP2_32;
+ Address CreateConstInBoundsGEP2_32(Address Addr, unsigned Idx0, unsigned Idx1,
+ const llvm::Twine &Name = "") {
+ const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
+
+ auto *GEP = cast<llvm::GetElementPtrInst>(CreateConstInBoundsGEP2_32(
+ Addr.getElementType(), Addr.getPointer(), Idx0, Idx1, Name));
+ llvm::APInt Offset(
+ DL.getIndexSizeInBits(Addr.getType()->getPointerAddressSpace()), 0,
+ /*isSigned=*/true);
+ if (!GEP->accumulateConstantOffset(DL, Offset))
+ llvm_unreachable("offset of GEP with constants is always computable");
+ return Address(GEP, GEP->getResultElementType(),
+ Addr.getAlignment().alignmentAtOffset(
+ CharUnits::fromQuantity(Offset.getSExtValue())));
+ }
+
+ using CGBuilderBaseTy::CreateMemCpy;
+ llvm::CallInst *CreateMemCpy(Address Dest, Address Src, llvm::Value *Size,
+ bool IsVolatile = false) {
+ return CreateMemCpy(Dest.getPointer(), Dest.getAlignment().getAsAlign(),
+ Src.getPointer(), Src.getAlignment().getAsAlign(), Size,
+ IsVolatile);
+ }
+ llvm::CallInst *CreateMemCpy(Address Dest, Address Src, uint64_t Size,
+ bool IsVolatile = false) {
+ return CreateMemCpy(Dest.getPointer(), Dest.getAlignment().getAsAlign(),
+ Src.getPointer(), Src.getAlignment().getAsAlign(), Size,
+ IsVolatile);
+ }
+
+ using CGBuilderBaseTy::CreateMemCpyInline;
+ llvm::CallInst *CreateMemCpyInline(Address Dest, Address Src, uint64_t Size) {
+ return CreateMemCpyInline(
+ Dest.getPointer(), Dest.getAlignment().getAsAlign(), Src.getPointer(),
+ Src.getAlignment().getAsAlign(), getInt64(Size));
+ }
+
+ using CGBuilderBaseTy::CreateMemMove;
+ llvm::CallInst *CreateMemMove(Address Dest, Address Src, llvm::Value *Size,
+ bool IsVolatile = false) {
+ return CreateMemMove(Dest.getPointer(), Dest.getAlignment().getAsAlign(),
+ Src.getPointer(), Src.getAlignment().getAsAlign(),
+ Size, IsVolatile);
+ }
+
+ using CGBuilderBaseTy::CreateMemSet;
+ llvm::CallInst *CreateMemSet(Address Dest, llvm::Value *Value,
+ llvm::Value *Size, bool IsVolatile = false) {
+ return CreateMemSet(Dest.getPointer(), Value, Size,
+ Dest.getAlignment().getAsAlign(), IsVolatile);
+ }
+
+ using CGBuilderBaseTy::CreateMemSetInline;
+ llvm::CallInst *CreateMemSetInline(Address Dest, llvm::Value *Value,
+ uint64_t Size) {
+ return CreateMemSetInline(Dest.getPointer(),
+ Dest.getAlignment().getAsAlign(), Value,
+ getInt64(Size));
+ }
+
+ using CGBuilderBaseTy::CreatePreserveStructAccessIndex;
+ Address CreatePreserveStructAccessIndex(Address Addr, unsigned Index,
+ unsigned FieldIndex,
+ llvm::MDNode *DbgInfo) {
+ llvm::StructType *ElTy = cast<llvm::StructType>(Addr.getElementType());
+ const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
+ const llvm::StructLayout *Layout = DL.getStructLayout(ElTy);
+ auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index));
+
+ return Address(CreatePreserveStructAccessIndex(ElTy, Addr.getPointer(),
+ Index, FieldIndex, DbgInfo),
+ ElTy->getElementType(Index),
+ Addr.getAlignment().alignmentAtOffset(Offset));
+ }
+
+ using CGBuilderBaseTy::CreateLaunderInvariantGroup;
+ Address CreateLaunderInvariantGroup(Address Addr) {
+ return Addr.withPointer(CreateLaunderInvariantGroup(Addr.getPointer()));
+ }
+};
+
+} // end namespace CodeGen
+} // end namespace clang
+
+#endif