Skip to content

Commit 7529707

Browse files
committed
[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.
1 parent 629e5b5 commit 7529707

File tree

4 files changed

+82
-8
lines changed

4 files changed

+82
-8
lines changed

clang/include/clang/Basic/BuiltinsBase.td

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,13 @@ def Consteval : Attribute<"EG">;
8686
// indicated by the remaining indices.
8787
class Callback<list<int> ArgIndices> : MultiIndexAttribute<"C", ArgIndices>;
8888

89+
// Prefixes
90+
// ========
91+
92+
class NamePrefix<string spelling> {
93+
string Spelling = spelling;
94+
}
95+
8996
// Builtin kinds
9097
// =============
9198

@@ -99,6 +106,9 @@ class Builtin {
99106
bit RequiresUndef = 0;
100107
// Enables builtins to generate `long long` outside of OpenCL and `long` inside.
101108
bit EnableOpenCLLong = 0;
109+
// Requires a common prefix to be prepended. Each generated set of builtins
110+
// can optionally extract one common prefix that is handled separately.
111+
NamePrefix RequiredNamePrefix;
102112
}
103113

104114
class AtomicBuiltin : Builtin;

clang/include/clang/Basic/BuiltinsX86Base.td

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@
1212

1313
include "clang/Basic/BuiltinsBase.td"
1414

15+
def X86Prefix : NamePrefix<"__builtin_ia32_">;
16+
1517
class X86Builtin<string prototype> : TargetBuiltin {
16-
let Spellings = ["__builtin_ia32_" # NAME];
18+
let Spellings = [NAME];
1719
let Prototype = prototype;
1820
let EnableOpenCLLong = 1;
21+
let RequiredNamePrefix = X86Prefix; // Adds a prefix to the name.
1922
}
2023

2124
class X86NoPrefixBuiltin<string prototype> : TargetBuiltin {

clang/lib/Basic/Targets/X86.cpp

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,14 @@ static constexpr Builtin::Info BuiltinInfos[] = {
4141
#include "clang/Basic/BuiltinsX86.inc"
4242
#undef GET_BUILTIN_INFOS
4343
};
44-
static_assert(std::size(BuiltinInfos) == NumX86Builtins);
44+
45+
static constexpr Builtin::Info PrefixedBuiltinInfos[] = {
46+
#define GET_BUILTIN_PREFIXED_INFOS
47+
#include "clang/Basic/BuiltinsX86.inc"
48+
#undef GET_BUILTIN_PREFIXED_INFOS
49+
};
50+
static_assert((std::size(BuiltinInfos) + std::size(PrefixedBuiltinInfos)) ==
51+
NumX86Builtins);
4552
} // namespace X86
4653

4754
namespace X86_64 {
@@ -54,7 +61,14 @@ static constexpr Builtin::Info BuiltinInfos[] = {
5461
#include "clang/Basic/BuiltinsX86_64.inc"
5562
#undef GET_BUILTIN_INFOS
5663
};
57-
static_assert(std::size(BuiltinInfos) == NumX86_64Builtins);
64+
65+
static constexpr Builtin::Info PrefixedBuiltinInfos[] = {
66+
#define GET_BUILTIN_PREFIXED_INFOS
67+
#include "clang/Basic/BuiltinsX86_64.inc"
68+
#undef GET_BUILTIN_PREFIXED_INFOS
69+
};
70+
static_assert((std::size(BuiltinInfos) + std::size(PrefixedBuiltinInfos)) ==
71+
NumX86_64Builtins);
5872
} // namespace X86_64
5973

6074
static const char *const GCCRegNames[] = {
@@ -1874,13 +1888,19 @@ ArrayRef<TargetInfo::AddlRegName> X86TargetInfo::getGCCAddlRegNames() const {
18741888

18751889
llvm::SmallVector<Builtin::InfosShard>
18761890
X86_32TargetInfo::getTargetBuiltins() const {
1877-
return {{&X86::BuiltinStrings, X86::BuiltinInfos}};
1891+
return {
1892+
{&X86::BuiltinStrings, X86::BuiltinInfos},
1893+
{&X86::BuiltinStrings, X86::PrefixedBuiltinInfos, "__builtin_ia32_"},
1894+
};
18781895
}
18791896

18801897
llvm::SmallVector<Builtin::InfosShard>
18811898
X86_64TargetInfo::getTargetBuiltins() const {
18821899
return {
18831900
{&X86::BuiltinStrings, X86::BuiltinInfos},
1901+
{&X86::BuiltinStrings, X86::PrefixedBuiltinInfos, "__builtin_ia32_"},
18841902
{&X86_64::BuiltinStrings, X86_64::BuiltinInfos},
1903+
{&X86_64::BuiltinStrings, X86_64::PrefixedBuiltinInfos,
1904+
"__builtin_ia32_"},
18851905
};
18861906
}

clang/utils/TableGen/ClangBuiltinsEmitter.cpp

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,13 @@ struct Builtin {
5959
const Record *BuiltinRecord;
6060

6161
void EmitEnumerator(llvm::raw_ostream &OS) const {
62-
OS << " BI" << Name << ",\n";
62+
OS << " BI";
63+
// If there is a required name prefix, include its spelling in the
64+
// enumerator.
65+
if (auto *PrefixRecord =
66+
BuiltinRecord->getValueAsOptionalDef("RequiredNamePrefix"))
67+
OS << PrefixRecord->getValueAsString("Spelling");
68+
OS << Name << ",\n";
6369
}
6470

6571
void EmitInfo(llvm::raw_ostream &OS, const StringToOffsetTable &Table) const {
@@ -482,17 +488,42 @@ void clang::EmitClangBuiltins(const RecordKeeper &Records, raw_ostream &OS) {
482488
for (const auto *BuiltinRecord :
483489
Records.getAllDerivedDefinitions("AtomicBuiltin"))
484490
collectBuiltins(BuiltinRecord, Builtins);
485-
486491
unsigned NumAtomicBuiltins = Builtins.size();
487492

488493
for (const auto *BuiltinRecord :
489494
Records.getAllDerivedDefinitions("Builtin")) {
490495
if (BuiltinRecord->isSubClassOf("AtomicBuiltin"))
491496
continue;
497+
// Prefixed builtins are also special and we emit them last so they can have
498+
// their own representation that skips the prefix.
499+
if (BuiltinRecord->getValueAsOptionalDef("RequiredNamePrefix"))
500+
continue;
501+
492502
collectBuiltins(BuiltinRecord, Builtins);
493503
}
494504

505+
// Now collect (and count) the prefixed builtins.
506+
unsigned NumPrefixedBuiltins = Builtins.size();
507+
const Record *FirstPrefix = nullptr;
508+
for (const auto *BuiltinRecord :
509+
Records.getAllDerivedDefinitions("Builtin")) {
510+
auto *Prefix = BuiltinRecord->getValueAsOptionalDef("RequiredNamePrefix");
511+
if (!Prefix)
512+
continue;
513+
514+
if (!FirstPrefix)
515+
FirstPrefix = Prefix;
516+
assert(Prefix == FirstPrefix &&
517+
"Multiple distinct prefixes which is not currently supported!");
518+
assert(!BuiltinRecord->isSubClassOf("AtomicBuiltin") &&
519+
"Cannot require a name prefix for an atomic builtin.");
520+
collectBuiltins(BuiltinRecord, Builtins);
521+
}
522+
NumPrefixedBuiltins = Builtins.size() - NumPrefixedBuiltins;
523+
495524
auto AtomicBuiltins = ArrayRef(Builtins).slice(0, NumAtomicBuiltins);
525+
auto UnprefixedBuiltins = ArrayRef(Builtins).drop_back(NumPrefixedBuiltins);
526+
auto PrefixedBuiltins = ArrayRef(Builtins).take_back(NumPrefixedBuiltins);
496527

497528
// Collect strings into a table.
498529
StringToOffsetTable Table;
@@ -524,14 +555,24 @@ void clang::EmitClangBuiltins(const RecordKeeper &Records, raw_ostream &OS) {
524555
#endif // GET_BUILTIN_STR_TABLE
525556
)c++";
526557

527-
// Emit a direct set of `Builtin::Info` initializers.
558+
// Emit a direct set of `Builtin::Info` initializers, first for the unprefixed
559+
// builtins and then for the prefixed builtins.
528560
OS << R"c++(
529561
#ifdef GET_BUILTIN_INFOS
530562
)c++";
531-
for (const auto &B : Builtins)
563+
for (const auto &B : UnprefixedBuiltins)
532564
B.EmitInfo(OS, Table);
533565
OS << R"c++(
534566
#endif // GET_BUILTIN_INFOS
567+
)c++";
568+
569+
OS << R"c++(
570+
#ifdef GET_BUILTIN_PREFIXED_INFOS
571+
)c++";
572+
for (const auto &B : PrefixedBuiltins)
573+
B.EmitInfo(OS, Table);
574+
OS << R"c++(
575+
#endif // GET_BUILTIN_PREFIXED_INFOS
535576
)c++";
536577

537578
// Emit X-macros for the atomic builtins to support various custome patterns

0 commit comments

Comments
 (0)