================ @@ -0,0 +1,826 @@ +//===- BuildBuiltins.cpp - Utility builder for builtins -------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "llvm/Transforms/Utils/BuildBuiltins.h" +#include "llvm/CodeGen/TargetLowering.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/Transforms/Utils/BuildLibCalls.h" + +using namespace llvm; + +namespace { +static IntegerType *getIntTy(IRBuilderBase &B, const TargetLibraryInfo *TLI) { + return B.getIntNTy(TLI->getIntSize()); +} + +static IntegerType *getSizeTTy(IRBuilderBase &B, const TargetLibraryInfo *TLI) { + const Module *M = B.GetInsertBlock()->getModule(); + return B.getIntNTy(TLI->getSizeTSize(*M)); +} + +/// In order to use one of the sized library calls such as +/// __atomic_fetch_add_4, the alignment must be sufficient, the size +/// must be one of the potentially-specialized sizes, and the value +/// type must actually exist in C on the target (otherwise, the +/// function wouldn't actually be defined.) +static bool canUseSizedAtomicCall(unsigned Size, Align Alignment, + const DataLayout &DL) { + // TODO: "LargestSize" is an approximation for "largest type that + // you can express in C". It seems to be the case that int128 is + // supported on all 64-bit platforms, otherwise only up to 64-bit + // integers are supported. If we get this wrong, then we'll try to + // call a sized libcall that doesn't actually exist. There should + // really be some more reliable way in LLVM of determining integer + // sizes which are valid in the target's C ABI... + unsigned LargestSize = DL.getLargestLegalIntTypeSizeInBits() >= 64 ? 16 : 8; + return Alignment >= Size && + (Size == 1 || Size == 2 || Size == 4 || Size == 8 || Size == 16) && + Size <= LargestSize; +} + +// Helper to check if a type is in a variant +template <typename T, typename Variant> struct is_in_variant; + +template <typename T, typename... Types> +struct is_in_variant<T, std::variant<Types...>> + : std::disjunction<std::is_same<T, Types>...> {}; + +/// Alternative to std::holds_alternative that works even if the std::variant +/// cannot hold T. +template <typename T, typename Variant> +constexpr bool holds_alternative_if_exists(const Variant &v) { + if constexpr (is_in_variant<T, Variant>::value) { + return std::holds_alternative<T>(v); + } else { + // Type T is not in the variant, return false or handle accordingly + return false; + } +} + +/// Common code for emitting an atomic builtin (load, store, cmpxchg). +class AtomicEmitter { ---------------- tblah wrote:
I have a warning here "AtomicEmitter has virtual functions but non-virtual destructor". https://github.com/llvm/llvm-project/pull/101966 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits