Skip to content

Commit 773a6a9

Browse files
committed
Revert "[clang][bytecode] Allocate InitMaps via Program/InterpState allocators (#170272)"
This reverts commit 8fe38c4. This breaks the clang-armv7-2stage build bot: https://lab.llvm.org/buildbot/#/builders/79/builds/2531
1 parent 0df8306 commit 773a6a9

File tree

12 files changed

+188
-185
lines changed

12 files changed

+188
-185
lines changed

clang/lib/AST/ByteCode/Descriptor.cpp

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,10 @@ static void dtorTy(Block *, std::byte *Ptr, const Descriptor *) {
5252
template <typename T>
5353
static void ctorArrayTy(Block *, std::byte *Ptr, bool, bool, bool, bool, bool,
5454
const Descriptor *D) {
55+
new (Ptr) InitMapPtr(std::nullopt);
56+
5557
if constexpr (needsCtor<T>()) {
56-
Ptr += sizeof(InitMap *);
58+
Ptr += sizeof(InitMapPtr);
5759
for (unsigned I = 0, NE = D->getNumElems(); I < NE; ++I) {
5860
new (&reinterpret_cast<T *>(Ptr)[I]) T();
5961
}
@@ -62,8 +64,13 @@ static void ctorArrayTy(Block *, std::byte *Ptr, bool, bool, bool, bool, bool,
6264

6365
template <typename T>
6466
static void dtorArrayTy(Block *, std::byte *Ptr, const Descriptor *D) {
67+
InitMapPtr &IMP = *reinterpret_cast<InitMapPtr *>(Ptr);
68+
69+
if (IMP)
70+
IMP = std::nullopt;
71+
6572
if constexpr (needsCtor<T>()) {
66-
Ptr += sizeof(InitMap *);
73+
Ptr += sizeof(InitMapPtr);
6774
for (unsigned I = 0, NE = D->getNumElems(); I < NE; ++I) {
6875
reinterpret_cast<T *>(Ptr)[I].~T();
6976
}
@@ -232,6 +239,12 @@ static bool needsRecordDtor(const Record *R) {
232239

233240
static BlockCtorFn getCtorPrim(PrimType T) {
234241
switch (T) {
242+
case PT_Float:
243+
return ctorTy<PrimConv<PT_Float>::T>;
244+
case PT_IntAP:
245+
return ctorTy<PrimConv<PT_IntAP>::T>;
246+
case PT_IntAPS:
247+
return ctorTy<PrimConv<PT_IntAPS>::T>;
235248
case PT_Ptr:
236249
return ctorTy<PrimConv<PT_Ptr>::T>;
237250
case PT_MemberPtr:
@@ -244,6 +257,12 @@ static BlockCtorFn getCtorPrim(PrimType T) {
244257

245258
static BlockDtorFn getDtorPrim(PrimType T) {
246259
switch (T) {
260+
case PT_Float:
261+
return dtorTy<PrimConv<PT_Float>::T>;
262+
case PT_IntAP:
263+
return dtorTy<PrimConv<PT_IntAP>::T>;
264+
case PT_IntAPS:
265+
return dtorTy<PrimConv<PT_IntAPS>::T>;
247266
case PT_Ptr:
248267
return dtorTy<PrimConv<PT_Ptr>::T>;
249268
case PT_MemberPtr:
@@ -254,16 +273,14 @@ static BlockDtorFn getDtorPrim(PrimType T) {
254273
llvm_unreachable("Unhandled PrimType");
255274
}
256275

257-
static BlockDtorFn getDtorArrayPrim(PrimType T) {
258-
switch (T) {
259-
case PT_Ptr:
260-
return dtorArrayTy<PrimConv<PT_Ptr>::T>;
261-
case PT_MemberPtr:
262-
return dtorArrayTy<PrimConv<PT_MemberPtr>::T>;
263-
default:
264-
return nullptr;
265-
}
266-
llvm_unreachable("Unhandled PrimType");
276+
static BlockCtorFn getCtorArrayPrim(PrimType Type) {
277+
TYPE_SWITCH(Type, return ctorArrayTy<T>);
278+
llvm_unreachable("unknown Expr");
279+
}
280+
281+
static BlockDtorFn getDtorArrayPrim(PrimType Type) {
282+
TYPE_SWITCH(Type, return dtorArrayTy<T>);
283+
llvm_unreachable("unknown Expr");
267284
}
268285

269286
/// Primitives.
@@ -285,9 +302,10 @@ Descriptor::Descriptor(const DeclTy &D, PrimType Type, MetadataSize MD,
285302
bool IsMutable)
286303
: Source(D), ElemSize(primSize(Type)), Size(ElemSize * NumElems),
287304
MDSize(MD.value_or(0)),
288-
AllocSize(align(MDSize) + align(Size) + sizeof(InitMap *)), PrimT(Type),
305+
AllocSize(align(MDSize) + align(Size) + sizeof(InitMapPtr)), PrimT(Type),
289306
IsConst(IsConst), IsMutable(IsMutable), IsTemporary(IsTemporary),
290-
IsArray(true), DtorFn(getDtorArrayPrim(Type)) {
307+
IsArray(true), CtorFn(getCtorArrayPrim(Type)),
308+
DtorFn(getDtorArrayPrim(Type)) {
291309
assert(Source && "Missing source");
292310
assert(NumElems <= (MaxArrayElemBytes / ElemSize));
293311
}
@@ -297,9 +315,10 @@ Descriptor::Descriptor(const DeclTy &D, PrimType Type, MetadataSize MD,
297315
bool IsTemporary, bool IsConst, UnknownSize)
298316
: Source(D), ElemSize(primSize(Type)), Size(UnknownSizeMark),
299317
MDSize(MD.value_or(0)),
300-
AllocSize(MDSize + sizeof(InitMap *) + alignof(void *)), PrimT(Type),
318+
AllocSize(MDSize + sizeof(InitMapPtr) + alignof(void *)), PrimT(Type),
301319
IsConst(IsConst), IsMutable(false), IsTemporary(IsTemporary),
302-
IsArray(true), DtorFn(getDtorArrayPrim(Type)) {
320+
IsArray(true), CtorFn(getCtorArrayPrim(Type)),
321+
DtorFn(getDtorArrayPrim(Type)) {
303322
assert(Source && "Missing source");
304323
}
305324

@@ -449,16 +468,15 @@ bool Descriptor::hasTrivialDtor() const {
449468

450469
bool Descriptor::isUnion() const { return isRecord() && ElemRecord->isUnion(); }
451470

452-
InitMap::InitMap(unsigned N) : UninitFields(N) {
453-
std::memset(data(), 0, numFields(N) * sizeof(T));
454-
}
471+
InitMap::InitMap(unsigned N)
472+
: UninitFields(N), Data(std::make_unique<T[]>(numFields(N))) {}
455473

456474
bool InitMap::initializeElement(unsigned I) {
457475
unsigned Bucket = I / PER_FIELD;
458476
T Mask = T(1) << (I % PER_FIELD);
459477
if (!(data()[Bucket] & Mask)) {
460478
data()[Bucket] |= Mask;
461-
--UninitFields;
479+
UninitFields -= 1;
462480
}
463481
return UninitFields == 0;
464482
}

clang/lib/AST/ByteCode/Descriptor.h

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
#include "PrimType.h"
1717
#include "clang/AST/Decl.h"
1818
#include "clang/AST/Expr.h"
19-
#include <limits>
2019

2120
namespace clang {
2221
namespace interp {
@@ -28,6 +27,7 @@ struct Descriptor;
2827
enum PrimType : uint8_t;
2928

3029
using DeclTy = llvm::PointerUnion<const Decl *, const Expr *>;
30+
using InitMapPtr = std::optional<std::pair<bool, std::shared_ptr<InitMap>>>;
3131

3232
/// Invoked whenever a block is created. The constructor method fills in the
3333
/// inline descriptors of all fields and array elements. It also initializes
@@ -146,7 +146,7 @@ struct Descriptor final {
146146

147147
/// Maximum number of bytes to be used for array elements.
148148
static constexpr unsigned MaxArrayElemBytes =
149-
std::numeric_limits<decltype(AllocSize)>::max() - sizeof(InitMap *) -
149+
std::numeric_limits<decltype(AllocSize)>::max() - sizeof(InitMapPtr) -
150150
align(std::max(*InlineDescMD, *GlobalMD));
151151

152152
/// Pointer to the record, if block contains records.
@@ -278,7 +278,7 @@ struct Descriptor final {
278278
};
279279

280280
/// Bitfield tracking the initialisation status of elements of primitive arrays.
281-
struct alignas(alignof(uint64_t)) InitMap final {
281+
struct InitMap final {
282282
private:
283283
/// Type packing bits.
284284
using T = uint64_t;
@@ -289,33 +289,12 @@ struct alignas(alignof(uint64_t)) InitMap final {
289289
/// Initializes the map with no fields set.
290290
explicit InitMap(unsigned N);
291291

292-
/// Checks if all elements have been initialized.
293-
static bool allInitialized(const InitMap *IM) {
294-
return reinterpret_cast<uintptr_t>(IM) ==
295-
std::numeric_limits<uintptr_t>::max();
296-
}
297-
298-
/// Marks all elements as initialized.
299-
static void markAllInitialized(InitMap *&IMPtr) {
300-
std::memset(&IMPtr, static_cast<int>(std::numeric_limits<uintptr_t>::max()),
301-
sizeof(void *));
302-
}
303-
304-
/// Returns the number of bytes needed to allocate the InitMap for
305-
/// \param N elements.
306-
static unsigned allocBytes(unsigned N) {
307-
return align(sizeof(InitMap)) + (numFields(N) * sizeof(T));
308-
}
309-
310292
private:
311293
friend class Pointer;
312294

313295
/// Returns a pointer to storage.
314-
T *data() {
315-
return reinterpret_cast<T *>(reinterpret_cast<std::byte *>(this) +
316-
align(sizeof(InitMap)));
317-
}
318-
const T *data() const { return const_cast<InitMap *>(this)->data(); }
296+
T *data() { return Data.get(); }
297+
const T *data() const { return Data.get(); }
319298

320299
/// Initializes an element. Returns true when object if fully initialized.
321300
bool initializeElement(unsigned I);
@@ -328,6 +307,7 @@ struct alignas(alignof(uint64_t)) InitMap final {
328307
}
329308
/// Number of fields not initialized.
330309
unsigned UninitFields;
310+
std::unique_ptr<T[]> Data;
331311
};
332312

333313
} // namespace interp

clang/lib/AST/ByteCode/Disasm.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ LLVM_DUMP_METHOD void Descriptor::dumpFull(unsigned Offset,
455455
OS.indent(Spaces) << "Elements: " << getNumElems() << '\n';
456456
OS.indent(Spaces) << "Element type: " << primTypeToString(getPrimType())
457457
<< '\n';
458-
unsigned FO = Offset + sizeof(InitMap *);
458+
unsigned FO = Offset + sizeof(InitMapPtr);
459459
for (unsigned I = 0; I != getNumElems(); ++I) {
460460
OS.indent(Spaces) << "Element " << I << " offset: " << FO << '\n';
461461
FO += getElemSize();

clang/lib/AST/ByteCode/EvaluationResult.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,12 @@ static bool CheckArrayInitialized(InterpState &S, SourceLocation Loc,
5454
} else {
5555
// Primitive arrays.
5656
if (S.getContext().canClassify(ElemType)) {
57-
if (BasePtr.allElementsInitialized())
57+
if (BasePtr.allElementsInitialized()) {
5858
return true;
59-
60-
DiagnoseUninitializedSubobject(S, Loc, BasePtr.getField());
61-
return false;
59+
} else {
60+
DiagnoseUninitializedSubobject(S, Loc, BasePtr.getField());
61+
return false;
62+
}
6263
}
6364

6465
for (size_t I = 0; I != NumElems; ++I) {

clang/lib/AST/ByteCode/Interp.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2318,7 +2318,7 @@ bool FinishInitGlobal(InterpState &S, CodePtr OpPC) {
23182318

23192319
finishGlobalRecurse(S, Ptr);
23202320
if (Ptr.canBeInitialized()) {
2321-
Ptr.initialize(S);
2321+
Ptr.initialize();
23222322
Ptr.activate();
23232323
}
23242324

0 commit comments

Comments
 (0)