Skip to content

Commit 0ed3113

Browse files
author
git apple-llvm automerger
committed
Merge commit 'aa406aaa6718' from llvm.org/main into next
2 parents 7784c59 + aa406aa commit 0ed3113

File tree

5 files changed

+148
-24
lines changed

5 files changed

+148
-24
lines changed

llvm/include/llvm/IR/RuntimeLibcalls.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#define LLVM_IR_RUNTIME_LIBCALLS_H
1616

1717
#include "llvm/ADT/ArrayRef.h"
18+
#include "llvm/ADT/Bitset.h"
1819
#include "llvm/ADT/Sequence.h"
1920
#include "llvm/ADT/StringTable.h"
2021
#include "llvm/IR/CallingConv.h"
@@ -54,8 +55,22 @@ static inline auto libcall_impls() {
5455
static_cast<RTLIB::LibcallImpl>(RTLIB::NumLibcallImpls));
5556
}
5657

58+
/// Manage a bitset representing the list of available libcalls for a module.
59+
class LibcallImplBitset : public Bitset<RTLIB::NumLibcallImpls> {
60+
public:
61+
constexpr LibcallImplBitset() = default;
62+
constexpr LibcallImplBitset(
63+
const std::array<uint64_t, (RTLIB::NumLibcallImpls + 63) / 64> &Src)
64+
: Bitset(Src) {}
65+
};
66+
5767
/// A simple container for information about the supported runtime calls.
5868
struct RuntimeLibcallsInfo {
69+
private:
70+
/// Bitset of libcalls a module may emit a call to.
71+
LibcallImplBitset AvailableLibcallImpls;
72+
73+
public:
5974
explicit RuntimeLibcallsInfo(
6075
const Triple &TT,
6176
ExceptionHandling ExceptionModel = ExceptionHandling::None,
@@ -129,6 +144,14 @@ struct RuntimeLibcallsInfo {
129144
return getLibcallName(RTLIB::MEMMOVE);
130145
}
131146

147+
bool isAvailable(RTLIB::LibcallImpl Impl) const {
148+
return AvailableLibcallImpls.test(Impl);
149+
}
150+
151+
void setAvailable(RTLIB::LibcallImpl Impl) {
152+
AvailableLibcallImpls.set(Impl);
153+
}
154+
132155
/// Return the libcall provided by \p Impl
133156
static RTLIB::Libcall getLibcallFromImpl(RTLIB::LibcallImpl Impl) {
134157
return ImplToLibcall[Impl];

llvm/test/TableGen/RuntimeLibcallEmitter-calling-conv.td

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ def MSP430LibraryWithCondCC : SystemRuntimeLibrary<isMSP430,
4848
// CHECK-NEXT: Entry = DefaultCC;
4949
// CHECK-NEXT: }
5050
// CHECK-EMPTY:
51+
// CHECK-NEXT: static constexpr LibcallImplBitset SystemAvailableImpls({
52+
// CHECK-NEXT: 0x0000000000001a
53+
// CHECK-NEXT: });
54+
// CHECK-NEXT: AvailableLibcallImpls = SystemAvailableImpls;
55+
// CHECK-EMPTY:
5156
// CHECK-NEXT: static const LibcallImplPair LibraryCalls[] = {
5257
// CHECK-NEXT: {RTLIB::MALLOC, RTLIB::impl_malloc}, // malloc
5358
// CHECK-NEXT: };
@@ -70,9 +75,14 @@ def MSP430LibraryWithCondCC : SystemRuntimeLibrary<isMSP430,
7075
// CHECK-NEXT: }
7176
// CHECK-EMPTY:
7277
// CHECK-NEXT: if (TT.getArch() == Triple::avr) {
73-
// CHECK-NEXT: static const LibcallImplPair LibraryCalls[] = {
74-
// CHECK-NEXT: {RTLIB::MALLOC, RTLIB::impl_malloc}, // malloc
75-
// CHECK-NEXT: };
78+
// CHECK-NEXT: static constexpr LibcallImplBitset SystemAvailableImpls({
79+
// CHECK-NEXT: 0x0000000000001a
80+
// CHECK-NEXT: });
81+
// CHECK-NEXT: AvailableLibcallImpls = SystemAvailableImpls;
82+
// CHECK-EMPTY:
83+
// CHECK-NEXT: static const LibcallImplPair LibraryCalls[] = {
84+
// CHECK-NEXT: {RTLIB::MALLOC, RTLIB::impl_malloc}, // malloc
85+
// CHECK-NEXT: };
7686
// CHECK-EMPTY:
7787
// CHECK-NEXT: for (const auto [Func, Impl] : LibraryCalls) {
7888
// CHECK-NEXT: setLibcallImpl(Func, Impl);
@@ -92,6 +102,11 @@ def MSP430LibraryWithCondCC : SystemRuntimeLibrary<isMSP430,
92102
// CHECK-NEXT: }
93103
// CHECK-EMPTY:
94104
// CHECK-NEXT: if (TT.getArch() == Triple::msp430) {
105+
// CHECK-NEXT: static constexpr LibcallImplBitset SystemAvailableImpls({
106+
// CHECK-NEXT: 0x00000000000010
107+
// CHECK-NEXT: });
108+
// CHECK-NEXT: AvailableLibcallImpls = SystemAvailableImpls;
109+
// CHECK-EMPTY:
95110
// CHECK-NEXT: static const LibcallImplPair LibraryCalls[] = {
96111
// CHECK-NEXT: {RTLIB::MALLOC, RTLIB::impl_malloc}, // malloc
97112
// CHECK-NEXT: };

llvm/test/TableGen/RuntimeLibcallEmitter-conflict-warning.td

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,32 +25,69 @@ def dup1 : RuntimeLibcallImpl<ANOTHER_DUP>;
2525
// func_a and func_b both provide SOME_FUNC.
2626

2727
// CHECK: if (isTargetArchA()) {
28-
// CHECK-NEXT: static const LibcallImplPair LibraryCalls[] = {
29-
// CHECK-NEXT: {RTLIB::SOME_FUNC, RTLIB::impl_func_b}, // func_b
30-
// CHECK-NEXT: };
28+
// CHECK-NEXT: static constexpr LibcallImplBitset SystemAvailableImpls({
29+
// CHECK-NEXT: 0x00000000000018
30+
// CHECK-NEXT: });
31+
// CHECK-NEXT: AvailableLibcallImpls = SystemAvailableImpls;
32+
// CHECK-EMPTY:
33+
34+
// CHECK-NEXT: static const LibcallImplPair LibraryCalls[] = {
35+
// CHECK-NEXT: {RTLIB::SOME_FUNC, RTLIB::impl_func_b}, // func_b
36+
// CHECK-NEXT: };
37+
// CHECK-EMPTY:
38+
// CHECK-NEXT: for (const auto [Func, Impl] : LibraryCalls) {
39+
// CHECK-NEXT: setLibcallImpl(Func, Impl);
40+
// CHECK-NEXT: }
41+
// CHECK-EMPTY:
42+
// CHECK-NEXT: return;
43+
// CHECK-NEXT: }
3144

3245
// ERR: :[[@LINE+1]]:5: warning: conflicting implementations for libcall SOME_FUNC: func_b, func_a
3346
def TheSystemLibraryA : SystemRuntimeLibrary<isTargetArchA,
3447
(add func_b, func_a)
3548
>;
3649

3750
// CHECK: if (isTargetArchB()) {
38-
// CHECK-NEXT: static const LibcallImplPair LibraryCalls[] = {
39-
// CHECK-NEXT: {RTLIB::OTHER_FUNC, RTLIB::impl_other_func}, // other_func
40-
// CHECK-NEXT: {RTLIB::SOME_FUNC, RTLIB::impl_func_a}, // func_a
41-
// CHECK-NEXT: };
51+
// CHECK-NEXT: static constexpr LibcallImplBitset SystemAvailableImpls({
52+
// CHECK-NEXT: 0x00000000000058
53+
// CHECK-NEXT: });
54+
// CHECK-NEXT: AvailableLibcallImpls = SystemAvailableImpls;
55+
// CHECK-EMPTY:
56+
// CHECK-NEXT: static const LibcallImplPair LibraryCalls[] = {
57+
// CHECK-NEXT: {RTLIB::OTHER_FUNC, RTLIB::impl_other_func}, // other_func
58+
// CHECK-NEXT: {RTLIB::SOME_FUNC, RTLIB::impl_func_a}, // func_a
59+
// CHECK-NEXT: };
60+
// CHECK-EMPTY:
61+
// CHECK-NEXT: for (const auto [Func, Impl] : LibraryCalls) {
62+
// CHECK-NEXT: setLibcallImpl(Func, Impl);
63+
// CHECK-NEXT: }
64+
// CHECK-EMPTY:
65+
// CHECK-NEXT: return;
66+
// CHECK-NEXT: }
4267

4368
// ERR: :[[@LINE+1]]:5: warning: conflicting implementations for libcall SOME_FUNC: func_a, func_b
4469
def TheSystemLibraryB : SystemRuntimeLibrary<isTargetArchB,
4570
(add func_a, other_func, func_b)
4671
>;
4772

4873
// CHECK: if (isTargetArchC()) {
49-
// CHECK-NEXT: static const LibcallImplPair LibraryCalls[] = {
50-
// CHECK-NEXT: {RTLIB::ANOTHER_DUP, RTLIB::impl_dup1}, // dup1
51-
// CHECK-NEXT: {RTLIB::OTHER_FUNC, RTLIB::impl_other_func}, // other_func
52-
// CHECK-NEXT: {RTLIB::SOME_FUNC, RTLIB::impl_func_a}, // func_a
53-
// CHECK-NEXT: };
74+
// CHECK-NEXT: static constexpr LibcallImplBitset SystemAvailableImpls({
75+
// CHECK-NEXT: 0x0000000000007e
76+
// CHECK-NEXT: });
77+
// CHECK-NEXT: AvailableLibcallImpls = SystemAvailableImpls;
78+
// CHECK-EMPTY:
79+
// CHECK-NEXT: static const LibcallImplPair LibraryCalls[] = {
80+
// CHECK-NEXT: {RTLIB::ANOTHER_DUP, RTLIB::impl_dup1}, // dup1
81+
// CHECK-NEXT: {RTLIB::OTHER_FUNC, RTLIB::impl_other_func}, // other_func
82+
// CHECK-NEXT: {RTLIB::SOME_FUNC, RTLIB::impl_func_a}, // func_a
83+
// CHECK-NEXT: };
84+
// CHECK-EMPTY:
85+
// CHECK-NEXT: for (const auto [Func, Impl] : LibraryCalls) {
86+
// CHECK-NEXT: setLibcallImpl(Func, Impl);
87+
// CHECK-NEXT: }
88+
// CHECK-EMPTY:
89+
// CHECK-NEXT: return;
90+
// CHECK-NEXT: }
5491

5592
// ERR: :[[@LINE+3]]:5: warning: conflicting implementations for libcall ANOTHER_DUP: dup1, dup0
5693
// ERR: :[[@LINE+2]]:5: warning: conflicting implementations for libcall SOME_FUNC: func_a, func_b

llvm/test/TableGen/RuntimeLibcallEmitter.td

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -196,15 +196,20 @@ def BlahLibrary : SystemRuntimeLibrary<isBlahArch, (add calloc, LibraryWithCondi
196196
// CHECK-NEXT: };
197197
// CHECK-EMPTY:
198198
// CHECK-NEXT: if (TT.getArch() == Triple::blah) {
199-
// CHECK-NEXT: static const LibcallImplPair LibraryCalls[] = {
200-
// CHECK-NEXT: {RTLIB::BZERO, RTLIB::impl_bzero}, // bzero
201-
// CHECK-NEXT: {RTLIB::CALLOC, RTLIB::impl_calloc}, // calloc
202-
// CHECK-NEXT: {RTLIB::SQRT_F128, RTLIB::impl_sqrtl_f128}, // sqrtl
203-
// CHECK-NEXT: };
199+
// CHECK-NEXT: static constexpr LibcallImplBitset SystemAvailableImpls({
200+
// CHECK-NEXT: 0x000000000000e0
201+
// CHECK-NEXT: });
202+
// CHECK-NEXT: AvailableLibcallImpls = SystemAvailableImpls;
204203
// CHECK-EMPTY:
205-
// CHECK-NEXT: for (const auto [Func, Impl] : LibraryCalls) {
206-
// CHECK-NEXT: setLibcallImpl(Func, Impl);
207-
// CHECK-NEXT: }
204+
// CHECK-NEXT: static const LibcallImplPair LibraryCalls[] = {
205+
// CHECK-NEXT: {RTLIB::BZERO, RTLIB::impl_bzero}, // bzero
206+
// CHECK-NEXT: {RTLIB::CALLOC, RTLIB::impl_calloc}, // calloc
207+
// CHECK-NEXT: {RTLIB::SQRT_F128, RTLIB::impl_sqrtl_f128}, // sqrtl
208+
// CHECK-NEXT: };
209+
// CHECK-EMPTY:
210+
// CHECK-NEXT: for (const auto [Func, Impl] : LibraryCalls) {
211+
// CHECK-NEXT: setLibcallImpl(Func, Impl);
212+
// CHECK-NEXT: }
208213
// CHECK-EMPTY:
209214
// CHECK-NEXT: if (TT.hasCompilerRT()) {
210215
// CHECK-NEXT: static const LibcallImplPair LibraryCalls_hasCompilerRT[] = {
@@ -233,6 +238,11 @@ def BlahLibrary : SystemRuntimeLibrary<isBlahArch, (add calloc, LibraryWithCondi
233238
// CHECK-NEXT: }
234239
// CHECK-EMPTY:
235240
// CHECK-NEXT: if (TT.getArch() == Triple::buzz) {
241+
// CHECK-NEXT: static constexpr LibcallImplBitset SystemAvailableImpls({
242+
// CHECK-NEXT: 0x00000000000118
243+
// CHECK-NEXT: });
244+
// CHECK-NEXT: AvailableLibcallImpls = SystemAvailableImpls;
245+
// CHECK-EMPTY:
236246
// CHECK-NEXT: static const LibcallImplPair LibraryCalls[] = {
237247
// CHECK-NEXT: {RTLIB::SHL_I32, RTLIB::impl___ashlsi3}, // __ashlsi3
238248
// CHECK-NEXT: {RTLIB::SQRT_F80, RTLIB::impl_sqrtl_f80}, // sqrtl
@@ -247,6 +257,11 @@ def BlahLibrary : SystemRuntimeLibrary<isBlahArch, (add calloc, LibraryWithCondi
247257
// CHECK-NEXT: }
248258
// CHECK-EMPTY:
249259
// CHECK-NEXT: if (TT.getArch() == Triple::foo) {
260+
// CHECK-NEXT: static constexpr LibcallImplBitset SystemAvailableImpls({
261+
// CHECK-NEXT: 0x000000000000a0
262+
// CHECK-NEXT: });
263+
// CHECK-NEXT: AvailableLibcallImpls = SystemAvailableImpls;
264+
// CHECK-EMPTY:
250265
// CHECK-NEXT: static const LibcallImplPair LibraryCalls[] = {
251266
// CHECK-NEXT: {RTLIB::BZERO, RTLIB::impl_bzero}, // bzero
252267
// CHECK-NEXT: {RTLIB::SQRT_F128, RTLIB::impl_sqrtl_f128}, // sqrtl
@@ -271,6 +286,11 @@ def BlahLibrary : SystemRuntimeLibrary<isBlahArch, (add calloc, LibraryWithCondi
271286
// CHECK-NEXT: }
272287
// CHECK-EMPTY:
273288
// CHECK-NEXT: if (TT.getArch() == Triple::simple) {
289+
// CHECK-NEXT: static constexpr LibcallImplBitset SystemAvailableImpls({
290+
// CHECK-NEXT: 0x00000000000158
291+
// CHECK-NEXT: });
292+
// CHECK-NEXT: AvailableLibcallImpls = SystemAvailableImpls;
293+
// CHECK-EMPTY:
274294
// CHECK-NEXT: static const LibcallImplPair LibraryCalls[] = {
275295
// CHECK-NEXT: {RTLIB::CALLOC, RTLIB::impl_calloc}, // calloc
276296
// CHECK-NEXT: {RTLIB::SHL_I32, RTLIB::impl___ashlsi3}, // __ashlsi3

llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,12 @@ void RuntimeLibcallEmitter::emitSystemRuntimeLibrarySetCalls(
588588
PredicateSorter.insert(
589589
PredicateWithCC()); // No predicate or CC override first.
590590

591+
constexpr unsigned BitsPerStorageElt = 64;
591592
DenseMap<PredicateWithCC, LibcallsWithCC> Pred2Funcs;
593+
594+
SmallVector<uint64_t, 32> BitsetValues(
595+
divideCeil(RuntimeLibcallImplDefList.size(), BitsPerStorageElt));
596+
592597
for (const Record *Elt : *Elements) {
593598
const RuntimeLibcallImpl *LibCallImpl = getRuntimeLibcallImpl(Elt);
594599
if (!LibCallImpl) {
@@ -597,23 +602,47 @@ void RuntimeLibcallEmitter::emitSystemRuntimeLibrarySetCalls(
597602
continue;
598603
}
599604

605+
size_t BitIdx = LibCallImpl->getEnumVal();
606+
uint64_t BitmaskVal = uint64_t(1) << (BitIdx % BitsPerStorageElt);
607+
size_t BitsetIdx = BitIdx / BitsPerStorageElt;
608+
600609
auto It = Func2Preds.find(LibCallImpl);
601610
if (It == Func2Preds.end()) {
611+
BitsetValues[BitsetIdx] |= BitmaskVal;
602612
Pred2Funcs[PredicateWithCC()].LibcallImpls.push_back(LibCallImpl);
603613
continue;
604614
}
605615

606616
for (const Record *Pred : It->second.first) {
607617
const Record *CC = It->second.second;
608-
PredicateWithCC Key(Pred, CC);
618+
AvailabilityPredicate SubsetPredicate(Pred);
619+
if (SubsetPredicate.isAlwaysAvailable())
620+
BitsetValues[BitsetIdx] |= BitmaskVal;
609621

622+
PredicateWithCC Key(Pred, CC);
610623
auto &Entry = Pred2Funcs[Key];
611624
Entry.LibcallImpls.push_back(LibCallImpl);
612625
Entry.CallingConv = It->second.second;
613626
PredicateSorter.insert(Key);
614627
}
615628
}
616629

630+
OS << " static constexpr LibcallImplBitset SystemAvailableImpls({\n"
631+
<< indent(6);
632+
633+
ListSeparator LS;
634+
unsigned EntryCount = 0;
635+
for (uint64_t Bits : BitsetValues) {
636+
if (EntryCount++ == 4) {
637+
EntryCount = 1;
638+
OS << ",\n" << indent(6);
639+
} else
640+
OS << LS;
641+
OS << format_hex(Bits, 16);
642+
}
643+
OS << "\n });\n"
644+
" AvailableLibcallImpls = SystemAvailableImpls;\n\n";
645+
617646
SmallVector<PredicateWithCC, 0> SortedPredicates =
618647
PredicateSorter.takeVector();
619648

0 commit comments

Comments
 (0)