Skip to content

Commit aa36f2b

Browse files
committed
RuntimeLibcalls: Split lowering decisions into LibcallLoweringInfo
Introduce a new class for the TargetLowering usage. This tracks the subtarget specific lowering decisions for which libcall to use. RuntimeLibcallsInfo is a module level property, which may have multiple implementations of a particular libcall available. This attempts to be a minimum boilerplate patch to introduce the new concept. In the future we should have a tablegen way of selecting which implementations should be used for a subtarget. Currently we do have some conflicting implementations added, it just happens to work out that the default cases to prefer is alphabetically first (plus some of these still are using manual overrides in TargetLowering constructors).
1 parent 338fb02 commit aa36f2b

File tree

12 files changed

+209
-164
lines changed

12 files changed

+209
-164
lines changed

llvm/include/llvm/CodeGen/TargetLowering.h

Lines changed: 60 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,58 @@ struct MemOp {
193193
}
194194
};
195195

196+
class LibcallLoweringInfo {
197+
private:
198+
LLVM_ABI const RTLIB::RuntimeLibcallsInfo &RTLCI;
199+
/// Stores the implementation choice for each each libcall.
200+
LLVM_ABI RTLIB::LibcallImpl LibcallImpls[RTLIB::UNKNOWN_LIBCALL + 1] = {
201+
RTLIB::Unsupported};
202+
203+
public:
204+
LLVM_ABI LibcallLoweringInfo(const RTLIB::RuntimeLibcallsInfo &RTLCI);
205+
206+
/// Get the libcall routine name for the specified libcall.
207+
// FIXME: This should be removed. Only LibcallImpl should have a name.
208+
LLVM_ABI const char *getLibcallName(RTLIB::Libcall Call) const {
209+
// FIXME: Return StringRef
210+
return RTLIB::RuntimeLibcallsInfo::getLibcallImplName(LibcallImpls[Call])
211+
.data();
212+
}
213+
214+
/// Return the lowering's selection of implementation call for \p Call
215+
LLVM_ABI RTLIB::LibcallImpl getLibcallImpl(RTLIB::Libcall Call) const {
216+
return LibcallImpls[Call];
217+
}
218+
219+
/// Rename the default libcall routine name for the specified libcall.
220+
LLVM_ABI void setLibcallImpl(RTLIB::Libcall Call, RTLIB::LibcallImpl Impl) {
221+
LibcallImpls[Call] = Impl;
222+
}
223+
224+
// FIXME: Remove this wrapper in favor of directly using
225+
// getLibcallImplCallingConv
226+
LLVM_ABI CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const {
227+
return RTLCI.LibcallImplCallingConvs[LibcallImpls[Call]];
228+
}
229+
230+
/// Get the CallingConv that should be used for the specified libcall.
231+
LLVM_ABI CallingConv::ID
232+
getLibcallImplCallingConv(RTLIB::LibcallImpl Call) const {
233+
return RTLCI.LibcallImplCallingConvs[Call];
234+
}
235+
236+
/// Return a function name compatible with RTLIB::MEMCPY, or nullptr if fully
237+
/// unsupported.
238+
LLVM_ABI StringRef getMemcpyName() const {
239+
RTLIB::LibcallImpl Memcpy = getLibcallImpl(RTLIB::MEMCPY);
240+
if (Memcpy != RTLIB::Unsupported)
241+
return RTLIB::RuntimeLibcallsInfo::getLibcallImplName(Memcpy);
242+
243+
// Fallback to memmove if memcpy isn't available.
244+
return getLibcallName(RTLIB::MEMMOVE);
245+
}
246+
};
247+
196248
/// This base class for TargetLowering contains the SelectionDAG-independent
197249
/// parts that can be used from the rest of CodeGen.
198250
class LLVM_ABI TargetLoweringBase {
@@ -3597,7 +3649,7 @@ class LLVM_ABI TargetLoweringBase {
35973649
}
35983650

35993651
const RTLIB::RuntimeLibcallsInfo &getRuntimeLibcallsInfo() const {
3600-
return Libcalls;
3652+
return RuntimeLibcallInfo;
36013653
}
36023654

36033655
void setLibcallImpl(RTLIB::Libcall Call, RTLIB::LibcallImpl Impl) {
@@ -3610,9 +3662,9 @@ class LLVM_ABI TargetLoweringBase {
36103662
}
36113663

36123664
/// Get the libcall routine name for the specified libcall.
3665+
// FIXME: This should be removed. Only LibcallImpl should have a name.
36133666
const char *getLibcallName(RTLIB::Libcall Call) const {
3614-
// FIXME: Return StringRef
3615-
return Libcalls.getLibcallName(Call).data();
3667+
return Libcalls.getLibcallName(Call);
36163668
}
36173669

36183670
/// Get the libcall routine name for the specified libcall implementation
@@ -3625,19 +3677,14 @@ class LLVM_ABI TargetLoweringBase {
36253677
/// Check if this is valid libcall for the current module, otherwise
36263678
/// RTLIB::Unsupported.
36273679
RTLIB::LibcallImpl getSupportedLibcallImpl(StringRef FuncName) const {
3628-
return Libcalls.getSupportedLibcallImpl(FuncName);
3680+
return RuntimeLibcallInfo.getSupportedLibcallImpl(FuncName);
36293681
}
36303682

36313683
/// Get the comparison predicate that's to be used to test the result of the
36323684
/// comparison libcall against zero. This should only be used with
36333685
/// floating-point compare libcalls.
36343686
ISD::CondCode getSoftFloatCmpLibcallPredicate(RTLIB::LibcallImpl Call) const;
36353687

3636-
/// Set the CallingConv that should be used for the specified libcall.
3637-
void setLibcallImplCallingConv(RTLIB::LibcallImpl Call, CallingConv::ID CC) {
3638-
Libcalls.setLibcallImplCallingConv(Call, CC);
3639-
}
3640-
36413688
/// Get the CallingConv that should be used for the specified libcall
36423689
/// implementation.
36433690
CallingConv::ID getLibcallImplCallingConv(RTLIB::LibcallImpl Call) const {
@@ -3834,8 +3881,11 @@ class LLVM_ABI TargetLoweringBase {
38343881
std::map<std::pair<unsigned, MVT::SimpleValueType>, MVT::SimpleValueType>
38353882
PromoteToType;
38363883

3884+
/// FIXME: This should not live here; it should come from an analysis.
3885+
const RTLIB::RuntimeLibcallsInfo RuntimeLibcallInfo;
3886+
38373887
/// The list of libcalls that the target will use.
3838-
RTLIB::RuntimeLibcallsInfo Libcalls;
3888+
LibcallLoweringInfo Libcalls;
38393889

38403890
/// The bits of IndexedModeActions used to store the legalisation actions
38413891
/// We store the data as | ML | MS | L | S | each taking 4 bits.

llvm/include/llvm/IR/RuntimeLibcalls.h

Lines changed: 13 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434

3535
namespace llvm {
3636

37+
class LibcallLoweringInfo;
38+
3739
template <> struct enum_iteration_traits<RTLIB::Libcall> {
3840
static constexpr bool is_iterable = true;
3941
};
@@ -70,6 +72,8 @@ struct RuntimeLibcallsInfo {
7072
LibcallImplBitset AvailableLibcallImpls;
7173

7274
public:
75+
friend class llvm::LibcallLoweringInfo;
76+
7377
explicit RuntimeLibcallsInfo(
7478
const Triple &TT,
7579
ExceptionHandling ExceptionModel = ExceptionHandling::None,
@@ -85,17 +89,6 @@ struct RuntimeLibcallsInfo {
8589
initLibcalls(TT, ExceptionModel, FloatABI, EABIVersion, ABIName);
8690
}
8791

88-
/// Rename the default libcall routine name for the specified libcall.
89-
void setLibcallImpl(RTLIB::Libcall Call, RTLIB::LibcallImpl Impl) {
90-
LibcallImpls[Call] = Impl;
91-
}
92-
93-
/// Get the libcall routine name for the specified libcall.
94-
// FIXME: This should be removed. Only LibcallImpl should have a name.
95-
StringRef getLibcallName(RTLIB::Libcall Call) const {
96-
return getLibcallImplName(LibcallImpls[Call]);
97-
}
98-
9992
/// Get the libcall routine name for the specified libcall implementation.
10093
static StringRef getLibcallImplName(RTLIB::LibcallImpl CallImpl) {
10194
if (CallImpl == RTLIB::Unsupported)
@@ -105,31 +98,20 @@ struct RuntimeLibcallsInfo {
10598
RuntimeLibcallNameSizeTable[CallImpl]);
10699
}
107100

108-
/// Return the lowering's selection of implementation call for \p Call
109-
RTLIB::LibcallImpl getLibcallImpl(RTLIB::Libcall Call) const {
110-
return LibcallImpls[Call];
111-
}
112-
113101
/// Set the CallingConv that should be used for the specified libcall
114102
/// implementation
115103
void setLibcallImplCallingConv(RTLIB::LibcallImpl Call, CallingConv::ID CC) {
116104
LibcallImplCallingConvs[Call] = CC;
117105
}
118106

119-
// FIXME: Remove this wrapper in favor of directly using
120-
// getLibcallImplCallingConv
121-
CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const {
122-
return LibcallImplCallingConvs[LibcallImpls[Call]];
123-
}
124-
125107
/// Get the CallingConv that should be used for the specified libcall.
126108
CallingConv::ID getLibcallImplCallingConv(RTLIB::LibcallImpl Call) const {
127109
return LibcallImplCallingConvs[Call];
128110
}
129111

130-
ArrayRef<RTLIB::LibcallImpl> getLibcallImpls() const {
131-
// Trim UNKNOWN_LIBCALL from the back
132-
return ArrayRef(LibcallImpls).drop_back();
112+
/// Return the libcall provided by \p Impl
113+
static RTLIB::Libcall getLibcallFromImpl(RTLIB::LibcallImpl Impl) {
114+
return ImplToLibcall[Impl];
133115
}
134116

135117
/// Return a function name compatible with RTLIB::MEMCPY, or nullptr if fully
@@ -143,6 +125,10 @@ struct RuntimeLibcallsInfo {
143125
return getLibcallImpl(RTLIB::MEMMOVE);
144126
}
145127

128+
unsigned getNumAvailableLibcallImpls() const {
129+
return AvailableLibcallImpls.count();
130+
}
131+
146132
bool isAvailable(RTLIB::LibcallImpl Impl) const {
147133
return AvailableLibcallImpls.test(Impl);
148134
}
@@ -151,11 +137,6 @@ struct RuntimeLibcallsInfo {
151137
AvailableLibcallImpls.set(Impl);
152138
}
153139

154-
/// Return the libcall provided by \p Impl
155-
static RTLIB::Libcall getLibcallFromImpl(RTLIB::LibcallImpl Impl) {
156-
return ImplToLibcall[Impl];
157-
}
158-
159140
/// Check if a function name is a recognized runtime call of any kind. This
160141
/// does not consider if this call is available for any current compilation,
161142
/// just that it is a known call somewhere. This returns the set of all
@@ -176,11 +157,8 @@ struct RuntimeLibcallsInfo {
176157
LLVM_ABI RTLIB::LibcallImpl
177158
getSupportedLibcallImpl(StringRef FuncName) const {
178159
for (RTLIB::LibcallImpl Impl : lookupLibcallImplName(FuncName)) {
179-
// FIXME: This should not depend on looking up ImplToLibcall, only the
180-
// list of libcalls for the module.
181-
RTLIB::LibcallImpl Recognized = LibcallImpls[ImplToLibcall[Impl]];
182-
if (Recognized != RTLIB::Unsupported)
183-
return Recognized;
160+
if (isAvailable(Impl))
161+
return Impl;
184162
}
185163

186164
return RTLIB::Unsupported;
@@ -197,10 +175,6 @@ struct RuntimeLibcallsInfo {
197175
LLVM_ABI static iota_range<RTLIB::LibcallImpl>
198176
lookupLibcallImplNameImpl(StringRef Name);
199177

200-
/// Stores the implementation choice for each each libcall.
201-
RTLIB::LibcallImpl LibcallImpls[RTLIB::UNKNOWN_LIBCALL + 1] = {
202-
RTLIB::Unsupported};
203-
204178
static_assert(static_cast<int>(CallingConv::C) == 0,
205179
"default calling conv should be encoded as 0");
206180

llvm/lib/CodeGen/TargetLoweringBase.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -695,11 +695,28 @@ ISD::CondCode TargetLoweringBase::getSoftFloatCmpLibcallPredicate(
695695
}
696696
}
697697

698+
LibcallLoweringInfo::LibcallLoweringInfo(
699+
const RTLIB::RuntimeLibcallsInfo &RTLCI)
700+
: RTLCI(RTLCI) {
701+
// TODO: This should be generated with lowering predicates, and assert the
702+
// call is available.
703+
for (RTLIB::LibcallImpl Impl : RTLIB::libcall_impls()) {
704+
if (RTLCI.isAvailable(Impl)) {
705+
RTLIB::Libcall LC = RTLIB::RuntimeLibcallsInfo::getLibcallFromImpl(Impl);
706+
// FIXME: Hack, assume the first available libcall wins.
707+
if (LibcallImpls[LC] == RTLIB::Unsupported)
708+
LibcallImpls[LC] = Impl;
709+
}
710+
}
711+
}
712+
698713
/// NOTE: The TargetMachine owns TLOF.
699714
TargetLoweringBase::TargetLoweringBase(const TargetMachine &tm)
700-
: TM(tm), Libcalls(TM.getTargetTriple(), TM.Options.ExceptionModel,
701-
TM.Options.FloatABIType, TM.Options.EABIVersion,
702-
TM.Options.MCOptions.getABIName()) {
715+
: TM(tm),
716+
RuntimeLibcallInfo(TM.getTargetTriple(), TM.Options.ExceptionModel,
717+
TM.Options.FloatABIType, TM.Options.EABIVersion,
718+
TM.Options.MCOptions.getABIName()),
719+
Libcalls(RuntimeLibcallInfo) {
703720
initActions();
704721

705722
// Perform these initializations only once.

llvm/lib/IR/RuntimeLibcalls.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
using namespace llvm;
2020
using namespace RTLIB;
2121

22+
#define GET_RUNTIME_LIBCALLS_INFO
2223
#define GET_INIT_RUNTIME_LIBCALL_NAMES
2324
#define GET_SET_TARGET_RUNTIME_LIBCALL_SETS
2425
#define DEFINE_GET_LOOKUP_LIBCALL_IMPL_NAME

llvm/lib/LTO/LTO.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1396,11 +1396,10 @@ Error LTO::runRegularLTO(AddStreamFn AddStream) {
13961396
SmallVector<const char *> LTO::getRuntimeLibcallSymbols(const Triple &TT) {
13971397
RTLIB::RuntimeLibcallsInfo Libcalls(TT);
13981398
SmallVector<const char *> LibcallSymbols;
1399-
ArrayRef<RTLIB::LibcallImpl> LibcallImpls = Libcalls.getLibcallImpls();
1400-
LibcallSymbols.reserve(LibcallImpls.size());
1399+
LibcallSymbols.reserve(Libcalls.getNumAvailableLibcallImpls());
14011400

1402-
for (RTLIB::LibcallImpl Impl : LibcallImpls) {
1403-
if (Impl != RTLIB::Unsupported)
1401+
for (RTLIB::LibcallImpl Impl : RTLIB::libcall_impls()) {
1402+
if (Libcalls.isAvailable(Impl))
14041403
LibcallSymbols.push_back(Libcalls.getLibcallImplName(Impl).data());
14051404
}
14061405

llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -532,13 +532,19 @@ struct StaticLibcallNameMap {
532532
// FIXME: This is broken if there are ever different triples compiled with
533533
// different libcalls.
534534
RTLIB::RuntimeLibcallsInfo RTCI(TT);
535-
for (RTLIB::Libcall LC : RTLIB::libcalls()) {
536-
StringRef NameLibcall = RTCI.getLibcallName(LC);
537-
if (!NameLibcall.empty() &&
538-
getRuntimeLibcallSignatures().Table[LC] != unsupported) {
539-
assert(!Map.contains(NameLibcall) &&
540-
"duplicate libcall names in name map");
541-
Map[NameLibcall] = LC;
535+
536+
ArrayRef<RuntimeLibcallSignature> Table =
537+
getRuntimeLibcallSignatures().Table;
538+
for (RTLIB::LibcallImpl Impl : RTLIB::libcall_impls()) {
539+
if (!RTCI.isAvailable(Impl))
540+
continue;
541+
RTLIB::Libcall LC = RTLIB::RuntimeLibcallsInfo::getLibcallFromImpl(Impl);
542+
if (Table[LC] != unsupported) {
543+
StringRef NameLibcall =
544+
RTLIB::RuntimeLibcallsInfo::getLibcallImplName(Impl);
545+
// FIXME: Map should be to LibcallImpl
546+
if (!Map.insert({NameLibcall, LC}).second)
547+
llvm_unreachable("duplicate libcall names in name map");
542548
}
543549
}
544550
}

llvm/lib/Transforms/Utils/DeclareRuntimeLibcalls.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ PreservedAnalyses DeclareRuntimeLibcallsPass::run(Module &M,
5454
const DataLayout &DL = M.getDataLayout();
5555
const Triple &TT = M.getTargetTriple();
5656

57-
for (RTLIB::LibcallImpl Impl : RTLCI.getLibcallImpls()) {
58-
if (Impl == RTLIB::Unsupported)
57+
for (RTLIB::LibcallImpl Impl : RTLIB::libcall_impls()) {
58+
if (!RTLCI.isAvailable(Impl))
5959
continue;
6060

6161
auto [FuncTy, FuncAttrs] = RTLCI.getFunctionTy(Ctx, TT, DL, Impl);

0 commit comments

Comments
 (0)