Skip to content

Commit 4e5f8a8

Browse files
authored
[clang][bytecode] Save a per-Block IsWeak bit (#111248)
Checking the decl for every load is rather expensive.
1 parent fba6c88 commit 4e5f8a8

File tree

5 files changed

+23
-18
lines changed

5 files changed

+23
-18
lines changed

clang/lib/AST/ByteCode/InterpBlock.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@ bool Block::hasPointer(const Pointer *P) const {
100100
#endif
101101

102102
DeadBlock::DeadBlock(DeadBlock *&Root, Block *Blk)
103-
: Root(Root),
104-
B(~0u, Blk->Desc, Blk->IsStatic, Blk->IsExtern, /*isDead=*/true) {
103+
: Root(Root), B(~0u, Blk->Desc, Blk->IsStatic, Blk->IsExtern, Blk->IsWeak,
104+
/*isDead=*/true) {
105105
// Add the block to the chain of dead blocks.
106106
if (Root)
107107
Root->Prev = this;

clang/lib/AST/ByteCode/InterpBlock.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,16 +50,17 @@ class Block final {
5050
public:
5151
/// Creates a new block.
5252
Block(unsigned EvalID, const std::optional<unsigned> &DeclID,
53-
const Descriptor *Desc, bool IsStatic = false, bool IsExtern = false)
53+
const Descriptor *Desc, bool IsStatic = false, bool IsExtern = false,
54+
bool IsWeak = false)
5455
: EvalID(EvalID), DeclID(DeclID), IsStatic(IsStatic), IsExtern(IsExtern),
55-
IsDynamic(false), Desc(Desc) {
56+
IsDynamic(false), IsWeak(IsWeak), Desc(Desc) {
5657
assert(Desc);
5758
}
5859

5960
Block(unsigned EvalID, const Descriptor *Desc, bool IsStatic = false,
60-
bool IsExtern = false)
61+
bool IsExtern = false, bool IsWeak = false)
6162
: EvalID(EvalID), DeclID((unsigned)-1), IsStatic(IsStatic),
62-
IsExtern(IsExtern), IsDynamic(false), Desc(Desc) {
63+
IsExtern(IsExtern), IsDynamic(false), IsWeak(IsWeak), Desc(Desc) {
6364
assert(Desc);
6465
}
6566

@@ -73,6 +74,7 @@ class Block final {
7374
bool isStatic() const { return IsStatic; }
7475
/// Checks if the block is temporary.
7576
bool isTemporary() const { return Desc->IsTemporary; }
77+
bool isWeak() const { return IsWeak; }
7678
bool isDynamic() const { return IsDynamic; }
7779
/// Returns the size of the block.
7880
unsigned getSize() const { return Desc->getAllocSize(); }
@@ -135,9 +137,9 @@ class Block final {
135137
friend class DynamicAllocator;
136138

137139
Block(unsigned EvalID, const Descriptor *Desc, bool IsExtern, bool IsStatic,
138-
bool IsDead)
140+
bool IsWeak, bool IsDead)
139141
: EvalID(EvalID), IsStatic(IsStatic), IsExtern(IsExtern), IsDead(true),
140-
IsDynamic(false), Desc(Desc) {
142+
IsDynamic(false), IsWeak(IsWeak), Desc(Desc) {
141143
assert(Desc);
142144
}
143145

@@ -170,6 +172,7 @@ class Block final {
170172
/// Flag indicating if this block has been allocated via dynamic
171173
/// memory allocation (e.g. malloc).
172174
bool IsDynamic = false;
175+
bool IsWeak = false;
173176
/// Pointer to the stack slot descriptor.
174177
const Descriptor *Desc;
175178
};

clang/lib/AST/ByteCode/Pointer.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -524,9 +524,7 @@ class Pointer {
524524
return false;
525525

526526
assert(isBlockPointer());
527-
if (const ValueDecl *VD = getDeclDesc()->asValueDecl())
528-
return VD->isWeak();
529-
return false;
527+
return asBlockPointer().Pointee->isWeak();
530528
}
531529
/// Checks if an object was initialized.
532530
bool isInitialized() const;

clang/lib/AST/ByteCode/Program.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,12 @@ std::optional<unsigned> Program::getOrCreateDummy(const DeclTy &D) {
152152
return It->second;
153153

154154
QualType QT;
155+
bool IsWeak = false;
155156
if (const auto *E = D.dyn_cast<const Expr *>()) {
156157
QT = E->getType();
157158
} else {
158159
const ValueDecl *VD = cast<ValueDecl>(D.get<const Decl *>());
160+
IsWeak = VD->isWeak();
159161
QT = VD->getType();
160162
if (const auto *RT = QT->getAs<ReferenceType>())
161163
QT = RT->getPointeeType();
@@ -182,7 +184,7 @@ std::optional<unsigned> Program::getOrCreateDummy(const DeclTy &D) {
182184

183185
auto *G = new (Allocator, Desc->getAllocSize())
184186
Global(Ctx.getEvalID(), getCurrentDecl(), Desc, /*IsStatic=*/true,
185-
/*IsExtern=*/false);
187+
/*IsExtern=*/false, IsWeak);
186188
G->block()->invokeCtor();
187189

188190
Globals.push_back(G);
@@ -193,6 +195,7 @@ std::optional<unsigned> Program::getOrCreateDummy(const DeclTy &D) {
193195
std::optional<unsigned> Program::createGlobal(const ValueDecl *VD,
194196
const Expr *Init) {
195197
bool IsStatic, IsExtern;
198+
bool IsWeak = VD->isWeak();
196199
if (const auto *Var = dyn_cast<VarDecl>(VD)) {
197200
IsStatic = Context::shouldBeGloballyIndexed(VD);
198201
IsExtern = Var->hasExternalStorage();
@@ -207,7 +210,8 @@ std::optional<unsigned> Program::createGlobal(const ValueDecl *VD,
207210

208211
// Register all previous declarations as well. For extern blocks, just replace
209212
// the index with the new variable.
210-
if (auto Idx = createGlobal(VD, VD->getType(), IsStatic, IsExtern, Init)) {
213+
if (auto Idx =
214+
createGlobal(VD, VD->getType(), IsStatic, IsExtern, IsWeak, Init)) {
211215
for (const Decl *P = VD; P; P = P->getPreviousDecl()) {
212216
if (P != VD) {
213217
unsigned PIdx = GlobalIndices[P];
@@ -225,7 +229,7 @@ std::optional<unsigned> Program::createGlobal(const Expr *E) {
225229
if (auto Idx = getGlobal(E))
226230
return Idx;
227231
if (auto Idx = createGlobal(E, E->getType(), /*isStatic=*/true,
228-
/*isExtern=*/false)) {
232+
/*isExtern=*/false, /*IsWeak=*/false)) {
229233
GlobalIndices[E] = *Idx;
230234
return *Idx;
231235
}
@@ -234,7 +238,7 @@ std::optional<unsigned> Program::createGlobal(const Expr *E) {
234238

235239
std::optional<unsigned> Program::createGlobal(const DeclTy &D, QualType Ty,
236240
bool IsStatic, bool IsExtern,
237-
const Expr *Init) {
241+
bool IsWeak, const Expr *Init) {
238242
// Create a descriptor for the global.
239243
Descriptor *Desc;
240244
const bool IsConst = Ty.isConstQualified();
@@ -251,8 +255,8 @@ std::optional<unsigned> Program::createGlobal(const DeclTy &D, QualType Ty,
251255
// Allocate a block for storage.
252256
unsigned I = Globals.size();
253257

254-
auto *G = new (Allocator, Desc->getAllocSize())
255-
Global(Ctx.getEvalID(), getCurrentDecl(), Desc, IsStatic, IsExtern);
258+
auto *G = new (Allocator, Desc->getAllocSize()) Global(
259+
Ctx.getEvalID(), getCurrentDecl(), Desc, IsStatic, IsExtern, IsWeak);
256260
G->block()->invokeCtor();
257261

258262
// Initialize InlineDescriptor fields.

clang/lib/AST/ByteCode/Program.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ class Program final {
152152

153153
std::optional<unsigned> createGlobal(const DeclTy &D, QualType Ty,
154154
bool IsStatic, bool IsExtern,
155-
const Expr *Init = nullptr);
155+
bool IsWeak, const Expr *Init = nullptr);
156156

157157
/// Reference to the VM context.
158158
Context &Ctx;

0 commit comments

Comments
 (0)