Skip to content

RuntimeLibcalls: Add bitset for available libcalls #150869

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion llvm/cmake/config-ix.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,9 @@ elseif (LLVM_NATIVE_ARCH MATCHES "riscv64")
set(LLVM_NATIVE_ARCH RISCV)
elseif (LLVM_NATIVE_ARCH STREQUAL "m68k")
set(LLVM_NATIVE_ARCH M68k)
elseif (LLVM_NATIVE_ARCH MATCHES "loongarch")
elseif (LLVM_NATIVE_ARCH MATCHES "loongarch32")
set(LLVM_NATIVE_ARCH LoongArch)
elseif (LLVM_NATIVE_ARCH MATCHES "loongarch64")
set(LLVM_NATIVE_ARCH LoongArch)
else ()
message(FATAL_ERROR "Unknown architecture ${LLVM_NATIVE_ARCH}")
Expand Down Expand Up @@ -616,6 +618,21 @@ else ()
endif ()
endif ()

foreach(i IN ITEMS 8 4)
try_compile(SIZEOF_UINTPTR_T_IS_${i}
SOURCE_FROM_CONTENT
"test-sizeof-uintptr_t.cpp"
"#include <cstdint>\n
static_assert(sizeof(uintptr_t) == ${i}); int main(){}"
CXX_STANDARD 17
LOG_DESCRIPTION "testing sizeof(uintptr_t)")

if(SIZEOF_UINTPTR_T_IS_${i})
set(LLVM_NATIVE_ARCH_SIZEOF_UINTPTR_T ${i})
break()
endif()
endforeach()

if( MSVC )
set(SHLIBEXT ".lib")
set(stricmp "_stricmp")
Expand Down
3 changes: 3 additions & 0 deletions llvm/include/llvm/Config/llvm-config.h.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
/* LLVM architecture name for the native architecture, if available */
#cmakedefine LLVM_NATIVE_ARCH ${LLVM_NATIVE_ARCH}

/* sizeof(uintptr_t) name for the native architecture, if available */
#cmakedefine LLVM_NATIVE_ARCH_SIZEOF_UINTPTR_T ${LLVM_NATIVE_ARCH_SIZEOF_UINTPTR_T}

/* LLVM name for the native AsmParser init function, if available */
#cmakedefine LLVM_NATIVE_ASMPARSER LLVMInitialize${LLVM_NATIVE_ARCH}AsmParser

Expand Down
23 changes: 23 additions & 0 deletions llvm/include/llvm/IR/RuntimeLibcalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#define LLVM_IR_RUNTIME_LIBCALLS_H

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Bitset.h"
#include "llvm/ADT/Sequence.h"
#include "llvm/ADT/StringTable.h"
#include "llvm/IR/CallingConv.h"
Expand Down Expand Up @@ -53,8 +54,22 @@ static inline auto libcall_impls() {
return enum_seq(static_cast<RTLIB::LibcallImpl>(1), RTLIB::NumLibcallImpls);
}

/// Manage a bitset representing the list of available libcalls for a module.
class LibcallImplBitset : public Bitset<RTLIB::NumLibcallImpls> {
public:
constexpr LibcallImplBitset() = default;
constexpr LibcallImplBitset(
const Bitset<RTLIB::NumLibcallImpls>::StorageType &Src)
: Bitset(Src) {}
};

