Skip to content
Merged
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
66 changes: 66 additions & 0 deletions llvm/include/llvm/CodeGen/LibcallLoweringInfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//===- LibcallLoweringInfo.h ------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/RuntimeLibcalls.h"

namespace llvm {

class LibcallLoweringInfo {
private:
LLVM_ABI const RTLIB::RuntimeLibcallsInfo &RTLCI;
/// Stores the implementation choice for each each libcall.
LLVM_ABI RTLIB::LibcallImpl LibcallImpls[RTLIB::UNKNOWN_LIBCALL + 1] = {
RTLIB::Unsupported};

public:
LLVM_ABI LibcallLoweringInfo(const RTLIB::RuntimeLibcallsInfo &RTLCI);

/// Get the libcall routine name for the specified libcall.
// FIXME: This should be removed. Only LibcallImpl should have a name.
LLVM_ABI const char *getLibcallName(RTLIB::Libcall Call) const {
// FIXME: Return StringRef
return RTLIB::RuntimeLibcallsInfo::getLibcallImplName(LibcallImpls[Call])
.data();
}

/// Return the lowering's selection of implementation call for \p Call
LLVM_ABI RTLIB::LibcallImpl getLibcallImpl(RTLIB::Libcall Call) const {
return LibcallImpls[Call];
}

/// Rename the default libcall routine name for the specified libcall.
LLVM_ABI void setLibcallImpl(RTLIB::Libcall Call, RTLIB::LibcallImpl Impl) {
LibcallImpls[Call] = Impl;
}

// FIXME: Remove this wrapper in favor of directly using
// getLibcallImplCallingConv
LLVM_ABI CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const {
return RTLCI.LibcallImplCallingConvs[LibcallImpls[Call]];
}

/// Get the CallingConv that should be used for the specified libcall.
LLVM_ABI CallingConv::ID
getLibcallImplCallingConv(RTLIB::LibcallImpl Call) const {
return RTLCI.LibcallImplCallingConvs[Call];
}

/// Return a function impl compatible with RTLIB::MEMCPY, or
/// RTLIB::Unsupported if fully unsupported.
RTLIB::LibcallImpl getMemcpyImpl() const {
RTLIB::LibcallImpl Memcpy = getLibcallImpl(RTLIB::MEMCPY);
if (Memcpy == RTLIB::Unsupported) {
// Fallback to memmove if memcpy isn't available.
return getLibcallImpl(RTLIB::MEMMOVE);
}

return Memcpy;
}
};

} // end namespace llvm
19 changes: 9 additions & 10 deletions llvm/include/llvm/CodeGen/TargetLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/DAGCombine.h"
#include "llvm/CodeGen/ISDOpcodes.h"
#include "llvm/CodeGen/LibcallLoweringInfo.h"
#include "llvm/CodeGen/LowLevelTypeUtils.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RuntimeLibcallUtil.h"
Expand Down Expand Up @@ -3597,7 +3598,7 @@ class LLVM_ABI TargetLoweringBase {
}

const RTLIB::RuntimeLibcallsInfo &getRuntimeLibcallsInfo() const {
return Libcalls;
return RuntimeLibcallInfo;
}

