@@ -78,7 +78,7 @@ StructLayout::StructLayout(IRGenModule &IGM,
78
78
} else {
79
79
MinimumAlign = builder.getAlignment ();
80
80
MinimumSize = builder.getSize ();
81
- SpareBits = std::move ( builder.getSpareBits () );
81
+ SpareBits = builder.getSpareBits ();
82
82
IsFixedLayout = builder.isFixedLayout ();
83
83
IsKnownPOD = builder.isPOD ();
84
84
IsKnownBitwiseTakable = builder.isBitwiseTakable ();
@@ -263,9 +263,11 @@ void StructLayoutBuilder::addFixedSizeElement(ElementLayout &elt) {
263
263
if (isFixedLayout ()) {
264
264
auto paddingTy = llvm::ArrayType::get (IGM.Int8Ty , paddingRequired);
265
265
StructFields.push_back (paddingTy);
266
-
266
+
267
267
// The padding can be used as spare bits by enum layout.
268
- CurSpareBits.appendSetBits (Size (paddingRequired).getValueInBits ());
268
+ auto numBits = Size (paddingRequired).getValueInBits ();
269
+ auto mask = llvm::APInt::getAllOnesValue (numBits);
270
+ CurSpareBits.push_back (SpareBitVector::fromAPInt (mask));
269
271
}
270
272
}
271
273
@@ -318,15 +320,15 @@ void StructLayoutBuilder::addElementAtFixedOffset(ElementLayout &elt) {
318
320
StructFields.push_back (elt.getType ().getStorageType ());
319
321
320
322
// Carry over the spare bits from the element.
321
- CurSpareBits.append (eltTI.getSpareBits ());
323
+ CurSpareBits.push_back (eltTI.getSpareBits ());
322
324
}
323
325
324
326
// / Add an element at a non-fixed offset to the aggregate.
325
327
void StructLayoutBuilder::addElementAtNonFixedOffset (ElementLayout &elt) {
326
328
assert (!isFixedLayout ());
327
329
elt.completeNonFixed (elt.getType ().isPOD (ResilienceExpansion::Maximal),
328
330
NextNonFixedOffsetIndex);
329
- CurSpareBits. clear ();
331
+ CurSpareBits = SmallVector<SpareBitVector, 8 > (); // clear spare bits
330
332
}
331
333
332
334
// / Add a non-fixed-size element to the aggregate at offset zero.
@@ -335,7 +337,7 @@ void StructLayoutBuilder::addNonFixedSizeElementAtOffsetZero(ElementLayout &elt)
335
337
assert (!isa<FixedTypeInfo>(elt.getType ()));
336
338
assert (CurSize.isZero ());
337
339
elt.completeInitialNonFixedSize (elt.getType ().isPOD (ResilienceExpansion::Maximal));
338
- CurSpareBits. clear ();
340
+ CurSpareBits = SmallVector<SpareBitVector, 8 > (); // clear spare bits
339
341
}
340
342
341
343
// / Produce the current fields as an anonymous structure.
@@ -358,3 +360,27 @@ void StructLayoutBuilder::setAsBodyOfStruct(llvm::StructType *type) const {
358
360
== CurSize.getValue ())
359
361
&& " LLVM size of fixed struct type does not match StructLayout size" );
360
362
}
363
+
364
+ // / Return the spare bit mask of the structure built so far.
365
+ SpareBitVector StructLayoutBuilder::getSpareBits () const {
366
+ // Calculate the size up front to reduce possible allocations.
367
+ unsigned numBits = 0 ;
368
+ for (auto &v : CurSpareBits) {
369
+ numBits += v.size ();
370
+ }
371
+ if (numBits == 0 ) {
372
+ return SpareBitVector ();
373
+ }
374
+ // Assemble the spare bit mask.
375
+ auto mask = llvm::APInt::getNullValue (numBits);
376
+ unsigned offset = 0 ;
377
+ for (auto &v : CurSpareBits) {
378
+ if (v.size () == 0 ) {
379
+ continue ;
380
+ }
381
+ mask.insertBits (v.asAPInt (), offset);
382
+ offset += v.size ();
383
+ }
384
+ assert (offset == numBits);
385
+ return SpareBitVector::fromAPInt (std::move (mask));
386
+ }
0 commit comments