Skip to content

Commit 46f2b35

Browse files
authored
[clang][bytecode][NFC] Remove instance pointer from emitDestruction (#157040)
We only call this when we just pushed a new pointer to the stack, so try to save the folling PopPtr op by removing the pointer inside emitDestruction directly, e.g. by letting the Call op just remove it.
1 parent 6711099 commit 46f2b35

File tree

5 files changed

+47
-59
lines changed

5 files changed

+47
-59
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 32 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -6284,26 +6284,21 @@ bool Compiler<Emitter>::compileDestructor(const CXXDestructorDecl *Dtor) {
62846284
// First, destroy all fields.
62856285
for (const Record::Field &Field : llvm::reverse(R->fields())) {
62866286
const Descriptor *D = Field.Desc;
6287-
if (!D->isPrimitive() && !D->isPrimitiveArray()) {
6288-
if (!this->emitGetPtrField(Field.Offset, SourceInfo{}))
6289-
return false;
6290-
if (!this->emitDestruction(D, SourceInfo{}))
6291-
return false;
6292-
if (!this->emitPopPtr(SourceInfo{}))
6293-
return false;
6294-
}
6287+
if (D->hasTrivialDtor())
6288+
continue;
6289+
if (!this->emitGetPtrField(Field.Offset, SourceInfo{}))
6290+
return false;
6291+
if (!this->emitDestructionPop(D, SourceInfo{}))
6292+
return false;
62956293
}
62966294
}
62976295

62986296
for (const Record::Base &Base : llvm::reverse(R->bases())) {
6299-
if (Base.R->isAnonymousUnion())
6297+
if (Base.R->hasTrivialDtor())
63006298
continue;
6301-
63026299
if (!this->emitGetPtrBase(Base.Offset, SourceInfo{}))
63036300
return false;
6304-
if (!this->emitRecordDestruction(Base.R, {}))
6305-
return false;
6306-
if (!this->emitPopPtr(SourceInfo{}))
6301+
if (!this->emitRecordDestructionPop(Base.R, {}))
63076302
return false;
63086303
}
63096304

@@ -7200,71 +7195,56 @@ bool Compiler<Emitter>::emitComplexComparison(const Expr *LHS, const Expr *RHS,
72007195
/// on the stack.
72017196
/// Emit destruction of record types (or arrays of record types).
72027197
template <class Emitter>
7203-
bool Compiler<Emitter>::emitRecordDestruction(const Record *R, SourceInfo Loc) {
7198+
bool Compiler<Emitter>::emitRecordDestructionPop(const Record *R,
7199+
SourceInfo Loc) {
72047200
assert(R);
7205-
assert(!R->isAnonymousUnion());
7201+
assert(!R->hasTrivialDtor());
72067202
const CXXDestructorDecl *Dtor = R->getDestructor();
7207-
if (!Dtor || Dtor->isTrivial())
7208-
return true;
7209-
72107203
assert(Dtor);
72117204
const Function *DtorFunc = getFunction(Dtor);
72127205
if (!DtorFunc)
72137206
return false;
72147207
assert(DtorFunc->hasThisPointer());
72157208
assert(DtorFunc->getNumParams() == 1);
7216-
if (!this->emitDupPtr(Loc))
7217-
return false;
72187209
return this->emitCall(DtorFunc, 0, Loc);
72197210
}
72207211
/// When calling this, we have a pointer of the local-to-destroy
72217212
/// on the stack.
72227213
/// Emit destruction of record types (or arrays of record types).
72237214
template <class Emitter>
7224-
bool Compiler<Emitter>::emitDestruction(const Descriptor *Desc,
7225-
SourceInfo Loc) {
7215+
bool Compiler<Emitter>::emitDestructionPop(const Descriptor *Desc,
7216+
SourceInfo Loc) {
72267217
assert(Desc);
7227-
assert(!Desc->isPrimitive());
7228-
assert(!Desc->isPrimitiveArray());
7218+
assert(!Desc->hasTrivialDtor());
72297219

72307220
// Arrays.
72317221
if (Desc->isArray()) {
72327222
const Descriptor *ElemDesc = Desc->ElemDesc;
72337223
assert(ElemDesc);
72347224

7235-
// Don't need to do anything for these.
7236-
if (ElemDesc->isPrimitiveArray())
7237-
return true;
7225+
unsigned N = Desc->getNumElems();
7226+
if (N == 0)
7227+
return this->emitPopPtr(Loc);
72387228

7239-
// If this is an array of record types, check if we need
7240-
// to call the element destructors at all. If not, try
7241-
// to save the work.
7242-
if (const Record *ElemRecord = ElemDesc->ElemRecord) {
7243-
if (const CXXDestructorDecl *Dtor = ElemRecord->getDestructor();
7244-
!Dtor || Dtor->isTrivial())
7245-
return true;
7246-
}
7247-
7248-
if (unsigned N = Desc->getNumElems()) {
7249-
for (ssize_t I = N - 1; I >= 0; --I) {
7250-
if (!this->emitConstUint64(I, Loc))
7251-
return false;
7252-
if (!this->emitArrayElemPtrUint64(Loc))
7253-
return false;
7254-
if (!this->emitDestruction(ElemDesc, Loc))
7255-
return false;
7256-
if (!this->emitPopPtr(Loc))
7257-
return false;
7258-
}
7229+
for (ssize_t I = N - 1; I >= 1; --I) {
7230+
if (!this->emitConstUint64(I, Loc))
7231+
return false;
7232+
if (!this->emitArrayElemPtrUint64(Loc))
7233+
return false;
7234+
if (!this->emitDestructionPop(ElemDesc, Loc))
7235+
return false;
72597236
}
7260-
return true;
7237+
// Last iteration, removes the instance pointer from the stack.
7238+
if (!this->emitConstUint64(0, Loc))
7239+
return false;
7240+
if (!this->emitArrayElemPtrPopUint64(Loc))
7241+
return false;
7242+
return this->emitDestructionPop(ElemDesc, Loc);
72617243
}
72627244

72637245
assert(Desc->ElemRecord);
7264-
if (Desc->ElemRecord->isAnonymousUnion())
7265-
return true;
7266-
7267-
return this->emitRecordDestruction(Desc->ElemRecord, Loc);
7246+
assert(!Desc->ElemRecord->hasTrivialDtor());
7247+
return this->emitRecordDestructionPop(Desc->ElemRecord, Loc);
72687248
}
72697249

72707250
/// Create a dummy pointer for the given decl (or expr) and

clang/lib/AST/ByteCode/Compiler.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -391,8 +391,8 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
391391
bool emitComplexBoolCast(const Expr *E);
392392
bool emitComplexComparison(const Expr *LHS, const Expr *RHS,
393393
const BinaryOperator *E);
394-
bool emitRecordDestruction(const Record *R, SourceInfo Loc);
395-
bool emitDestruction(const Descriptor *Desc, SourceInfo Loc);
394+
bool emitRecordDestructionPop(const Record *R, SourceInfo Loc);
395+
bool emitDestructionPop(const Descriptor *Desc, SourceInfo Loc);
396396
bool emitDummyPtr(const DeclTy &D, const Expr *E);
397397
bool emitFloat(const APFloat &F, const Expr *E);
398398
unsigned collectBaseOffset(const QualType BaseType,
@@ -587,11 +587,9 @@ template <class Emitter> class LocalScope : public VariableScope<Emitter> {
587587
if (!this->Ctx->emitGetPtrLocal(Local.Offset, E))
588588
return false;
589589

590-
if (!this->Ctx->emitDestruction(Local.Desc, Local.Desc->getLoc()))
590+
if (!this->Ctx->emitDestructionPop(Local.Desc, Local.Desc->getLoc()))
591591
return false;
592592

593-
if (!this->Ctx->emitPopPtr(E))
594-
return false;
595593
removeIfStoredOpaqueValue(Local);
596594
}
597595
return true;

clang/lib/AST/ByteCode/Descriptor.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -457,8 +457,7 @@ bool Descriptor::hasTrivialDtor() const {
457457

458458
if (isRecord()) {
459459
assert(ElemRecord);
460-
const CXXDestructorDecl *Dtor = ElemRecord->getDestructor();
461-
return !Dtor || Dtor->isTrivial();
460+
return ElemRecord->hasTrivialDtor();
462461
}
463462

464463
if (!ElemDesc)

clang/lib/AST/ByteCode/Record.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@ std::string Record::getName() const {
3737
return Ret;
3838
}
3939

40+
bool Record::hasTrivialDtor() const {
41+
if (isAnonymousUnion())
42+
return true;
43+
const CXXDestructorDecl *Dtor = getDestructor();
44+
return !Dtor || Dtor->isTrivial();
45+
}
46+
4047
const Record::Field *Record::getField(const FieldDecl *FD) const {
4148
auto It = FieldMap.find(FD->getFirstDecl());
4249
assert(It != FieldMap.end() && "Missing field");

clang/lib/AST/ByteCode/Record.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ class Record final {
7676
return nullptr;
7777
}
7878

79+
/// Returns true for anonymous unions and records
80+
/// with no destructor or for those with a trivial destructor.
81+
bool hasTrivialDtor() const;
82+
7983
using const_field_iter = FieldList::const_iterator;
8084
llvm::iterator_range<const_field_iter> fields() const {
8185
return llvm::make_range(Fields.begin(), Fields.end());

0 commit comments

Comments
 (0)