Skip to content

Commit abadac7

Browse files
Applied code review changes
1 parent 0a215e1 commit abadac7

File tree

4 files changed

+52
-53
lines changed

4 files changed

+52
-53
lines changed

clang/include/clang/CIR/MissingFeatures.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ struct MissingFeatures {
203203
static bool writebacks() { return false; }
204204
static bool cleanupsToDeactivate() { return false; }
205205
static bool stackBase() { return false; }
206+
static bool nonFineGrainedBitfields() { return false; }
206207

207208
// Missing types
208209
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: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,8 @@ void CIRRecordLowering::setBitFieldInfo(const FieldDecl *fd,
210210

211211
if (info.size > info.storageSize)
212212
info.size = info.storageSize;
213-
// Reverse the bit offsets for big endian machines. Because we represent
214-
// a bitfield as a single large integer load, we can imagine the bits
213+
// Reverse the bit offsets for big endian machines. Since bitfields are laid
214+
// out as packed bits within an integer-sized unit, we can imagine the bits
215215
// counting from the most-significant-bit instead of the
216216
// least-significant-bit.
217217
assert(!cir::MissingFeatures::isBigEndian());
@@ -281,35 +281,25 @@ void CIRRecordLowering::fillOutputFields() {
281281

282282
void CIRRecordLowering::accumulateBitFields(
283283
RecordDecl::field_iterator field, RecordDecl::field_iterator fieldEnd) {
284-
// Run stores the first element of the current run of bitfields. FieldEnd is
285-
// used as a special value to note that we don't have a current run. A
284+
// 'run' stores the first element of the current run of bitfields. 'fieldEnd'
285+
// is used as a special value to note that we don't have a current run. A
286286
// bitfield run is a contiguous collection of bitfields that can be stored in
287287
// the same storage block. Zero-sized bitfields and bitfields that would
288288
// cross an alignment boundary break a run and start a new one.
289289
RecordDecl::field_iterator run = fieldEnd;
290-
// Tail is the offset of the first bit off the end of the current run. It's
290+
// 'tail' is the offset of the first bit off the end of the current run. It's
291291
// used to determine if the ASTRecordLayout is treating these two bitfields as
292-
// contiguous. StartBitOffset is offset of the beginning of the Run.
292+
// contiguous. 'startBitOffset' is offset of the beginning of the run.
293293
uint64_t startBitOffset, tail = 0;
294294
assert(!cir::MissingFeatures::isDiscreteBitFieldABI());
295295

296-
// Check if OffsetInRecord (the size in bits of the current run) is better
296+
// Check if 'offsetInRecord' (the size in bits of the current run) is better
297297
// as a single field run. When OffsetInRecord has legal integer width, and
298298
// its bitfield offset is naturally aligned, it is better to make the
299299
// bitfield a separate storage component so as it can be accessed directly
300300
// with lower cost.
301-
auto isBetterAsSingleFieldRun = [&](uint64_t offsetInRecord,
302-
uint64_t startBitOffset,
303-
uint64_t nextTail = 0) {
304-
if (!cirGenTypes.getCGModule().getCodeGenOpts().FineGrainedBitfieldAccesses)
305-
return false;
306-
cirGenTypes.getCGModule().errorNYI(field->getSourceRange(),
307-
"NYI FineGrainedBitfield");
308-
return true;
309-
};
301+
assert(!cir::MissingFeatures::nonFineGrainedBitfields());
310302

311-
// The start field is better as a single field run.
312-
bool startFieldAsSingleRun = false;
313303
for (;;) {
314304
// Check to see if we need to start a new run.
315305
if (run == fieldEnd) {
@@ -321,27 +311,34 @@ void CIRRecordLowering::accumulateBitFields(
321311
run = field;
322312
startBitOffset = getFieldBitOffset(*field);
323313
tail = startBitOffset + field->getBitWidthValue();
324-
startFieldAsSingleRun =
325-
isBetterAsSingleFieldRun(tail - startBitOffset, startBitOffset);
314+
assert(!cir::MissingFeatures::nonFineGrainedBitfields());
326315
}
327316
++field;
328317
continue;
329318
}
330319

331-
// If the start field of a new run is better as a single run, or if current
332-
// field (or consecutive fields) is better as a single run, or if current
333-
// field has zero width bitfield and either UseZeroLengthBitfieldAlignment
334-
// or UseBitFieldTypeAlignment is set to true, or if the offset of current
335-
// field is inconsistent with the offset of previous field plus its offset,
336-
// skip the block below and go ahead to emit the storage. Otherwise, try to
337-
// add bitfields to the run.
320+
// Decide whether to continue extending the current bitfield run.
321+
//
322+
// Skip the block below and go directly to emitting storage if any of the
323+
// following is true:
324+
// - 1. The first field in the run is better treated as its own run.
325+
// - 2. We have reached the end of the fields.
326+
// - 3. The current field (or set of fields) is better as its own run.
327+
// - 4. The current field is a zero-width bitfield or:
328+
// - Zero-length bitfield alignment is enabled, and
329+
// - Bitfield type alignment is enabled.
330+
// - 5. The current field's offset doesn't match the expected tail (i.e.,
331+
// layout isn't contiguous).
332+
//
333+
// If none of the above conditions are met, add the current field to the
334+
// current run.
338335
uint64_t nextTail = tail;
339336
if (field != fieldEnd)
340337
nextTail += field->getBitWidthValue();
341338

342-
if (!startFieldAsSingleRun && field != fieldEnd &&
343-
!isBetterAsSingleFieldRun(tail - startBitOffset, startBitOffset,
344-
nextTail) &&
339+
// TODO: add condition 1 and 3
340+
assert(!cir::MissingFeatures::nonFineGrainedBitfields());
341+
if (field != fieldEnd &&
345342
(!field->isZeroLengthBitField() ||
346343
(!astContext.getTargetInfo().useZeroLengthBitfieldAlignment() &&
347344
!astContext.getTargetInfo().useBitFieldTypeAlignment())) &&
@@ -362,7 +359,6 @@ void CIRRecordLowering::accumulateBitFields(
362359
members.push_back(MemberInfo(bitsToCharUnits(startBitOffset),
363360
MemberInfo::InfoKind::Field, nullptr, *run));
364361
run = fieldEnd;
365-
startFieldAsSingleRun = false;
366362
}
367363
}
368364

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)