blob: 6c9897602b2faab05556f07736d3f9746e3b714b [file] [log] [blame] [edit]
//===------------------------------------------------------------*- 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