[clang] c15b867 - [clang][Interp][NFC] Add GetPtrFieldPop opcode
Timm Bäder via cfe-commits
cfe-commits at lists.llvm.org
Fri Jun 7 00:40:35 PDT 2024
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];
More information about the cfe-commits
mailing list