Author: Timm Baeder Date: 2026-08-30T09:45:48+02:00 New Revision: 95473a6cc68b44aed2ee0622d0bb2e60313caad9
URL: https://github.com/llvm/llvm-project/commit/95473a6cc68b44aed2ee0622d0bb2e60313caad9 DIFF: https://github.com/llvm/llvm-project/commit/95473a6cc68b44aed2ee0622d0bb2e60313caad9.diff LOG: [clang][bytecode] Remove native pointer marshalling (#218911) Just emit pointers to bytecode as uintptr_t. This avoids a vector and a DenseMap in Program. We used to emit the ID as uint32_t, but since all arguments are pointer-aligned in bytecode anyway, switching to uint64_t shouldn't cause a memory regression. Added: Modified: clang/lib/AST/ByteCode/ByteCodeEmitter.cpp clang/lib/AST/ByteCode/Disasm.cpp clang/lib/AST/ByteCode/Function.cpp clang/lib/AST/ByteCode/Function.h clang/lib/AST/ByteCode/Interp.h clang/lib/AST/ByteCode/Program.cpp clang/lib/AST/ByteCode/Program.h clang/utils/TableGen/ClangOpcodesEmitter.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp b/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp index f04478eb6ac16..81f5fe25fcc35 100644 --- a/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp +++ b/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp @@ -130,7 +130,6 @@ int32_t ByteCodeEmitter::getOffset(LabelTy Label) { } /// Helper to write bytecode and bail out if 32-bit offsets become invalid. -/// Pointers will be automatically marshalled as 32-bit IDs. template <typename T> static void emit(Program &P, llvm::SmallVectorImpl<std::byte> &Code, const T &Val, bool &Success) { @@ -138,7 +137,7 @@ static void emit(Program &P, llvm::SmallVectorImpl<std::byte> &Code, size_t Size; if constexpr (std::is_pointer_v<T>) - Size = align(sizeof(uint32_t)); + Size = align(sizeof(uintptr_t)); else Size = align(sizeof(T)); @@ -152,12 +151,10 @@ static void emit(Program &P, llvm::SmallVectorImpl<std::byte> &Code, assert(aligned(ValPos + Size)); Code.resize_for_overwrite(ValPos + Size); - if constexpr (!std::is_pointer_v<T>) { + if constexpr (std::is_pointer_v<T>) + new (Code.data() + ValPos) uintptr_t(reinterpret_cast<uintptr_t>(Val)); + else new (Code.data() + ValPos) T(Val); - } else { - uint32_t ID = P.getOrCreateNativePointer(Val); - new (Code.data() + ValPos) uint32_t(ID); - } } /// Emits a serializable value. These usually (potentially) contain diff --git a/clang/lib/AST/ByteCode/Disasm.cpp b/clang/lib/AST/ByteCode/Disasm.cpp index 9499d3a246706..611d64a2f1f54 100644 --- a/clang/lib/AST/ByteCode/Disasm.cpp +++ b/clang/lib/AST/ByteCode/Disasm.cpp @@ -33,13 +33,12 @@ using namespace clang; using namespace clang::interp; -template <typename T> -inline static std::string printArg(Program &P, CodePtr &OpPC) { +template <typename T> inline static std::string printArg(CodePtr &OpPC) { if constexpr (std::is_pointer_v<T>) { - uint32_t ID = OpPC.read<uint32_t>(); + uintptr_t Ptr = OpPC.read<uintptr_t>(); std::string Result; llvm::raw_string_ostream SS(Result); - SS << reinterpret_cast<T>(P.getNativePointer(ID)); + SS << reinterpret_cast<void *>(Ptr); return Result; } else { std::string Result; @@ -63,7 +62,7 @@ inline static std::string printArg(Program &P, CodePtr &OpPC) { } } -template <> inline std::string printArg<Floating>(Program &P, CodePtr &OpPC) { +template <> inline std::string printArg<Floating>(CodePtr &OpPC) { auto Sem = Floating::deserializeSemantics(*OpPC); unsigned BitWidth = llvm::APFloatBase::semanticsSizeInBits( @@ -81,8 +80,7 @@ template <> inline std::string printArg<Floating>(Program &P, CodePtr &OpPC) { return S; } -template <> -inline std::string printArg<IntegralAP<false>>(Program &P, CodePtr &OpPC) { +template <> inline std::string printArg<IntegralAP<false>>(CodePtr &OpPC) { using T = IntegralAP<false>; uint32_t BitWidth = T::deserializeSize(*OpPC); auto Memory = @@ -99,8 +97,7 @@ inline std::string printArg<IntegralAP<false>>(Program &P, CodePtr &OpPC) { return Str; } -template <> -inline std::string printArg<IntegralAP<true>>(Program &P, CodePtr &OpPC) { +template <> inline std::string printArg<IntegralAP<true>>(CodePtr &OpPC) { using T = IntegralAP<true>; uint32_t BitWidth = T::deserializeSize(*OpPC); auto Memory = @@ -117,7 +114,7 @@ inline std::string printArg<IntegralAP<true>>(Program &P, CodePtr &OpPC) { return Str; } -template <> inline std::string printArg<FixedPoint>(Program &P, CodePtr &OpPC) { +template <> inline std::string printArg<FixedPoint>(CodePtr &OpPC) { auto F = FixedPoint::deserialize(*OpPC); OpPC += align(F.bytesToSerialize()); @@ -152,9 +149,8 @@ LLVM_DUMP_METHOD void Function::dump(llvm::raw_ostream &OS, { ColorScope SC(OS, true, {llvm::raw_ostream::BRIGHT_GREEN, true}); if (const FunctionDecl *FD = getDecl()) { - FD->getNameForDiagnostic( - OS, P.getContext().getASTContext().getPrintingPolicy(), - /*Qualified=*/true); + FD->getNameForDiagnostic(OS, FD->getASTContext().getPrintingPolicy(), + /*Qualified=*/true); } else { OS << getName(); } diff --git a/clang/lib/AST/ByteCode/Function.cpp b/clang/lib/AST/ByteCode/Function.cpp index 49282c9dc7a33..a609af5828d92 100644 --- a/clang/lib/AST/ByteCode/Function.cpp +++ b/clang/lib/AST/ByteCode/Function.cpp @@ -15,10 +15,10 @@ using namespace clang; using namespace clang::interp; -Function::Function(Program &P, FunctionDeclTy Source, unsigned ArgSize, +Function::Function(FunctionDeclTy Source, unsigned ArgSize, llvm::SmallVectorImpl<ParamDescriptor> &&ParamDescriptors, bool HasThisPointer, bool HasRVO, bool IsLambdaStaticInvoker) - : P(P), Kind(FunctionKind::Normal), Source(Source), ArgSize(ArgSize), + : Kind(FunctionKind::Normal), Source(Source), ArgSize(ArgSize), ParamDescriptors(std::move(ParamDescriptors)), IsValid(false), IsFullyCompiled(false), HasThisPointer(HasThisPointer), HasRVO(HasRVO), HasBody(false), Defined(false) { diff --git a/clang/lib/AST/ByteCode/Function.h b/clang/lib/AST/ByteCode/Function.h index 9742a16b50f2c..5dec1a0eee8ca 100644 --- a/clang/lib/AST/ByteCode/Function.h +++ b/clang/lib/AST/ByteCode/Function.h @@ -25,7 +25,6 @@ namespace clang { namespace interp { -class Program; class ByteCodeEmitter; class Pointer; enum PrimType : uint8_t; @@ -254,7 +253,7 @@ class Function final { private: /// Construct a function representing an actual function. - Function(Program &P, FunctionDeclTy Source, unsigned ArgSize, + Function(FunctionDeclTy Source, unsigned ArgSize, llvm::SmallVectorImpl<ParamDescriptor> &&ParamDescriptors, bool HasThisPointer, bool HasRVO, bool IsLambdaStaticInvoker); @@ -280,8 +279,6 @@ class Function final { friend class ByteCodeEmitter; friend class Context; - /// Program reference. - Program &P; /// Function Kind. FunctionKind Kind; /// Declaration this function was compiled from. diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index 2fe62fd511ea3..d58f3ce46d41a 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -4088,12 +4088,10 @@ inline bool IsBaseClass(InterpState &S) { //===----------------------------------------------------------------------===// template <typename T> inline T ReadArg(InterpState &S, CodePtr &OpPC) { - if constexpr (std::is_pointer<T>::value) { - uint32_t ID = OpPC.read<uint32_t>(); - return reinterpret_cast<T>(S.P.getNativePointer(ID)); - } else { + if constexpr (std::is_pointer<T>::value) + return reinterpret_cast<T>(OpPC.read<uintptr_t>()); + else return OpPC.read<T>(); - } } template <> inline Floating ReadArg<Floating>(InterpState &S, CodePtr &OpPC) { diff --git a/clang/lib/AST/ByteCode/Program.cpp b/clang/lib/AST/ByteCode/Program.cpp index af2f108ef6970..257fa9214076e 100644 --- a/clang/lib/AST/ByteCode/Program.cpp +++ b/clang/lib/AST/ByteCode/Program.cpp @@ -17,19 +17,6 @@ using namespace clang; using namespace clang::interp; -unsigned Program::getOrCreateNativePointer(const void *Ptr) { - auto [It, Inserted] = - NativePointerIndices.try_emplace(Ptr, NativePointers.size()); - if (Inserted) - NativePointers.push_back(Ptr); - - return It->second; -} - -const void *Program::getNativePointer(unsigned Idx) const { - return NativePointers[Idx]; -} - Pointer Program::getPtrGlobal(unsigned Idx) const { assert(Idx < Globals.size()); return Pointer(Globals[Idx]->block()); diff --git a/clang/lib/AST/ByteCode/Program.h b/clang/lib/AST/ByteCode/Program.h index ea9e5b6bead72..19c64f8e914e7 100644 --- a/clang/lib/AST/ByteCode/Program.h +++ b/clang/lib/AST/ByteCode/Program.h @@ -57,12 +57,6 @@ class Program final { const Context &getContext() const { return Ctx; } - /// Marshals a native pointer to an ID for embedding in bytecode. - unsigned getOrCreateNativePointer(const void *Ptr); - - /// Returns the value of a marshalled native pointer. - const void *getNativePointer(unsigned Idx) const; - /// Returns a pointer to a global. Pointer getPtrGlobal(unsigned Idx) const; @@ -98,13 +92,13 @@ class Program final { template <typename... Ts> Function *createFunction(const FunctionDecl *Def, Ts &&...Args) { Def = Def->getCanonicalDecl(); - auto *Func = new Function(*this, Def, std::forward<Ts>(Args)...); + auto *Func = new Function(Def, std::forward<Ts>(Args)...); Funcs.insert({Def, std::unique_ptr<Function>(Func)}); return Func; } /// Creates an anonymous function. template <typename... Ts> Function *createFunction(Ts &&...Args) { - auto *Func = new Function(*this, std::forward<Ts>(Args)...); + auto *Func = new Function(std::forward<Ts>(Args)...); AnonFuncs.emplace_back(Func); return Func; } @@ -175,11 +169,6 @@ class Program final { /// List of anonymous functions. std::vector<std::unique_ptr<Function>> AnonFuncs; - /// Native pointers referenced by bytecode. - std::vector<const void *> NativePointers; - /// Cached native pointer indices. - llvm::DenseMap<const void *, unsigned> NativePointerIndices; - /// Custom allocator for global storage. using PoolAllocTy = llvm::BumpPtrAllocator; diff --git a/clang/utils/TableGen/ClangOpcodesEmitter.cpp b/clang/utils/TableGen/ClangOpcodesEmitter.cpp index 8e70a070696ea..8165dd7547712 100644 --- a/clang/utils/TableGen/ClangOpcodesEmitter.cpp +++ b/clang/utils/TableGen/ClangOpcodesEmitter.cpp @@ -232,7 +232,7 @@ void ClangOpcodesEmitter::EmitDisasm(raw_ostream &OS, StringRef N, OS << " Text.Op = PrintName(\"" << ID << "\");\n"; for (const auto *Arg : R->getValueAsListOfDefs("Args")) OS << " Text.Args.push_back(printArg<" << Arg->getValueAsString("Name") - << ">(P, PC));\n"; + << ">(PC));\n"; OS << " break;\n"; }); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
