Skip to content

Commit 3745a2e

Browse files
authored
[clang][bytecode][NFC] Cache the BuiltinID in Function (#106745)
FunctionDecl::getBuiltinID() is surprisingly slow and we tend to call it quite a bit, especially when interpreting builtin functions. Caching the BuiltinID here reduces the time I need to compile the floating_comparison namespace from builtin-functions.cpp from 7.2s to 6.3s locally.
1 parent 02eb03d commit 3745a2e

File tree

3 files changed

+24
-28
lines changed

3 files changed

+24
-28
lines changed

clang/lib/AST/ByteCode/ByteCodeEmitter.cpp

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,6 @@
2121
using namespace clang;
2222
using namespace clang::interp;
2323

24-
/// Unevaluated builtins don't get their arguments put on the stack
25-
/// automatically. They instead operate on the AST of their Call
26-
/// Expression.
27-
/// Similar information is available via ASTContext::BuiltinInfo,
28-
/// but that is not correct for our use cases.
29-
static bool isUnevaluatedBuiltin(unsigned BuiltinID) {
30-
return BuiltinID == Builtin::BI__builtin_classify_type ||
31-
BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size ||
32-
BuiltinID == Builtin::BI__builtin_constant_p;
33-
}
34-
3524
Function *ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) {
3625

3726
// Manually created functions that haven't been assigned proper
@@ -147,14 +136,11 @@ Function *ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) {
147136
// Create a handle over the emitted code.
148137
Function *Func = P.getFunction(FuncDecl);
149138
if (!Func) {
150-
bool IsUnevaluatedBuiltin = false;
151-
if (unsigned BI = FuncDecl->getBuiltinID())
152-
IsUnevaluatedBuiltin = isUnevaluatedBuiltin(BI);
153-
139+
unsigned BuiltinID = FuncDecl->getBuiltinID();
154140
Func =
155141
P.createFunction(FuncDecl, ParamOffset, std::move(ParamTypes),
156142
std::move(ParamDescriptors), std::move(ParamOffsets),
157-
HasThisPointer, HasRVO, IsUnevaluatedBuiltin);
143+
HasThisPointer, HasRVO, BuiltinID);
158144
}
159145

160146
assert(Func);

clang/lib/AST/ByteCode/Function.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,10 @@ Function::Function(Program &P, FunctionDeclTy Source, unsigned ArgSize,
2020
llvm::SmallVectorImpl<PrimType> &&ParamTypes,
2121
llvm::DenseMap<unsigned, ParamDescriptor> &&Params,
2222
llvm::SmallVectorImpl<unsigned> &&ParamOffsets,
23-
bool HasThisPointer, bool HasRVO, bool UnevaluatedBuiltin)
23+
bool HasThisPointer, bool HasRVO, unsigned BuiltinID)
2424
: P(P), Source(Source), ArgSize(ArgSize), ParamTypes(std::move(ParamTypes)),
2525
Params(std::move(Params)), ParamOffsets(std::move(ParamOffsets)),
26-
HasThisPointer(HasThisPointer), HasRVO(HasRVO),
27-
IsUnevaluatedBuiltin(UnevaluatedBuiltin) {
26+
HasThisPointer(HasThisPointer), HasRVO(HasRVO), BuiltinID(BuiltinID) {
2827
if (const auto *F = Source.dyn_cast<const FunctionDecl *>())
2928
Variadic = F->isVariadic();
3029
}
@@ -53,3 +52,18 @@ bool Function::isVirtual() const {
5352
return M->isVirtual();
5453
return false;
5554
}
55+
56+
/// Unevaluated builtins don't get their arguments put on the stack
57+
/// automatically. They instead operate on the AST of their Call
58+
/// Expression.
59+
/// Similar information is available via ASTContext::BuiltinInfo,
60+
/// but that is not correct for our use cases.
61+
static bool isUnevaluatedBuiltin(unsigned BuiltinID) {
62+
return BuiltinID == Builtin::BI__builtin_classify_type ||
63+
BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size ||
64+
BuiltinID == Builtin::BI__builtin_constant_p;
65+
}
66+
67+
bool Function::isUnevaluatedBuiltin() const {
68+
return ::isUnevaluatedBuiltin(BuiltinID);
69+
}

clang/lib/AST/ByteCode/Function.h

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -193,15 +193,11 @@ class Function final {
193193

194194
bool isVariadic() const { return Variadic; }
195195

196-
unsigned getBuiltinID() const {
197-
return Source.get<const FunctionDecl *>()->getBuiltinID();
198-
}
196+
unsigned getBuiltinID() const { return BuiltinID; }
199197

200-
bool isBuiltin() const {
201-
return Source.get<const FunctionDecl *>()->getBuiltinID() != 0;
202-
}
198+
bool isBuiltin() const { return getBuiltinID() != 0; }
203199

204-
bool isUnevaluatedBuiltin() const { return IsUnevaluatedBuiltin; }
200+
bool isUnevaluatedBuiltin() const;
205201

206202
unsigned getNumParams() const { return ParamTypes.size(); }
207203

@@ -232,7 +228,7 @@ class Function final {
232228
llvm::SmallVectorImpl<PrimType> &&ParamTypes,
233229
llvm::DenseMap<unsigned, ParamDescriptor> &&Params,
234230
llvm::SmallVectorImpl<unsigned> &&ParamOffsets, bool HasThisPointer,
235-
bool HasRVO, bool UnevaluatedBuiltin);
231+
bool HasRVO, unsigned BuiltinID);
236232

237233
/// Sets the code of a function.
238234
void setCode(unsigned NewFrameSize, std::vector<std::byte> &&NewCode,
@@ -289,7 +285,7 @@ class Function final {
289285
bool HasBody = false;
290286
bool Defined = false;
291287
bool Variadic = false;
292-
bool IsUnevaluatedBuiltin = false;
288+
unsigned BuiltinID = 0;
293289

294290
public:
295291
/// Dumps the disassembled bytecode to \c llvm::errs().

0 commit comments

Comments
 (0)