void setLibcallImpl(RTLIB::Libcall Call, RTLIB::LibcallImpl Impl) {
Expand All @@ -3610,9 +3611,9 @@ class LLVM_ABI TargetLoweringBase {
}

/// Get the libcall routine name for the specified libcall.
// FIXME: This should be removed. Only LibcallImpl should have a name.
const char *getLibcallName(RTLIB::Libcall Call) const {
// FIXME: Return StringRef
return Libcalls.getLibcallName(Call).data();
return Libcalls.getLibcallName(Call);
}

/// Get the libcall routine name for the specified libcall implementation
Expand All @@ -3625,19 +3626,14 @@ class LLVM_ABI TargetLoweringBase {
/// Check if this is valid libcall for the current module, otherwise
/// RTLIB::Unsupported.
RTLIB::LibcallImpl getSupportedLibcallImpl(StringRef FuncName) const {
return Libcalls.getSupportedLibcallImpl(FuncName);
return RuntimeLibcallInfo.getSupportedLibcallImpl(FuncName);
}

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

/// Set the CallingConv that should be used for the specified libcall.
void setLibcallImplCallingConv(RTLIB::LibcallImpl Call, CallingConv::ID CC) {
Libcalls.setLibcallImplCallingConv(Call, CC);
}

/// Get the CallingConv that should be used for the specified libcall
/// implementation.
CallingConv::ID getLibcallImplCallingConv(RTLIB::LibcallImpl Call) const {
Expand Down Expand Up @@ -3834,8 +3830,11 @@ class LLVM_ABI TargetLoweringBase {
std::map<std::pair<unsigned, MVT::SimpleValueType>, MVT::SimpleValueType>
PromoteToType;

/// FIXME: This should not live here; it should come from an analysis.
const RTLIB::RuntimeLibcallsInfo RuntimeLibcallInfo;

/// The list of libcalls that the target will use.
RTLIB::RuntimeLibcallsInfo Libcalls;
LibcallLoweringInfo Libcalls;

/// The bits of IndexedModeActions used to store the legalisation actions
/// We store the data as | ML | MS | L | S | each taking 4 bits.
Expand Down
60 changes: 12 additions & 48 deletions llvm/include/llvm/IR/RuntimeLibcalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ template <> struct enum_iteration_traits<RTLIB::LibcallImpl> {
static constexpr bool is_iterable = true;
};

class LibcallLoweringInfo;

namespace RTLIB {

// Return an iterator over all Libcall values.
Expand Down Expand Up @@ -70,6 +72,8 @@ struct RuntimeLibcallsInfo {
LibcallImplBitset AvailableLibcallImpls;

public:
friend class llvm::LibcallLoweringInfo;

explicit RuntimeLibcallsInfo(
const Triple &TT,
ExceptionHandling ExceptionModel = ExceptionHandling::None,
Expand All @@ -85,17 +89,6 @@ struct RuntimeLibcallsInfo {
initLibcalls(TT, ExceptionModel, FloatABI, EABIVersion, ABIName);
}

/// Rename the default libcall routine name for the specified libcall.
void setLibcallImpl(RTLIB::Libcall Call, RTLIB::LibcallImpl Impl) {
LibcallImpls[Call] = Impl;
}

/// Get the libcall routine name for the specified libcall.
// FIXME: This should be removed. Only LibcallImpl should have a name.
StringRef getLibcallName(RTLIB::Libcall Call) const {
return getLibcallImplName(LibcallImpls[Call]);
}

/// Get the libcall routine name for the specified libcall implementation.
static StringRef getLibcallImplName(RTLIB::LibcallImpl CallImpl) {
if (CallImpl == RTLIB::Unsupported)
Expand All @@ -105,42 +98,24 @@ struct RuntimeLibcallsInfo {
RuntimeLibcallNameSizeTable[CallImpl]);
}

/// Return the lowering's selection of implementation call for \p Call
RTLIB::LibcallImpl getLibcallImpl(RTLIB::Libcall Call) const {
return LibcallImpls[Call];
}

/// Set the CallingConv that should be used for the specified libcall
/// implementation
void setLibcallImplCallingConv(RTLIB::LibcallImpl Call, CallingConv::ID CC) {
LibcallImplCallingConvs[Call] = CC;
}

// FIXME: Remove this wrapper in favor of directly using
// getLibcallImplCallingConv
CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const {
return LibcallImplCallingConvs[LibcallImpls[Call]];
}

/// Get the CallingConv that should be used for the specified libcall.
CallingConv::ID getLibcallImplCallingConv(RTLIB::LibcallImpl Call) const {
return LibcallImplCallingConvs[Call];
}

ArrayRef<RTLIB::LibcallImpl> getLibcallImpls() const {
// Trim UNKNOWN_LIBCALL from the back
return ArrayRef(LibcallImpls).drop_back();
/// Return the libcall provided by \p Impl
static RTLIB::Libcall getLibcallFromImpl(RTLIB::LibcallImpl Impl) {
return ImplToLibcall[Impl];
}

/// Return a function name compatible with RTLIB::MEMCPY, or nullptr if fully
/// unsupported.
RTLIB::LibcallImpl getMemcpyImpl() const {
RTLIB::LibcallImpl Memcpy = getLibcallImpl(RTLIB::MEMCPY);
if (Memcpy != RTLIB::Unsupported)
return Memcpy;

// Fallback to memmove if memcpy isn't available.
return getLibcallImpl(RTLIB::MEMMOVE);
unsigned getNumAvailableLibcallImpls() const {
return AvailableLibcallImpls.count();
}

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

/// Return the libcall provided by \p Impl
static RTLIB::Libcall getLibcallFromImpl(RTLIB::LibcallImpl Impl) {
return ImplToLibcall[Impl];
}

/// Check if a function name is a recognized runtime call of any kind. This
/// does not consider if this call is available for any current compilation,
/// just that it is a known call somewhere. This returns the set of all
Expand All @@ -176,11 +146,8 @@ struct RuntimeLibcallsInfo {
LLVM_ABI RTLIB::LibcallImpl
getSupportedLibcallImpl(StringRef FuncName) const {
for (RTLIB::LibcallImpl Impl : lookupLibcallImplName(FuncName)) {
// 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 All @@ -197,10 +164,6 @@ struct RuntimeLibcallsInfo {
LLVM_ABI static iota_range<RTLIB::LibcallImpl>
lookupLibcallImplNameImpl(StringRef Name);

/// Stores the implementation choice for each each libcall.
RTLIB::LibcallImpl LibcallImpls[RTLIB::UNKNOWN_LIBCALL + 1] = {
RTLIB::Unsupported};

static_assert(static_cast<int>(CallingConv::C) == 0,
"default calling conv should be encoded as 0");

Expand Down Expand Up @@ -274,6 +237,7 @@ struct RuntimeLibcallsInfo {
};

} // namespace RTLIB

} // namespace llvm

#endif // LLVM_IR_RUNTIME_LIBCALLS_H
1 change: 1 addition & 0 deletions llvm/lib/CodeGen/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ add_llvm_component_library(LLVMCodeGen
LatencyPriorityQueue.cpp
LazyMachineBlockFrequencyInfo.cpp
LexicalScopes.cpp
LibcallLoweringInfo.cpp
LiveDebugVariables.cpp
LiveIntervals.cpp
LiveInterval.cpp
Expand Down
26 changes: 26 additions & 0 deletions llvm/lib/CodeGen/LibcallLoweringInfo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//===- LibcallLoweringInfo.cpp - Interface for runtime libcalls -----------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/LibcallLoweringInfo.h"

using namespace llvm;

LibcallLoweringInfo::LibcallLoweringInfo(
const RTLIB::RuntimeLibcallsInfo &RTLCI)
: RTLCI(RTLCI) {
// TODO: This should be generated with lowering predicates, and assert the
// call is available.
for (RTLIB::LibcallImpl Impl : RTLIB::libcall_impls()) {
if (RTLCI.isAvailable(Impl)) {
RTLIB::Libcall LC = RTLIB::RuntimeLibcallsInfo::getLibcallFromImpl(Impl);
// FIXME: Hack, assume the first available libcall wins.
if (LibcallImpls[LC] == RTLIB::Unsupported)
LibcallImpls[LC] = Impl;
}
}
}
8 changes: 5 additions & 3 deletions llvm/lib/CodeGen/TargetLoweringBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -697,9 +697,11 @@ ISD::CondCode TargetLoweringBase::getSoftFloatCmpLibcallPredicate(

/// NOTE: The TargetMachine owns TLOF.
TargetLoweringBase::TargetLoweringBase(const TargetMachine &tm)
: TM(tm), Libcalls(TM.getTargetTriple(), TM.Options.ExceptionModel,
TM.Options.FloatABIType, TM.Options.EABIVersion,
TM.Options.MCOptions.getABIName()) {
: TM(tm),
RuntimeLibcallInfo(TM.getTargetTriple(), TM.Options.ExceptionModel,
TM.Options.FloatABIType, TM.Options.EABIVersion,
TM.Options.MCOptions.getABIName()),
Libcalls(RuntimeLibcallInfo) {
initActions();

// Perform these initializations only once.
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/IR/RuntimeLibcalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
using namespace llvm;
using namespace RTLIB;

#define GET_RUNTIME_LIBCALLS_INFO
#define GET_INIT_RUNTIME_LIBCALL_NAMES
#define GET_SET_TARGET_RUNTIME_LIBCALL_SETS
#define DEFINE_GET_LOOKUP_LIBCALL_IMPL_NAME
Expand Down
7 changes: 3 additions & 4 deletions llvm/lib/LTO/LTO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1396,11 +1396,10 @@ Error LTO::runRegularLTO(AddStreamFn AddStream) {
SmallVector<const char *> LTO::getRuntimeLibcallSymbols(const Triple &TT) {
RTLIB::RuntimeLibcallsInfo Libcalls(TT);
SmallVector<const char *> LibcallSymbols;
ArrayRef<RTLIB::LibcallImpl> LibcallImpls = Libcalls.getLibcallImpls();
LibcallSymbols.reserve(LibcallImpls.size());
LibcallSymbols.reserve(Libcalls.getNumAvailableLibcallImpls());

for (RTLIB::LibcallImpl Impl : LibcallImpls) {
if (Impl != RTLIB::Unsupported)
for (RTLIB::LibcallImpl Impl : RTLIB::libcall_impls()) {
if (Libcalls.isAvailable(Impl))
LibcallSymbols.push_back(Libcalls.getLibcallImplName(Impl).data());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -532,13 +532,19 @@ struct StaticLibcallNameMap {
// FIXME: This is broken if there are ever different triples compiled with
// different libcalls.
RTLIB::RuntimeLibcallsInfo RTCI(TT);
for (RTLIB::Libcall LC : RTLIB::libcalls()) {
StringRef NameLibcall = RTCI.getLibcallName(LC);
if (!NameLibcall.empty() &&
getRuntimeLibcallSignatures().Table[LC] != unsupported) {
assert(!Map.contains(NameLibcall) &&
"duplicate libcall names in name map");
Map[NameLibcall] = LC;

ArrayRef<RuntimeLibcallSignature> Table =
getRuntimeLibcallSignatures().Table;
for (RTLIB::LibcallImpl Impl : RTLIB::libcall_impls()) {
if (!RTCI.isAvailable(Impl))
continue;
RTLIB::Libcall LC = RTLIB::RuntimeLibcallsInfo::getLibcallFromImpl(Impl);
if (Table[LC] != unsupported) {
StringRef NameLibcall =
RTLIB::RuntimeLibcallsInfo::getLibcallImplName(Impl);
// FIXME: Map should be to LibcallImpl
if (!Map.insert({NameLibcall, LC}).second)
llvm_unreachable("duplicate libcall names in name map");
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Transforms/Utils/DeclareRuntimeLibcalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ PreservedAnalyses DeclareRuntimeLibcallsPass::run(Module &M,
const DataLayout &DL = M.getDataLayout();
const Triple &TT = M.getTargetTriple();

for (RTLIB::LibcallImpl Impl : RTLCI.getLibcallImpls()) {
if (Impl == RTLIB::Unsupported)
for (RTLIB::LibcallImpl Impl : RTLIB::libcall_impls()) {
if (!RTLCI.isAvailable(Impl))
continue;

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