diff options
Diffstat (limited to 'llvm/utils/TableGen/Basic/RuntimeLibcalls.h')
| -rw-r--r-- | llvm/utils/TableGen/Basic/RuntimeLibcalls.h | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/llvm/utils/TableGen/Basic/RuntimeLibcalls.h b/llvm/utils/TableGen/Basic/RuntimeLibcalls.h new file mode 100644 index 0000000..6c98976 --- /dev/null +++ b/llvm/utils/TableGen/Basic/RuntimeLibcalls.h @@ -0,0 +1,189 @@ +//===------------------------------------------------------------*- 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_UTILS_TABLEGEN_COMMON_RUNTIMELIBCALLS_H +#define LLVM_UTILS_TABLEGEN_COMMON_RUNTIMELIBCALLS_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/SetTheory.h" + +namespace llvm { + +class AvailabilityPredicate { + const Record *TheDef; + StringRef PredicateString; + +public: + AvailabilityPredicate(const Record *Def) : TheDef(Def) { + if (TheDef) + PredicateString = TheDef->getValueAsString("Cond"); + } + + const Record *getDef() const { return TheDef; } + + bool isAlwaysAvailable() const { return PredicateString.empty(); } + + void emitIf(raw_ostream &OS) const { + OS << "if (" << PredicateString << ") {\n"; + } + + void emitEndIf(raw_ostream &OS) const { OS << "}\n"; } + + void emitTableVariableNameSuffix(raw_ostream &OS) const { + if (TheDef) + OS << '_' << TheDef->getName(); + } +}; + +class RuntimeLibcalls; +class RuntimeLibcallImpl; + +/// Used to apply predicates to nested sets of libcalls. +struct LibcallPredicateExpander : SetTheory::Expander { + const RuntimeLibcalls &Libcalls; + DenseMap<const RuntimeLibcallImpl *, + std::pair<std::vector<const Record *>, const Record *>> &Func2Preds; + + LibcallPredicateExpander( + const RuntimeLibcalls &Libcalls, + DenseMap<const RuntimeLibcallImpl *, + std::pair<std::vector<const Record *>, const Record *>> + &Func2Preds) + : Libcalls(Libcalls), Func2Preds(Func2Preds) {} + + void expand(SetTheory &ST, const Record *Def, + SetTheory::RecSet &Elts) override; +}; + +class RuntimeLibcall { + const Record *TheDef = nullptr; + const size_t EnumVal; + +public: + RuntimeLibcall() = delete; + RuntimeLibcall(const Record *Def, size_t EnumVal) + : TheDef(Def), EnumVal(EnumVal) { + assert(Def); + } + + ~RuntimeLibcall() { assert(TheDef); } + + const Record *getDef() const { return TheDef; } + + StringRef getName() const { return TheDef->getName(); } + + size_t getEnumVal() const { return EnumVal; } + + void emitEnumEntry(raw_ostream &OS) const { + OS << "RTLIB::" << TheDef->getValueAsString("Name"); + } +}; + +class RuntimeLibcallImpl { + const Record *TheDef; + const RuntimeLibcall *Provides = nullptr; + const size_t EnumVal; + +public: + RuntimeLibcallImpl( + const Record *Def, + const DenseMap<const Record *, const RuntimeLibcall *> &ProvideMap, + size_t EnumVal) + : TheDef(Def), EnumVal(EnumVal) { + if (const Record *ProvidesDef = Def->getValueAsDef("Provides")) + Provides = ProvideMap.lookup(ProvidesDef); + } + + ~RuntimeLibcallImpl() = default; + + const Record *getDef() const { return TheDef; } + + StringRef getName() const { return TheDef->getName(); } + + size_t getEnumVal() const { return EnumVal; } + + const RuntimeLibcall *getProvides() const { return Provides; } + + StringRef getLibcallFuncName() const { + return TheDef->getValueAsString("LibCallFuncName"); + } + + const Record *getCallingConv() const { + return TheDef->getValueAsOptionalDef("CallingConv"); + } + + void emitQuotedLibcallFuncName(raw_ostream &OS) const { + OS << '\"' << getLibcallFuncName() << '\"'; + } + + bool isDefault() const { return TheDef->getValueAsBit("IsDefault"); } + + void emitEnumEntry(raw_ostream &OS) const { + OS << "RTLIB::impl_" << this->getName(); + } + + void emitSetImplCall(raw_ostream &OS) const { + OS << "setLibcallImpl("; + Provides->emitEnumEntry(OS); + OS << ", "; + emitEnumEntry(OS); + OS << "); // " << getLibcallFuncName() << '\n'; + } + + void emitTableEntry(raw_ostream &OS) const { + OS << '{'; + Provides->emitEnumEntry(OS); + OS << ", "; + emitEnumEntry(OS); + OS << "}, // " << getLibcallFuncName() << '\n'; + } + + void emitSetCallingConv(raw_ostream &OS) const {} +}; + +struct LibcallsWithCC { + std::vector<const RuntimeLibcallImpl *> LibcallImpls; + const Record *CallingConv = nullptr; +}; + +class RuntimeLibcalls { +private: + DenseMap<const Record *, const RuntimeLibcall *> Def2RuntimeLibcall; + DenseMap<const Record *, const RuntimeLibcallImpl *> Def2RuntimeLibcallImpl; + + std::vector<RuntimeLibcall> RuntimeLibcallDefList; + std::vector<RuntimeLibcallImpl> RuntimeLibcallImplDefList; + + DenseMap<const RuntimeLibcall *, const RuntimeLibcallImpl *> + LibCallToDefaultImpl; + +public: + RuntimeLibcalls(const RecordKeeper &Records); + + ArrayRef<RuntimeLibcall> getRuntimeLibcallDefList() const { + return RuntimeLibcallDefList; + } + + ArrayRef<RuntimeLibcallImpl> getRuntimeLibcallImplDefList() const { + return RuntimeLibcallImplDefList; + } + + const RuntimeLibcall *getRuntimeLibcall(const Record *Def) const { + return Def2RuntimeLibcall.lookup(Def); + } + + const RuntimeLibcallImpl *getRuntimeLibcallImpl(const Record *Def) const { + return Def2RuntimeLibcallImpl.lookup(Def); + } +}; + +} // namespace llvm + +#endif // LLVM_UTILS_TABLEGEN_COMMON_RUNTIMELIBCALLS_H |
