Timm =?utf-8?q?Bäder?= <[email protected]> Message-ID: In-Reply-To: <llvm.org/llvm/llvm-project/pull/[email protected]>
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/173756 >From 826988d6e87f79a08613ceb7cf3911cf851124ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]> Date: Thu, 15 Jan 2026 03:46:30 +0100 Subject: [PATCH 1/2] test --- clang/lib/AST/ExprConstant.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 2a228d2896730..79d4c1c26e41a 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -931,7 +931,7 @@ namespace { : Ctx(const_cast<ASTContext &>(C)), EvalStatus(S), CurrentCall(nullptr), CallStackDepth(0), NextCallIndex(1), StepsLeft(C.getLangOpts().ConstexprStepLimit), - EnableNewConstInterp(C.getLangOpts().EnableNewConstInterp), + EnableNewConstInterp(true), BottomFrame(*this, SourceLocation(), /*Callee=*/nullptr, /*This=*/nullptr, /*CallExpr=*/nullptr, CallRef()), >From a4d5933b47595f7dec0b06120666c30312e29b41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]> Date: Fri, 26 Dec 2025 09:06:45 +0100 Subject: [PATCH 2/2] musttail --- clang/lib/AST/ByteCode/Interp.cpp | 34 ++++++++++ clang/utils/TableGen/ClangOpcodesEmitter.cpp | 70 ++++++++++++++++++++ 2 files changed, 104 insertions(+) diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index 0205d840fd71e..cb63e0f723aa1 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -2374,6 +2374,11 @@ bool FinishInitGlobal(InterpState &S, CodePtr OpPC) { #if defined(_MSC_VER) && !defined(__clang__) && !defined(NDEBUG) #pragma optimize("", off) #endif + + + +bool InterpNext(InterpState &S, CodePtr &PC); + bool Interpret(InterpState &S) { // The current stack frame when we started Interpret(). // This is being used by the ops to determine wheter @@ -2383,10 +2388,14 @@ bool Interpret(InterpState &S) { assert(!S.Current->isRoot()); CodePtr PC = S.Current->getPC(); + // S.Current->dump(); + // Empty program. if (!PC) return true; + return InterpNext(S, PC); + for (;;) { auto Op = PC.read<Opcode>(); CodePtr OpPC = PC; @@ -2398,6 +2407,31 @@ bool Interpret(InterpState &S) { } } } + + + + +#define GET_INTERPFNS_ +#include "Opcodes.inc" +#undef GET_INTERPFNS_ + + + +using InterpFn = bool (*)(InterpState &, CodePtr &PC); + +const InterpFn InterpFunctions[] = { +#define GET_INTERPFNS +#include "Opcodes.inc" +#undef GET_INTERPFNS +}; + + +bool InterpNext(InterpState &S, CodePtr &PC) { + auto Op = PC.read<Opcode>(); + auto Fn = InterpFunctions[Op]; + [[clang::musttail]] return Fn(S, PC); +} + // https://github.com/llvm/llvm-project/issues/102513 #if defined(_MSC_VER) && !defined(__clang__) && !defined(NDEBUG) #pragma optimize("", on) diff --git a/clang/utils/TableGen/ClangOpcodesEmitter.cpp b/clang/utils/TableGen/ClangOpcodesEmitter.cpp index d26122aca46bd..4d05d781dbda2 100644 --- a/clang/utils/TableGen/ClangOpcodesEmitter.cpp +++ b/clang/utils/TableGen/ClangOpcodesEmitter.cpp @@ -36,6 +36,8 @@ class ClangOpcodesEmitter { /// Emits the switch case and the invocation in the interpreter. void EmitInterp(raw_ostream &OS, StringRef N, const Record *R); + void EmitInterpFns(raw_ostream &OS, StringRef N, const Record *R); + void EmitInterpFns_(raw_ostream &OS, StringRef N, const Record *R); /// Emits the disassembler. void EmitDisasm(raw_ostream &OS, StringRef N, const Record *R); @@ -92,6 +94,8 @@ void ClangOpcodesEmitter::run(raw_ostream &OS) { EmitEnum(OS, N, Opcode); EmitInterp(OS, N, Opcode); + EmitInterpFns(OS, N, Opcode); + EmitInterpFns_(OS, N, Opcode); EmitDisasm(OS, N, Opcode); EmitProto(OS, N, Opcode); EmitGroup(OS, N, Opcode); @@ -109,6 +113,72 @@ void ClangOpcodesEmitter::EmitEnum(raw_ostream &OS, StringRef N, OS << "#endif\n"; } +void ClangOpcodesEmitter::EmitInterpFns_(raw_ostream &OS, StringRef N, + const Record *R) { + OS << "#ifdef GET_INTERPFNS_\n"; + Enumerate(R, N, [&](ArrayRef<const Record *>TS, const Twine &ID) { + OS << "static bool Interp_" << ID << "(InterpState &S, CodePtr &PC) {\n"; + + bool CanReturn = R->getValueAsBit("CanReturn"); + const auto &Args = R->getValueAsListOfDefs("Args"); + bool ChangesPC = R->getValueAsBit("ChangesPC"); + + OS << "{\n"; + + OS << "CodePtr OpPC = PC;\n"; + + // Emit calls to read arguments. + for (size_t I = 0, N = Args.size(); I < N; ++I) { + const auto *Arg = Args[I]; + bool AsRef = Arg->getValueAsBit("AsRef"); + + if (AsRef) + OS << " const auto &V" << I; + else + OS << " const auto V" << I; + OS << " = "; + OS << "ReadArg<" << Arg->getValueAsString("Name") + << ">(S, PC);\n"; + } + + + OS << " if (!" << N; + PrintTypes(OS, TS); + OS << "(S"; + // OS << ", OpPC"; + if (ChangesPC) + OS << ", PC"; + else + OS << ", OpPC"; + for (size_t I = 0, N = Args.size(); I < N; ++I) + OS << ", V" << I; + OS << "))\n"; + OS << " return false;\n"; + + OS << "}\n"; + + if (!CanReturn) + OS << "[[clang::musttail]] return InterpNext(S, PC);\n"; + else + OS << " return true;\n"; + // OS << " return false;\n"; + + OS << "}\n"; + }); + OS << "#endif\n"; +} + + + +void ClangOpcodesEmitter::EmitInterpFns(raw_ostream &OS, StringRef N, + const Record *R) { + OS << "#ifdef GET_INTERPFNS\n"; + Enumerate(R, N, [&OS](ArrayRef<const Record *>, const Twine &ID) { + OS << "&Interp_" << ID << ",\n"; + }); + OS << "#endif\n"; +} + void ClangOpcodesEmitter::EmitInterp(raw_ostream &OS, StringRef N, const Record *R) { OS << "#ifdef GET_INTERP\n"; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
