Files
gps/tools/local/circt/include/llvm/CodeGen/LibcallLoweringInfo.h
T
2026-07-12 11:01:51 +03:00

152 lines
4.8 KiB
C++

//===- 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
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_LIBCALLLOWERINGINFO_H
#define LLVM_CODEGEN_LIBCALLLOWERINGINFO_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/Analysis/RuntimeLibcallInfo.h"
#include "llvm/IR/RuntimeLibcalls.h"
#include "llvm/Pass.h"
namespace llvm {
class RuntimeLibraryInfoWrapper;
class TargetSubtargetInfo;
class TargetMachine;
/// Tracks which library functions to use for a particular subtarget.
class LibcallLoweringInfo {
private:
const RTLIB::RuntimeLibcallsInfo &RTLCI;
/// Stores the implementation choice for each each libcall.
RTLIB::LibcallImpl LibcallImpls[RTLIB::UNKNOWN_LIBCALL + 1] = {
RTLIB::Unsupported};
public:
LLVM_ABI LibcallLoweringInfo(const RTLIB::RuntimeLibcallsInfo &RTLCI,
const TargetSubtargetInfo &Subtarget);
const RTLIB::RuntimeLibcallsInfo &getRuntimeLibcallsInfo() const {
return RTLCI;
}
/// 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 RTLIB::RuntimeLibcallsInfo::getLibcallImplName(LibcallImpls[Call])
.data();
}
/// Return the lowering's selection of implementation call for \p Call
RTLIB::LibcallImpl getLibcallImpl(RTLIB::Libcall Call) const {
return LibcallImpls[Call];
}
/// Rename the default libcall routine name for the specified libcall.
void setLibcallImpl(RTLIB::Libcall Call, RTLIB::LibcallImpl Impl) {
LibcallImpls[Call] = Impl;
}
// FIXME: Remove this wrapper in favor of directly using
// getLibcallImplCallingConv
CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const {
return RTLCI.LibcallImplCallingConvs[LibcallImpls[Call]];
}
/// Get the CallingConv that should be used for the specified libcall.
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;
}
};
/// Record a mapping from subtarget to LibcallLoweringInfo.
class LibcallLoweringModuleAnalysisResult {
private:
using LibcallLoweringMap =
DenseMap<const TargetSubtargetInfo *, LibcallLoweringInfo>;
mutable LibcallLoweringMap LoweringMap;
const RTLIB::RuntimeLibcallsInfo *RTLCI = nullptr;
public:
LibcallLoweringModuleAnalysisResult() = default;
LibcallLoweringModuleAnalysisResult(RTLIB::RuntimeLibcallsInfo &RTLCI)
: RTLCI(&RTLCI) {}
void init(const RTLIB::RuntimeLibcallsInfo *RT) { RTLCI = RT; }
void clear() {
RTLCI = nullptr;
LoweringMap.clear();
}
operator bool() const { return RTLCI != nullptr; }
LLVM_ABI bool invalidate(Module &, const PreservedAnalyses &,
ModuleAnalysisManager::Invalidator &);
const LibcallLoweringInfo &
getLibcallLowering(const TargetSubtargetInfo &Subtarget) const {
return LoweringMap.try_emplace(&Subtarget, *RTLCI, Subtarget).first->second;
}
};
class LibcallLoweringModuleAnalysis
: public AnalysisInfoMixin<LibcallLoweringModuleAnalysis> {
private:
friend AnalysisInfoMixin<LibcallLoweringModuleAnalysis>;
LLVM_ABI static AnalysisKey Key;
LibcallLoweringModuleAnalysisResult LibcallLoweringMap;
public:
using Result = LibcallLoweringModuleAnalysisResult;
LLVM_ABI Result run(Module &M, ModuleAnalysisManager &);
};
class LLVM_ABI LibcallLoweringInfoWrapper : public ImmutablePass {
LibcallLoweringModuleAnalysisResult Result;
RuntimeLibraryInfoWrapper *RuntimeLibcallsWrapper = nullptr;
public:
static char ID;
LibcallLoweringInfoWrapper();
const LibcallLoweringInfo &
getLibcallLowering(const Module &M, const TargetSubtargetInfo &Subtarget) {
return getResult(M).getLibcallLowering(Subtarget);
}
const LibcallLoweringModuleAnalysisResult &getResult(const Module &M) {
if (!Result)
Result.init(&RuntimeLibcallsWrapper->getRTLCI(M));
return Result;
}
void initializePass() override;
void getAnalysisUsage(AnalysisUsage &AU) const override;
void releaseMemory() override;
};
} // end namespace llvm
#endif // LLVM_CODEGEN_LIBCALLLOWERINGINFO_H