[CodeGen] Increase applicability of ffine-grained-bitfield-accesses for targets with limited native integer widths
As pointed out in PR45708, -ffine-grained-bitfield-accesses doesn't trigger in all cases you think it might for RISC-V. The logic in CGRecordLowering::accumulateBitFields checks OffsetInRecord is a legal integer according to the datalayout. RISC targets will typically only have the native width as a legal integer type so this check will fail for OffsetInRecord of 8 or 16 when you would expect the transformation is still worthwhile. This patch changes the logic to check for an OffsetInRecord of a at least 1 byte, that fits in a legal integer, and is a power of 2. We would prefer to query whether native load/store operations are available, but I don't believe that is possible. Differential Revision: https://reviews.llvm.org/D79155
This commit is contained in:
parent
f257c2138f
commit
3dcfd482cb
|
@ -406,15 +406,17 @@ CGRecordLowering::accumulateBitFields(RecordDecl::field_iterator Field,
|
|||
return;
|
||||
}
|
||||
|
||||
// Check if OffsetInRecord is better as a single field run. When OffsetInRecord
|
||||
// has legal integer width, and its bitfield offset is naturally aligned, it
|
||||
// is better to make the bitfield a separate storage component so as it can be
|
||||
// accessed directly with lower cost.
|
||||
// Check if OffsetInRecord (the size in bits of the current run) is better
|
||||
// as a single field run. When OffsetInRecord has legal integer width, and
|
||||
// its bitfield offset is naturally aligned, it is better to make the
|
||||
// bitfield a separate storage component so as it can be accessed directly
|
||||
// with lower cost.
|
||||
auto IsBetterAsSingleFieldRun = [&](uint64_t OffsetInRecord,
|
||||
uint64_t StartBitOffset) {
|
||||
if (!Types.getCodeGenOpts().FineGrainedBitfieldAccesses)
|
||||
return false;
|
||||
if (!DataLayout.isLegalInteger(OffsetInRecord))
|
||||
if (OffsetInRecord < 8 || !llvm::isPowerOf2_64(OffsetInRecord) ||
|
||||
!DataLayout.fitsInLegalInteger(OffsetInRecord))
|
||||
return false;
|
||||
// Make sure StartBitOffset is natually aligned if it is treated as an
|
||||
// IType integer.
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
// RUN: %clang_cc1 -triple x86_64-linux-gnu -ffine-grained-bitfield-accesses \
|
||||
// RUN: -emit-llvm -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple riscv64-linux-gnu -ffine-grained-bitfield-accesses \
|
||||
// RUN: -emit-llvm -o - %s | FileCheck %s
|
||||
|
||||
// Note: This test checks the X86-64 and RISC-V targets in order to explore
|
||||
// behaviour when i8/i16 are native integer widths (X86-64) and when they're
|
||||
// not (RISC-V).
|
||||
|
||||
struct S4 {
|
||||
unsigned long f1:28;
|
||||
unsigned long f2:4;
|
||||
|
|
Loading…
Reference in New Issue