Author: Timm Baeder Date: 2024-10-05T17:35:52+02:00 New Revision: 4e5f8a8f0bf855fdac93fa09b4b82b69339235b9
URL: https://github.com/llvm/llvm-project/commit/4e5f8a8f0bf855fdac93fa09b4b82b69339235b9 DIFF: https://github.com/llvm/llvm-project/commit/4e5f8a8f0bf855fdac93fa09b4b82b69339235b9.diff LOG: [clang][bytecode] Save a per-Block IsWeak bit (#111248) Checking the decl for every load is rather expensive. Added: Modified: clang/lib/AST/ByteCode/InterpBlock.cpp clang/lib/AST/ByteCode/InterpBlock.h clang/lib/AST/ByteCode/Pointer.h clang/lib/AST/ByteCode/Program.cpp clang/lib/AST/ByteCode/Program.h Removed: ################################################################################ diff --git a/clang/lib/AST/ByteCode/InterpBlock.cpp b/clang/lib/AST/ByteCode/InterpBlock.cpp index 0ce88ca7e52365..9ef44cd29ff875 100644 --- a/clang/lib/AST/ByteCode/InterpBlock.cpp +++ b/clang/lib/AST/ByteCode/InterpBlock.cpp @@ -100,8 +100,8 @@ bool Block::hasPointer(const Pointer *P) const { #endif DeadBlock::DeadBlock(DeadBlock *&Root, Block *Blk) - : Root(Root), - B(~0u, Blk->Desc, Blk->IsStatic, Blk->IsExtern, /*isDead=*/true) { + : Root(Root), B(~0u, Blk->Desc, Blk->IsStatic, Blk->IsExtern, Blk->IsWeak, + /*isDead=*/true) { // Add the block to the chain of dead blocks. if (Root) Root->Prev = this; diff --git a/clang/lib/AST/ByteCode/InterpBlock.h b/clang/lib/AST/ByteCode/InterpBlock.h index a5cd58e3a655a0..985e4c152191c6 100644 --- a/clang/lib/AST/ByteCode/InterpBlock.h +++ b/clang/lib/AST/ByteCode/InterpBlock.h @@ -50,16 +50,17 @@ class Block final { public: /// Creates a new block. Block(unsigned EvalID, const std::optional<unsigned> &DeclID, - const Descriptor *Desc, bool IsStatic = false, bool IsExtern = false) + const Descriptor *Desc, bool IsStatic = false, bool IsExtern = false, + bool IsWeak = false) : EvalID(EvalID), DeclID(DeclID), IsStatic(IsStatic), IsExtern(IsExtern), - IsDynamic(false), Desc(Desc) { + IsDynamic(false), IsWeak(IsWeak), Desc(Desc) { assert(Desc); } Block(unsigned EvalID, const Descriptor *Desc, bool IsStatic = false, - bool IsExtern = false) + bool IsExtern = false, bool IsWeak = false) : EvalID(EvalID), DeclID((unsigned)-1), IsStatic(IsStatic), - IsExtern(IsExtern), IsDynamic(false), Desc(Desc) { + IsExtern(IsExtern), IsDynamic(false), IsWeak(IsWeak), Desc(Desc) { assert(Desc); } @@ -73,6 +74,7 @@ class Block final { bool isStatic() const { return IsStatic; } /// Checks if the block is temporary. bool isTemporary() const { return Desc->IsTemporary; } + bool isWeak() const { return IsWeak; } bool isDynamic() const { return IsDynamic; } /// Returns the size of the block. unsigned getSize() const { return Desc->getAllocSize(); } @@ -135,9 +137,9 @@ class Block final { friend class DynamicAllocator; Block(unsigned EvalID, const Descriptor *Desc, bool IsExtern, bool IsStatic, - bool IsDead) + bool IsWeak, bool IsDead) : EvalID(EvalID), IsStatic(IsStatic), IsExtern(IsExtern), IsDead(true), - IsDynamic(false), Desc(Desc) { + IsDynamic(false), IsWeak(IsWeak), Desc(Desc) { assert(Desc); } @@ -170,6 +172,7 @@ class Block final { /// Flag indicating if this block has been allocated via dynamic /// memory allocation (e.g. malloc). bool IsDynamic = false; + bool IsWeak = false; /// Pointer to the stack slot descriptor. const Descriptor *Desc; }; diff --git a/clang/lib/AST/ByteCode/Pointer.h b/clang/lib/AST/ByteCode/Pointer.h index 08bc4b7e40b636..72e255dba13f6b 100644 --- a/clang/lib/AST/ByteCode/Pointer.h +++ b/clang/lib/AST/ByteCode/Pointer.h @@ -524,9 +524,7 @@ class Pointer { return false; assert(isBlockPointer()); - if (const ValueDecl *VD = getDeclDesc()->asValueDecl()) - return VD->isWeak(); - return false; + return asBlockPointer().Pointee->isWeak(); } /// Checks if an object was initialized. bool isInitialized() const; diff --git a/clang/lib/AST/ByteCode/Program.cpp b/clang/lib/AST/ByteCode/Program.cpp index 79c645257306e0..969f523db51dfe 100644 --- a/clang/lib/AST/ByteCode/Program.cpp +++ b/clang/lib/AST/ByteCode/Program.cpp @@ -152,10 +152,12 @@ std::optional<unsigned> Program::getOrCreateDummy(const DeclTy &D) { return It->second; QualType QT; + bool IsWeak = false; if (const auto *E = D.dyn_cast<const Expr *>()) { QT = E->getType(); } else { const ValueDecl *VD = cast<ValueDecl>(D.get<const Decl *>()); + IsWeak = VD->isWeak(); QT = VD->getType(); if (const auto *RT = QT->getAs<ReferenceType>()) QT = RT->getPointeeType(); @@ -182,7 +184,7 @@ std::optional<unsigned> Program::getOrCreateDummy(const DeclTy &D) { auto *G = new (Allocator, Desc->getAllocSize()) Global(Ctx.getEvalID(), getCurrentDecl(), Desc, /*IsStatic=*/true, - /*IsExtern=*/false); + /*IsExtern=*/false, IsWeak); G->block()->invokeCtor(); Globals.push_back(G); @@ -193,6 +195,7 @@ std::optional<unsigned> Program::getOrCreateDummy(const DeclTy &D) { std::optional<unsigned> Program::createGlobal(const ValueDecl *VD, const Expr *Init) { bool IsStatic, IsExtern; + bool IsWeak = VD->isWeak(); if (const auto *Var = dyn_cast<VarDecl>(VD)) { IsStatic = Context::shouldBeGloballyIndexed(VD); IsExtern = Var->hasExternalStorage(); @@ -207,7 +210,8 @@ std::optional<unsigned> Program::createGlobal(const ValueDecl *VD, // Register all previous declarations as well. For extern blocks, just replace // the index with the new variable. - if (auto Idx = createGlobal(VD, VD->getType(), IsStatic, IsExtern, Init)) { + if (auto Idx = + createGlobal(VD, VD->getType(), IsStatic, IsExtern, IsWeak, Init)) { for (const Decl *P = VD; P; P = P->getPreviousDecl()) { if (P != VD) { unsigned PIdx = GlobalIndices[P]; @@ -225,7 +229,7 @@ std::optional<unsigned> Program::createGlobal(const Expr *E) { if (auto Idx = getGlobal(E)) return Idx; if (auto Idx = createGlobal(E, E->getType(), /*isStatic=*/true, - /*isExtern=*/false)) { + /*isExtern=*/false, /*IsWeak=*/false)) { GlobalIndices[E] = *Idx; return *Idx; } @@ -234,7 +238,7 @@ std::optional<unsigned> Program::createGlobal(const Expr *E) { std::optional<unsigned> Program::createGlobal(const DeclTy &D, QualType Ty, bool IsStatic, bool IsExtern, - const Expr *Init) { + bool IsWeak, const Expr *Init) { // Create a descriptor for the global. Descriptor *Desc; const bool IsConst = Ty.isConstQualified(); @@ -251,8 +255,8 @@ std::optional<unsigned> Program::createGlobal(const DeclTy &D, QualType Ty, // Allocate a block for storage. unsigned I = Globals.size(); - auto *G = new (Allocator, Desc->getAllocSize()) - Global(Ctx.getEvalID(), getCurrentDecl(), Desc, IsStatic, IsExtern); + auto *G = new (Allocator, Desc->getAllocSize()) Global( + Ctx.getEvalID(), getCurrentDecl(), Desc, IsStatic, IsExtern, IsWeak); G->block()->invokeCtor(); // Initialize InlineDescriptor fields. diff --git a/clang/lib/AST/ByteCode/Program.h b/clang/lib/AST/ByteCode/Program.h index bd2672a762b82a..be84c40714a60b 100644 --- a/clang/lib/AST/ByteCode/Program.h +++ b/clang/lib/AST/ByteCode/Program.h @@ -152,7 +152,7 @@ class Program final { std::optional<unsigned> createGlobal(const DeclTy &D, QualType Ty, bool IsStatic, bool IsExtern, - const Expr *Init = nullptr); + bool IsWeak, const Expr *Init = nullptr); /// Reference to the VM context. Context &Ctx; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits