Skip to content

Commit c15b867

Browse files
committed
[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.
1 parent 240512c commit c15b867

File tree

3 files changed

+42
-63
lines changed

3 files changed

+42
-63
lines changed

clang/lib/AST/Interp/ByteCodeExprGen.cpp

Lines changed: 5 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,14 +1104,9 @@ bool ByteCodeExprGen<Emitter>::visitInitList(ArrayRef<const Expr *> Inits,
11041104
if (!this->visit(Init))
11051105
return false;
11061106

1107-
if (FieldToInit->isBitField()) {
1108-
if (!this->emitInitBitField(T, FieldToInit, E))
1109-
return false;
1110-
} else {
1111-
if (!this->emitInitField(T, FieldToInit->Offset, E))
1112-
return false;
1113-
}
1114-
return this->emitPopPtr(E);
1107+
if (FieldToInit->isBitField())
1108+
return this->emitInitBitField(T, FieldToInit, E);
1109+
return this->emitInitField(T, FieldToInit->Offset, E);
11151110
};
11161111

11171112
auto initCompositeField = [=](const Record::Field *FieldToInit,
@@ -1147,9 +1142,6 @@ bool ByteCodeExprGen<Emitter>::visitInitList(ArrayRef<const Expr *> Inits,
11471142
else
11481143
FToInit = cast<CXXParenListInitExpr>(E)->getInitializedFieldInUnion();
11491144

1150-
if (!this->emitDupPtr(E))
1151-
return false;
1152-
11531145
const Record::Field *FieldToInit = R->getField(FToInit);
11541146
if (std::optional<PrimType> T = classify(Init)) {
11551147
if (!initPrimitiveField(FieldToInit, Init, *T))
@@ -1169,8 +1161,6 @@ bool ByteCodeExprGen<Emitter>::visitInitList(ArrayRef<const Expr *> Inits,
11691161
while (InitIndex < R->getNumFields() &&
11701162
R->getField(InitIndex)->Decl->isUnnamedBitField())
11711163
++InitIndex;
1172-
if (!this->emitDupPtr(E))
1173-
return false;
11741164

11751165
if (std::optional<PrimType> T = classify(Init)) {
11761166
const Record::Field *FieldToInit = R->getField(InitIndex);
@@ -1180,7 +1170,7 @@ bool ByteCodeExprGen<Emitter>::visitInitList(ArrayRef<const Expr *> Inits,
11801170
} else {
11811171
// Initializer for a direct base class.
11821172
if (const Record::Base *B = R->getBase(Init->getType())) {
1183-
if (!this->emitGetPtrBasePop(B->Offset, Init))
1173+
if (!this->emitGetPtrBase(B->Offset, Init))
11841174
return false;
11851175

11861176
if (!this->visitInitializer(Init))
@@ -1513,7 +1503,7 @@ bool ByteCodeExprGen<Emitter>::VisitMemberExpr(const MemberExpr *E) {
15131503
// Leave a pointer to the field on the stack.
15141504
if (F->Decl->getType()->isReferenceType())
15151505
return this->emitGetFieldPop(PT_Ptr, F->Offset, E) && maybeLoadValue();
1516-
return this->emitGetPtrField(F->Offset, E) && maybeLoadValue();
1506+
return this->emitGetPtrFieldPop(F->Offset, E) && maybeLoadValue();
15171507
}
15181508

15191509
return false;
@@ -2147,9 +2137,6 @@ bool ByteCodeExprGen<Emitter>::VisitLambdaExpr(const LambdaExpr *E) {
21472137
if (!this->emitInitField(*T, F.Offset, E))
21482138
return false;
21492139
} else {
2150-
if (!this->emitDupPtr(E))
2151-
return false;
2152-
21532140
if (!this->emitGetPtrField(F.Offset, E))
21542141
return false;
21552142

@@ -2846,9 +2833,6 @@ bool ByteCodeExprGen<Emitter>::visitZeroRecordInitializer(const Record *R,
28462833
continue;
28472834
}
28482835

2849-
// TODO: Add GetPtrFieldPop and get rid of this dup.
2850-
if (!this->emitDupPtr(E))
2851-
return false;
28522836
if (!this->emitGetPtrField(Field.Offset, E))
28532837
return false;
28542838

@@ -3258,8 +3242,6 @@ bool ByteCodeExprGen<Emitter>::visitAPValueInitializer(const APValue &Val,
32583242
PrimType ElemT = classifyPrim(ArrType->getElementType());
32593243
assert(ArrType);
32603244

3261-
if (!this->emitDupPtr(E))
3262-
return false;
32633245
if (!this->emitGetPtrField(RF->Offset, E))
32643246
return false;
32653247

@@ -3273,8 +3255,6 @@ bool ByteCodeExprGen<Emitter>::visitAPValueInitializer(const APValue &Val,
32733255
if (!this->emitPopPtr(E))
32743256
return false;
32753257
} else if (F.isStruct() || F.isUnion()) {
3276-
if (!this->emitDupPtr(E))
3277-
return false;
32783258
if (!this->emitGetPtrField(RF->Offset, E))
32793259
return false;
32803260
if (!this->visitAPValueInitializer(F, E))
@@ -4201,8 +4181,6 @@ bool ByteCodeExprGen<Emitter>::emitRecordDestruction(const Record *R) {
42014181
for (const Record::Field &Field : llvm::reverse(R->fields())) {
42024182
const Descriptor *D = Field.Desc;
42034183
if (!D->isPrimitive() && !D->isPrimitiveArray()) {
4204-
if (!this->emitDupPtr(SourceInfo{}))
4205-
return false;
42064184
if (!this->emitGetPtrField(Field.Offset, SourceInfo{}))
42074185
return false;
42084186
if (!this->emitDestruction(D))

clang/lib/AST/Interp/Interp.h

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1283,9 +1283,32 @@ inline bool GetPtrGlobal(InterpState &S, CodePtr OpPC, uint32_t I) {
12831283
return true;
12841284
}
12851285

1286-
/// 1) Pops a Pointer from the stack
1286+
/// 1) Peeks a Pointer
12871287
/// 2) Pushes Pointer.atField(Off) on the stack
12881288
inline bool GetPtrField(InterpState &S, CodePtr OpPC, uint32_t Off) {
1289+
const Pointer &Ptr = S.Stk.peek<Pointer>();
1290+
1291+
if (S.getLangOpts().CPlusPlus && S.inConstantContext() &&
1292+
!CheckNull(S, OpPC, Ptr, CSK_Field))
1293+
return false;
1294+
1295+
if (!CheckExtern(S, OpPC, Ptr))
1296+
return false;
1297+
if (!CheckRange(S, OpPC, Ptr, CSK_Field))
1298+
return false;
1299+
if (!CheckArray(S, OpPC, Ptr))
1300+
return false;
1301+
if (!CheckSubobject(S, OpPC, Ptr, CSK_Field))
1302+
return false;
1303+
1304+
if (Ptr.isBlockPointer() && Off > Ptr.block()->getSize())
1305+
return false;
1306+
1307+
S.Stk.push<Pointer>(Ptr.atField(Off));
1308+
return true;
1309+
}
1310+
1311+
inline bool GetPtrFieldPop(InterpState &S, CodePtr OpPC, uint32_t Off) {
12891312
const Pointer &Ptr = S.Stk.pop<Pointer>();
12901313

12911314
if (S.getLangOpts().CPlusPlus && S.inConstantContext() &&

clang/lib/AST/Interp/Opcodes.td

Lines changed: 13 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -281,53 +281,31 @@ def Null : Opcode {
281281
//===----------------------------------------------------------------------===//
282282
// Pointer generation
283283
//===----------------------------------------------------------------------===//
284+
class OffsetOpcode : Opcode {
285+
let Args = [ArgUint32];
286+
}
284287

285288
// [] -> [Pointer]
286-
def GetPtrLocal : Opcode {
287-
// Offset of local.
288-
let Args = [ArgUint32];
289+
def GetPtrLocal : OffsetOpcode {
289290
bit HasCustomEval = 1;
290291
}
291292
// [] -> [Pointer]
292-
def GetPtrParam : Opcode {
293-
// Offset of parameter.
294-
let Args = [ArgUint32];
295-
}
293+
def GetPtrParam : OffsetOpcode;
296294
// [] -> [Pointer]
297-
def GetPtrGlobal : Opcode {
298-
// Index of global.
299-
let Args = [ArgUint32];
300-
}
295+
def GetPtrGlobal : OffsetOpcode;
301296
// [Pointer] -> [Pointer]
302-
def GetPtrField : Opcode {
303-
// Offset of field.
304-
let Args = [ArgUint32];
305-
}
297+
def GetPtrField : OffsetOpcode;
298+
def GetPtrFieldPop : OffsetOpcode;
306299
// [Pointer] -> [Pointer]
307-
def GetPtrActiveField : Opcode {
308-
// Offset of field.
309-
let Args = [ArgUint32];
310-
}
300+
def GetPtrActiveField : OffsetOpcode;
311301
// [] -> [Pointer]
312-
def GetPtrActiveThisField : Opcode {
313-
// Offset of field.
314-
let Args = [ArgUint32];
315-
}
302+
def GetPtrActiveThisField : OffsetOpcode;
316303
// [] -> [Pointer]
317-
def GetPtrThisField : Opcode {
318-
// Offset of field.
319-
let Args = [ArgUint32];
320-
}
304+
def GetPtrThisField : OffsetOpcode;
321305
// [Pointer] -> [Pointer]
322-
def GetPtrBase : Opcode {
323-
// Offset of field, which is a base.
324-
let Args = [ArgUint32];
325-
}
306+
def GetPtrBase : OffsetOpcode;
326307
// [Pointer] -> [Pointer]
327-
def GetPtrBasePop : Opcode {
328-
// Offset of field, which is a base.
329-
let Args = [ArgUint32];
330-
}
308+
def GetPtrBasePop : OffsetOpcode;
331309
def GetMemberPtrBasePop : Opcode {
332310
// Offset of field, which is a base.
333311
let Args = [ArgSint32];

0 commit comments

Comments
 (0)