Author: Timm Bäder Date: 2024-06-07T09:40:26+02:00 New Revision: c15b86731b78de88fadbc16ea1c2df2f60c991e9
URL: https://github.com/llvm/llvm-project/commit/c15b86731b78de88fadbc16ea1c2df2f60c991e9 DIFF: https://github.com/llvm/llvm-project/commit/c15b86731b78de88fadbc16ea1c2df2f60c991e9.diff LOG: [clang][Interp][NFC] Add GetPtrFieldPop opcode And change the previous GetPtrField to only peek() the base pointer. We can get rid of a whole bunch of DupPtr ops this way. Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/lib/AST/Interp/Interp.h clang/lib/AST/Interp/Opcodes.td Removed: ################################################################################ diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 9073175263645..1d0c36d0bf09f 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -1104,14 +1104,9 @@ bool ByteCodeExprGen<Emitter>::visitInitList(ArrayRef<const Expr *> Inits, if (!this->visit(Init)) return false; - if (FieldToInit->isBitField()) { - if (!this->emitInitBitField(T, FieldToInit, E)) - return false; - } else { - if (!this->emitInitField(T, FieldToInit->Offset, E)) - return false; - } - return this->emitPopPtr(E); + if (FieldToInit->isBitField()) + return this->emitInitBitField(T, FieldToInit, E); + return this->emitInitField(T, FieldToInit->Offset, E); }; auto initCompositeField = [=](const Record::Field *FieldToInit, @@ -1147,9 +1142,6 @@ bool ByteCodeExprGen<Emitter>::visitInitList(ArrayRef<const Expr *> Inits, else FToInit = cast<CXXParenListInitExpr>(E)->getInitializedFieldInUnion(); - if (!this->emitDupPtr(E)) - return false; - const Record::Field *FieldToInit = R->getField(FToInit); if (std::optional<PrimType> T = classify(Init)) { if (!initPrimitiveField(FieldToInit, Init, *T)) @@ -1169,8 +1161,6 @@ bool ByteCodeExprGen<Emitter>::visitInitList(ArrayRef<const Expr *> Inits, while (InitIndex < R->getNumFields() && R->getField(InitIndex)->Decl->isUnnamedBitField()) ++InitIndex; - if (!this->emitDupPtr(E)) - return false; if (std::optional<PrimType> T = classify(Init)) { const Record::Field *FieldToInit = R->getField(InitIndex); @@ -1180,7 +1170,7 @@ bool ByteCodeExprGen<Emitter>::visitInitList(ArrayRef<const Expr *> Inits, } else { // Initializer for a direct base class. if (const Record::Base *B = R->getBase(Init->getType())) { - if (!this->emitGetPtrBasePop(B->Offset, Init)) + if (!this->emitGetPtrBase(B->Offset, Init)) return false; if (!this->visitInitializer(Init)) @@ -1513,7 +1503,7 @@ bool ByteCodeExprGen<Emitter>::VisitMemberExpr(const MemberExpr *E) { // Leave a pointer to the field on the stack. if (F->Decl->getType()->isReferenceType()) return this->emitGetFieldPop(PT_Ptr, F->Offset, E) && maybeLoadValue(); - return this->emitGetPtrField(F->Offset, E) && maybeLoadValue(); + return this->emitGetPtrFieldPop(F->Offset, E) && maybeLoadValue(); } return false; @@ -2147,9 +2137,6 @@ bool ByteCodeExprGen<Emitter>::VisitLambdaExpr(const LambdaExpr *E) { if (!this->emitInitField(*T, F.Offset, E)) return false; } else { - if (!this->emitDupPtr(E)) - return false; - if (!this->emitGetPtrField(F.Offset, E)) return false; @@ -2846,9 +2833,6 @@ bool ByteCodeExprGen<Emitter>::visitZeroRecordInitializer(const Record *R, continue; } - // TODO: Add GetPtrFieldPop and get rid of this dup. - if (!this->emitDupPtr(E)) - return false; if (!this->emitGetPtrField(Field.Offset, E)) return false; @@ -3258,8 +3242,6 @@ bool ByteCodeExprGen<Emitter>::visitAPValueInitializer(const APValue &Val, PrimType ElemT = classifyPrim(ArrType->getElementType()); assert(ArrType); - if (!this->emitDupPtr(E)) - return false; if (!this->emitGetPtrField(RF->Offset, E)) return false; @@ -3273,8 +3255,6 @@ bool ByteCodeExprGen<Emitter>::visitAPValueInitializer(const APValue &Val, if (!this->emitPopPtr(E)) return false; } else if (F.isStruct() || F.isUnion()) { - if (!this->emitDupPtr(E)) - return false; if (!this->emitGetPtrField(RF->Offset, E)) return false; if (!this->visitAPValueInitializer(F, E)) @@ -4201,8 +4181,6 @@ bool ByteCodeExprGen<Emitter>::emitRecordDestruction(const Record *R) { for (const Record::Field &Field : llvm::reverse(R->fields())) { const Descriptor *D = Field.Desc; if (!D->isPrimitive() && !D->isPrimitiveArray()) { - if (!this->emitDupPtr(SourceInfo{})) - return false; if (!this->emitGetPtrField(Field.Offset, SourceInfo{})) return false; if (!this->emitDestruction(D)) diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index 98caea5c70147..f63711da90c7e 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -1283,9 +1283,32 @@ inline bool GetPtrGlobal(InterpState &S, CodePtr OpPC, uint32_t I) { return true; } -/// 1) Pops a Pointer from the stack +/// 1) Peeks a Pointer /// 2) Pushes Pointer.atField(Off) on the stack inline bool GetPtrField(InterpState &S, CodePtr OpPC, uint32_t Off) { + const Pointer &Ptr = S.Stk.peek<Pointer>(); + + if (S.getLangOpts().CPlusPlus && S.inConstantContext() && + !CheckNull(S, OpPC, Ptr, CSK_Field)) + return false; + + if (!CheckExtern(S, OpPC, Ptr)) + return false; + if (!CheckRange(S, OpPC, Ptr, CSK_Field)) + return false; + if (!CheckArray(S, OpPC, Ptr)) + return false; + if (!CheckSubobject(S, OpPC, Ptr, CSK_Field)) + return false; + + if (Ptr.isBlockPointer() && Off > Ptr.block()->getSize()) + return false; + + S.Stk.push<Pointer>(Ptr.atField(Off)); + return true; +} + +inline bool GetPtrFieldPop(InterpState &S, CodePtr OpPC, uint32_t Off) { const Pointer &Ptr = S.Stk.pop<Pointer>(); if (S.getLangOpts().CPlusPlus && S.inConstantContext() && diff --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td index cb4f299c8d515..a5ac8206104c8 100644 --- a/clang/lib/AST/Interp/Opcodes.td +++ b/clang/lib/AST/Interp/Opcodes.td @@ -281,53 +281,31 @@ def Null : Opcode { //===----------------------------------------------------------------------===// // Pointer generation //===----------------------------------------------------------------------===// +class OffsetOpcode : Opcode { + let Args = [ArgUint32]; +} // [] -> [Pointer] -def GetPtrLocal : Opcode { - // Offset of local. - let Args = [ArgUint32]; +def GetPtrLocal : OffsetOpcode { bit HasCustomEval = 1; } // [] -> [Pointer] -def GetPtrParam : Opcode { - // Offset of parameter. - let Args = [ArgUint32]; -} +def GetPtrParam : OffsetOpcode; // [] -> [Pointer] -def GetPtrGlobal : Opcode { - // Index of global. - let Args = [ArgUint32]; -} +def GetPtrGlobal : OffsetOpcode; // [Pointer] -> [Pointer] -def GetPtrField : Opcode { - // Offset of field. - let Args = [ArgUint32]; -} +def GetPtrField : OffsetOpcode; +def GetPtrFieldPop : OffsetOpcode; // [Pointer] -> [Pointer] -def GetPtrActiveField : Opcode { - // Offset of field. - let Args = [ArgUint32]; -} +def GetPtrActiveField : OffsetOpcode; // [] -> [Pointer] -def GetPtrActiveThisField : Opcode { - // Offset of field. - let Args = [ArgUint32]; -} +def GetPtrActiveThisField : OffsetOpcode; // [] -> [Pointer] -def GetPtrThisField : Opcode { - // Offset of field. - let Args = [ArgUint32]; -} +def GetPtrThisField : OffsetOpcode; // [Pointer] -> [Pointer] -def GetPtrBase : Opcode { - // Offset of field, which is a base. - let Args = [ArgUint32]; -} +def GetPtrBase : OffsetOpcode; // [Pointer] -> [Pointer] -def GetPtrBasePop : Opcode { - // Offset of field, which is a base. - let Args = [ArgUint32]; -} +def GetPtrBasePop : OffsetOpcode; def GetMemberPtrBasePop : Opcode { // Offset of field, which is a base. let Args = [ArgSint32]; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits