[clang][bytecode] Avoid classifying in visitArrayElemInit() (#139674)

We usually call this more than once, but the type of the initializer
never changes. Let's classify only once and pass that to
visitArrayElemInit().
This commit is contained in:
Timm Baeder 2025-05-13 11:01:59 +02:00 committed by GitHub
parent fd3fecfc09
commit 3de2fa91e1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 14 additions and 11 deletions

View File

@ -570,11 +570,11 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
return false;
}
PrimType T = classifyPrim(SubExpr->getType());
// Init the complex value to {SubExpr, 0}.
if (!this->visitArrayElemInit(0, SubExpr))
if (!this->visitArrayElemInit(0, SubExpr, T))
return false;
// Zero-init the second element.
PrimType T = classifyPrim(SubExpr->getType());
if (!this->visitZeroInitializer(T, SubExpr->getType(), SubExpr))
return false;
return this->emitInitElem(T, 1, SubExpr);
@ -772,7 +772,7 @@ bool Compiler<Emitter>::VisitImaginaryLiteral(const ImaginaryLiteral *E) {
return false;
if (!this->emitInitElem(SubExprT, 0, SubExpr))
return false;
return this->visitArrayElemInit(1, SubExpr);
return this->visitArrayElemInit(1, SubExpr, SubExprT);
}
template <class Emitter>
@ -1886,6 +1886,7 @@ bool Compiler<Emitter>::visitInitList(ArrayRef<const Expr *> Inits,
if (!this->emitCheckArraySize(NumElems, E))
return false;
std::optional<PrimType> InitT = classify(CAT->getElementType());
unsigned ElementIndex = 0;
for (const Expr *Init : Inits) {
if (const auto *EmbedS =
@ -1905,7 +1906,7 @@ bool Compiler<Emitter>::visitInitList(ArrayRef<const Expr *> Inits,
if (!EmbedS->doForEachDataElement(Eval, ElementIndex))
return false;
} else {
if (!this->visitArrayElemInit(ElementIndex, Init))
if (!this->visitArrayElemInit(ElementIndex, Init, InitT))
return false;
++ElementIndex;
}
@ -1915,7 +1916,7 @@ bool Compiler<Emitter>::visitInitList(ArrayRef<const Expr *> Inits,
// FIXME: This should go away.
if (ArrayFiller) {
for (; ElementIndex != NumElems; ++ElementIndex) {
if (!this->visitArrayElemInit(ElementIndex, ArrayFiller))
if (!this->visitArrayElemInit(ElementIndex, ArrayFiller, InitT))
return false;
}
}
@ -1998,13 +1999,13 @@ bool Compiler<Emitter>::visitInitList(ArrayRef<const Expr *> Inits,
/// Pointer to the array(not the element!) must be on the stack when calling
/// this.
template <class Emitter>
bool Compiler<Emitter>::visitArrayElemInit(unsigned ElemIndex,
const Expr *Init) {
if (std::optional<PrimType> T = classify(Init->getType())) {
bool Compiler<Emitter>::visitArrayElemInit(unsigned ElemIndex, const Expr *Init,
std::optional<PrimType> InitT) {
if (InitT) {
// Visit the primitive element like normal.
if (!this->visit(Init))
return false;
return this->emitInitElem(*T, ElemIndex, Init);
return this->emitInitElem(*InitT, ElemIndex, Init);
}
InitLinkScope<Emitter> ILS(this, InitLink::Elem(ElemIndex));
@ -2298,6 +2299,7 @@ bool Compiler<Emitter>::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E) {
// Investigate compiling this to a loop.
const Expr *SubExpr = E->getSubExpr();
size_t Size = E->getArraySize().getZExtValue();
std::optional<PrimType> SubExprT = classify(SubExpr);
// So, every iteration, we execute an assignment here
// where the LHS is on the stack (the target array)
@ -2306,7 +2308,7 @@ bool Compiler<Emitter>::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E) {
ArrayIndexScope<Emitter> IndexScope(this, I);
BlockScope<Emitter> BS(this);
if (!this->visitArrayElemInit(I, SubExpr))
if (!this->visitArrayElemInit(I, SubExpr, SubExprT))
return false;
if (!BS.destroyLocals())
return false;

View File

@ -302,7 +302,8 @@ protected:
bool visitInitList(ArrayRef<const Expr *> Inits, const Expr *ArrayFiller,
const Expr *E);
bool visitArrayElemInit(unsigned ElemIndex, const Expr *Init);
bool visitArrayElemInit(unsigned ElemIndex, const Expr *Init,
std::optional<PrimType> InitT);
/// Creates a local primitive value.
unsigned allocateLocalPrimitive(DeclTy &&Decl, PrimType Ty, bool IsConst,