Skip to content

Commit 865d544

Browse files
Applied code review changes
1 parent b0c5e46 commit 865d544

File tree

4 files changed

+53
-54
lines changed

4 files changed

+53
-54
lines changed

clang/include/clang/CIR/MissingFeatures.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ struct MissingFeatures {
219219
static bool peepholeProtection() { return false; }
220220
static bool instrumentation() { return false; }
221221
static bool cleanupAfterErrorDiags() { return false; }
222+
static bool nonFineGrainedBitfields() { return false; }
222223

223224
// Missing types
224225
static bool dataMemberType() { return false; }

clang/lib/CIR/CodeGen/CIRGenRecordLayout.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,9 @@ namespace clang::CIRGen {
4141
/// unsigned still_more_bits : 7;
4242
/// };
4343
///
44-
/// This will end up as the following cir.record. The first array is the
45-
/// bitfield, and the second is the padding out to a 4-byte alignment.
44+
/// This will end up as the following cir.record. The bitfield members are
45+
/// represented by two !u8i values, and the array provides padding to align the
46+
/// struct to a 4-byte alignment.
4647
///
4748
/// !rec_S = !cir.record<struct "S" padded {!s8i, !s8i, !s8i, !u8i, !u8i,
4849
/// !cir.array<!u8i x 3>}>
@@ -51,16 +52,16 @@ namespace clang::CIRGen {
5152
/// essentially like this:
5253
///
5354
/// #bfi_more_bits = #cir.bitfield_info<name = "more_bits", storage_type =
54-
/// !u16i, size = 4, offset = 3, is_signed = false>
55+
/// !u8i, size = 4, offset = 3, is_signed = false>
5556
///
5657
/// cir.func @store_field() {
5758
/// %0 = cir.alloca !rec_S, !cir.ptr<!rec_S>, ["s"] {alignment = 4 : i64}
5859
/// %1 = cir.const #cir.int<2> : !s32i
5960
/// %2 = cir.cast(integral, %1 : !s32i), !u32i
60-
/// %3 = cir.get_member %0[4] {name = "more_bits"} : !cir.ptr<!rec_S> ->
61-
/// !cir.ptr<!u16i>
61+
/// %3 = cir.get_member %0[3] {name = "more_bits"} : !cir.ptr<!rec_S> ->
62+
/// !cir.ptr<!u8i>
6263
/// %4 = cir.set_bitfield(#bfi_more_bits, %3 :
63-
/// !cir.ptr<!u16i>, %2 : !u32i) -> !u32i
64+
/// !cir.ptr<!u8i>, %2 : !u32i) -> !u32i
6465
/// cir.return
6566
/// }
6667
///
@@ -110,7 +111,7 @@ struct CIRGenBitFieldInfo {
110111
storageSize(storageSize), storageOffset(storageOffset) {}
111112

112113
void print(llvm::raw_ostream &os) const;
113-
void dump() const;
114+
LLVM_DUMP_METHOD void dump() const;
114115
};
115116

116117
/// This class handles record and union layout info while lowering AST types

clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -223,9 +223,9 @@ void CIRRecordLowering::setBitFieldInfo(const FieldDecl *fd,
223223

224224
if (info.size > info.storageSize)
225225
info.size = info.storageSize;
226-
// Reverse the bit offsets for big endian machines. Because we represent
227-
// a bitfield as a single large integer load, we can imagine the bits
228-
// counting from the most-significant-bit instead the
226+
// Reverse the bit offsets for big endian machines. Since bitfields are laid
227+
// out as packed bits within an integer-sized unit, we can imagine the bits
228+
// counting from the most-significant-bit instead of the
229229
// least-significant-bit.
230230
assert(!cir::MissingFeatures::isBigEndian());
231231

@@ -292,35 +292,25 @@ void CIRRecordLowering::fillOutputFields() {
292292

293293
void CIRRecordLowering::accumulateBitFields(
294294
RecordDecl::field_iterator field, RecordDecl::field_iterator fieldEnd) {
295-
// Run stores the first element of the current run of bitfields. FieldEnd is
296-
// used as a special value to note that we don't have a current run. A
295+
// 'run' stores the first element of the current run of bitfields. 'fieldEnd'
296+
// is used as a special value to note that we don't have a current run. A
297297
// bitfield run is a contiguous collection of bitfields that can be stored in
298298
// the same storage block. Zero-sized bitfields and bitfields that would
299299
// cross an alignment boundary break a run and start a new one.
300300
RecordDecl::field_iterator run = fieldEnd;
301-
// Tail is the offset of the first bit off the end of the current run. It's
301+
// 'tail' is the offset of the first bit off the end of the current run. It's
302302
// used to determine if the ASTRecordLayout is treating these two bitfields as
303-
// contiguous. StartBitOffset is offset of the beginning of the Run.
303+
// contiguous. 'startBitOffset' is offset of the beginning of the run.
304304
uint64_t startBitOffset, tail = 0;
305305
assert(!cir::MissingFeatures::isDiscreteBitFieldABI());
306306

307-
// Check if OffsetInRecord (the size in bits of the current run) is better
307+
// Check if 'offsetInRecord' (the size in bits of the current run) is better
308308
// as a single field run. When OffsetInRecord has legal integer width, and
309309
// its bitfield offset is naturally aligned, it is better to make the
310310
// bitfield a separate storage component so as it can be accessed directly
311311
// with lower cost.
312-
auto isBetterAsSingleFieldRun = [&](uint64_t offsetInRecord,
313-
uint64_t startBitOffset,
314-
uint64_t nextTail = 0) {
315-
if (!cirGenTypes.getCGModule().getCodeGenOpts().FineGrainedBitfieldAccesses)
316-
return false;
317-
cirGenTypes.getCGModule().errorNYI(field->getSourceRange(),
318-
"NYI FineGrainedBitfield");
319-
return true;
320-
};
312+
assert(!cir::MissingFeatures::nonFineGrainedBitfields());
321313

322-
// The start field is better as a single field run.
323-
bool startFieldAsSingleRun = false;
324314
for (;;) {
325315
// Check to see if we need to start a new run.
326316
if (run == fieldEnd) {
@@ -332,27 +322,34 @@ void CIRRecordLowering::accumulateBitFields(
332322
run = field;
333323
startBitOffset = getFieldBitOffset(*field);
334324
tail = startBitOffset + field->getBitWidthValue();
335-
startFieldAsSingleRun =
336-
isBetterAsSingleFieldRun(tail - startBitOffset, startBitOffset);
325+
assert(!cir::MissingFeatures::nonFineGrainedBitfields());
337326
}
338327
++field;
339328
continue;
340329
}
341330

342-
// If the start field of a new run is better as a single run, or if current
343-
// field (or consecutive fields) is better as a single run, or if current
344-
// field has zero width bitfield and either UseZeroLengthBitfieldAlignment
345-
// or UseBitFieldTypeAlignment is set to true, or if the offset of current
346-
// field is inconsistent with the offset of previous field plus its offset,
347-
// skip the block below and go ahead to emit the storage. Otherwise, try to
348-
// add bitfields to the run.
331+
// Decide whether to continue extending the current bitfield run.
332+
//
333+
// Skip the block below and go directly to emitting storage if any of the
334+
// following is true:
335+
// - 1. The first field in the run is better treated as its own run.
336+
// - 2. We have reached the end of the fields.
337+
// - 3. The current field (or set of fields) is better as its own run.
338+
// - 4. The current field is a zero-width bitfield or:
339+
// - Zero-length bitfield alignment is enabled, and
340+
// - Bitfield type alignment is enabled.
341+
// - 5. The current field's offset doesn't match the expected tail (i.e.,
342+
// layout isn't contiguous).
343+
//
344+
// If none of the above conditions are met, add the current field to the
345+
// current run.
349346
uint64_t nextTail = tail;
350347
if (field != fieldEnd)
351348
nextTail += field->getBitWidthValue();
352349

353-
if (!startFieldAsSingleRun && field != fieldEnd &&
354-
!isBetterAsSingleFieldRun(tail - startBitOffset, startBitOffset,
355-
nextTail) &&
350+
// TODO: add condition 1 and 3
351+
assert(!cir::MissingFeatures::nonFineGrainedBitfields());
352+
if (field != fieldEnd &&
356353
(!field->isZeroLengthBitField() ||
357354
(!astContext.getTargetInfo().useZeroLengthBitfieldAlignment() &&
358355
!astContext.getTargetInfo().useBitFieldTypeAlignment())) &&
@@ -373,7 +370,6 @@ void CIRRecordLowering::accumulateBitFields(
373370
members.push_back(MemberInfo(bitsToCharUnits(startBitOffset),
374371
MemberInfo::InfoKind::Field, nullptr, *run));
375372
run = fieldEnd;
376-
startFieldAsSingleRun = false;
377373
}
378374
}
379375

clang/test/CIR/CodeGen/bitfields.cpp

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,20 @@ struct A {
1212
unsigned still_more_bits : 7;
1313
};
1414

15+
// CIR-DAG: !rec_A = !cir.record<struct "A" padded {!s8i, !s8i, !s8i, !u8i, !u8i, !cir.array<!u8i x 3>}>
16+
// LLVM-DAG: %struct.A = type { i8, i8, i8, i8, i8, [3 x i8] }
17+
// OGCG-DAG: %struct.A = type <{ i8, i8, i8, i16, [3 x i8] }>
18+
1519
typedef struct {
1620
int a : 4;
1721
int b : 5;
1822
int c;
1923
} D;
2024

25+
// CIR-DAG: !rec_D = !cir.record<struct "D" {!u16i, !s32i}>
26+
// LLVM-DAG: %struct.D = type { i16, i32 }
27+
// OGCG-DAG: %struct.D = type { i16, i32 }
28+
2129
typedef struct {
2230
int a : 4;
2331
int b : 27;
@@ -27,11 +35,19 @@ typedef struct {
2735
unsigned f; // type other than int above, not a bitfield
2836
} S;
2937

38+
// CIR-DAG: !rec_S = !cir.record<struct "S" {!u32i, !cir.array<!u8i x 3>, !u16i, !u32i}>
39+
// LLVM-DAG: %struct.S = type { i32, [3 x i8], i16, i32 }
40+
// OGCG-DAG: %struct.S = type { i64, i16, i32 }
41+
3042
typedef struct {
3143
int a : 3; // one bitfield with size < 8
3244
unsigned b;
3345
} T;
3446

47+
// CIR-DAG: !rec_T = !cir.record<struct "T" {!u8i, !u32i}>
48+
// LLVM-DAG: %struct.T = type { i8, i32 }
49+
// OGCG-DAG: %struct.T = type { i8, i32 }
50+
3551
typedef struct {
3652
char a;
3753
char b;
@@ -51,24 +67,9 @@ typedef struct {
5167
// because (tail - startOffset) is 65 after 'l' field
5268
} U;
5369

54-
// CIR-DAG: !rec_D = !cir.record<struct "D" {!u16i, !s32i}>
55-
// CIR-DAG: !rec_T = !cir.record<struct "T" {!u8i, !u32i}>
5670
// CIR-DAG: !rec_U = !cir.record<struct "U" {!s8i, !s8i, !s8i, !cir.array<!u8i x 9>}>
57-
// CIR-DAG: !rec_A = !cir.record<struct "A" padded {!s8i, !s8i, !s8i, !u8i, !u8i, !cir.array<!u8i x 3>}>
58-
// CIR-DAG: !rec_S = !cir.record<struct "S" {!u32i, !cir.array<!u8i x 3>, !u16i, !u32i}>
59-
60-
61-
// LLVM-DAG: %struct.D = type { i16, i32 }
6271
// LLVM-DAG: %struct.U = type { i8, i8, i8, [9 x i8] }
63-
// LLVM-DAG: %struct.A = type { i8, i8, i8, i8, i8, [3 x i8] }
64-
// LLVM-DAG: %struct.S = type { i32, [3 x i8], i16, i32 }
65-
// LLVM-DAG: %struct.T = type { i8, i32 }
66-
67-
// OGCG-DAG: %struct.D = type { i16, i32 }
6872
// OGCG-DAG: %struct.U = type <{ i8, i8, i8, i8, i64 }>
69-
// OGCG-DAG: %struct.A = type <{ i8, i8, i8, i16, [3 x i8] }>
70-
// OGCG-DAG: %struct.S = type { i64, i16, i32 }
71-
// OGCG-DAG: %struct.T = type { i8, i32 }
7273

7374
void def() {
7475
A a;

0 commit comments

Comments
 (0)