diff options
author | Timm Baeder <tbaeder@redhat.com> | 2025-06-18 14:37:29 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-06-18 14:37:29 +0200 |
commit | 7c15edb306932e41c159f3d69c161ed0d89d47b7 (patch) | |
tree | b1b581d5c5e160486bb7786fde214343ceffd396 /clang/lib/AST/ByteCode/Interp.cpp | |
parent | 34a48941498d95ec2682f7adaeb6115b7b4d70ba (diff) | |
download | llvm-7c15edb306932e41c159f3d69c161ed0d89d47b7.zip llvm-7c15edb306932e41c159f3d69c161ed0d89d47b7.tar.gz llvm-7c15edb306932e41c159f3d69c161ed0d89d47b7.tar.bz2 |
Reapply "[clang][bytecode] Allocate IntegralAP and Floating types usi… (#144676)
…ng an allocator (#144246)"
This reverts commit 57828fec760f086b334ce0cb1c465fc559dcaea4.
Diffstat (limited to 'clang/lib/AST/ByteCode/Interp.cpp')
-rw-r--r-- | clang/lib/AST/ByteCode/Interp.cpp | 106 |
1 files changed, 102 insertions, 4 deletions
diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index 5c8abff..1e2032f 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -1935,8 +1935,10 @@ bool CastPointerIntegralAP(InterpState &S, CodePtr OpPC, uint32_t BitWidth) { if (!CheckPointerToIntegralCast(S, OpPC, Ptr, BitWidth)) return false; - S.Stk.push<IntegralAP<false>>( - IntegralAP<false>::from(Ptr.getIntegerRepresentation(), BitWidth)); + auto Result = S.allocAP<IntegralAP<false>>(BitWidth); + Result.copy(APInt(BitWidth, Ptr.getIntegerRepresentation())); + + S.Stk.push<IntegralAP<false>>(Result); return true; } @@ -1946,8 +1948,10 @@ bool CastPointerIntegralAPS(InterpState &S, CodePtr OpPC, uint32_t BitWidth) { if (!CheckPointerToIntegralCast(S, OpPC, Ptr, BitWidth)) return false; - S.Stk.push<IntegralAP<true>>( - IntegralAP<true>::from(Ptr.getIntegerRepresentation(), BitWidth)); + auto Result = S.allocAP<IntegralAP<true>>(BitWidth); + Result.copy(APInt(BitWidth, Ptr.getIntegerRepresentation())); + + S.Stk.push<IntegralAP<true>>(Result); return true; } @@ -2053,6 +2057,100 @@ bool arePotentiallyOverlappingStringLiterals(const Pointer &LHS, return Shorter == Longer.take_front(Shorter.size()); } +static void copyPrimitiveMemory(InterpState &S, const Pointer &Ptr, + PrimType T) { + + if (T == PT_IntAPS) { + auto &Val = Ptr.deref<IntegralAP<true>>(); + if (!Val.singleWord()) { + uint64_t *NewMemory = new (S.P) uint64_t[Val.numWords()]; + Val.take(NewMemory); + } + } else if (T == PT_IntAP) { + auto &Val = Ptr.deref<IntegralAP<false>>(); + if (!Val.singleWord()) { + uint64_t *NewMemory = new (S.P) uint64_t[Val.numWords()]; + Val.take(NewMemory); + } + } else if (T == PT_Float) { + auto &Val = Ptr.deref<Floating>(); + if (!Val.singleWord()) { + uint64_t *NewMemory = new (S.P) uint64_t[Val.numWords()]; + Val.take(NewMemory); + } + } +} + +template <typename T> +static void copyPrimitiveMemory(InterpState &S, const Pointer &Ptr) { + assert(needsAlloc<T>()); + auto &Val = Ptr.deref<T>(); + if (!Val.singleWord()) { + uint64_t *NewMemory = new (S.P) uint64_t[Val.numWords()]; + Val.take(NewMemory); + } +} + +static void finishGlobalRecurse(InterpState &S, const Pointer &Ptr) { + if (const Record *R = Ptr.getRecord()) { + for (const Record::Field &Fi : R->fields()) { + if (Fi.Desc->isPrimitive()) { + TYPE_SWITCH_ALLOC(Fi.Desc->getPrimType(), { + copyPrimitiveMemory<T>(S, Ptr.atField(Fi.Offset)); + }); + copyPrimitiveMemory(S, Ptr.atField(Fi.Offset), Fi.Desc->getPrimType()); + } else + finishGlobalRecurse(S, Ptr.atField(Fi.Offset)); + } + return; + } + + if (const Descriptor *D = Ptr.getFieldDesc(); D && D->isArray()) { + unsigned NumElems = D->getNumElems(); + if (NumElems == 0) + return; + + if (D->isPrimitiveArray()) { + PrimType PT = D->getPrimType(); + if (!needsAlloc(PT)) + return; + assert(NumElems >= 1); + const Pointer EP = Ptr.atIndex(0); + bool AllSingleWord = true; + TYPE_SWITCH_ALLOC(PT, { + if (!EP.deref<T>().singleWord()) { + copyPrimitiveMemory<T>(S, EP); + AllSingleWord = false; + } + }); + if (AllSingleWord) + return; + for (unsigned I = 1; I != D->getNumElems(); ++I) { + const Pointer EP = Ptr.atIndex(I); + copyPrimitiveMemory(S, EP, PT); + } + } else { + assert(D->isCompositeArray()); + for (unsigned I = 0; I != D->getNumElems(); ++I) { + const Pointer EP = Ptr.atIndex(I).narrow(); + finishGlobalRecurse(S, EP); + } + } + } +} + +bool FinishInitGlobal(InterpState &S, CodePtr OpPC) { + const Pointer &Ptr = S.Stk.pop<Pointer>(); + + finishGlobalRecurse(S, Ptr); + if (Ptr.canBeInitialized()) { + Ptr.initialize(); + Ptr.activate(); + } + + return true; +} + // https://github.com/llvm/llvm-project/issues/102513 #if defined(_MSC_VER) && !defined(__clang__) && !defined(NDEBUG) #pragma optimize("", off) |