[StrTable] Add prefixes for x86 builtins.
This requires adding support to the general builtins emission for producing prefixed builtin infos separately from un-prefixed which is a bit crufty. But we don't currently have any good way of having a more refined model than a single hard-coded prefix string per TableGen emission. Something more powerful and/or elegant is possible, but this is a fairly minimal first step that at least allows factoring out the builtin prefix for something like X86.
This commit is contained in:
parent
212ecb9d5c
commit
2ff42bdac3
@ -86,6 +86,13 @@ def Consteval : Attribute<"EG">;
|
||||
// indicated by the remaining indices.
|
||||
class Callback<list<int> ArgIndices> : MultiIndexAttribute<"C", ArgIndices>;
|
||||
|
||||
// Prefixes
|
||||
// ========
|
||||
|
||||
class NamePrefix<string spelling> {
|
||||
string Spelling = spelling;
|
||||
}
|
||||
|
||||
// Builtin kinds
|
||||
// =============
|
||||
|
||||
@ -99,6 +106,9 @@ class Builtin {
|
||||
bit RequiresUndef = 0;
|
||||
// Enables builtins to generate `long long` outside of OpenCL and `long` inside.
|
||||
bit EnableOpenCLLong = 0;
|
||||
// Requires a common prefix to be prepended. Each generated set of builtins
|
||||
// can optionally extract one common prefix that is handled separately.
|
||||
NamePrefix RequiredNamePrefix;
|
||||
}
|
||||
|
||||
class AtomicBuiltin : Builtin;
|
||||
|
@ -12,10 +12,13 @@
|
||||
|
||||
include "clang/Basic/BuiltinsBase.td"
|
||||
|
||||
def X86Prefix : NamePrefix<"__builtin_ia32_">;
|
||||
|
||||
class X86Builtin<string prototype> : TargetBuiltin {
|
||||
let Spellings = ["__builtin_ia32_" # NAME];
|
||||
let Spellings = [NAME];
|
||||
let Prototype = prototype;
|
||||
let EnableOpenCLLong = 1;
|
||||
let RequiredNamePrefix = X86Prefix; // Adds a prefix to the name.
|
||||
}
|
||||
|
||||
class X86NoPrefixBuiltin<string prototype> : TargetBuiltin {
|
||||
|
@ -41,7 +41,14 @@ static constexpr Builtin::Info BuiltinInfos[] = {
|
||||
#include "clang/Basic/BuiltinsX86.inc"
|
||||
#undef GET_BUILTIN_INFOS
|
||||
};
|
||||
static_assert(std::size(BuiltinInfos) == NumX86Builtins);
|
||||
|
||||
static constexpr Builtin::Info PrefixedBuiltinInfos[] = {
|
||||
#define GET_BUILTIN_PREFIXED_INFOS
|
||||
#include "clang/Basic/BuiltinsX86.inc"
|
||||
#undef GET_BUILTIN_PREFIXED_INFOS
|
||||
};
|
||||
static_assert((std::size(BuiltinInfos) + std::size(PrefixedBuiltinInfos)) ==
|
||||
NumX86Builtins);
|
||||
} // namespace X86
|
||||
|
||||
namespace X86_64 {
|
||||
@ -54,7 +61,14 @@ static constexpr Builtin::Info BuiltinInfos[] = {
|
||||
#include "clang/Basic/BuiltinsX86_64.inc"
|
||||
#undef GET_BUILTIN_INFOS
|
||||
};
|
||||
static_assert(std::size(BuiltinInfos) == NumX86_64Builtins);
|
||||
|
||||
static constexpr Builtin::Info PrefixedBuiltinInfos[] = {
|
||||
#define GET_BUILTIN_PREFIXED_INFOS
|
||||
#include "clang/Basic/BuiltinsX86_64.inc"
|
||||
#undef GET_BUILTIN_PREFIXED_INFOS
|
||||
};
|
||||
static_assert((std::size(BuiltinInfos) + std::size(PrefixedBuiltinInfos)) ==
|
||||
NumX86_64Builtins);
|
||||
} // namespace X86_64
|
||||
|
||||
static const char *const GCCRegNames[] = {
|
||||
@ -1874,13 +1888,19 @@ ArrayRef<TargetInfo::AddlRegName> X86TargetInfo::getGCCAddlRegNames() const {
|
||||
|
||||
llvm::SmallVector<Builtin::InfosShard>
|
||||
X86_32TargetInfo::getTargetBuiltins() const {
|
||||
return {{&X86::BuiltinStrings, X86::BuiltinInfos}};
|
||||
return {
|
||||
{&X86::BuiltinStrings, X86::BuiltinInfos},
|
||||
{&X86::BuiltinStrings, X86::PrefixedBuiltinInfos, "__builtin_ia32_"},
|
||||
};
|
||||
}
|
||||
|
||||
llvm::SmallVector<Builtin::InfosShard>
|
||||
X86_64TargetInfo::getTargetBuiltins() const {
|
||||
return {
|
||||
{&X86::BuiltinStrings, X86::BuiltinInfos},
|
||||
{&X86::BuiltinStrings, X86::PrefixedBuiltinInfos, "__builtin_ia32_"},
|
||||
{&X86_64::BuiltinStrings, X86_64::BuiltinInfos},
|
||||
{&X86_64::BuiltinStrings, X86_64::PrefixedBuiltinInfos,
|
||||
"__builtin_ia32_"},
|
||||
};
|
||||
}
|
||||
|
@ -59,7 +59,13 @@ struct Builtin {
|
||||
const Record *BuiltinRecord;
|
||||
|
||||
void EmitEnumerator(llvm::raw_ostream &OS) const {
|
||||
OS << " BI" << Name << ",\n";
|
||||
OS << " BI";
|
||||
// If there is a required name prefix, include its spelling in the
|
||||
// enumerator.
|
||||
if (auto *PrefixRecord =
|
||||
BuiltinRecord->getValueAsOptionalDef("RequiredNamePrefix"))
|
||||
OS << PrefixRecord->getValueAsString("Spelling");
|
||||
OS << Name << ",\n";
|
||||
}
|
||||
|
||||
void EmitInfo(llvm::raw_ostream &OS, const StringToOffsetTable &Table) const {
|
||||
@ -482,17 +488,42 @@ void clang::EmitClangBuiltins(const RecordKeeper &Records, raw_ostream &OS) {
|
||||
for (const auto *BuiltinRecord :
|
||||
Records.getAllDerivedDefinitions("AtomicBuiltin"))
|
||||
collectBuiltins(BuiltinRecord, Builtins);
|
||||
|
||||
unsigned NumAtomicBuiltins = Builtins.size();
|
||||
|
||||
for (const auto *BuiltinRecord :
|
||||
Records.getAllDerivedDefinitions("Builtin")) {
|
||||
if (BuiltinRecord->isSubClassOf("AtomicBuiltin"))
|
||||
continue;
|
||||
// Prefixed builtins are also special and we emit them last so they can have
|
||||
// their own representation that skips the prefix.
|
||||
if (BuiltinRecord->getValueAsOptionalDef("RequiredNamePrefix"))
|
||||
continue;
|
||||
|
||||
collectBuiltins(BuiltinRecord, Builtins);
|
||||
}
|
||||
|
||||
// Now collect (and count) the prefixed builtins.
|
||||
unsigned NumPrefixedBuiltins = Builtins.size();
|
||||
const Record *FirstPrefix = nullptr;
|
||||
for (const auto *BuiltinRecord :
|
||||
Records.getAllDerivedDefinitions("Builtin")) {
|
||||
auto *Prefix = BuiltinRecord->getValueAsOptionalDef("RequiredNamePrefix");
|
||||
if (!Prefix)
|
||||
continue;
|
||||
|
||||
if (!FirstPrefix)
|
||||
FirstPrefix = Prefix;
|
||||
assert(Prefix == FirstPrefix &&
|
||||
"Multiple distinct prefixes which is not currently supported!");
|
||||
assert(!BuiltinRecord->isSubClassOf("AtomicBuiltin") &&
|
||||
"Cannot require a name prefix for an atomic builtin.");
|
||||
collectBuiltins(BuiltinRecord, Builtins);
|
||||
}
|
||||
NumPrefixedBuiltins = Builtins.size() - NumPrefixedBuiltins;
|
||||
|
||||
auto AtomicBuiltins = ArrayRef(Builtins).slice(0, NumAtomicBuiltins);
|
||||
auto UnprefixedBuiltins = ArrayRef(Builtins).drop_back(NumPrefixedBuiltins);
|
||||
auto PrefixedBuiltins = ArrayRef(Builtins).take_back(NumPrefixedBuiltins);
|
||||
|
||||
// Collect strings into a table.
|
||||
StringToOffsetTable Table;
|
||||
@ -524,14 +555,24 @@ void clang::EmitClangBuiltins(const RecordKeeper &Records, raw_ostream &OS) {
|
||||
#endif // GET_BUILTIN_STR_TABLE
|
||||
)c++";
|
||||
|
||||
// Emit a direct set of `Builtin::Info` initializers.
|
||||
// Emit a direct set of `Builtin::Info` initializers, first for the unprefixed
|
||||
// builtins and then for the prefixed builtins.
|
||||
OS << R"c++(
|
||||
#ifdef GET_BUILTIN_INFOS
|
||||
)c++";
|
||||
for (const auto &B : Builtins)
|
||||
for (const auto &B : UnprefixedBuiltins)
|
||||
B.EmitInfo(OS, Table);
|
||||
OS << R"c++(
|
||||
#endif // GET_BUILTIN_INFOS
|
||||
)c++";
|
||||
|
||||
OS << R"c++(
|
||||
#ifdef GET_BUILTIN_PREFIXED_INFOS
|
||||
)c++";
|
||||
for (const auto &B : PrefixedBuiltins)
|
||||
B.EmitInfo(OS, Table);
|
||||
OS << R"c++(
|
||||
#endif // GET_BUILTIN_PREFIXED_INFOS
|
||||
)c++";
|
||||
|
||||
// Emit X-macros for the atomic builtins to support various custome patterns
|
||||
|
Loading…
x
Reference in New Issue
Block a user