Skip to content

Commit d14829d

Browse files
tbaederrmahesh-attarde
authored andcommitted
[clang][bytecode] Reintroduce Pointer::elem() (llvm#149693)
As a way of writing atIndex(I).deref<T>(), which creates an intermediate Pointer, which in turn adds (and removes) that pointer from the pointer list of the Block. This way we can avoid that.
1 parent 6ec71fe commit d14829d

File tree

7 files changed

+67
-52
lines changed

7 files changed

+67
-52
lines changed

clang/lib/AST/ByteCode/Context.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ bool Context::evaluateStrlen(State &Parent, const Expr *E, uint64_t &Result) {
254254
Result = 0;
255255
for (unsigned I = Ptr.getIndex(); I != N; ++I) {
256256
INT_TYPE_SWITCH(ElemT, {
257-
auto Elem = Ptr.atIndex(I).deref<T>();
257+
auto Elem = Ptr.elem<T>(I);
258258
if (Elem.isZero())
259259
return true;
260260
++Result;

clang/lib/AST/ByteCode/EvaluationResult.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ static void collectBlocks(const Pointer &Ptr,
204204

205205
} else if (Desc->isPrimitiveArray() && Desc->getPrimType() == PT_Ptr) {
206206
for (unsigned I = 0; I != Desc->getNumElems(); ++I) {
207-
const Pointer &ElemPointee = Ptr.atIndex(I).deref<Pointer>();
207+
const Pointer &ElemPointee = Ptr.elem<Pointer>(I);
208208
if (isUsefulPtr(ElemPointee) && !Blocks.contains(ElemPointee.block()))
209209
collectBlocks(ElemPointee, Blocks);
210210
}

clang/lib/AST/ByteCode/Interp.h

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -468,10 +468,10 @@ inline bool Mulc(InterpState &S, CodePtr OpPC) {
468468
const Pointer &Result = S.Stk.peek<Pointer>();
469469

470470
if constexpr (std::is_same_v<T, Floating>) {
471-
APFloat A = LHS.atIndex(0).deref<Floating>().getAPFloat();
472-
APFloat B = LHS.atIndex(1).deref<Floating>().getAPFloat();
473-
APFloat C = RHS.atIndex(0).deref<Floating>().getAPFloat();
474-
APFloat D = RHS.atIndex(1).deref<Floating>().getAPFloat();
471+
APFloat A = LHS.elem<Floating>(0).getAPFloat();
472+
APFloat B = LHS.elem<Floating>(1).getAPFloat();
473+
APFloat C = RHS.elem<Floating>(0).getAPFloat();
474+
APFloat D = RHS.elem<Floating>(1).getAPFloat();
475475

476476
APFloat ResR(A.getSemantics());
477477
APFloat ResI(A.getSemantics());
@@ -480,20 +480,20 @@ inline bool Mulc(InterpState &S, CodePtr OpPC) {
480480
// Copy into the result.
481481
Floating RA = S.allocFloat(A.getSemantics());
482482
RA.copy(ResR);
483-
Result.atIndex(0).deref<Floating>() = RA; // Floating(ResR);
483+
Result.elem<Floating>(0) = RA; // Floating(ResR);
484484
Result.atIndex(0).initialize();
485485

486486
Floating RI = S.allocFloat(A.getSemantics());
487487
RI.copy(ResI);
488-
Result.atIndex(1).deref<Floating>() = RI; // Floating(ResI);
488+
Result.elem<Floating>(1) = RI; // Floating(ResI);
489489
Result.atIndex(1).initialize();
490490
Result.initialize();
491491
} else {
492492
// Integer element type.
493-
const T &LHSR = LHS.atIndex(0).deref<T>();
494-
const T &LHSI = LHS.atIndex(1).deref<T>();
495-
const T &RHSR = RHS.atIndex(0).deref<T>();
496-
const T &RHSI = RHS.atIndex(1).deref<T>();
493+
const T &LHSR = LHS.elem<T>(0);
494+
const T &LHSI = LHS.elem<T>(1);
495+
const T &RHSR = RHS.elem<T>(0);
496+
const T &RHSI = RHS.elem<T>(1);
497497
unsigned Bits = LHSR.bitWidth();
498498

499499
// real(Result) = (real(LHS) * real(RHS)) - (imag(LHS) * imag(RHS))
@@ -503,7 +503,7 @@ inline bool Mulc(InterpState &S, CodePtr OpPC) {
503503
T B;
504504
if (T::mul(LHSI, RHSI, Bits, &B))
505505
return false;
506-
if (T::sub(A, B, Bits, &Result.atIndex(0).deref<T>()))
506+
if (T::sub(A, B, Bits, &Result.elem<T>(0)))
507507
return false;
508508
Result.atIndex(0).initialize();
509509

@@ -512,7 +512,7 @@ inline bool Mulc(InterpState &S, CodePtr OpPC) {
512512
return false;
513513
if (T::mul(LHSI, RHSR, Bits, &B))
514514
return false;
515-
if (T::add(A, B, Bits, &Result.atIndex(1).deref<T>()))
515+
if (T::add(A, B, Bits, &Result.elem<T>(1)))
516516
return false;
517517
Result.atIndex(1).initialize();
518518
Result.initialize();
@@ -528,10 +528,10 @@ inline bool Divc(InterpState &S, CodePtr OpPC) {
528528
const Pointer &Result = S.Stk.peek<Pointer>();
529529

530530
if constexpr (std::is_same_v<T, Floating>) {
531-
APFloat A = LHS.atIndex(0).deref<Floating>().getAPFloat();
532-
APFloat B = LHS.atIndex(1).deref<Floating>().getAPFloat();
533-
APFloat C = RHS.atIndex(0).deref<Floating>().getAPFloat();
534-
APFloat D = RHS.atIndex(1).deref<Floating>().getAPFloat();
531+
APFloat A = LHS.elem<Floating>(0).getAPFloat();
532+
APFloat B = LHS.elem<Floating>(1).getAPFloat();
533+
APFloat C = RHS.elem<Floating>(0).getAPFloat();
534+
APFloat D = RHS.elem<Floating>(1).getAPFloat();
535535

536536
APFloat ResR(A.getSemantics());
537537
APFloat ResI(A.getSemantics());
@@ -540,21 +540,21 @@ inline bool Divc(InterpState &S, CodePtr OpPC) {
540540
// Copy into the result.
541541
Floating RA = S.allocFloat(A.getSemantics());
542542
RA.copy(ResR);
543-
Result.atIndex(0).deref<Floating>() = RA; // Floating(ResR);
543+
Result.elem<Floating>(0) = RA; // Floating(ResR);
544544
Result.atIndex(0).initialize();
545545

546546
Floating RI = S.allocFloat(A.getSemantics());
547547
RI.copy(ResI);
548-
Result.atIndex(1).deref<Floating>() = RI; // Floating(ResI);
548+
Result.elem<Floating>(1) = RI; // Floating(ResI);
549549
Result.atIndex(1).initialize();
550550

551551
Result.initialize();
552552
} else {
553553
// Integer element type.
554-
const T &LHSR = LHS.atIndex(0).deref<T>();
555-
const T &LHSI = LHS.atIndex(1).deref<T>();
556-
const T &RHSR = RHS.atIndex(0).deref<T>();
557-
const T &RHSI = RHS.atIndex(1).deref<T>();
554+
const T &LHSR = LHS.elem<T>(0);
555+
const T &LHSI = LHS.elem<T>(1);
556+
const T &RHSR = RHS.elem<T>(0);
557+
const T &RHSI = RHS.elem<T>(1);
558558
unsigned Bits = LHSR.bitWidth();
559559
const T Zero = T::from(0, Bits);
560560

@@ -581,8 +581,8 @@ inline bool Divc(InterpState &S, CodePtr OpPC) {
581581
}
582582

583583
// real(Result) = ((real(LHS) * real(RHS)) + (imag(LHS) * imag(RHS))) / Den
584-
T &ResultR = Result.atIndex(0).deref<T>();
585-
T &ResultI = Result.atIndex(1).deref<T>();
584+
T &ResultR = Result.elem<T>(0);
585+
T &ResultI = Result.elem<T>(1);
586586

587587
if (T::mul(LHSR, RHSR, Bits, &A) || T::mul(LHSI, RHSI, Bits, &B))
588588
return false;
@@ -3103,7 +3103,7 @@ inline bool ArrayElem(InterpState &S, CodePtr OpPC, uint32_t Index) {
31033103
return false;
31043104

31053105
assert(Ptr.atIndex(Index).getFieldDesc()->getPrimType() == Name);
3106-
S.Stk.push<T>(Ptr.atIndex(Index).deref<T>());
3106+
S.Stk.push<T>(Ptr.elem<T>(Index));
31073107
return true;
31083108
}
31093109

@@ -3115,7 +3115,7 @@ inline bool ArrayElemPop(InterpState &S, CodePtr OpPC, uint32_t Index) {
31153115
return false;
31163116

31173117
assert(Ptr.atIndex(Index).getFieldDesc()->getPrimType() == Name);
3118-
S.Stk.push<T>(Ptr.atIndex(Index).deref<T>());
3118+
S.Stk.push<T>(Ptr.elem<T>(Index));
31193119
return true;
31203120
}
31213121

clang/lib/AST/ByteCode/InterpBuiltin.cpp

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,9 +1098,9 @@ static bool interp__builtin_complex(InterpState &S, CodePtr OpPC,
10981098
const Floating &Arg1 = S.Stk.pop<Floating>();
10991099
Pointer &Result = S.Stk.peek<Pointer>();
11001100

1101-
Result.atIndex(0).deref<Floating>() = Arg1;
1101+
Result.elem<Floating>(0) = Arg1;
11021102
Result.atIndex(0).initialize();
1103-
Result.atIndex(1).deref<Floating>() = Arg2;
1103+
Result.elem<Floating>(1) = Arg2;
11041104
Result.atIndex(1).initialize();
11051105
Result.initialize();
11061106

@@ -1644,10 +1644,10 @@ static bool interp__builtin_vector_reduce(InterpState &S, CodePtr OpPC,
16441644
unsigned NumElems = Arg.getNumElems();
16451645

16461646
INT_TYPE_SWITCH_NO_BOOL(ElemT, {
1647-
T Result = Arg.atIndex(0).deref<T>();
1647+
T Result = Arg.elem<T>(0);
16481648
unsigned BitWidth = Result.bitWidth();
16491649
for (unsigned I = 1; I != NumElems; ++I) {
1650-
T Elem = Arg.atIndex(I).deref<T>();
1650+
T Elem = Arg.elem<T>(I);
16511651
T PrevResult = Result;
16521652

16531653
if (ID == Builtin::BI__builtin_reduce_add) {
@@ -1723,11 +1723,10 @@ static bool interp__builtin_elementwise_popcount(InterpState &S, CodePtr OpPC,
17231723
for (unsigned I = 0; I != NumElems; ++I) {
17241724
INT_TYPE_SWITCH_NO_BOOL(ElemT, {
17251725
if (BuiltinID == Builtin::BI__builtin_elementwise_popcount) {
1726-
Dst.atIndex(I).deref<T>() =
1727-
T::from(Arg.atIndex(I).deref<T>().toAPSInt().popcount());
1726+
Dst.elem<T>(I) = T::from(Arg.elem<T>(I).toAPSInt().popcount());
17281727
} else {
1729-
Dst.atIndex(I).deref<T>() = T::from(
1730-
Arg.atIndex(I).deref<T>().toAPSInt().reverseBits().getZExtValue());
1728+
Dst.elem<T>(I) =
1729+
T::from(Arg.elem<T>(I).toAPSInt().reverseBits().getZExtValue());
17311730
}
17321731
Dst.atIndex(I).initialize();
17331732
});
@@ -2296,8 +2295,8 @@ static bool interp__builtin_elementwise_sat(InterpState &S, CodePtr OpPC,
22962295
APSInt Elem1;
22972296
APSInt Elem2;
22982297
INT_TYPE_SWITCH_NO_BOOL(ElemT, {
2299-
Elem1 = LHS.atIndex(I).deref<T>().toAPSInt();
2300-
Elem2 = RHS.atIndex(I).deref<T>().toAPSInt();
2298+
Elem1 = LHS.elem<T>(I).toAPSInt();
2299+
Elem2 = RHS.elem<T>(I).toAPSInt();
23012300
});
23022301

23032302
APSInt Result;
@@ -2942,7 +2941,7 @@ static bool copyComposite(InterpState &S, CodePtr OpPC, const Pointer &Src,
29422941
for (unsigned I = 0, N = DestDesc->getNumElems(); I != N; ++I) {
29432942
Pointer DestElem = Dest.atIndex(I);
29442943
TYPE_SWITCH(ET, {
2945-
DestElem.deref<T>() = Src.atIndex(I).deref<T>();
2944+
DestElem.deref<T>() = Src.elem<T>(I);
29462945
DestElem.initialize();
29472946
});
29482947
}

clang/lib/AST/ByteCode/Pointer.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -760,14 +760,14 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx,
760760
std::optional<PrimType> ElemT = Ctx.classify(ElemTy);
761761
assert(ElemT);
762762
INT_TYPE_SWITCH(*ElemT, {
763-
auto V1 = Ptr.atIndex(0).deref<T>();
764-
auto V2 = Ptr.atIndex(1).deref<T>();
763+
auto V1 = Ptr.elem<T>(0);
764+
auto V2 = Ptr.elem<T>(1);
765765
R = APValue(V1.toAPSInt(), V2.toAPSInt());
766766
return true;
767767
});
768768
} else if (ElemTy->isFloatingType()) {
769-
R = APValue(Ptr.atIndex(0).deref<Floating>().getAPFloat(),
770-
Ptr.atIndex(1).deref<Floating>().getAPFloat());
769+
R = APValue(Ptr.elem<Floating>(0).getAPFloat(),
770+
Ptr.elem<Floating>(1).getAPFloat());
771771
return true;
772772
}
773773
return false;
@@ -782,9 +782,8 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx,
782782
SmallVector<APValue> Values;
783783
Values.reserve(VT->getNumElements());
784784
for (unsigned I = 0; I != VT->getNumElements(); ++I) {
785-
TYPE_SWITCH(ElemT, {
786-
Values.push_back(Ptr.atIndex(I).deref<T>().toAPValue(ASTCtx));
787-
});
785+
TYPE_SWITCH(ElemT,
786+
{ Values.push_back(Ptr.elem<T>(I).toAPValue(ASTCtx)); });
788787
}
789788

790789
assert(Values.size() == VT->getNumElements());

clang/lib/AST/ByteCode/Pointer.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,25 @@ class Pointer {
693693
return *reinterpret_cast<T *>(asBlockPointer().Pointee->rawData() + Offset);
694694
}
695695

696+
/// Dereferences the element at index \p I.
697+
/// This is equivalent to atIndex(I).deref<T>().
698+
template <typename T> T &elem(unsigned I) const {
699+
assert(isLive() && "Invalid pointer");
700+
assert(isBlockPointer());
701+
assert(asBlockPointer().Pointee);
702+
assert(isDereferencable());
703+
assert(getFieldDesc()->isPrimitiveArray());
704+
705+
unsigned ElemByteOffset = I * getFieldDesc()->getElemSize();
706+
if (isArrayRoot())
707+
return *reinterpret_cast<T *>(asBlockPointer().Pointee->rawData() +
708+
asBlockPointer().Base + sizeof(InitMapPtr) +
709+
ElemByteOffset);
710+
711+
return *reinterpret_cast<T *>(asBlockPointer().Pointee->rawData() + Offset +
712+
ElemByteOffset);
713+
}
714+
696715
/// Whether this block can be read from at all. This is only true for
697716
/// block pointers that point to a valid location inside that block.
698717
bool isDereferencable() const {

clang/lib/AST/ByteCode/Program.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,27 +74,25 @@ unsigned Program::createGlobalString(const StringLiteral *S, const Expr *Base) {
7474

7575
const Pointer Ptr(G->block());
7676
if (CharWidth == 1) {
77-
std::memcpy(&Ptr.atIndex(0).deref<char>(), S->getString().data(),
78-
StringLength);
77+
std::memcpy(&Ptr.elem<char>(0), S->getString().data(), StringLength);
7978
} else {
8079
// Construct the string in storage.
8180
for (unsigned I = 0; I <= StringLength; ++I) {
82-
Pointer Field = Ptr.atIndex(I);
8381
const uint32_t CodePoint = I == StringLength ? 0 : S->getCodeUnit(I);
8482
switch (CharType) {
8583
case PT_Sint8: {
8684
using T = PrimConv<PT_Sint8>::T;
87-
Field.deref<T>() = T::from(CodePoint, BitWidth);
85+
Ptr.elem<T>(I) = T::from(CodePoint, BitWidth);
8886
break;
8987
}
9088
case PT_Uint16: {
9189
using T = PrimConv<PT_Uint16>::T;
92-
Field.deref<T>() = T::from(CodePoint, BitWidth);
90+
Ptr.elem<T>(I) = T::from(CodePoint, BitWidth);
9391
break;
9492
}
9593
case PT_Uint32: {
9694
using T = PrimConv<PT_Uint32>::T;
97-
Field.deref<T>() = T::from(CodePoint, BitWidth);
95+
Ptr.elem<T>(I) = T::from(CodePoint, BitWidth);
9896
break;
9997
}
10098
default:

0 commit comments

Comments
 (0)