mirror of
https://github.com/intel/llvm.git
synced 2026-01-16 05:32:28 +08:00
[clang][bytecode] Reintroduce Pointer::elem() (#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.
This commit is contained in:
@@ -254,7 +254,7 @@ bool Context::evaluateStrlen(State &Parent, const Expr *E, uint64_t &Result) {
|
||||
Result = 0;
|
||||
for (unsigned I = Ptr.getIndex(); I != N; ++I) {
|
||||
INT_TYPE_SWITCH(ElemT, {
|
||||
auto Elem = Ptr.atIndex(I).deref<T>();
|
||||
auto Elem = Ptr.elem<T>(I);
|
||||
if (Elem.isZero())
|
||||
return true;
|
||||
++Result;
|
||||
|
||||
@@ -204,7 +204,7 @@ static void collectBlocks(const Pointer &Ptr,
|
||||
|
||||
} else if (Desc->isPrimitiveArray() && Desc->getPrimType() == PT_Ptr) {
|
||||
for (unsigned I = 0; I != Desc->getNumElems(); ++I) {
|
||||
const Pointer &ElemPointee = Ptr.atIndex(I).deref<Pointer>();
|
||||
const Pointer &ElemPointee = Ptr.elem<Pointer>(I);
|
||||
if (isUsefulPtr(ElemPointee) && !Blocks.contains(ElemPointee.block()))
|
||||
collectBlocks(ElemPointee, Blocks);
|
||||
}
|
||||
|
||||
@@ -468,10 +468,10 @@ inline bool Mulc(InterpState &S, CodePtr OpPC) {
|
||||
const Pointer &Result = S.Stk.peek<Pointer>();
|
||||
|
||||
if constexpr (std::is_same_v<T, Floating>) {
|
||||
APFloat A = LHS.atIndex(0).deref<Floating>().getAPFloat();
|
||||
APFloat B = LHS.atIndex(1).deref<Floating>().getAPFloat();
|
||||
APFloat C = RHS.atIndex(0).deref<Floating>().getAPFloat();
|
||||
APFloat D = RHS.atIndex(1).deref<Floating>().getAPFloat();
|
||||
APFloat A = LHS.elem<Floating>(0).getAPFloat();
|
||||
APFloat B = LHS.elem<Floating>(1).getAPFloat();
|
||||
APFloat C = RHS.elem<Floating>(0).getAPFloat();
|
||||
APFloat D = RHS.elem<Floating>(1).getAPFloat();
|
||||
|
||||
APFloat ResR(A.getSemantics());
|
||||
APFloat ResI(A.getSemantics());
|
||||
@@ -480,20 +480,20 @@ inline bool Mulc(InterpState &S, CodePtr OpPC) {
|
||||
// Copy into the result.
|
||||
Floating RA = S.allocFloat(A.getSemantics());
|
||||
RA.copy(ResR);
|
||||
Result.atIndex(0).deref<Floating>() = RA; // Floating(ResR);
|
||||
Result.elem<Floating>(0) = RA; // Floating(ResR);
|
||||
Result.atIndex(0).initialize();
|
||||
|
||||
Floating RI = S.allocFloat(A.getSemantics());
|
||||
RI.copy(ResI);
|
||||
Result.atIndex(1).deref<Floating>() = RI; // Floating(ResI);
|
||||
Result.elem<Floating>(1) = RI; // Floating(ResI);
|
||||
Result.atIndex(1).initialize();
|
||||
Result.initialize();
|
||||
} else {
|
||||
// Integer element type.
|
||||
const T &LHSR = LHS.atIndex(0).deref<T>();
|
||||
const T &LHSI = LHS.atIndex(1).deref<T>();
|
||||
const T &RHSR = RHS.atIndex(0).deref<T>();
|
||||
const T &RHSI = RHS.atIndex(1).deref<T>();
|
||||
const T &LHSR = LHS.elem<T>(0);
|
||||
const T &LHSI = LHS.elem<T>(1);
|
||||
const T &RHSR = RHS.elem<T>(0);
|
||||
const T &RHSI = RHS.elem<T>(1);
|
||||
unsigned Bits = LHSR.bitWidth();
|
||||
|
||||
// real(Result) = (real(LHS) * real(RHS)) - (imag(LHS) * imag(RHS))
|
||||
@@ -503,7 +503,7 @@ inline bool Mulc(InterpState &S, CodePtr OpPC) {
|
||||
T B;
|
||||
if (T::mul(LHSI, RHSI, Bits, &B))
|
||||
return false;
|
||||
if (T::sub(A, B, Bits, &Result.atIndex(0).deref<T>()))
|
||||
if (T::sub(A, B, Bits, &Result.elem<T>(0)))
|
||||
return false;
|
||||
Result.atIndex(0).initialize();
|
||||
|
||||
@@ -512,7 +512,7 @@ inline bool Mulc(InterpState &S, CodePtr OpPC) {
|
||||
return false;
|
||||
if (T::mul(LHSI, RHSR, Bits, &B))
|
||||
return false;
|
||||
if (T::add(A, B, Bits, &Result.atIndex(1).deref<T>()))
|
||||
if (T::add(A, B, Bits, &Result.elem<T>(1)))
|
||||
return false;
|
||||
Result.atIndex(1).initialize();
|
||||
Result.initialize();
|
||||
@@ -528,10 +528,10 @@ inline bool Divc(InterpState &S, CodePtr OpPC) {
|
||||
const Pointer &Result = S.Stk.peek<Pointer>();
|
||||
|
||||
if constexpr (std::is_same_v<T, Floating>) {
|
||||
APFloat A = LHS.atIndex(0).deref<Floating>().getAPFloat();
|
||||
APFloat B = LHS.atIndex(1).deref<Floating>().getAPFloat();
|
||||
APFloat C = RHS.atIndex(0).deref<Floating>().getAPFloat();
|
||||
APFloat D = RHS.atIndex(1).deref<Floating>().getAPFloat();
|
||||
APFloat A = LHS.elem<Floating>(0).getAPFloat();
|
||||
APFloat B = LHS.elem<Floating>(1).getAPFloat();
|
||||
APFloat C = RHS.elem<Floating>(0).getAPFloat();
|
||||
APFloat D = RHS.elem<Floating>(1).getAPFloat();
|
||||
|
||||
APFloat ResR(A.getSemantics());
|
||||
APFloat ResI(A.getSemantics());
|
||||
@@ -540,21 +540,21 @@ inline bool Divc(InterpState &S, CodePtr OpPC) {
|
||||
// Copy into the result.
|
||||
Floating RA = S.allocFloat(A.getSemantics());
|
||||
RA.copy(ResR);
|
||||
Result.atIndex(0).deref<Floating>() = RA; // Floating(ResR);
|
||||
Result.elem<Floating>(0) = RA; // Floating(ResR);
|
||||
Result.atIndex(0).initialize();
|
||||
|
||||
Floating RI = S.allocFloat(A.getSemantics());
|
||||
RI.copy(ResI);
|
||||
Result.atIndex(1).deref<Floating>() = RI; // Floating(ResI);
|
||||
Result.elem<Floating>(1) = RI; // Floating(ResI);
|
||||
Result.atIndex(1).initialize();
|
||||
|
||||
Result.initialize();
|
||||
} else {
|
||||
// Integer element type.
|
||||
const T &LHSR = LHS.atIndex(0).deref<T>();
|
||||
const T &LHSI = LHS.atIndex(1).deref<T>();
|
||||
const T &RHSR = RHS.atIndex(0).deref<T>();
|
||||
const T &RHSI = RHS.atIndex(1).deref<T>();
|
||||
const T &LHSR = LHS.elem<T>(0);
|
||||
const T &LHSI = LHS.elem<T>(1);
|
||||
const T &RHSR = RHS.elem<T>(0);
|
||||
const T &RHSI = RHS.elem<T>(1);
|
||||
unsigned Bits = LHSR.bitWidth();
|
||||
const T Zero = T::from(0, Bits);
|
||||
|
||||
@@ -581,8 +581,8 @@ inline bool Divc(InterpState &S, CodePtr OpPC) {
|
||||
}
|
||||
|
||||
// real(Result) = ((real(LHS) * real(RHS)) + (imag(LHS) * imag(RHS))) / Den
|
||||
T &ResultR = Result.atIndex(0).deref<T>();
|
||||
T &ResultI = Result.atIndex(1).deref<T>();
|
||||
T &ResultR = Result.elem<T>(0);
|
||||
T &ResultI = Result.elem<T>(1);
|
||||
|
||||
if (T::mul(LHSR, RHSR, Bits, &A) || T::mul(LHSI, RHSI, Bits, &B))
|
||||
return false;
|
||||
@@ -3103,7 +3103,7 @@ inline bool ArrayElem(InterpState &S, CodePtr OpPC, uint32_t Index) {
|
||||
return false;
|
||||
|
||||
assert(Ptr.atIndex(Index).getFieldDesc()->getPrimType() == Name);
|
||||
S.Stk.push<T>(Ptr.atIndex(Index).deref<T>());
|
||||
S.Stk.push<T>(Ptr.elem<T>(Index));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3115,7 +3115,7 @@ inline bool ArrayElemPop(InterpState &S, CodePtr OpPC, uint32_t Index) {
|
||||
return false;
|
||||
|
||||
assert(Ptr.atIndex(Index).getFieldDesc()->getPrimType() == Name);
|
||||
S.Stk.push<T>(Ptr.atIndex(Index).deref<T>());
|
||||
S.Stk.push<T>(Ptr.elem<T>(Index));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1098,9 +1098,9 @@ static bool interp__builtin_complex(InterpState &S, CodePtr OpPC,
|
||||
const Floating &Arg1 = S.Stk.pop<Floating>();
|
||||
Pointer &Result = S.Stk.peek<Pointer>();
|
||||
|
||||
Result.atIndex(0).deref<Floating>() = Arg1;
|
||||
Result.elem<Floating>(0) = Arg1;
|
||||
Result.atIndex(0).initialize();
|
||||
Result.atIndex(1).deref<Floating>() = Arg2;
|
||||
Result.elem<Floating>(1) = Arg2;
|
||||
Result.atIndex(1).initialize();
|
||||
Result.initialize();
|
||||
|
||||
@@ -1644,10 +1644,10 @@ static bool interp__builtin_vector_reduce(InterpState &S, CodePtr OpPC,
|
||||
unsigned NumElems = Arg.getNumElems();
|
||||
|
||||
INT_TYPE_SWITCH_NO_BOOL(ElemT, {
|
||||
T Result = Arg.atIndex(0).deref<T>();
|
||||
T Result = Arg.elem<T>(0);
|
||||
unsigned BitWidth = Result.bitWidth();
|
||||
for (unsigned I = 1; I != NumElems; ++I) {
|
||||
T Elem = Arg.atIndex(I).deref<T>();
|
||||
T Elem = Arg.elem<T>(I);
|
||||
T PrevResult = Result;
|
||||
|
||||
if (ID == Builtin::BI__builtin_reduce_add) {
|
||||
@@ -1723,11 +1723,10 @@ static bool interp__builtin_elementwise_popcount(InterpState &S, CodePtr OpPC,
|
||||
for (unsigned I = 0; I != NumElems; ++I) {
|
||||
INT_TYPE_SWITCH_NO_BOOL(ElemT, {
|
||||
if (BuiltinID == Builtin::BI__builtin_elementwise_popcount) {
|
||||
Dst.atIndex(I).deref<T>() =
|
||||
T::from(Arg.atIndex(I).deref<T>().toAPSInt().popcount());
|
||||
Dst.elem<T>(I) = T::from(Arg.elem<T>(I).toAPSInt().popcount());
|
||||
} else {
|
||||
Dst.atIndex(I).deref<T>() = T::from(
|
||||
Arg.atIndex(I).deref<T>().toAPSInt().reverseBits().getZExtValue());
|
||||
Dst.elem<T>(I) =
|
||||
T::from(Arg.elem<T>(I).toAPSInt().reverseBits().getZExtValue());
|
||||
}
|
||||
Dst.atIndex(I).initialize();
|
||||
});
|
||||
@@ -2296,8 +2295,8 @@ static bool interp__builtin_elementwise_sat(InterpState &S, CodePtr OpPC,
|
||||
APSInt Elem1;
|
||||
APSInt Elem2;
|
||||
INT_TYPE_SWITCH_NO_BOOL(ElemT, {
|
||||
Elem1 = LHS.atIndex(I).deref<T>().toAPSInt();
|
||||
Elem2 = RHS.atIndex(I).deref<T>().toAPSInt();
|
||||
Elem1 = LHS.elem<T>(I).toAPSInt();
|
||||
Elem2 = RHS.elem<T>(I).toAPSInt();
|
||||
});
|
||||
|
||||
APSInt Result;
|
||||
@@ -2942,7 +2941,7 @@ static bool copyComposite(InterpState &S, CodePtr OpPC, const Pointer &Src,
|
||||
for (unsigned I = 0, N = DestDesc->getNumElems(); I != N; ++I) {
|
||||
Pointer DestElem = Dest.atIndex(I);
|
||||
TYPE_SWITCH(ET, {
|
||||
DestElem.deref<T>() = Src.atIndex(I).deref<T>();
|
||||
DestElem.deref<T>() = Src.elem<T>(I);
|
||||
DestElem.initialize();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -760,14 +760,14 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx,
|
||||
std::optional<PrimType> ElemT = Ctx.classify(ElemTy);
|
||||
assert(ElemT);
|
||||
INT_TYPE_SWITCH(*ElemT, {
|
||||
auto V1 = Ptr.atIndex(0).deref<T>();
|
||||
auto V2 = Ptr.atIndex(1).deref<T>();
|
||||
auto V1 = Ptr.elem<T>(0);
|
||||
auto V2 = Ptr.elem<T>(1);
|
||||
R = APValue(V1.toAPSInt(), V2.toAPSInt());
|
||||
return true;
|
||||
});
|
||||
} else if (ElemTy->isFloatingType()) {
|
||||
R = APValue(Ptr.atIndex(0).deref<Floating>().getAPFloat(),
|
||||
Ptr.atIndex(1).deref<Floating>().getAPFloat());
|
||||
R = APValue(Ptr.elem<Floating>(0).getAPFloat(),
|
||||
Ptr.elem<Floating>(1).getAPFloat());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -782,9 +782,8 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx,
|
||||
SmallVector<APValue> Values;
|
||||
Values.reserve(VT->getNumElements());
|
||||
for (unsigned I = 0; I != VT->getNumElements(); ++I) {
|
||||
TYPE_SWITCH(ElemT, {
|
||||
Values.push_back(Ptr.atIndex(I).deref<T>().toAPValue(ASTCtx));
|
||||
});
|
||||
TYPE_SWITCH(ElemT,
|
||||
{ Values.push_back(Ptr.elem<T>(I).toAPValue(ASTCtx)); });
|
||||
}
|
||||
|
||||
assert(Values.size() == VT->getNumElements());
|
||||
|
||||
@@ -693,6 +693,25 @@ public:
|
||||
return *reinterpret_cast<T *>(asBlockPointer().Pointee->rawData() + Offset);
|
||||
}
|
||||
|
||||
/// Dereferences the element at index \p I.
|
||||
/// This is equivalent to atIndex(I).deref<T>().
|
||||
template <typename T> T &elem(unsigned I) const {
|
||||
assert(isLive() && "Invalid pointer");
|
||||
assert(isBlockPointer());
|
||||
assert(asBlockPointer().Pointee);
|
||||
assert(isDereferencable());
|
||||
assert(getFieldDesc()->isPrimitiveArray());
|
||||
|
||||
unsigned ElemByteOffset = I * getFieldDesc()->getElemSize();
|
||||
if (isArrayRoot())
|
||||
return *reinterpret_cast<T *>(asBlockPointer().Pointee->rawData() +
|
||||
asBlockPointer().Base + sizeof(InitMapPtr) +
|
||||
ElemByteOffset);
|
||||
|
||||
return *reinterpret_cast<T *>(asBlockPointer().Pointee->rawData() + Offset +
|
||||
ElemByteOffset);
|
||||
}
|
||||
|
||||
/// Whether this block can be read from at all. This is only true for
|
||||
/// block pointers that point to a valid location inside that block.
|
||||
bool isDereferencable() const {
|
||||
|
||||
@@ -74,27 +74,25 @@ unsigned Program::createGlobalString(const StringLiteral *S, const Expr *Base) {
|
||||
|
||||
const Pointer Ptr(G->block());
|
||||
if (CharWidth == 1) {
|
||||
std::memcpy(&Ptr.atIndex(0).deref<char>(), S->getString().data(),
|
||||
StringLength);
|
||||
std::memcpy(&Ptr.elem<char>(0), S->getString().data(), StringLength);
|
||||
} else {
|
||||
// Construct the string in storage.
|
||||
for (unsigned I = 0; I <= StringLength; ++I) {
|
||||
Pointer Field = Ptr.atIndex(I);
|
||||
const uint32_t CodePoint = I == StringLength ? 0 : S->getCodeUnit(I);
|
||||
switch (CharType) {
|
||||
case PT_Sint8: {
|
||||
using T = PrimConv<PT_Sint8>::T;
|
||||
Field.deref<T>() = T::from(CodePoint, BitWidth);
|
||||
Ptr.elem<T>(I) = T::from(CodePoint, BitWidth);
|
||||
break;
|
||||
}
|
||||
case PT_Uint16: {
|
||||
using T = PrimConv<PT_Uint16>::T;
|
||||
Field.deref<T>() = T::from(CodePoint, BitWidth);
|
||||
Ptr.elem<T>(I) = T::from(CodePoint, BitWidth);
|
||||
break;
|
||||
}
|
||||
case PT_Uint32: {
|
||||
using T = PrimConv<PT_Uint32>::T;
|
||||
Field.deref<T>() = T::from(CodePoint, BitWidth);
|
||||
Ptr.elem<T>(I) = T::from(CodePoint, BitWidth);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user