190 lines · c
1//===------------------------------------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_UTILS_TABLEGEN_COMMON_RUNTIMELIBCALLS_H10#define LLVM_UTILS_TABLEGEN_COMMON_RUNTIMELIBCALLS_H11 12#include "llvm/ADT/StringRef.h"13#include "llvm/Support/raw_ostream.h"14#include "llvm/TableGen/Record.h"15#include "llvm/TableGen/SetTheory.h"16 17namespace llvm {18 19class AvailabilityPredicate {20 const Record *TheDef;21 StringRef PredicateString;22 23public:24 AvailabilityPredicate(const Record *Def) : TheDef(Def) {25 if (TheDef)26 PredicateString = TheDef->getValueAsString("Cond");27 }28 29 const Record *getDef() const { return TheDef; }30 31 bool isAlwaysAvailable() const { return PredicateString.empty(); }32 33 void emitIf(raw_ostream &OS) const {34 OS << "if (" << PredicateString << ") {\n";35 }36 37 void emitEndIf(raw_ostream &OS) const { OS << "}\n"; }38 39 void emitTableVariableNameSuffix(raw_ostream &OS) const {40 if (TheDef)41 OS << '_' << TheDef->getName();42 }43};44 45class RuntimeLibcalls;46class RuntimeLibcallImpl;47 48/// Used to apply predicates to nested sets of libcalls.49struct LibcallPredicateExpander : SetTheory::Expander {50 const RuntimeLibcalls &Libcalls;51 DenseMap<const RuntimeLibcallImpl *,52 std::pair<std::vector<const Record *>, const Record *>> &Func2Preds;53 54 LibcallPredicateExpander(55 const RuntimeLibcalls &Libcalls,56 DenseMap<const RuntimeLibcallImpl *,57 std::pair<std::vector<const Record *>, const Record *>>58 &Func2Preds)59 : Libcalls(Libcalls), Func2Preds(Func2Preds) {}60 61 void expand(SetTheory &ST, const Record *Def,62 SetTheory::RecSet &Elts) override;63};64 65class RuntimeLibcall {66 const Record *TheDef = nullptr;67 const size_t EnumVal;68 69public:70 RuntimeLibcall() = delete;71 RuntimeLibcall(const Record *Def, size_t EnumVal)72 : TheDef(Def), EnumVal(EnumVal) {73 assert(Def);74 }75 76 ~RuntimeLibcall() { assert(TheDef); }77 78 const Record *getDef() const { return TheDef; }79 80 StringRef getName() const { return TheDef->getName(); }81 82 size_t getEnumVal() const { return EnumVal; }83 84 void emitEnumEntry(raw_ostream &OS) const {85 OS << "RTLIB::" << TheDef->getValueAsString("Name");86 }87};88 89class RuntimeLibcallImpl {90 const Record *TheDef;91 const RuntimeLibcall *Provides = nullptr;92 const size_t EnumVal;93 94public:95 RuntimeLibcallImpl(96 const Record *Def,97 const DenseMap<const Record *, const RuntimeLibcall *> &ProvideMap,98 size_t EnumVal)99 : TheDef(Def), EnumVal(EnumVal) {100 if (const Record *ProvidesDef = Def->getValueAsDef("Provides"))101 Provides = ProvideMap.lookup(ProvidesDef);102 }103 104 ~RuntimeLibcallImpl() = default;105 106 const Record *getDef() const { return TheDef; }107 108 StringRef getName() const { return TheDef->getName(); }109 110 size_t getEnumVal() const { return EnumVal; }111 112 const RuntimeLibcall *getProvides() const { return Provides; }113 114 StringRef getLibcallFuncName() const {115 return TheDef->getValueAsString("LibCallFuncName");116 }117 118 const Record *getCallingConv() const {119 return TheDef->getValueAsOptionalDef("CallingConv");120 }121 122 void emitQuotedLibcallFuncName(raw_ostream &OS) const {123 OS << '\"' << getLibcallFuncName() << '\"';124 }125 126 bool isDefault() const { return TheDef->getValueAsBit("IsDefault"); }127 128 void emitEnumEntry(raw_ostream &OS) const {129 OS << "RTLIB::impl_" << this->getName();130 }131 132 void emitSetImplCall(raw_ostream &OS) const {133 OS << "setLibcallImpl(";134 Provides->emitEnumEntry(OS);135 OS << ", ";136 emitEnumEntry(OS);137 OS << "); // " << getLibcallFuncName() << '\n';138 }139 140 void emitTableEntry(raw_ostream &OS) const {141 OS << '{';142 Provides->emitEnumEntry(OS);143 OS << ", ";144 emitEnumEntry(OS);145 OS << "}, // " << getLibcallFuncName() << '\n';146 }147 148 void emitSetCallingConv(raw_ostream &OS) const {}149};150 151struct LibcallsWithCC {152 std::vector<const RuntimeLibcallImpl *> LibcallImpls;153 const Record *CallingConv = nullptr;154};155 156class RuntimeLibcalls {157private:158 DenseMap<const Record *, const RuntimeLibcall *> Def2RuntimeLibcall;159 DenseMap<const Record *, const RuntimeLibcallImpl *> Def2RuntimeLibcallImpl;160 161 std::vector<RuntimeLibcall> RuntimeLibcallDefList;162 std::vector<RuntimeLibcallImpl> RuntimeLibcallImplDefList;163 164 DenseMap<const RuntimeLibcall *, const RuntimeLibcallImpl *>165 LibCallToDefaultImpl;166 167public:168 RuntimeLibcalls(const RecordKeeper &Records);169 170 ArrayRef<RuntimeLibcall> getRuntimeLibcallDefList() const {171 return RuntimeLibcallDefList;172 }173 174 ArrayRef<RuntimeLibcallImpl> getRuntimeLibcallImplDefList() const {175 return RuntimeLibcallImplDefList;176 }177 178 const RuntimeLibcall *getRuntimeLibcall(const Record *Def) const {179 return Def2RuntimeLibcall.lookup(Def);180 }181 182 const RuntimeLibcallImpl *getRuntimeLibcallImpl(const Record *Def) const {183 return Def2RuntimeLibcallImpl.lookup(Def);184 }185};186 187} // namespace llvm188 189#endif // LLVM_UTILS_TABLEGEN_COMMON_RUNTIMELIBCALLS_H190