/// A simple container for information about the supported runtime calls.
struct RuntimeLibcallsInfo {
private:
/// Bitset of libcalls a module may emit a call to.
LibcallImplBitset AvailableLibcallImpls;

public:
explicit RuntimeLibcallsInfo(
const Triple &TT,
ExceptionHandling ExceptionModel = ExceptionHandling::None,
Expand Down Expand Up @@ -132,6 +147,14 @@ struct RuntimeLibcallsInfo {
return ImplToLibcall[Impl];
}

bool isAvailable(RTLIB::LibcallImpl Impl) const {
return AvailableLibcallImpls.test(Impl);
}

void setAvailable(RTLIB::LibcallImpl Impl) {
AvailableLibcallImpls.set(Impl);
}

/// Check if this is valid libcall for the current module, otherwise
/// RTLIB::Unsupported.
LLVM_ABI RTLIB::LibcallImpl getSupportedLibcallImpl(StringRef FuncName) const;
Expand Down
8 changes: 2 additions & 6 deletions llvm/lib/IR/RuntimeLibcalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,8 @@ RuntimeLibcallsInfo::getSupportedLibcallImpl(StringRef FuncName) const {
for (auto I = Range.begin(); I != Range.end(); ++I) {
RTLIB::LibcallImpl Impl =
static_cast<RTLIB::LibcallImpl>(I - RuntimeLibcallNameOffsets.begin());

// FIXME: This should not depend on looking up ImplToLibcall, only the list
// of libcalls for the module.
RTLIB::LibcallImpl Recognized = LibcallImpls[ImplToLibcall[Impl]];
if (Recognized != RTLIB::Unsupported)
return Recognized;
if (isAvailable(Impl))
return Impl;
}

return RTLIB::Unsupported;
Expand Down
22 changes: 22 additions & 0 deletions llvm/test/TableGen/RuntimeLibcallEmitter-calling-conv.td
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,18 @@ def MSP430LibraryWithCondCC : SystemRuntimeLibrary<isMSP430,
// CHECK-NEXT: Entry = DefaultCC;
// CHECK-NEXT: }
// CHECK-EMPTY:
// CHECK-NEXT: static constexpr LibcallImplBitset SystemAvailableImpls({
// CHECK-NEXT: 0x0000000000001a
// CHECK-NEXT: });
// CHECK-NEXT: AvailableLibcallImpls = SystemAvailableImpls;
// CHECK-EMPTY:
// CHECK-NEXT: static const LibcallImplPair LibraryCalls[] = {
// CHECK-NEXT: {RTLIB::MALLOC, RTLIB::malloc}, // malloc
// CHECK-NEXT: };
// CHECK-EMPTY:
// CHECK-NEXT: for (const auto [Func, Impl] : LibraryCalls) {
// CHECK-NEXT: setLibcallImpl(Func, Impl);
// CHECK-NEXT: setAvailable(Impl);
// CHECK-NEXT: }
// CHECK-EMPTY:
// CHECK-NEXT: static const LibcallImplPair LibraryCalls_AlwaysAvailable[] = {
Expand All @@ -63,19 +69,26 @@ def MSP430LibraryWithCondCC : SystemRuntimeLibrary<isMSP430,
// CHECK-EMPTY:
// CHECK-NEXT: for (const auto [Func, Impl] : LibraryCalls_AlwaysAvailable) {
// CHECK-NEXT: setLibcallImpl(Func, Impl);
// CHECK-NEXT: setAvailable(Impl);
// CHECK-NEXT: setLibcallImplCallingConv(Impl, CallingConv::AVR_BUILTIN);
// CHECK-NEXT: }
// CHECK-EMPTY:
// CHECK-NEXT: return;
// CHECK-NEXT: }
// CHECK-EMPTY:
// CHECK-NEXT: if (TT.getArch() == Triple::avr) {
// CHECK-NEXT: static constexpr LibcallImplBitset SystemAvailableImpls({
// CHECK-NEXT: 0x0000000000001a
// CHECK-NEXT: });
// CHECK-NEXT: AvailableLibcallImpls = SystemAvailableImpls;
// CHECK-EMPTY:
// CHECK-NEXT: static const LibcallImplPair LibraryCalls[] = {
// CHECK-NEXT: {RTLIB::MALLOC, RTLIB::malloc}, // malloc
// CHECK-NEXT: };
// CHECK-EMPTY:
// CHECK-NEXT: for (const auto [Func, Impl] : LibraryCalls) {
// CHECK-NEXT: setLibcallImpl(Func, Impl);
// CHECK-NEXT: setAvailable(Impl);
// CHECK-NEXT: }
// CHECK-EMPTY:
// CHECK-NEXT: static const LibcallImplPair LibraryCalls_AlwaysAvailable[] = {
Expand All @@ -85,19 +98,26 @@ def MSP430LibraryWithCondCC : SystemRuntimeLibrary<isMSP430,
// CHECK-EMPTY:
// CHECK-NEXT: for (const auto [Func, Impl] : LibraryCalls_AlwaysAvailable) {
// CHECK-NEXT: setLibcallImpl(Func, Impl);
// CHECK-NEXT: setAvailable(Impl);
// CHECK-NEXT: setLibcallImplCallingConv(Impl, CallingConv::AVR_BUILTIN);
// CHECK-NEXT: }
// CHECK-EMPTY:
// CHECK-NEXT: return;
// CHECK-NEXT: }
// CHECK-EMPTY:
// CHECK-NEXT: if (TT.getArch() == Triple::msp430) {
// CHECK-NEXT: static constexpr LibcallImplBitset SystemAvailableImpls({
// CHECK-NEXT: 0x00000000000010
// CHECK-NEXT: });
// CHECK-NEXT: AvailableLibcallImpls = SystemAvailableImpls;
// CHECK-EMPTY:
// CHECK-NEXT: static const LibcallImplPair LibraryCalls[] = {
// CHECK-NEXT: {RTLIB::MALLOC, RTLIB::malloc}, // malloc
// CHECK-NEXT: };
// CHECK-EMPTY:
// CHECK-NEXT: for (const auto [Func, Impl] : LibraryCalls) {
// CHECK-NEXT: setLibcallImpl(Func, Impl);
// CHECK-NEXT: setAvailable(Impl);
// CHECK-NEXT: }
// CHECK-EMPTY:
// CHECK-NEXT: if ( isFoo() ) {
Expand All @@ -107,6 +127,7 @@ def MSP430LibraryWithCondCC : SystemRuntimeLibrary<isMSP430,
// CHECK-EMPTY:
// CHECK-NEXT: for (const auto [Func, Impl] : LibraryCalls_anonymous_3) {
// CHECK-NEXT: setLibcallImpl(Func, Impl);
// CHECK-NEXT: setAvailable(Impl);
// CHECK-NEXT: setLibcallImplCallingConv(Impl, CallingConv::AVR_BUILTIN);
// CHECK-NEXT: }
// CHECK-EMPTY:
Expand All @@ -119,6 +140,7 @@ def MSP430LibraryWithCondCC : SystemRuntimeLibrary<isMSP430,
// CHECK-EMPTY:
// CHECK-NEXT: for (const auto [Func, Impl] : LibraryCalls_anonymous_5) {
// CHECK-NEXT: setLibcallImpl(Func, Impl);
// CHECK-NEXT: setAvailable(Impl);
// CHECK-NEXT: setLibcallImplCallingConv(Impl, CallingConv::MSP430_BUILTIN);
// CHECK-NEXT: }
// CHECK-EMPTY:
Expand Down
15 changes: 15 additions & 0 deletions llvm/test/TableGen/RuntimeLibcallEmitter-conflict-warning.td
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ def dup1 : RuntimeLibcallImpl<ANOTHER_DUP>;
// func_a and func_b both provide SOME_FUNC.

// CHECK: if (isTargetArchA()) {
// CHECK-NEXT: static constexpr LibcallImplBitset SystemAvailableImpls({
// CHECK-NEXT: 0x00000000000018
// CHECK-NEXT: });
// CHECK-NEXT: AvailableLibcallImpls = SystemAvailableImpls;
// CHECK-EMPTY:
// CHECK-NEXT: static const LibcallImplPair LibraryCalls[] = {
// CHECK-NEXT: {RTLIB::SOME_FUNC, RTLIB::func_b}, // func_b
// CHECK-NEXT: };
Expand All @@ -35,6 +40,11 @@ def TheSystemLibraryA : SystemRuntimeLibrary<isTargetArchA,
>;

// CHECK: if (isTargetArchB()) {
// CHECK-NEXT: static constexpr LibcallImplBitset SystemAvailableImpls({
// CHECK-NEXT: 0x00000000000058
// CHECK-NEXT: });
// CHECK-NEXT: AvailableLibcallImpls = SystemAvailableImpls;
// CHECK-EMPTY:
// CHECK-NEXT: static const LibcallImplPair LibraryCalls[] = {
// CHECK-NEXT: {RTLIB::OTHER_FUNC, RTLIB::other_func}, // other_func
// CHECK-NEXT: {RTLIB::SOME_FUNC, RTLIB::func_a}, // func_a
Expand All @@ -46,6 +56,11 @@ def TheSystemLibraryB : SystemRuntimeLibrary<isTargetArchB,
>;

// CHECK: if (isTargetArchC()) {
// CHECK-NEXT: static constexpr LibcallImplBitset SystemAvailableImpls({
// CHECK-NEXT: 0x0000000000007e
// CHECK-NEXT: });
// CHECK-NEXT: AvailableLibcallImpls = SystemAvailableImpls;
// CHECK-EMPTY:
// CHECK-NEXT: static const LibcallImplPair LibraryCalls[] = {
// CHECK-NEXT: {RTLIB::ANOTHER_DUP, RTLIB::dup1}, // dup1
// CHECK-NEXT: {RTLIB::OTHER_FUNC, RTLIB::other_func}, // other_func
Expand Down
27 changes: 27 additions & 0 deletions llvm/test/TableGen/RuntimeLibcallEmitter.td
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,11 @@ def BlahLibrary : SystemRuntimeLibrary<isBlahArch, (add calloc, LibraryWithCondi
// CHECK-NEXT: };
// CHECK-EMPTY:
// CHECK-NEXT: if (TT.getArch() == Triple::blah) {
// CHECK-NEXT: static constexpr LibcallImplBitset SystemAvailableImpls({
// CHECK-NEXT: 0x000000000000e0
// CHECK-NEXT: });
// CHECK-NEXT: AvailableLibcallImpls = SystemAvailableImpls;
// CHECK-EMPTY:
// CHECK-NEXT: static const LibcallImplPair LibraryCalls[] = {
// CHECK-NEXT: {RTLIB::BZERO, RTLIB::bzero}, // bzero
// CHECK-NEXT: {RTLIB::CALLOC, RTLIB::calloc}, // calloc
Expand All @@ -165,6 +170,7 @@ def BlahLibrary : SystemRuntimeLibrary<isBlahArch, (add calloc, LibraryWithCondi
// CHECK-EMPTY:
// CHECK-NEXT: for (const auto [Func, Impl] : LibraryCalls) {
// CHECK-NEXT: setLibcallImpl(Func, Impl);
// CHECK-NEXT: setAvailable(Impl);
// CHECK-NEXT: }
// CHECK-EMPTY:
// CHECK-NEXT: if (TT.hasCompilerRT()) {
Expand All @@ -175,6 +181,7 @@ def BlahLibrary : SystemRuntimeLibrary<isBlahArch, (add calloc, LibraryWithCondi
// CHECK-EMPTY:
// CHECK-NEXT: for (const auto [Func, Impl] : LibraryCalls_hasCompilerRT) {
// CHECK-NEXT: setLibcallImpl(Func, Impl);
// CHECK-NEXT: setAvailable(Impl);
// CHECK-NEXT: }
// CHECK-EMPTY:
// CHECK-NEXT: }
Expand All @@ -186,6 +193,7 @@ def BlahLibrary : SystemRuntimeLibrary<isBlahArch, (add calloc, LibraryWithCondi
// CHECK-EMPTY:
// CHECK-NEXT: for (const auto [Func, Impl] : LibraryCalls_isBarOS) {
// CHECK-NEXT: setLibcallImpl(Func, Impl);
// CHECK-NEXT: setAvailable(Impl);
// CHECK-NEXT: }
// CHECK-EMPTY:
// CHECK-NEXT: }
Expand All @@ -194,6 +202,11 @@ def BlahLibrary : SystemRuntimeLibrary<isBlahArch, (add calloc, LibraryWithCondi
// CHECK-NEXT: }
// CHECK-EMPTY:
// CHECK-NEXT: if (TT.getArch() == Triple::buzz) {
// CHECK-NEXT: static constexpr LibcallImplBitset SystemAvailableImpls({
// CHECK-NEXT: 0x00000000000118
// CHECK-NEXT: });
// CHECK-NEXT: AvailableLibcallImpls = SystemAvailableImpls;
// CHECK-EMPTY:
// CHECK-NEXT: static const LibcallImplPair LibraryCalls[] = {
// CHECK-NEXT: {RTLIB::SHL_I32, RTLIB::__ashlsi3}, // __ashlsi3
// CHECK-NEXT: {RTLIB::SQRT_F80, RTLIB::sqrtl_f80}, // sqrtl
Expand All @@ -202,19 +215,26 @@ def BlahLibrary : SystemRuntimeLibrary<isBlahArch, (add calloc, LibraryWithCondi
// CHECK-EMPTY:
// CHECK-NEXT: for (const auto [Func, Impl] : LibraryCalls) {
// CHECK-NEXT: setLibcallImpl(Func, Impl);
// CHECK-NEXT: setAvailable(Impl);
// CHECK-NEXT: }
// CHECK-EMPTY:
// CHECK-NEXT: return;
// CHECK-NEXT: }
// CHECK-EMPTY:
// CHECK-NEXT: if (TT.getArch() == Triple::foo) {
// CHECK-NEXT: static constexpr LibcallImplBitset SystemAvailableImpls({
// CHECK-NEXT: 0x000000000000a0
// CHECK-NEXT: });
// CHECK-NEXT: AvailableLibcallImpls = SystemAvailableImpls;
// CHECK-EMPTY:
// CHECK-NEXT: static const LibcallImplPair LibraryCalls[] = {
// CHECK-NEXT: {RTLIB::BZERO, RTLIB::bzero}, // bzero
// CHECK-NEXT: {RTLIB::SQRT_F128, RTLIB::sqrtl_f128}, // sqrtl
// CHECK-NEXT: };
// CHECK-EMPTY:
// CHECK-NEXT: for (const auto [Func, Impl] : LibraryCalls) {
// CHECK-NEXT: setLibcallImpl(Func, Impl);
// CHECK-NEXT: setAvailable(Impl);
// CHECK-NEXT: }
// CHECK-EMPTY:
// CHECK-NEXT: if (TT.getOS() == Triple::bar) {
Expand All @@ -224,6 +244,7 @@ def BlahLibrary : SystemRuntimeLibrary<isBlahArch, (add calloc, LibraryWithCondi
// CHECK-EMPTY:
// CHECK-NEXT: for (const auto [Func, Impl] : LibraryCalls_isBarOS) {
// CHECK-NEXT: setLibcallImpl(Func, Impl);
// CHECK-NEXT: setAvailable(Impl);
// CHECK-NEXT: }
// CHECK-EMPTY:
// CHECK-NEXT: }
Expand All @@ -232,6 +253,11 @@ def BlahLibrary : SystemRuntimeLibrary<isBlahArch, (add calloc, LibraryWithCondi
// CHECK-NEXT: }
// CHECK-EMPTY:
// CHECK-NEXT: if (TT.getArch() == Triple::simple) {
// CHECK-NEXT: static constexpr LibcallImplBitset SystemAvailableImpls({
// CHECK-NEXT: 0x00000000000158
// CHECK-NEXT: });
// CHECK-NEXT: AvailableLibcallImpls = SystemAvailableImpls;
// CHECK-EMPTY:
// CHECK-NEXT: static const LibcallImplPair LibraryCalls[] = {
// CHECK-NEXT: {RTLIB::CALLOC, RTLIB::calloc}, // calloc
// CHECK-NEXT: {RTLIB::SHL_I32, RTLIB::__ashlsi3}, // __ashlsi3
Expand All @@ -241,6 +267,7 @@ def BlahLibrary : SystemRuntimeLibrary<isBlahArch, (add calloc, LibraryWithCondi
// CHECK-EMPTY:
// CHECK-NEXT: for (const auto [Func, Impl] : LibraryCalls) {
// CHECK-NEXT: setLibcallImpl(Func, Impl);
// CHECK-NEXT: setAvailable(Impl);
// CHECK-NEXT: }
// CHECK-EMPTY:
// CHECK-NEXT: return;
Expand Down
Loading
Loading