Skip to content

Commit 0d40671

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 f8b5f86 commit 0d40671

File tree

12 files changed

+203
-173
lines changed

12 files changed

+203
-173
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
@@ -3628,19 +3680,14 @@ class LLVM_ABI TargetLoweringBase {
36283680
/// Check if this is valid libcall for the current module, otherwise
36293681
/// RTLIB::Unsupported.
36303682
RTLIB::LibcallImpl getSupportedLibcallImpl(StringRef FuncName) const {
3631-
return Libcalls.getSupportedLibcallImpl(FuncName);
3683+
return RuntimeLibcallInfo.getSupportedLibcallImpl(FuncName);
36323684
}
36333685

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

3639-
/// Set the CallingConv that should be used for the specified libcall.
3640-
void setLibcallImplCallingConv(RTLIB::LibcallImpl Call, CallingConv::ID CC) {
3641-
Libcalls.setLibcallImplCallingConv(Call, CC);
3642-
}
3643-
36443691
/// Get the CallingConv that should be used for the specified libcall
36453692
/// implementation.
36463693
CallingConv::ID getLibcallImplCallingConv(RTLIB::LibcallImpl Call) const {
@@ -3837,8 +3884,11 @@ class LLVM_ABI TargetLoweringBase {
38373884
std::map<std::pair<unsigned, MVT::SimpleValueType>, MVT::SimpleValueType>
38383885
PromoteToType;
38393886

3887+
/// FIXME: This should not live here; it should come from an analysis.
3888+
const RTLIB::RuntimeLibcallsInfo RuntimeLibcallInfo;
3889+
38403890
/// The list of libcalls that the target will use.
3841-
RTLIB::RuntimeLibcallsInfo Libcalls;
3891+
LibcallLoweringInfo Libcalls;
38423892

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

llvm/include/llvm/IR/RuntimeLibcalls.h

Lines changed: 11 additions & 48 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,42 +98,24 @@ 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

135-
/// Return a function name compatible with RTLIB::MEMCPY, or nullptr if fully
136-
/// unsupported.
137-
StringRef getMemcpyName() const {
138-
RTLIB::LibcallImpl Memcpy = getLibcallImpl(RTLIB::MEMCPY);
139-
if (Memcpy != RTLIB::Unsupported)
140-
return getLibcallImplName(Memcpy);
141-
142-
// Fallback to memmove if memcpy isn't available.
143-
return getLibcallName(RTLIB::MEMMOVE);
117+
unsigned getNumAvailableLibcallImpls() const {
118+
return AvailableLibcallImpls.count();
144119
}
145120

146121
bool isAvailable(RTLIB::LibcallImpl Impl) const {
@@ -151,11 +126,6 @@ struct RuntimeLibcallsInfo {
151126
AvailableLibcallImpls.set(Impl);
152127
}
153128

154-
/// Return the libcall provided by \p Impl
155-
static RTLIB::Libcall getLibcallFromImpl(RTLIB::LibcallImpl Impl) {
156-
return ImplToLibcall[Impl];
157-
}
158-
159129
/// Check if a function name is a recognized runtime call of any kind. This
160130
/// does not consider if this call is available for any current compilation,
161131
/// just that it is a known call somewhere. This returns the set of all
@@ -176,11 +146,8 @@ struct RuntimeLibcallsInfo {
176146
LLVM_ABI RTLIB::LibcallImpl
177147
getSupportedLibcallImpl(StringRef FuncName) const {
178148
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;
149+
if (isAvailable(Impl))
150+
return Impl;
184151
}
185152

186153
return RTLIB::Unsupported;
@@ -190,10 +157,6 @@ struct RuntimeLibcallsInfo {
190157
LLVM_ABI static iota_range<RTLIB::LibcallImpl>
191158
lookupLibcallImplNameImpl(StringRef Name);
192159

193-
/// Stores the implementation choice for each each libcall.
194-
RTLIB::LibcallImpl LibcallImpls[RTLIB::UNKNOWN_LIBCALL + 1] = {
195-
RTLIB::Unsupported};
196-
197160
static_assert(static_cast<int>(CallingConv::C) == 0,
198161
"default calling conv should be encoded as 0");
199162

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
@@ -17,6 +17,7 @@
1717
using namespace llvm;
1818
using namespace RTLIB;
1919

20+
#define GET_RUNTIME_LIBCALLS_INFO
2021
#define GET_INIT_RUNTIME_LIBCALL_NAMES
2122
#define GET_SET_TARGET_RUNTIME_LIBCALL_SETS
2223
#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
@@ -1400,11 +1400,10 @@ Error LTO::runRegularLTO(AddStreamFn AddStream) {
14001400
SmallVector<const char *> LTO::getRuntimeLibcallSymbols(const Triple &TT) {
14011401
RTLIB::RuntimeLibcallsInfo Libcalls(TT);
14021402
SmallVector<const char *> LibcallSymbols;
1403-
ArrayRef<RTLIB::LibcallImpl> LibcallImpls = Libcalls.getLibcallImpls();
1404-
LibcallSymbols.reserve(LibcallImpls.size());
1403+
LibcallSymbols.reserve(Libcalls.getNumAvailableLibcallImpls());
14051404

1406-
for (RTLIB::LibcallImpl Impl : LibcallImpls) {
1407-
if (Impl != RTLIB::Unsupported)
1405+
for (RTLIB::LibcallImpl Impl : RTLIB::libcall_impls()) {
1406+
if (Libcalls.isAvailable(Impl))
14081407
LibcallSymbols.push_back(Libcalls.getLibcallImplName(Impl).data());
14091408
}
14101409

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
@@ -21,8 +21,8 @@ PreservedAnalyses DeclareRuntimeLibcallsPass::run(Module &M,
2121
RTLIB::RuntimeLibcallsInfo RTLCI(M.getTargetTriple());
2222
LLVMContext &Ctx = M.getContext();
2323

24-
for (RTLIB::LibcallImpl Impl : RTLCI.getLibcallImpls()) {
25-
if (Impl == RTLIB::Unsupported)
24+
for (RTLIB::LibcallImpl Impl : RTLIB::libcall_impls()) {
25+
if (!RTLCI.isAvailable(Impl))
2626
continue;
2727

2828
// TODO: Declare with correct type, calling convention, and attributes.

0 commit comments

Comments
 (0)