diff --git a/llvm/cmake/config-ix.cmake b/llvm/cmake/config-ix.cmake index a8e4e5a63244d..f321ab0bdebe5 100644 --- a/llvm/cmake/config-ix.cmake +++ b/llvm/cmake/config-ix.cmake @@ -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}") @@ -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 \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") diff --git a/llvm/include/llvm/Config/llvm-config.h.cmake b/llvm/include/llvm/Config/llvm-config.h.cmake index 39136bc45c292..13767a2e80325 100644 --- a/llvm/include/llvm/Config/llvm-config.h.cmake +++ b/llvm/include/llvm/Config/llvm-config.h.cmake @@ -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 diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.h b/llvm/include/llvm/IR/RuntimeLibcalls.h index f39e2e3c26900..04bda69c40280 100644 --- a/llvm/include/llvm/IR/RuntimeLibcalls.h +++ b/llvm/include/llvm/IR/RuntimeLibcalls.h @@ -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" @@ -53,8 +54,22 @@ static inline auto libcall_impls() { return enum_seq(static_cast(1), RTLIB::NumLibcallImpls); } +/// Manage a bitset representing the list of available libcalls for a module. +class LibcallImplBitset : public Bitset { +public: + constexpr LibcallImplBitset() = default; + constexpr LibcallImplBitset( + const Bitset::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, @@ -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; diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp index a8e6c7938cf54..21a8d03c3a552 100644 --- a/llvm/lib/IR/RuntimeLibcalls.cpp +++ b/llvm/lib/IR/RuntimeLibcalls.cpp @@ -96,12 +96,8 @@ RuntimeLibcallsInfo::getSupportedLibcallImpl(StringRef FuncName) const { for (auto I = Range.begin(); I != Range.end(); ++I) { RTLIB::LibcallImpl Impl = static_cast(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; diff --git a/llvm/test/TableGen/RuntimeLibcallEmitter-calling-conv.td b/llvm/test/TableGen/RuntimeLibcallEmitter-calling-conv.td index 49d5ecaa0e5c5..14c811da64910 100644 --- a/llvm/test/TableGen/RuntimeLibcallEmitter-calling-conv.td +++ b/llvm/test/TableGen/RuntimeLibcallEmitter-calling-conv.td @@ -48,12 +48,18 @@ def MSP430LibraryWithCondCC : SystemRuntimeLibrary; // 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: }; @@ -35,6 +40,11 @@ def TheSystemLibraryA : SystemRuntimeLibrary; // 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 @@ -46,6 +56,11 @@ def TheSystemLibraryB : SystemRuntimeLibrary; // 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 diff --git a/llvm/test/TableGen/RuntimeLibcallEmitter.td b/llvm/test/TableGen/RuntimeLibcallEmitter.td index 642f8b85a89c6..97a632e8e75c7 100644 --- a/llvm/test/TableGen/RuntimeLibcallEmitter.td +++ b/llvm/test/TableGen/RuntimeLibcallEmitter.td @@ -157,6 +157,11 @@ def BlahLibrary : SystemRuntimeLibrary Pred2Funcs; + + SmallVector BitsetValues( + divideCeil(RuntimeLibcallImplDefList.size(), BitsPerStorageElt)); + for (const Record *Elt : *Elements) { const RuntimeLibcallImpl *LibCallImpl = getRuntimeLibcallImpl(Elt); if (!LibCallImpl) { @@ -410,16 +418,24 @@ void RuntimeLibcallEmitter::emitSystemRuntimeLibrarySetCalls( continue; } + size_t BitIdx = LibCallImpl->getEnumVal(); + uint64_t BitmaskVal = uint64_t(1) << (BitIdx % BitsPerStorageElt); + size_t BitsetIdx = BitIdx / BitsPerStorageElt; + auto It = Func2Preds.find(LibCallImpl); if (It == Func2Preds.end()) { + BitsetValues[BitsetIdx] |= BitmaskVal; Pred2Funcs[PredicateWithCC()].LibcallImpls.push_back(LibCallImpl); continue; } for (const Record *Pred : It->second.first) { const Record *CC = It->second.second; - PredicateWithCC Key(Pred, CC); + AvailabilityPredicate SubsetPredicate(Pred); + if (SubsetPredicate.isAlwaysAvailable()) + BitsetValues[BitsetIdx] |= BitmaskVal; + PredicateWithCC Key(Pred, CC); auto &Entry = Pred2Funcs[Key]; Entry.LibcallImpls.push_back(LibCallImpl); Entry.CallingConv = It->second.second; @@ -427,6 +443,22 @@ void RuntimeLibcallEmitter::emitSystemRuntimeLibrarySetCalls( } } + OS << " static constexpr LibcallImplBitset SystemAvailableImpls({\n" + << indent(6); + + ListSeparator LS; + unsigned EntryCount = 0; + for (uint64_t Bits : BitsetValues) { + if (EntryCount++ == 4) { + EntryCount = 1; + OS << ",\n" << indent(6); + } else + OS << LS; + OS << format_hex(Bits, 16); + } + OS << "\n });\n" + " AvailableLibcallImpls = SystemAvailableImpls;\n\n"; + SmallVector SortedPredicates = PredicateSorter.takeVector(); @@ -498,8 +530,11 @@ void RuntimeLibcallEmitter::emitSystemRuntimeLibrarySetCalls( << indent(IndentDepth + 2) << "for (const auto [Func, Impl] : LibraryCalls"; SubsetPredicate.emitTableVariableNameSuffix(OS); + + // TODO: setAvailable should be emitted without the uniquing above OS << ") {\n" - << indent(IndentDepth + 4) << "setLibcallImpl(Func, Impl);\n"; + << indent(IndentDepth + 4) << "setLibcallImpl(Func, Impl);\n" + << indent(IndentDepth + 4) << "setAvailable(Impl);\n"; if (FuncsWithCC.CallingConv) { StringRef CCEnum =