Skip to content

Commit b1f2e19

Browse files
committed
[clang][Interp][NFC] Use ArrayElem{,Pop} ops more often
Instead of the longer ArrayElemPtr + Load.
1 parent 101a13d commit b1f2e19

File tree

3 files changed

+42
-37
lines changed

3 files changed

+42
-37
lines changed

clang/lib/AST/Interp/ByteCodeExprGen.cpp

+20-37
Original file line numberDiff line numberDiff line change
@@ -314,11 +314,7 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
314314
for (unsigned I = 0; I != 2; ++I) {
315315
if (!this->emitGetLocal(PT_Ptr, *SubExprOffset, CE))
316316
return false;
317-
if (!this->emitConstUint8(I, CE))
318-
return false;
319-
if (!this->emitArrayElemPtrPopUint8(CE))
320-
return false;
321-
if (!this->emitLoadPop(SourceElemT, CE))
317+
if (!this->emitArrayElemPop(SourceElemT, I, CE))
322318
return false;
323319

324320
// Do the cast.
@@ -729,11 +725,8 @@ bool ByteCodeExprGen<Emitter>::VisitComplexBinOp(const BinaryOperator *E) {
729725
if (IsComplex) {
730726
if (!this->emitGetLocal(PT_Ptr, Offset, E))
731727
return false;
732-
if (!this->emitConstUint8(ElemIndex, E))
733-
return false;
734-
if (!this->emitArrayElemPtrPopUint8(E))
735-
return false;
736-
return this->emitLoadPop(classifyComplexElementType(E->getType()), E);
728+
return this->emitArrayElemPop(classifyComplexElementType(E->getType()),
729+
ElemIndex, E);
737730
}
738731
if (ElemIndex == 0)
739732
return this->emitGetLocal(classifyPrim(E->getType()), Offset, E);
@@ -3127,16 +3120,16 @@ bool ByteCodeExprGen<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
31273120

31283121
if (!this->visit(SubExpr))
31293122
return false;
3130-
if (!this->emitConstUint8(1, E))
3131-
return false;
3132-
if (!this->emitArrayElemPtrPopUint8(E))
3133-
return false;
3123+
3124+
if (SubExpr->isLValue()) {
3125+
if (!this->emitConstUint8(1, E))
3126+
return false;
3127+
return this->emitArrayElemPtrPopUint8(E);
3128+
}
31343129

31353130
// Since our _Complex implementation does not map to a primitive type,
31363131
// we sometimes have to do the lvalue-to-rvalue conversion here manually.
3137-
if (!SubExpr->isLValue())
3138-
return this->emitLoadPop(classifyPrim(E->getType()), E);
3139-
return true;
3132+
return this->emitArrayElemPop(classifyPrim(E->getType()), 1, E);
31403133
}
31413134
case UO_Extension:
31423135
return this->delegate(SubExpr);
@@ -3347,17 +3340,15 @@ bool ByteCodeExprGen<Emitter>::emitComplexReal(const Expr *SubExpr) {
33473340

33483341
if (!this->visit(SubExpr))
33493342
return false;
3350-
if (!this->emitConstUint8(0, SubExpr))
3351-
return false;
3352-
if (!this->emitArrayElemPtrPopUint8(SubExpr))
3353-
return false;
3343+
if (SubExpr->isLValue()) {
3344+
if (!this->emitConstUint8(0, SubExpr))
3345+
return false;
3346+
return this->emitArrayElemPtrPopUint8(SubExpr);
3347+
}
33543348

3355-
// Since our _Complex implementation does not map to a primitive type,
3356-
// we sometimes have to do the lvalue-to-rvalue conversion here manually.
3357-
if (!SubExpr->isLValue())
3358-
return this->emitLoadPop(classifyComplexElementType(SubExpr->getType()),
3359-
SubExpr);
3360-
return true;
3349+
// Rvalue, load the actual element.
3350+
return this->emitArrayElemPop(classifyComplexElementType(SubExpr->getType()),
3351+
0, SubExpr);
33613352
}
33623353

33633354
template <class Emitter>
@@ -3366,11 +3357,7 @@ bool ByteCodeExprGen<Emitter>::emitComplexBoolCast(const Expr *E) {
33663357
PrimType ElemT = classifyComplexElementType(E->getType());
33673358
// We emit the expression (__real(E) != 0 || __imag(E) != 0)
33683359
// for us, that means (bool)E[0] || (bool)E[1]
3369-
if (!this->emitConstUint8(0, E))
3370-
return false;
3371-
if (!this->emitArrayElemPtrUint8(E))
3372-
return false;
3373-
if (!this->emitLoadPop(ElemT, E))
3360+
if (!this->emitArrayElem(ElemT, 0, E))
33743361
return false;
33753362
if (ElemT == PT_Float) {
33763363
if (!this->emitCastFloatingIntegral(PT_Bool, E))
@@ -3385,11 +3372,7 @@ bool ByteCodeExprGen<Emitter>::emitComplexBoolCast(const Expr *E) {
33853372
if (!this->jumpTrue(LabelTrue))
33863373
return false;
33873374

3388-
if (!this->emitConstUint8(1, E))
3389-
return false;
3390-
if (!this->emitArrayElemPtrPopUint8(E))
3391-
return false;
3392-
if (!this->emitLoadPop(ElemT, E))
3375+
if (!this->emitArrayElemPop(ElemT, 1, E))
33933376
return false;
33943377
if (ElemT == PT_Float) {
33953378
if (!this->emitCastFloatingIntegral(PT_Bool, E))

clang/lib/AST/Interp/Interp.h

+14
Original file line numberDiff line numberDiff line change
@@ -1959,10 +1959,24 @@ inline bool ArrayElemPtrPop(InterpState &S, CodePtr OpPC) {
19591959
return NarrowPtr(S, OpPC);
19601960
}
19611961

1962+
template <PrimType Name, class T = typename PrimConv<Name>::T>
1963+
inline bool ArrayElem(InterpState &S, CodePtr OpPC, uint32_t Index) {
1964+
const Pointer &Ptr = S.Stk.peek<Pointer>();
1965+
1966+
if (!CheckLoad(S, OpPC, Ptr))
1967+
return false;
1968+
1969+
S.Stk.push<T>(Ptr.atIndex(Index).deref<T>());
1970+
return true;
1971+
}
1972+
19621973
template <PrimType Name, class T = typename PrimConv<Name>::T>
19631974
inline bool ArrayElemPop(InterpState &S, CodePtr OpPC, uint32_t Index) {
19641975
const Pointer &Ptr = S.Stk.pop<Pointer>();
19651976

1977+
if (!CheckLoad(S, OpPC, Ptr))
1978+
return false;
1979+
19661980
S.Stk.push<T>(Ptr.atIndex(Index).deref<T>());
19671981
return true;
19681982
}

clang/lib/AST/Interp/Opcodes.td

+8
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,14 @@ def ArrayElemPop : Opcode {
368368
let HasGroup = 1;
369369
}
370370

371+
def ArrayElem : Opcode {
372+
let Args = [ArgUint32];
373+
let Types = [AllTypeClass];
374+
let HasGroup = 1;
375+
}
376+
377+
378+
371379
//===----------------------------------------------------------------------===//
372380
// Direct field accessors
373381
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)